'use client'; import { useRouter } from 'next/navigation'; import { useState, useTransition } from 'react'; import { Loader2, Pencil, PuzzleIcon, Trash2 } from 'lucide-react'; import { toast } from 'sonner'; import { deleteCollectionItem, updateCollectionItem } from '@/app/(app)/sammlung/actions'; import type { MissingPartRow } from '@/lib/queries/collection'; import { MissingPartsDialog } from './missing-parts-dialog'; import type { CollectionStatus, Completeness, Condition } from '@/db/types'; import { collectorBadgeClass } from '@/lib/collector-colors'; import { formatDate, toDateInputValue } from '@/lib/format'; import { COMPLETENESS_LABELS, CONDITION_LABELS, STATUS_LABELS, completenessLabel, conditionLabel, statusLabel, } from '@/lib/labels'; import { centsToInput, formatEuro } from '@/lib/money'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Field } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; import { NativeSelect } from '@/components/ui/native-select'; import { Textarea } from '@/components/ui/textarea'; export type CollectionItemRow = { id: string; setId: string; status: CollectionStatus; completeness: Completeness; condition: Condition | null; locationId: string | null; locationName?: string | null; acquiredAt: Date | null; acquiredPriceCents: number | null; acquiredFrom: string | null; giftedBy: string | null; lentOutTo: string | null; notes: string | null; setName: string; missingParts: MissingPartRow[]; collectorId: string | null; collectorName: string | null; collectorColor: string | null; }; export function CollectionItemsSection({ items, locations, collectors, }: { items: CollectionItemRow[]; locations: Array<{ id: string; name: string }>; collectors: Array<{ id: string; name: string }>; }) { const router = useRouter(); const [pending, startTransition] = useTransition(); const [editing, setEditing] = useState(null); const [deleting, setDeleting] = useState(null); // Only the id, never a snapshot: the dialog shows a live list, and a copy // taken when it opened would not show a part that was just added. const [partsItemId, setPartsItemId] = useState(null); const partsItem = items.find((item) => item.id === partsItemId) ?? null; function submit(event: React.FormEvent) { event.preventDefault(); const item = editing; if (!item) return; const input = Object.fromEntries(new FormData(event.currentTarget).entries()); startTransition(async () => { const result = await updateCollectionItem(item.id, { ...input, setId: item.setId }); if (!result.ok) { toast.error(result.error); return; } toast.success('Sammlungseintrag gespeichert.'); setEditing(null); router.refresh(); }); } function remove() { const item = deleting; if (!item) return; startTransition(async () => { const result = await deleteCollectionItem(item.id); if (!result.ok) { toast.error(result.error); return; } toast.success('Sammlungseintrag entfernt.'); setDeleting(null); router.refresh(); }); } if (items.length === 0) { return (

Dieses Set ist noch nicht in der Sammlung.

); } return (
    {items.map((item) => (
  • {collectors.length > 1 && item.collectorName ? ( {item.collectorName} ) : null} {statusLabel(item.status)} {completenessLabel(item.completeness)} {item.missingParts.some((part) => !part.resolved) ? ( {item.missingParts.filter((part) => !part.resolved).length} Fehlteile ) : null} {item.locationName ? ( {item.locationName} ) : null}

    {[ item.acquiredAt ? `Seit ${formatDate(item.acquiredAt)}` : null, item.acquiredPriceCents !== null ? `Gekauft für ${formatEuro(item.acquiredPriceCents)}` : null, item.giftedBy ? `Geschenk von ${item.giftedBy}` : null, item.lentOutTo ? `Verliehen an ${item.lentOutTo}` : null, item.condition ? conditionLabel(item.condition) : null, ] .filter(Boolean) .join(' · ') || 'Keine weiteren Angaben'}

    {item.notes ?

    {item.notes}

    : null}
  • ))}
!open && setEditing(null)}> Sammlungseintrag bearbeiten
{collectors.length > 1 ? ( {collectors.map((entry) => ( ))} ) : null} {Object.entries(STATUS_LABELS).map(([value, label]) => ( ))} {Object.entries(COMPLETENESS_LABELS).map(([value, label]) => ( ))} {Object.entries(CONDITION_LABELS).map(([value, label]) => ( ))} {locations.map((item) => ( ))}