Files
kita-planer/src/app/dashboard/admin/news/news-form.tsx
T

147 lines
4.7 KiB
TypeScript

"use client";
import { useState, useTransition } from "react";
import { Loader2, Send, UploadCloud } from "lucide-react";
import { toast } from "sonner";
import { createAnnouncement } from "@/actions/announcements";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { MarkdownContent } from "@/components/markdown-content";
export function NewsForm() {
const [isPending, startTransition] = useTransition();
const [sendEmail, setSendEmail] = useState(false);
const [content, setContent] = useState("");
function handleSubmit(formData: FormData) {
startTransition(async () => {
if (sendEmail) {
formData.set("sendEmail", "on");
}
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.");
}
});
}
return (
<form action={handleSubmit} className="grid gap-5">
<div className="grid gap-2">
<Label htmlFor="news-title">Titel</Label>
<Input
id="news-title"
name="title"
placeholder="Sommerfest: Aufbau und Mitbringliste"
required
/>
</div>
<div className="grid gap-2">
<Label htmlFor="news-content">Text</Label>
<Textarea
id="news-content"
name="content"
rows={10}
value={content}
onChange={(event) => setContent(event.target.value)}
placeholder={
"## Liebe Familien,\n\nhier stehen die offiziellen Informationen..."
}
required
/>
<p className="text-xs text-[var(--ink-muted)]">
Markdown ist aktiv. HTML wird nicht interpretiert.
</p>
</div>
{content.trim() && (
<div className="rounded-lg border border-[var(--hairline)] bg-[var(--surface-2)] p-4 text-sm">
<p className="mb-3 text-[11px] font-semibold uppercase text-[var(--ink-muted)] [letter-spacing:0.12em]">
Vorschau
</p>
<MarkdownContent content={content} />
</div>
)}
<div className="grid gap-2">
<Label htmlFor="attachments">Anhänge</Label>
<div className="rounded-lg border border-dashed border-[var(--hairline)] bg-[var(--surface-2)] p-4">
<Input
id="attachments"
name="attachments"
type="file"
accept=".pdf,.jpg,.jpeg,.png,application/pdf,image/jpeg,image/png"
multiple
/>
<p className="mt-2 flex items-center gap-1 text-xs text-[var(--ink-muted)]">
<UploadCloud className="h-3.5 w-3.5 [stroke-width:1.7]" />
PDF, JPG und PNG: maximal 5 Dateien, je 10 MB und insgesamt 25 MB.
</p>
</div>
</div>
<div className="rounded-lg border border-[var(--hairline)] bg-[var(--surface-2)] p-4">
<div className="flex items-center gap-2">
<Checkbox
id="sendEmail"
checked={sendEmail}
onCheckedChange={(checked) => setSendEmail(checked === true)}
/>
<Label htmlFor="sendEmail" className="cursor-pointer">
Auch als E-Mail versenden
</Label>
</div>
<div className="mt-4 grid gap-2">
<Label htmlFor="news-audience">Empfängergruppe</Label>
<p className="text-xs text-[var(--ink-soft)]">
Bestimmt, wer die Meldung und Anhänge in der App sehen darf und
optional die E-Mail erhält.
</p>
<Select name="audience" defaultValue="ELTERN">
<SelectTrigger id="news-audience">
<SelectValue placeholder="Empfänger auswählen" />
</SelectTrigger>
<SelectContent>
<SelectItem value="ELTERN">Eltern</SelectItem>
<SelectItem value="ERZIEHER">ErzieherInnen</SelectItem>
<SelectItem value="ALLE">Eltern und ErzieherInnen</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="flex justify-end">
<Button type="submit" disabled={isPending}>
{isPending ? (
<Loader2 className="h-4 w-4 animate-spin [stroke-width:1.7]" />
) : (
<Send className="h-4 w-4 [stroke-width:1.7]" />
)}
Veröffentlichen
</Button>
</div>
</form>
);
}