142 lines
7.8 KiB
TypeScript
142 lines
7.8 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Navigate, Route, Routes, useLocation, useNavigate, useParams } from "react-router-dom";
|
|
import { useGuardedNavigate } from "@govoplan/core-webui";
|
|
import type { ApiSettings, AuthInfo, CampaignWorkspaceSection } from "../../types";
|
|
import SectionSidebar from "../../layout/SectionSidebar";
|
|
import CampaignOverviewPage from "./CampaignOverviewPage";
|
|
import CampaignFieldsPage from "./CampaignFieldsPage";
|
|
import GlobalSettingsPage from "./GlobalSettingsPage";
|
|
import RecipientDataPage from "./RecipientDataPage";
|
|
import RecipientDetailsPage from "./RecipientDetailsPage";
|
|
import TemplateDataPage from "./TemplateDataPage";
|
|
import AttachmentsDataPage from "./AttachmentsDataPage";
|
|
import MailSettingsPage from "./MailSettingsPage";
|
|
import ReviewSendPage from "./ReviewSendPage";
|
|
import CreateWizard from "./wizard/CreateWizard";
|
|
import ReviewWizard from "./wizard/ReviewWizard";
|
|
import SendWizard from "./wizard/SendWizard";
|
|
import CampaignJsonView from "./CampaignJsonView";
|
|
import CampaignReportPage from "./CampaignReportPage";
|
|
import CampaignAuditPage from "./CampaignAuditPage";
|
|
|
|
const sectionPaths: Record<CampaignWorkspaceSection, string> = {
|
|
overview: "",
|
|
campaign: "recipients",
|
|
"global-settings": "global-settings",
|
|
policies: "policies",
|
|
fields: "fields",
|
|
recipients: "recipients",
|
|
"recipient-data": "recipient-data",
|
|
template: "template",
|
|
files: "files",
|
|
"mail-settings": "mail-settings",
|
|
"mail-policy": "mail-policy",
|
|
review: "review",
|
|
report: "report",
|
|
audit: "audit",
|
|
json: "json"
|
|
};
|
|
|
|
export default function CampaignWorkspace({ settings, auth }: { settings: ApiSettings; auth: AuthInfo }) {
|
|
return <CampaignWorkspaceInner settings={settings} auth={auth} />;
|
|
}
|
|
|
|
function CampaignWorkspaceInner({ settings, auth }: { settings: ApiSettings; auth: AuthInfo }) {
|
|
const { campaignId } = useParams();
|
|
const navigate = useNavigate();
|
|
const guardedNavigate = useGuardedNavigate();
|
|
const location = useLocation();
|
|
const active = sectionFromPath(location.pathname);
|
|
const urlVersionId = new URLSearchParams(location.search).get("version");
|
|
const [selectedVersionId, setSelectedVersionId] = useState<string | null>(urlVersionId);
|
|
|
|
useEffect(() => {
|
|
if (urlVersionId) setSelectedVersionId(urlVersionId);
|
|
}, [urlVersionId]);
|
|
|
|
// Relative links inside the workspace historically dropped ?version=. Keep
|
|
// the selected version stable for the lifetime of this campaign workspace,
|
|
// while still opening the latest version on a fresh campaign entry.
|
|
useEffect(() => {
|
|
if (urlVersionId || !selectedVersionId) return;
|
|
const params = new URLSearchParams(location.search);
|
|
params.set("version", selectedVersionId);
|
|
navigate(`${location.pathname}?${params.toString()}`, { replace: true });
|
|
}, [location.pathname, location.search, navigate, selectedVersionId, urlVersionId]);
|
|
|
|
function select(section: CampaignWorkspaceSection) {
|
|
const path = sectionPaths[section];
|
|
const pathname = path ? `/campaigns/${campaignId}/${path}` : `/campaigns/${campaignId}`;
|
|
const params = new URLSearchParams(location.search);
|
|
const versionId = urlVersionId ?? selectedVersionId;
|
|
if (versionId) params.set("version", versionId);
|
|
const query = params.toString();
|
|
const target = query ? `${pathname}?${query}` : pathname;
|
|
if (`${location.pathname}${location.search}` === target) return;
|
|
guardedNavigate(target);
|
|
}
|
|
|
|
return (
|
|
<div className="workspace">
|
|
<SectionSidebar active={active} onSelect={select} />
|
|
<section className="workspace-content">
|
|
<Routes>
|
|
<Route index element={<CampaignOverviewPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="data" element={<Navigate to="../recipients" replace />} />
|
|
<Route path="fields" element={<CampaignFieldsPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="recipients" element={<RecipientDataPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="recipient-data" element={<RecipientDetailsPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="template" element={<TemplateDataPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="files" element={<AttachmentsDataPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="attachments" element={<Navigate to="../files" replace />} />
|
|
<Route path="mail-settings" element={<MailSettingsPage settings={settings} campaignId={campaignId || ""} view="settings" />} />
|
|
<Route path="mail-policy" element={<MailSettingsPage settings={settings} campaignId={campaignId || ""} view="policy" />} />
|
|
<Route path="mail-policies" element={<Navigate to="../mail-policy" replace />} />
|
|
<Route path="server-settings" element={<Navigate to="../mail-settings" replace />} />
|
|
<Route path="global-settings" element={<GlobalSettingsPage settings={settings} auth={auth} campaignId={campaignId || ""} view="settings" />} />
|
|
<Route path="policies" element={<GlobalSettingsPage settings={settings} auth={auth} campaignId={campaignId || ""} view="policy" />} />
|
|
<Route path="policy" element={<Navigate to="../policies" replace />} />
|
|
<Route path="review" element={<ReviewSendPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="send" element={<Navigate to="../review" replace />} />
|
|
<Route path="report" element={<CampaignReportPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="reports" element={<Navigate to="../report" replace />} />
|
|
<Route path="audit" element={<CampaignAuditPage settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="json" element={<CampaignJsonView settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="wizard/create" element={<CreateWizard settings={settings} campaignId={campaignId || ""} />} />
|
|
<Route path="wizard/review" element={<ReviewWizard />} />
|
|
<Route path="wizard/send" element={<SendWizard />} />
|
|
<Route path="create" element={<Navigate to="../wizard/create" replace />} />
|
|
<Route path="campaign" element={<Navigate to="../data" replace />} />
|
|
<Route path="mail" element={<Navigate to="../mail-settings" replace />} />
|
|
<Route path="settings" element={<Navigate to="../global-settings" replace />} />
|
|
<Route path="Review" element={<Navigate to="../" replace />} />
|
|
<Route path="*" element={<Navigate to="../" replace />} />
|
|
</Routes>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function sectionFromPath(pathname: string): CampaignWorkspaceSection {
|
|
const segments = pathname.split("/").filter(Boolean);
|
|
const section = segments[2];
|
|
|
|
if (!section || section === "wizard" || section === "create") return "overview";
|
|
if (section === "data" || section === "campaign") return "recipients";
|
|
if (section === "global-settings" || section === "settings") return "global-settings";
|
|
if (section === "policies" || section === "policy") return "policies";
|
|
if (section === "fields") return "fields";
|
|
if (section === "recipients") return "recipients";
|
|
if (section === "recipient-data" || section === "recipient-details") return "recipient-data";
|
|
if (section === "template") return "template";
|
|
if (section === "files" || section === "attachments") return "files";
|
|
if (section === "mail-settings" || section === "server-settings" || section === "mail") return "mail-settings";
|
|
if (section === "mail-policy" || section === "mail-policies") return "mail-policy";
|
|
if (section === "review") return "review";
|
|
if (section === "send") return "review";
|
|
if (section === "report" || section === "reports") return "report";
|
|
if (section === "audit") return "audit";
|
|
if (section === "json") return "json";
|
|
return "overview";
|
|
}
|