93 lines
3.2 KiB
TypeScript
93 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import { useActionState } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { vorlageBearbeitenAktion, type AktionsErgebnis } from "@/server/actions/vorlagen";
|
|
import { FELD } from "@/lib/formular";
|
|
|
|
/**
|
|
* Kopfdaten einer Vorlage: Name, Beschreibung, Kategorie, Schlagworte, Kunde.
|
|
*
|
|
* Sie haengen an der Vorlage, nicht an einer Version — deshalb lassen sie sich
|
|
* jederzeit aendern, auch wenn die neueste Version veroeffentlicht ist. Ein
|
|
* Tippfehler im Namen soll keine neue Version kosten, und die Schritte, auf die
|
|
* ein Lauf verweist, bleiben davon unberuehrt.
|
|
*/
|
|
export function VorlageKopfdaten({
|
|
vorlage,
|
|
kunden,
|
|
}: {
|
|
vorlage: {
|
|
readonly id: string;
|
|
readonly name: string;
|
|
readonly beschreibung: string | null;
|
|
readonly kategorie: string | null;
|
|
readonly schlagworte: readonly string[];
|
|
readonly kundeId: string | null;
|
|
};
|
|
kunden: readonly { id: string; name: string }[];
|
|
}) {
|
|
const [ergebnis, aktion, laeuft] = useActionState<AktionsErgebnis, FormData>(vorlageBearbeitenAktion, {});
|
|
|
|
return (
|
|
<form action={aktion} className="flex flex-col gap-4">
|
|
<input type="hidden" name="vorlageId" value={vorlage.id} />
|
|
<label className="flex flex-col gap-1.5 text-sm">
|
|
<span className="text-nebentext">Name</span>
|
|
<input name="name" required defaultValue={vorlage.name} className={FELD} />
|
|
</label>
|
|
<label className="flex flex-col gap-1.5 text-sm">
|
|
<span className="text-nebentext">Beschreibung</span>
|
|
<textarea
|
|
name="beschreibung"
|
|
rows={2}
|
|
defaultValue={vorlage.beschreibung ?? ""}
|
|
className={`${FELD} py-2`}
|
|
/>
|
|
</label>
|
|
<div className="grid gap-4 sm:grid-cols-2">
|
|
<label className="flex flex-col gap-1.5 text-sm">
|
|
<span className="text-nebentext">Kategorie</span>
|
|
<input name="kategorie" defaultValue={vorlage.kategorie ?? ""} className={FELD} />
|
|
</label>
|
|
<label className="flex flex-col gap-1.5 text-sm">
|
|
<span className="text-nebentext">Schlagworte, mit Komma getrennt</span>
|
|
<input name="schlagworte" defaultValue={vorlage.schlagworte.join(", ")} className={FELD} />
|
|
</label>
|
|
</div>
|
|
{kunden.length > 0 ? (
|
|
<label className="flex flex-col gap-1.5 text-sm">
|
|
<span className="text-nebentext">Nur für einen Kunden</span>
|
|
<select name="kundeId" defaultValue={vorlage.kundeId ?? ""} className={FELD}>
|
|
<option value="">für alle Kunden</option>
|
|
{kunden.map((kunde) => (
|
|
<option key={kunde.id} value={kunde.id}>
|
|
{kunde.name}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</label>
|
|
) : null}
|
|
|
|
{ergebnis.fehler ? (
|
|
<p role="alert" className="text-sm text-fehler">
|
|
{ergebnis.fehler}
|
|
</p>
|
|
) : null}
|
|
{ergebnis.erfolg ? (
|
|
<p role="status" className="text-sm text-erledigt">
|
|
{ergebnis.erfolg}
|
|
</p>
|
|
) : null}
|
|
|
|
<Button
|
|
type="submit"
|
|
disabled={laeuft}
|
|
className="h-11 self-start rounded-pille px-5 text-sm font-semibold"
|
|
>
|
|
{laeuft ? "Wird gespeichert …" : "Kopfdaten speichern"}
|
|
</Button>
|
|
</form>
|
|
);
|
|
}
|