Reloading redesign

This commit is contained in:
2026-06-10 14:36:42 +02:00
parent 4544a89443
commit 7de516c5e3
17 changed files with 149 additions and 51 deletions

View File

@@ -4,6 +4,7 @@ import Button from "../../components/Button";
import Card from "../../components/Card";
import FormField from "../../components/FormField";
import PageTitle from "../../components/PageTitle";
import LoadingFrame from "../../components/LoadingFrame";
import ToggleSwitch from "../../components/ToggleSwitch";
import EmailAddressInput from "../../components/email/EmailAddressInput";
import { autosaveCampaignVersion } from "../../api/campaigns";
@@ -41,18 +42,19 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
const version = data.currentVersion;
const locked = isAuditLockedVersion(version);
const recipientsSection = asRecord(draft?.recipients);
const entries = asRecord(draft?.entries);
const displayDraft = draft ?? ensureCampaignDraft(null);
const recipientsSection = asRecord(displayDraft.recipients);
const entries = asRecord(displayDraft.entries);
const inlineEntries = asArray(entries.inline).map(asRecord);
const source = asRecord(entries.source);
const fieldDefinitions = useMemo(() => getDraftFields(draft), [draft]);
const attachmentSection = asRecord(draft?.attachments);
const attachmentBasePaths = useMemo(() => normalizeAttachmentBasePaths(attachmentSection.base_paths, attachmentSection), [draft?.attachments]);
const fieldDefinitions = useMemo(() => getDraftFields(displayDraft), [displayDraft]);
const attachmentSection = asRecord(displayDraft.attachments);
const attachmentBasePaths = useMemo(() => normalizeAttachmentBasePaths(attachmentSection.base_paths, attachmentSection), [attachmentSection]);
const individualAttachmentBasePaths = useMemo(() => {
const enabled = attachmentBasePaths.filter((basePath) => basePath.allow_individual);
return enabled.length > 0 ? enabled : attachmentBasePaths;
}, [attachmentBasePaths]);
const addressSuggestions = useMemo(() => collectCampaignAddressSuggestions(draft), [draft]);
const addressSuggestions = useMemo(() => collectCampaignAddressSuggestions(displayDraft), [displayDraft]);
const globalRecipientValues: Record<string, MailboxAddress[]> = {
to: addressesFromValue(recipientsSection.to),
cc: addressesFromValue(recipientsSection.cc),
@@ -180,7 +182,7 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
{localError && <div className="alert danger">{localError}</div>}
{locked && <div className="alert info">This version is read-only. {versionLockReason(version)}</div>}
{draft && (
<LoadingFrame loading={loading || !draft} label="Loading campaign draft…">
<>
<Card title="Global recipient headers">
<div className="campaign-header-stack">
@@ -214,11 +216,11 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
title="Recipients"
actions={[<Button disabled={true}>Import</Button>, <Button variant="primary" onClick={addRecipient} disabled={locked}>Add recipient</Button>]}
>
{draft && inlineEntries.length === 0 && !source.type && <p className="muted">No recipient data is stored in the current version yet.</p>}
{draft && inlineEntries.length === 0 && Boolean(source.type) && (
{inlineEntries.length === 0 && !source.type && <p className="muted">No recipient data is stored in the current version yet.</p>}
{inlineEntries.length === 0 && Boolean(source.type) && (
<div className="alert info">This campaign references an external recipient source. A parsed preview table will be added when file/source preview support is implemented.</div>
)}
{draft && inlineEntries.length > 0 && (
{inlineEntries.length > 0 && (
<div className="app-table-wrap recipient-table-wrap">
<table className="app-table recipient-table recipient-editor-table">
<thead>
@@ -328,7 +330,7 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
<Button variant="primary" onClick={() => saveRecipients("manual")} disabled={!dirty || locked}>Save</Button>
</div>
</>
)}
</LoadingFrame>
</div>
);
}