143 lines
4.5 KiB
TypeScript
143 lines
4.5 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>
|
|
|
|
{sendEmail && (
|
|
<div className="mt-4 grid gap-2">
|
|
<Label>Empfänger</Label>
|
|
<Select name="audience" defaultValue="ELTERN">
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Empfänger auswählen" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="ELTERN">Eltern</SelectItem>
|
|
<SelectItem value="ERZIEHER">ErzieherInnen</SelectItem>
|
|
<SelectItem value="ALLE">Alle</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>
|
|
);
|
|
}
|