import { createFileRoute } from '@tanstack/react-router' import { useState, useMemo } from 'react' import { useThreadManagement } from '@/hooks/useThreadManagement' import { useThreads } from '@/hooks/useThreads' import { useTranslation } from '@/i18n/react-i18next-compat' import HeaderPage from '@/containers/HeaderPage' import ThreadList from '@/containers/ThreadList' import { IconCirclePlus, IconPencil, IconTrash, IconFolder, IconChevronDown, IconChevronRight, } from '@tabler/icons-react' import AddProjectDialog from '@/containers/dialogs/AddProjectDialog' import { DeleteProjectDialog } from '@/containers/dialogs/DeleteProjectDialog' import { Button } from '@/components/ui/button' import { formatDate } from '@/utils/formatDate' export const Route = createFileRoute('/project/')({ component: Project, }) function Project() { return } function ProjectContent() { const { t } = useTranslation() const { folders, addFolder, updateFolder, deleteFolder, getFolderById } = useThreadManagement() const threads = useThreads((state) => state.threads) const [open, setOpen] = useState(false) const [editingKey, setEditingKey] = useState(null) const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false) const [deletingId, setDeletingId] = useState(null) const [expandedProjects, setExpandedProjects] = useState>( new Set() ) const handleDelete = (id: string) => { setDeletingId(id) setDeleteConfirmOpen(true) } const confirmDelete = () => { if (deletingId) { deleteFolder(deletingId) setDeleteConfirmOpen(false) setDeletingId(null) } } const handleSave = (name: string) => { if (editingKey) { updateFolder(editingKey, name) } else { addFolder(name) } setOpen(false) setEditingKey(null) } const formatProjectDate = (timestamp: number) => { return formatDate(new Date(timestamp), { includeTime: false }) } // Get threads for a specific project const getThreadsForProject = useMemo(() => { return (projectId: string) => { return Object.values(threads) .filter((thread) => thread.metadata?.project?.id === projectId) .sort((a, b) => (b.updated || 0) - (a.updated || 0)) } }, [threads]) const toggleProjectExpansion = (projectId: string) => { setExpandedProjects((prev) => { const newSet = new Set(prev) if (newSet.has(projectId)) { newSet.delete(projectId) } else { newSet.add(projectId) } return newSet }) } return (
{t('projects.title')}
{folders.length === 0 ? (

{t('projects.noProjectsYet')}

{t('projects.noProjectsYetDesc')}

) : (
{folders .slice() .sort((a, b) => a.updated_at - b.updated_at) .map((folder) => { const projectThreads = getThreadsForProject(folder.id) const isExpanded = expandedProjects.has(folder.id) return (

{folder.name}

{projectThreads.length}{' '} {projectThreads.length === 1 ? t('projects.thread') : t('projects.threads')}

{t('projects.updated')}{' '} {formatProjectDate(folder.updated_at)}

{projectThreads.length > 0 && ( )}
{/* Thread List */} {isExpanded && projectThreads.length > 0 && (
)}
) })}
)}
) }