import { useEffect, useState } from "react"; import { Button, ConfirmDialog, Dialog, DocumentationHelpLink, DismissibleAlert, FormField, i18nMessage, useUnsavedChanges, useUnsavedDraftGuard, type ApiSettings } from "@govoplan/core-webui"; import { finalizeProviderBallot, finalizeVotingBallot, type CommitteeRecord } from "../../api/committee"; import { COMMITTEE_FIELD_DOCUMENTATION, COMMITTEE_INTERFACE_I18N } from "./interfacePatterns"; export default function CommitteeBallotDialog({ settings, record, open, onClose, onSaved }: { settings: ApiSettings; record: CommitteeRecord; open: boolean; onClose: () => void; onSaved: (record: CommitteeRecord) => void; }) { const [providerBallotRef, setProviderBallotRef] = useState(""); const [approvalId, setApprovalId] = useState(""); const [changeReason, setChangeReason] = useState("Imported verified ballot aggregate."); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); const [confirming, setConfirming] = useState(false); const { requestDiscard } = useUnsavedChanges(); useEffect(() => { if (!open) return; setProviderBallotRef(""); setApprovalId(""); setChangeReason("Imported verified ballot aggregate."); setError(""); setConfirming(false); }, [open, record.object_id]); const dirty = Boolean(providerBallotRef || approvalId || changeReason !== "Imported verified ballot aggregate."); async function finalize(closeAfter = true): Promise { setBusy(true); setError(""); try { const saved = votingBallotId ? await finalizeVotingBallot(settings, record, { approvalId, changeReason }) : await finalizeProviderBallot(settings, record, { providerBallotRef, approvalId, changeReason }); onSaved(saved); if (closeAfter) onClose(); return true; } catch (reason) { setError(reason instanceof Error ? reason.message : "Ballot result could not be imported."); return false; } finally { setBusy(false); } } useUnsavedDraftGuard({ dirty: open && dirty, onSave: () => finalize(false), onDiscard: () => { setProviderBallotRef(""); setApprovalId(""); setChangeReason("Imported verified ballot aggregate."); }, title: "i18n:govoplan-committee.unsaved_title", message: "i18n:govoplan-committee.unsaved_message" }); function requestClose() { if (busy) return; if (dirty) requestDiscard(onClose); else onClose(); } const providerId = String(record.attributes.provider_id ?? ""); const votingBallotId = String(record.attributes.voting_ballot_id ?? "").trim(); const incomplete = (!votingBallotId && !providerBallotRef.trim()) || !approvalId.trim() || !changeReason.trim(); return ( <> } onClose={requestClose} closeDisabled={busy} portal className="committee-ballot-dialog" footer={ <> } >
{error ? {error} : null}

{votingBallotId ? <>Voting ballot {votingBallotId} will be closed and its aggregate result recorded in the Committee minutes. : <>Provider {providerId} returns only the verified aggregate result, receipt hash and evidence.}

{!votingBallotId ? setProviderBallotRef(event.target.value)} /> : null} setApprovalId(event.target.value)} /> setChangeReason(event.target.value)} />
{ setConfirming(false); void finalize(); }} onCancel={() => setConfirming(false)} /> ); }