"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:
No projects yet
Default Project
Your default memory storage
{project.name}
Created{" "} {new Date(project.createdAt).toLocaleDateString()}