import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Eye, RefreshCw } from "lucide-react"; import { useSearchParams } from "react-router"; import { Button, Card, DataGrid, DismissibleAlert, LoadingFrame, MetricCard, PageScrollViewport, PageTitle, StatusBadge, TableActionGroup, formatDateTime, i18nMessage, type ApiSettings, type DataGridColumn, type DataGridListOption } from "@govoplan/core-webui"; import { getAggregateCampaignReport, listAggregateReportCampaigns, type AggregateCampaignReport, type AggregateReportCampaignListItem, type AggregateReportCount } from "../../api/campaigns"; const CAMPAIGN_STATUS_OPTIONS: DataGridListOption[] = [ { value: "draft", label: "i18n:govoplan-campaign.draft.23d33e22" }, { value: "validated", label: "i18n:govoplan-campaign.valid.a4aefa35" }, { value: "needs_review", label: "i18n:govoplan-campaign.needs_review.33a506cf" }, { value: "ready_to_queue", label: "i18n:govoplan-campaign.ready.20c7c552" }, { value: "queued", label: "i18n:govoplan-campaign.queued.6a599877" }, { value: "sending", label: "i18n:govoplan-campaign.sending.cf765512" }, { value: "sent", label: "i18n:govoplan-campaign.sent.35f49dcf" }, { value: "partially_completed", label: "i18n:govoplan-campaign.partially_completed.760bc5e6" }, { value: "outcome_unknown", label: "i18n:govoplan-campaign.outcome_unknown.6e929fca" }, { value: "failed", label: "i18n:govoplan-campaign.failed.09fef5d8" }, { value: "cancelled", label: "i18n:govoplan-campaign.cancelled.a1bf92ef" }, { value: "archived", label: "i18n:govoplan-campaign.archived.eddc813f" } ]; export default function AggregateReportsPage({ settings }: {settings: ApiSettings;}) { const [searchParams, setSearchParams] = useSearchParams(); const selectedFromUrl = searchParams.get("campaign") ?? ""; const [campaigns, setCampaigns] = useState([]); const [report, setReport] = useState(null); const [listLoading, setListLoading] = useState(true); const [reportLoading, setReportLoading] = useState(false); const [error, setError] = useState(""); const reportRequest = useRef(0); const selectCampaign = useCallback((campaignId: string) => { setSearchParams(campaignId ? { campaign: campaignId } : {}, { replace: true }); }, [setSearchParams]); const loadCampaigns = useCallback(async () => { setListLoading(true); setError(""); try { const rows = await listAggregateReportCampaigns(settings); setCampaigns(rows); const requested = selectedFromUrl && rows.some((row) => row.id === selectedFromUrl) ? selectedFromUrl : rows[0]?.id ?? ""; if (requested !== selectedFromUrl) selectCampaign(requested); if (!requested) setReport(null); } catch (err) { setError(err instanceof Error ? err.message : String(err)); setCampaigns([]); setReport(null); } finally { setListLoading(false); } }, [settings, selectedFromUrl, selectCampaign]); const loadReport = useCallback(async (campaignId: string) => { if (!campaignId) { setReport(null); return; } const requestId = ++reportRequest.current; setReportLoading(true); setError(""); try { const next = await getAggregateCampaignReport(settings, campaignId); if (requestId === reportRequest.current) setReport(next); } catch (err) { if (requestId === reportRequest.current) { setError(err instanceof Error ? err.message : String(err)); setReport(null); } } finally { if (requestId === reportRequest.current) setReportLoading(false); } }, [settings]); useEffect(() => { void loadCampaigns(); }, [settings.apiBaseUrl, settings.apiKey, settings.accessToken]); useEffect(() => { if (!listLoading && selectedFromUrl && campaigns.some((row) => row.id === selectedFromUrl)) { void loadReport(selectedFromUrl); } }, [campaigns, listLoading, loadReport, selectedFromUrl]); const columns = useMemo[]>(() => [ { id: "campaign", header: "i18n:govoplan-campaign.campaign.69390e16", width: "minmax(260px, 1fr)", maxWidth: 680, sortable: true, filterable: true, sticky: "start", render: (campaign) => (
{campaign.name}
), value: (campaign) => campaign.name }, { id: "status", header: "i18n:govoplan-campaign.status.bae7d5be", width: 170, sortable: true, filterable: true, columnType: "from-list", list: { options: CAMPAIGN_STATUS_OPTIONS, display: "pill" }, render: (campaign) => , value: (campaign) => campaign.status }, { id: "updated", header: "i18n:govoplan-campaign.updated.f2f8570d", width: 190, sortable: true, filterable: true, filterType: "date", render: (campaign) => formatDateTime(campaign.updated_at), value: (campaign) => campaign.updated_at }, { id: "actions", header: "i18n:govoplan-campaign.actions.c3cd636a", width: 72, sticky: "end", align: "right", render: (campaign) => (