"use client"; import * as React from "react"; import * as Popover from "@radix-ui/react-popover"; import { Check, Search } from "lucide-react"; import { cn } from "@/lib/utils"; import { Avatar, AvatarFallback, AvatarImage, } from "@/components/ui/avatar"; import { Input } from "@/components/ui/input"; export interface WorkspaceUser { id: string; name: string; avatarUrl?: string | null; } /** Default mock list; override via `users` prop when wiring real data */ export const WORKSPACE_USERS: WorkspaceUser[] = [ { id: "u1", name: "Alice", avatarUrl: null }, { id: "u2", name: "Bob", avatarUrl: null }, { id: "u3", name: "Charlie", avatarUrl: null }, { id: "u4", name: "Diana", avatarUrl: null }, ]; function initials(name: string) { return name .split(/\s+/) .map((p) => p[0]) .join("") .slice(0, 2) .toUpperCase(); } export interface AssigneePickerProps { open: boolean; onOpenChange: (open: boolean) => void; assignedIds: string[]; onToggle: (userId: string) => void; users?: WorkspaceUser[]; children: React.ReactNode; side?: "top" | "right" | "bottom" | "left"; align?: "start" | "center" | "end"; } export function AssigneePicker({ open, onOpenChange, assignedIds, onToggle, users = WORKSPACE_USERS, children, side = "bottom", align = "start", }: AssigneePickerProps) { const [q, setQ] = React.useState(""); const filtered = React.useMemo(() => { const s = q.trim().toLowerCase(); if (!s) return users; return users.filter((u) => u.name.toLowerCase().includes(s)); }, [q, users]); React.useEffect(() => { if (!open) setQ(""); }, [open]); return ( {children}
setQ(e.target.value)} placeholder="Search people…" className="h-8 border-0 bg-muted/50 pl-8 text-xs focus-visible:ring-1" />
{filtered.length === 0 ? (

No matches

) : ( filtered.map((user) => { const assigned = assignedIds.includes(user.id); return ( ); }) )}
); }