Add non-destructive dev seed on startup

This commit is contained in:
t.indorf
2026-05-06 22:31:07 +02:00
parent 9f452fccac
commit b686e714ff
77 changed files with 10862 additions and 87 deletions
@@ -0,0 +1,119 @@
"use client";
import { useState, useTransition } from "react";
import { MitbringselItem } from "@prisma/client";
import { Trash2, Plus, Utensils } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { addMitbringsel, deleteMitbringsel } from "../actions";
type ItemWithUser = MitbringselItem & {
user: { firstName: string; lastName: string };
};
export function MitbringselList({
terminId,
items,
currentUserId,
isAdmin,
}: {
terminId: string;
items: ItemWithUser[];
currentUserId: string;
isAdmin: boolean;
}) {
const [content, setContent] = useState("");
const [isPending, startTransition] = useTransition();
const handleAdd = () => {
if (!content.trim()) return;
startTransition(async () => {
const res = await addMitbringsel({ terminId, content });
if (res.error) {
toast.error(res.error);
} else {
toast.success("Eintrag hinzugefügt.");
setContent("");
}
});
};
const handleDelete = (id: string) => {
startTransition(async () => {
const res = await deleteMitbringsel(id);
if (res.error) {
toast.error(res.error);
} else {
toast.success("Eintrag gelöscht.");
}
});
};
return (
<div className="flex flex-col gap-3 rounded-md bg-muted/50 p-3">
<div className="flex items-center gap-2 font-medium text-sm mb-1">
<Utensils className="h-4 w-4 text-muted-foreground" />
Mitbring-Liste
</div>
<div className="flex flex-col gap-2 max-h-40 overflow-y-auto">
{items.length === 0 ? (
<p className="text-xs text-muted-foreground italic">Noch keine Einträge vorhanden.</p>
) : (
items.map((item) => (
<div
key={item.id}
className="flex items-center justify-between gap-2 rounded-sm bg-background p-2 text-sm shadow-sm"
>
<div className="flex flex-col">
<span className="font-medium text-xs text-primary">
{item.user.firstName} {item.user.lastName}
</span>
<span>{item.content}</span>
</div>
{(isAdmin || item.userId === currentUserId) && (
<Button
variant="ghost"
size="icon"
className="h-6 w-6 text-muted-foreground hover:text-destructive shrink-0"
onClick={() => handleDelete(item.id)}
disabled={isPending}
>
<Trash2 className="h-4 w-4" />
</Button>
)}
</div>
))
)}
</div>
<div className="flex gap-2 mt-1">
<Input
placeholder="Was bringst du mit?"
value={content}
onChange={(e) => setContent(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
handleAdd();
}
}}
disabled={isPending}
className="h-8 text-sm"
/>
<Button
size="sm"
className="h-8 shrink-0"
onClick={handleAdd}
disabled={!content.trim() || isPending}
>
<Plus className="h-4 w-4 mr-1" />
Hinzufügen
</Button>
</div>
</div>
);
}