"use client" import { $fetch } from "@lib/api" import { Button } from "@repo/ui/components/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@repo/ui/components/dialog" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@repo/ui/components/dropdown-menu" import { Input } from "@repo/ui/components/input" import { Label } from "@repo/ui/components/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@repo/ui/components/select" import { Skeleton } from "@repo/ui/components/skeleton" import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" import { FolderIcon, Loader2, MoreVertical, Plus, Trash2 } from "lucide-react" import { AnimatePresence, motion } from "motion/react" import { useState } from "react" import { toast } from "sonner" import { useProject } from "@/stores" // Projects View Component export function ProjectsView() { const queryClient = useQueryClient() const { selectedProject, setSelectedProject } = useProject() const [showCreateDialog, setShowCreateDialog] = useState(false) const [projectName, setProjectName] = useState("") const [deleteDialog, setDeleteDialog] = useState<{ open: boolean project: null | { id: string; name: string; containerTag: string } action: "move" | "delete" targetProjectId: string }>({ open: false, project: null, action: "move", targetProjectId: "", }) const [expDialog, setExpDialog] = useState<{ open: boolean projectId: string }>({ open: false, projectId: "", }) // Fetch projects const { data: projects = [], isLoading, // error, } = useQuery({ queryKey: ["projects"], queryFn: async () => { const response = await $fetch("@get/projects") if (response.error) { throw new Error(response.error?.message || "Failed to load projects") } return response.data?.projects || [] }, staleTime: 30 * 1000, }) // Create project mutation const createProjectMutation = useMutation({ mutationFn: async (name: string) => { const response = await $fetch("@post/projects", { body: { name }, }) if (response.error) { throw new Error(response.error?.message || "Failed to create project") } return response.data }, onSuccess: () => { toast.success("Project created successfully!") setShowCreateDialog(false) setProjectName("") queryClient.invalidateQueries({ queryKey: ["projects"] }) }, onError: (error) => { toast.error("Failed to create project", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) // Delete project mutation const deleteProjectMutation = useMutation({ mutationFn: async ({ projectId, action, targetProjectId, }: { projectId: string action: "move" | "delete" targetProjectId?: string }) => { const response = await $fetch(`@delete/projects/${projectId}`, { body: { action, targetProjectId }, }) if (response.error) { throw new Error(response.error?.message || "Failed to delete project") } return response.data }, onSuccess: () => { toast.success("Project deleted successfully") setDeleteDialog({ open: false, project: null, action: "move", targetProjectId: "", }) queryClient.invalidateQueries({ queryKey: ["projects"] }) // If we deleted the selected project, switch to default if (deleteDialog.project?.containerTag === selectedProject) { setSelectedProject("sm_project_default") } }, onError: (error) => { toast.error("Failed to delete project", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) // Enable experimental mode mutation const enableExperimentalMutation = useMutation({ mutationFn: async (projectId: string) => { const response = await $fetch( `@post/projects/${projectId}/enable-experimental`, ) if (response.error) { throw new Error( response.error?.message || "Failed to enable experimental mode", ) } return response.data }, onSuccess: () => { toast.success("Experimental mode enabled for project") queryClient.invalidateQueries({ queryKey: ["projects"] }) setExpDialog({ open: false, projectId: "" }) }, onError: (error) => { toast.error("Failed to enable experimental mode", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) // Handle project selection const handleProjectSelect = (containerTag: string) => { setSelectedProject(containerTag) toast.success("Project switched successfully") } return (

Organize your memories into separate projects

Current project:

{isLoading ? (
{[...Array(2)].map((_, i) => ( ))}
) : projects.length === 0 ? (

No projects yet

) : ( {/* Default project */} handleProjectSelect("sm_project_default")} >

Default Project

Your default memory storage

{selectedProject === "sm_project_default" && (
)} {/* User projects */} {projects .filter((p) => p.containerTag !== "sm_project_default") .map((project, index) => ( handleProjectSelect(project.containerTag)} transition={{ delay: (index + 1) * 0.05 }} >

{project.name}

Created{" "} {new Date(project.createdAt).toLocaleDateString()}

{selectedProject === project.containerTag && (
)} {/* Show experimental toggle only if NOT experimental and NOT default project */} {!project.isExperimental && project.containerTag !== "sm_project_default" && ( { e.stopPropagation() setExpDialog({ open: true, projectId: project.id, }) }} >
Enable Experimental Mode )} {project.isExperimental && (
Experimental Mode Active )} { e.stopPropagation() setDeleteDialog({ open: true, project: { id: project.id, name: project.name, containerTag: project.containerTag, }, action: "move", targetProjectId: "", }) }} > Delete Project
))} )} {/* Create Project Dialog */} {showCreateDialog && ( Create New Project Give your project a unique name
setProjectName(e.target.value)} placeholder="My Awesome Project" value={projectName} />

This will help you organize your memories

)}
{/* Delete Project Dialog */} {deleteDialog.open && deleteDialog.project && ( setDeleteDialog((prev) => ({ ...prev, open })) } open={deleteDialog.open} > Delete Project Are you sure you want to delete "{deleteDialog.project.name} "? Choose what to do with the documents in this project.
setDeleteDialog((prev) => ({ ...prev, action: "move", })) } type="radio" />
{deleteDialog.action === "move" && ( )}
setDeleteDialog((prev) => ({ ...prev, action: "delete", })) } type="radio" />
{deleteDialog.action === "delete" && ( ⚠️ This action cannot be undone. All documents will be permanently deleted. )}
)}
{/* Experimental Mode Confirmation Dialog */} {expDialog.open && ( setExpDialog({ ...expDialog, open })} open={expDialog.open} > Enable Experimental Mode? Experimental mode enables beta features and advanced memory relationships for this project.

Warning: {" "} This action is{" "} irreversible . Once enabled, you cannot return to regular mode for this project.
)}
) }