Add announcement editing and reliable per-recipient mail delivery

This commit is contained in:
t.indorf
2026-10-13 08:53:22 +02:00
parent 661776e609
commit 1472779781
22 changed files with 1655 additions and 190 deletions
+31 -11
View File
@@ -1,6 +1,6 @@
"use client";
import { useState, useTransition } from "react";
import { useRef, useState, useTransition } from "react";
import { Loader2, Send, UploadCloud } from "lucide-react";
import { toast } from "sonner";
@@ -20,6 +20,7 @@ import { Textarea } from "@/components/ui/textarea";
import { MarkdownContent } from "@/components/markdown-content";
export function NewsForm() {
const formRef = useRef<HTMLFormElement>(null);
const [isPending, startTransition] = useTransition();
const [sendEmail, setSendEmail] = useState(false);
const [content, setContent] = useState("");
@@ -30,27 +31,43 @@ export function NewsForm() {
formData.set("sendEmail", "on");
}
const result = await createAnnouncement(formData);
if (result.error) {
toast.error(result.error);
return;
}
try {
const result = await createAnnouncement(formData);
if (result.error) {
toast.error(result.error);
return;
}
if (result.warning) {
toast.warning(result.warning);
} else {
toast.success("Ankündigung veröffentlicht.");
if (result.warning) {
toast.warning(result.warning);
} else {
toast.success(
sendEmail
? "Ankündigung veröffentlicht. E-Mails sind zum Versand vorgemerkt."
: "Ankündigung veröffentlicht.",
);
}
formRef.current?.reset();
setContent("");
setSendEmail(false);
} catch {
toast.error(
"Ankündigung konnte nicht veröffentlicht werden. Bitte versuche es erneut.",
);
}
});
}
return (
<form action={handleSubmit} className="grid gap-5">
<form ref={formRef} action={handleSubmit} className="grid gap-5">
<div className="grid gap-2">
<Label htmlFor="news-title">Titel</Label>
<Input
id="news-title"
name="title"
minLength={3}
maxLength={160}
disabled={isPending}
placeholder="Sommerfest: Aufbau und Mitbringliste"
required
/>
@@ -62,6 +79,9 @@ export function NewsForm() {
id="news-content"
name="content"
rows={10}
minLength={3}
maxLength={20_000}
disabled={isPending}
value={content}
onChange={(event) => setContent(event.target.value)}
placeholder={