"use client"; import Link from "next/link"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { ChevronLeft, Plus, Calendar, MoreHorizontal, Video, Loader2, X, Trash2, Search, } from "lucide-react"; import { TProject } from "@/types/project"; import Image from "next/image"; import { DropdownMenu, DropdownMenuItem, DropdownMenuContent, DropdownMenuTrigger, DropdownMenuSeparator, } from "@/components/ui/dropdown-menu"; import { useProjectStore } from "@/stores/project-store"; import { useRouter } from "next/navigation"; import { DeleteProjectDialog } from "@/components/delete-project-dialog"; import { RenameProjectDialog } from "@/components/rename-project-dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; export default function ProjectsPage() { const { createNewProject, savedProjects, isLoading, isInitialized, deleteProject, } = useProjectStore(); const router = useRouter(); const [isSelectionMode, setIsSelectionMode] = useState(false); const [selectedProjects, setSelectedProjects] = useState>( new Set() ); const [isBulkDeleteDialogOpen, setIsBulkDeleteDialogOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [sortOption, setSortOption] = useState("createdAt-desc"); const handleCreateProject = async () => { const projectId = await createNewProject("New Project"); console.log("projectId", projectId); router.push(`/editor/${projectId}`); }; const handleSelectProject = (projectId: string, checked: boolean) => { const newSelected = new Set(selectedProjects); if (checked) { newSelected.add(projectId); } else { newSelected.delete(projectId); } setSelectedProjects(newSelected); }; const handleSelectAll = (checked: boolean) => { if (checked) { setSelectedProjects(new Set(filteredProjects.map((p) => p.id))); } else { setSelectedProjects(new Set()); } }; const handleCancelSelection = () => { setIsSelectionMode(false); setSelectedProjects(new Set()); }; const handleBulkDelete = async () => { await Promise.all( Array.from(selectedProjects).map((projectId) => deleteProject(projectId)) ); setSelectedProjects(new Set()); setIsSelectionMode(false); setIsBulkDeleteDialogOpen(false); }; const filteredProjects = savedProjects.filter((project) => project.name.toLowerCase().includes(searchQuery.toLowerCase()) ); const sortedProjects = [...filteredProjects].sort((a, b) => { const [key, order] = sortOption.split("-"); const aValue = a[key as keyof TProject]; const bValue = b[key as keyof TProject]; if (aValue === undefined || bValue === undefined) return 0; if (order === "asc") { if (aValue < bValue) return -1; if (aValue > bValue) return 1; return 0; } else { if (aValue > bValue) return -1; if (aValue < bValue) return 1; return 0; } }); const allSelected = sortedProjects.length > 0 && selectedProjects.size === sortedProjects.length; const someSelected = selectedProjects.size > 0 && selectedProjects.size < sortedProjects.length; return (
Back
{isSelectionMode ? (
{selectedProjects.size > 0 && ( )}
) : ( )}

Your Projects

{savedProjects.length}{" "} {savedProjects.length === 1 ? "project" : "projects"} {isSelectionMode && selectedProjects.size > 0 && ( • {selectedProjects.size} selected )}

{isSelectionMode ? (
{selectedProjects.size > 0 && ( )}
) : (
)}
setSearchQuery(e.target.value)} />
{isSelectionMode && sortedProjects.length > 0 && (
handleSelectAll(!!value)} /> {allSelected ? "Deselect All" : "Select All"} ({selectedProjects.size} of {sortedProjects.length} selected)
)} {isLoading || !isInitialized ? (
) : savedProjects.length === 0 ? ( ) : sortedProjects.length === 0 ? ( setSearchQuery("")} /> ) : (
{sortedProjects.map((project) => ( ))}
)}
); } interface ProjectCardProps { project: TProject; isSelectionMode?: boolean; isSelected?: boolean; onSelect?: (projectId: string, checked: boolean) => void; searchQuery?: string; } function ProjectCard({ project, isSelectionMode = false, isSelected = false, onSelect, searchQuery, }: ProjectCardProps) { const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false); const { deleteProject, renameProject, duplicateProject } = useProjectStore(); const formatDate = (date: Date): string => { return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); }; const handleDeleteProject = async () => { await deleteProject(project.id); setIsDropdownOpen(false); }; const handleRenameProject = async (newName: string) => { await renameProject(project.id, newName); setIsRenameDialogOpen(false); }; const handleDuplicateProject = async () => { setIsDropdownOpen(false); await duplicateProject(project.id); }; const handleCardClick = (e: React.MouseEvent) => { if (isSelectionMode) { e.preventDefault(); onSelect?.(project.id, !isSelected); } }; return ( <> {isSelectionMode ? (
{/* Selection checkbox */} {isSelectionMode && (
onSelect?.(project.id, checked as boolean) } onClick={(e) => e.stopPropagation()} className="w-4 h-4" />
)} {/* Thumbnail preview or placeholder */}
{project.thumbnail ? ( Project thumbnail ) : (
)}

{!isSelectionMode && ( { e.preventDefault(); e.stopPropagation(); }} > { e.preventDefault(); e.stopPropagation(); setIsDropdownOpen(false); setIsRenameDialogOpen(true); }} > Rename { e.preventDefault(); e.stopPropagation(); handleDuplicateProject(); }} > Duplicate { e.preventDefault(); e.stopPropagation(); setIsDropdownOpen(false); setIsDeleteDialogOpen(true); }} > Delete )}
Created {formatDate(project.createdAt)}
) : (
{/* Thumbnail preview or placeholder */}
{project.thumbnail ? ( Project thumbnail ) : (
)}

{ e.preventDefault(); e.stopPropagation(); }} > { e.preventDefault(); e.stopPropagation(); setIsDropdownOpen(false); setIsRenameDialogOpen(true); }} > Rename { e.preventDefault(); e.stopPropagation(); handleDuplicateProject(); }} > Duplicate { e.preventDefault(); e.stopPropagation(); setIsDropdownOpen(false); setIsDeleteDialogOpen(true); }} > Delete
Created {formatDate(project.createdAt)}
)} ); } function Highlight({ text, query }: { text: string; query?: string }) { if (!query) { return {text}; } const parts = text.split(new RegExp(`(${query})`, "gi")); return ( {parts.map((part, i) => part.toLowerCase() === query.toLowerCase() ? ( {part} ) : ( part ) )} ); } function CreateButton({ onClick }: { onClick?: () => void }) { return ( ); } function NoProjects({ onCreateProject }: { onCreateProject: () => void }) { return (

No projects yet

Start creating your first video project. Import media, edit, and export professional videos.

); } function NoResults({ searchQuery, onClearSearch, }: { searchQuery: string; onClearSearch: () => void; }) { return (

No results found

Your search for "{searchQuery}" did not return any results.

); }