'use client'; import Link from 'next/link'; import type { Route } from 'next'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { ArrowLeft, Download, Mail, Loader2 } from 'lucide-react'; import { toast } from 'sonner'; import { PageHeader } from '@/components/shared/page-header'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { EmptyState } from '@/components/shared/empty-state'; import { apiFetch } from '@/lib/api/client'; import type { ReportRun } from '@/lib/db/schema/reports'; interface ListResponse { data: ReportRun[]; total: number; hasMore: boolean; } const STATUS_VARIANT: Record = { pending: 'secondary', rendering: 'secondary', complete: 'default', failed: 'destructive', }; export function ReportRunsPageClient({ portSlug }: { portSlug: string }) { const qc = useQueryClient(); const { data, isLoading } = useQuery({ queryKey: ['report-runs'], queryFn: () => apiFetch('/api/v1/reports/runs?limit=50&order=desc'), refetchInterval: (query) => { // Auto-poll while any row is in flight so the rep sees status flip // without manual refresh. const rows = query.state.data?.data ?? []; return rows.some((r) => r.status === 'pending' || r.status === 'rendering') ? 5_000 : false; }, }); const rerunMutation = useMutation({ mutationFn: async (run: ReportRun) => { return apiFetch('/api/v1/reports/runs', { method: 'POST', body: { kind: run.kind, config: run.config, outputFormat: run.outputFormat, ...(run.templateId ? { templateId: run.templateId } : {}), }, }); }, onSuccess: () => { toast.success('Re-run queued'); qc.invalidateQueries({ queryKey: ['report-runs'] }); }, onError: (err) => toast.error(err instanceof Error ? err.message : 'Re-run failed'), }); const rows = data?.data ?? []; return (
All reports } /> {isLoading ? ( ) : rows.length === 0 ? ( ) : ( Kind Status Triggered Created Output Actions {rows.map((r) => ( {r.kind} {r.status} {r.triggeredBy} {new Date(r.createdAt).toLocaleString()} {r.outputFormat}
{r.status === 'complete' && r.storageKey ? ( ) : null}
))}
)}
); }