// TODO: P3-F29 — Implement DMS trash endpoint /** * DMS trash page. * Shows soft-deleted files with restore button per file. */ import React, { useState, useEffect, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import { Button } from '@/components/ui/Button'; import { Card } from '@/components/ui/Card'; import { formatDateShort } from '@/utils/date'; import { Table, TableColumn } from '@/components/ui/Table'; import { EmptyState } from '@/components/ui/EmptyState'; import { Skeleton } from '@/components/ui/Skeleton'; import { useToast } from '@/components/ui/Toast'; import { restoreFile, type DmsFile } from '@/api/dms'; import { Trash2 } from 'lucide-react'; export function DmsTrashPage() { const { t } = useTranslation(); const toast = useToast(); const [trashFiles, setTrashFiles] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [restoringId, setRestoringId] = useState(null); // In a real implementation we would fetch from a trash endpoint // For now we use an empty state as the API doesn't have a dedicated trash list useEffect(() => { setLoading(true); // The DMS API doesn't have a GET /trash endpoint in the spec // We would need to filter deleted_at !== null from file listing // Using empty list for now as trash listing is not in the API spec setTrashFiles([]); setLoading(false); }, []); const handleRestore = useCallback(async (fileId: string) => { setRestoringId(fileId); try { await restoreFile(fileId); toast.success(t('dms.restored')); setTrashFiles((prev) => prev.filter((f) => f.id !== fileId)); } catch (err) { const msg = err instanceof Error ? err.message : String(err); toast.error(msg); } setRestoringId(null); }, [toast, t]); const columns: TableColumn[] = [ { key: 'name', header: t('dms.name'), sortable: true, render: (file) => ( {file.name} ), }, { key: 'size', header: t('dms.fileSize'), sortable: true, accessor: (file) => file.size_bytes ?? file.size ?? 0, render: (file) => { const sz = file.size_bytes ?? file.size ?? 0; if (sz < 1024) return `${sz} B`; if (sz < 1024 * 1024) return `${(sz / 1024).toFixed(1)} KB`; return `${(sz / (1024 * 1024)).toFixed(1)} MB`; }, }, { key: 'mime_type', header: t('dms.fileType'), render: (file) => file.mime_type.split('/')[1]?.toUpperCase() || '—', }, { key: 'deleted_at', header: t('dms.fileModified'), sortable: true, accessor: (file) => file.deleted_at || '', render: (file) => file.deleted_at ? (formatDateShort(file.deleted_at) || '—') : '—', }, { key: 'actions', header: t('dms.actions'), render: (file) => ( ), }, ]; if (loading) { return (
); } if (error) { return (
window.location.reload()}>{t('dms.cancel')}} />
); } return (
← {t('dms.title')}

{t('dms.trash')}

{trashFiles.length === 0 ? ( ) : ( file.id} emptyMessage={t('dms.trashEmpty')} /> )} ); }