import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Plus, Trash2, Pencil, Eye } from 'lucide-react'; import { toast } from 'sonner'; import { fetchWorkspaces, deleteWorkspace, type Workspace } from '../api/workspaces'; import { useTranslation } from '../hooks/useTranslation'; import { WORKSPACE_DELETE, WORKSPACE_EDIT, canWorkspace, type WorkspaceRole, } from '../lib/permissions'; import FilterBar from '../components/FilterBar'; import { ListPageSkeleton } from '../components/ListPageSkeleton'; import { Button } from '../components/ui/button'; import { Input } from '../components/ui/input'; import { Card, CardContent, CardTitle } from '../components/ui/card'; import { Pagination } from '../components/Pagination'; import { Modal } from '../components/Modal'; const RoleBadge = ({ role }: { role?: WorkspaceRole }) => { const { t } = useTranslation(); if (!role) return null; const styles: Record = { owner: 'bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-400', admin: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-400', member: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-400', guest: 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-400', }; return ( {role ? t.workspace?.roles[role] : "-"} ); }; export default function Workspaces() { const [workspaces, setWorkspaces] = useState([]); const [isLoading, setIsLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [ordering, setOrdering] = useState('-created_at'); const [currentPage, setCurrentPage] = useState(1); const [totalItems, setTotalItems] = useState(0); const [limit, setLimit] = useState(10); const [deleteModal, setDeleteModal] = useState<{isOpen: boolean; workspace: Workspace | null}>({isOpen: false, workspace: null}); const [deleteInput, setDeleteInput] = useState(''); const navigate = useNavigate(); const { t } = useTranslation(); const orderingOptions = [ { value: '-created_at', label: t.ordering?.createdAtDesc || 'Newest First' }, { value: 'created_at', label: t.ordering?.createdAt || 'Oldest First' }, { value: 'name', label: t.ordering?.name || 'Name (A-Z)' }, { value: '-name', label: t.ordering?.nameDesc || 'Name (Z-A)' }, { value: '-updated_at', label: t.ordering?.updatedAtDesc || 'Recently Updated' }, ]; useEffect(() => { setCurrentPage(1); }, [searchQuery, ordering]); useEffect(() => { const timer = setTimeout(() => { loadWorkspaces(); }, 400); return () => clearTimeout(timer); }, [searchQuery, ordering, currentPage, limit]); const loadWorkspaces = async () => { try { setIsLoading(true); const params: Record = { limit: limit, offset: (currentPage - 1) * limit, }; if (searchQuery) params.search = searchQuery; if (ordering) params.ordering = ordering; const data = await fetchWorkspaces(params as any); const items = Array.isArray(data) ? data : (data?.results || []); const count = !Array.isArray(data) && data?.count !== undefined ? data.count : items.length; setWorkspaces(items); setTotalItems(count); } catch (error) { toast.error(t.workspace?.fetchError || 'Error fetching workspaces'); } finally { setIsLoading(false); } }; const confirmDelete = async () => { if (!deleteModal.workspace) return; try { const deletedId = deleteModal.workspace.id; await deleteWorkspace(deletedId); loadWorkspaces(); window.dispatchEvent(new CustomEvent('workspace_deleted', { detail: { id: deletedId } })); toast.success(t.workspace?.deleteSuccess || 'Workspace deleted successfully'); setDeleteModal({ isOpen: false, workspace: null }); setDeleteInput(''); } catch (error) { toast.error(t.workspace?.deleteError || 'Failed to delete workspace'); } }; return (

{t.workspace?.title || 'Workspaces'}

{t.workspace?.subtitle || 'Manage your workspaces'}

{isLoading ? ( ) : (
{workspaces.map((workspace) => { const canDeleteWorkspace = canWorkspace(workspace.my_role, WORKSPACE_DELETE); const canEditWorkspace = canWorkspace(workspace.my_role, WORKSPACE_EDIT); return (
{workspace.thumbnail ? (
{workspace.name}
) : (
{workspace.name.trim().charAt(0).toUpperCase() || "W"}
)} {workspace.name}

{workspace.description || t.workspace?.noDescription || 'No description'}

{canDeleteWorkspace && ( )} {canEditWorkspace && ( )}
); })} {workspaces.length === 0 && (

{t.workspace?.emptyState || 'No workspaces found'}

)}
)}
{deleteModal.workspace && ( { setDeleteModal({ isOpen: false, workspace: null }); setDeleteInput(''); }} title={t.workspace?.deleteTitle || 'Delete Workspace'} maxWidth="max-w-md" footer={ <> } >

{t.workspace?.deleteWarning || 'To confirm deletion, please type the workspace name:'} {deleteModal.workspace.name}

setDeleteInput(e.target.value)} placeholder={deleteModal.workspace.name} />
)}
); }