import { Link2, RefreshCw } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { ActionToolbar, Button, DocumentationHelpLink, DismissibleAlert, LoadingIndicator, PageScrollViewport, StatusBadge, hasScope, i18nMessage, useGuardedNavigate, usePlatformLanguage, type PlatformRouteContext } from "@govoplan/core-webui"; import { listFormInstances, type FormInstance } from "../../api/formsRuntime"; import { FORMS_RUNTIME_DOCUMENTATION, FORMS_RUNTIME_I18N } from "./interfacePatterns"; import IntakeProfilesDialog from "./IntakeProfilesDialog"; const OPEN_STATUSES = ["started", "draft", "submitted", "validated", "needs_review"]; export default function FormsRuntimePage({ settings, auth }: PlatformRouteContext) { const navigate = useGuardedNavigate(); const { language } = usePlatformLanguage(); const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [status, setStatus] = useState("open"); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [intakeOpen, setIntakeOpen] = useState(false); const canAdmin = hasScope(auth, "forms_runtime:workspace:admin"); const load = useCallback((signal?: AbortSignal) => { setLoading(true); setError(""); return listFormInstances(settings, { statuses: status === "open" ? OPEN_STATUSES : status ? [status] : undefined, limit: 200 }, signal). then((result) => { setItems(result.instances); setTotal(result.total); }). finally(() => setLoading(false)); }, [settings, status]); useEffect(() => { const controller = new AbortController(); load(controller.signal).catch((reason) => { if ((reason as Error).name !== "AbortError") { setError(reason instanceof Error ? reason.message : "Forms could not be loaded."); } }); return () => controller.abort(); }, [load]); return (
{canAdmin && } {i18nMessage("i18n:govoplan-forms-runtime.form_count", { total })} {error && {error} } {loading && } {!loading && !error && items.length === 0 &&
No matching Forms.
} {!loading && items.length > 0 &&
{items.map((item) => )}
}
setIntakeOpen(false)} />
); } function isOpen(status: string): boolean { return OPEN_STATUSES.includes(status); } function formatDateTime(value: string, locale?: string): string { return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(new Date(value)); } function humanize(value: string): string { return value.replace(/[_:.-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase()); } function stateLabel(value: string): string { return `i18n:govoplan-forms-runtime.state_${value}`; }