"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/hooks/useAuth"; import { useSearch, DEFAULT_PAGE_SIZE } from "@/hooks/useSearch"; import { useSavedSearches } from "@/hooks/useSavedSearches"; import { useMailUpload } from "@/hooks/useMailUpload"; import { exportMailsZIP, exportEDiscovery } from "@/lib/api"; import { Navbar } from "@/components/navbar"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { SearchFilterBar } from "@/components/search/SearchFilterBar"; import { SearchResultsTable } from "@/components/search/SearchResultsTable"; import { ExportZipDialog, EDiscoveryDialog, UploadDialog, } from "@/components/search/ExportDialogs"; export default function SearchPage() { const { user, loading: authLoading } = useAuth(); const router = useRouter(); const pageSize = user?.list_page_size ?? DEFAULT_PAGE_SIZE; const search = useSearch(user, pageSize); const { query, setQuery, fromFilter, setFromFilter, toFilter, setToFilter, dateFrom, setDateFrom, dateTo, setDateTo, sort, setSort, hasAttachment, setHasAttachment, results, setResults, total, setTotal, page, setPage, searching, setSearching, searched, setSearched, doSearch, } = search; // Selection state const [selected, setSelected] = useState>(new Set()); const [exportOpen, setExportOpen] = useState(false); const [exportAttachments, setExportAttachments] = useState(false); const [exporting, setExporting] = useState(false); const [ediscoveryOpen, setEdiscoveryOpen] = useState(false); const [ediscoveryCaseName, setEdiscoveryCaseName] = useState(""); const [ediscoveryLoading, setEdiscoveryLoading] = useState(false); const upload = useMailUpload(() => doSearch(1)); const saved = useSavedSearches({ user, pageSize, query, fromFilter, toFilter, dateFrom, dateTo, hasAttachment, setQuery, setFromFilter, setToFilter, setDateFrom, setDateTo, setHasAttachment, setResults, setTotal, setPage, setSearching, setSearched, }); // Clear selection when results change useEffect(() => { setSelected(new Set()); }, [results]); // Superadmin has no mail access — redirect to admin dashboard useEffect(() => { if (user?.role === "superadmin") { router.replace("/admin"); } }, [user, router]); function handleSubmit(e: React.FormEvent) { e.preventDefault(); doSearch(1); } async function handleEDiscoveryExport() { setEdiscoveryLoading(true); try { const { blob, filename } = await exportEDiscovery({ case_name: ediscoveryCaseName || undefined, q: query || undefined, from: fromFilter || undefined, to: toFilter || undefined, date_from: dateFrom || undefined, date_to: dateTo || undefined, }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); setEdiscoveryOpen(false); } catch (e) { alert(`eDiscovery Export fehlgeschlagen: ${e instanceof Error ? e.message : e}`); } finally { setEdiscoveryLoading(false); } } async function handleExportZIP() { setExporting(true); try { const { blob } = await exportMailsZIP(Array.from(selected), exportAttachments); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "archivmail-export.zip"; a.click(); URL.revokeObjectURL(url); setExportOpen(false); setSelected(new Set()); } catch (e) { alert(`Export fehlgeschlagen: ${e instanceof Error ? e.message : e}`); } finally { setExporting(false); } } const hasActiveSearch = !!(query || fromFilter || toFilter || dateFrom || dateTo || hasAttachment); const totalPages = Math.ceil(total / pageSize); return (
{(authLoading || !user) && (
)} {!authLoading && user && (<>
{/* Main content */}
upload.setUploadOpen(true)} hasActiveSearch={hasActiveSearch} savePopoverOpen={saved.savePopoverOpen} setSavePopoverOpen={saved.setSavePopoverOpen} saveName={saved.saveName} setSaveName={saved.setSaveName} saving={saved.saving} onSaveSearch={saved.handleSaveSearch} savedListOpen={saved.savedListOpen} setSavedListOpen={saved.setSavedListOpen} savedLoading={saved.savedLoading} savedSearches={saved.savedSearches} onApplySavedSearch={saved.handleApplySavedSearch} onDeleteSavedSearch={saved.handleDeleteSavedSearch} />
{searching ? ( {Array.from({ length: 5 }).map((_, i) => ( ))} ) : searched && results.length === 0 ? ( Keine E-Mails gefunden. ) : results.length > 0 ? ( <>
{query || fromFilter || toFilter || dateFrom || dateTo ? `${total} Ergebnis${total !== 1 ? "se" : ""} gefunden` : `${total} E-Mail${total !== 1 ? "s" : ""} im Archiv`}
{selected.size > 0 && ( <> {selected.size} ausgewählt )}
doSearch(p)} /> ) : null}
{/* end flex-1 */}
{/* end flex gap-6 */} { if (!open) upload.handleUploadClose(); else upload.setUploadOpen(true); }} dragging={upload.uploadDragging} setDragging={upload.setUploadDragging} job={upload.uploadJob} error={upload.uploadError} loading={upload.uploadLoading} onUploadFiles={upload.handleUploadFiles} onClose={upload.handleUploadClose} /> )}
); }