"use client" import { useState, useMemo, useEffect } from "react" import { dmSans125ClassName, dmSansClassName } from "@/lib/fonts" import { Dialog, DialogContent } from "@repo/ui/components/dialog" import { cn } from "@lib/utils" import * as DialogPrimitive from "@radix-ui/react-dialog" import { XIcon, Search, Check } from "lucide-react" import { Button } from "@ui/components/button" import { DEFAULT_PROJECT_ID } from "@lib/constants" import type { ContainerTagListType } from "@lib/types" import { compareSpacesUserFirst, spaceSelectorDisplayName, } from "@/lib/ingest-auto-space" interface SelectSpacesModalProps { isOpen: boolean onClose: () => void selectedProjects: string[] onApply: (selected: string[]) => void projects: ContainerTagListType[] singleSelect?: boolean } export function SelectSpacesModal({ isOpen, onClose, selectedProjects, onApply, projects, singleSelect = false, }: SelectSpacesModalProps) { const [searchQuery, setSearchQuery] = useState("") const [localSelection, setLocalSelection] = useState(selectedProjects) useEffect(() => { if (isOpen) { setLocalSelection(selectedProjects) } }, [isOpen, selectedProjects]) const handleOpenChange = (open: boolean) => { if (!open) { onClose() setSearchQuery("") setLocalSelection(selectedProjects) } } const handleToggle = (containerTag: string) => { if (singleSelect) { setLocalSelection([containerTag]) return } setLocalSelection((prev) => { if (prev.includes(containerTag)) { return prev.filter((tag) => tag !== containerTag) } return [...prev, containerTag] }) } const handleApply = () => { onApply(localSelection) setSearchQuery("") } const handleCancel = () => { onClose() setSearchQuery("") setLocalSelection(selectedProjects) } const filteredProjects = useMemo(() => { const defaultSpace = { id: "default", name: "My Space", emoji: "📁", containerTag: DEFAULT_PROJECT_ID, isExperimental: false, isNova: false, createdAt: "", updatedAt: "", } as ContainerTagListType const rest = projects .filter((p) => p.containerTag !== DEFAULT_PROJECT_ID) .sort(compareSpacesUserFirst) const allSpaces = [defaultSpace, ...rest] if (!searchQuery.trim()) { return allSpaces } const query = searchQuery.trim().toLowerCase() return allSpaces.filter( (p) => p.containerTag.toLowerCase().includes(query) || (p.name ?? "").toLowerCase().includes(query), ) }, [projects, searchQuery]) return (

Select Space{!singleSelect && "s"}

{singleSelect ? "Choose a space for your memory" : "Choose one or more spaces to filter your memories"}

Close
setSearchQuery(e.target.value)} placeholder="Search spaces..." className={cn( "w-full bg-[#14161A] border border-[rgba(82,89,102,0.2)] pl-10 pr-4 py-3 rounded-[12px] text-[#fafafa] text-[14px] placeholder:text-[#737373] focus:outline-none focus:ring-1 focus:ring-[rgba(115,115,115,0.3)]", dmSansClassName(), )} style={{ boxShadow: "0px 1px 2px 0px rgba(0,43,87,0.1), inset 0px 0px 0px 1px rgba(43,49,67,0.08), inset 0px 1px 1px 0px rgba(0,0,0,0.08), inset 0px 2px 4px 0px rgba(0,0,0,0.02)", }} autoFocus />
{filteredProjects.length === 0 ? (

No spaces found

) : ( filteredProjects.map((project) => { const isSelected = localSelection.includes(project.containerTag) return ( ) }) )}

{singleSelect ? localSelection.length === 0 ? "No space selected" : "1 space selected" : localSelection.length === 0 ? "No spaces selected (showing all)" : `${localSelection.length} space${localSelection.length > 1 ? "s" : ""} selected`}

) }