Files
ApiCore/ApiCore-Frontend/src/lib/warnings/toast-warnings.ts
T
Nick SzaunigandClaude Opus 5.5 32c61c8e14 feat: T4 wave 6 - reminders and morning digest, next steps UI, warnings and notifications UI
- In-app reminders: task due (skips rescheduled tasks, catch-up wording)
  and a per-user morning digest step in the daily job
- Frontend: "Als Nächstes" on the colony page, "Heute" on the dashboard,
  inspection-due card, season chip, apiary overview fields, cleanup
  sheet for ended colonies
- Frontend: plausibility warnings that stay until dismissed, withdrawal
  spans in the calendar, notification bell with categories and links,
  notification settings in the profile
- ARCHITECTURE.md: T4a sections 11.1-11.10, assumptions 31-41, handler
  table and daily job step order

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-14 17:05:32 +02:00

45 lines
1.4 KiB
TypeScript

import { toast } from "sonner";
import type { PlausibilityWarning } from "./types";
/** Warnings about food safety must not time out: they stay until dismissed. */
function mustStay(warnings: readonly PlausibilityWarning[]): boolean {
return warnings.some(
(warning) =>
warning.severity === "WARNUNG" || warning.severity === "BESTAETIGEN",
);
}
/**
* After a successful save: "<saved> · 1 Warnung" plus one line per text. The
* record is saved either way; warnings only point at something to check.
* A WARNUNG or BESTAETIGEN stays until the person dismisses it. Does nothing
* for an empty list - the caller shows its own success then.
*/
export function toastWarnings(
warnings: readonly PlausibilityWarning[],
savedLabel = "Gespeichert",
): void {
if (warnings.length === 0) return;
const count = warnings.length;
const title = `${savedLabel} \u00b7 ${count} ${count === 1 ? "Warnung" : "Warnungen"}`;
const description = warnings.map((warning) => warning.message).join("\n");
if (!mustStay(warnings)) {
toast.warning(title, {
description,
classNames: { description: "whitespace-pre-line" },
});
return;
}
toast.warning(title, {
description,
duration: Infinity,
closeButton: true,
action: { label: "Verstanden", onClick: () => undefined },
classNames: {
description: "whitespace-pre-line",
actionButton: "min-h-11 min-w-11",
closeButton: "size-11",
},
});
}