'use client' import React, { useState } from 'react' import { WhistleblowerReport, ReportStatus, REPORT_CATEGORY_INFO, REPORT_STATUS_INFO } from '@/lib/sdk/whistleblower/types' export function CaseDetailPanel({ report, onClose, onUpdated, onDeleted, }: { report: WhistleblowerReport onClose: () => void onUpdated: () => void onDeleted?: () => void }) { const [officerName, setOfficerName] = useState(report.assignedTo || '') const [commentText, setCommentText] = useState('') const [isSavingOfficer, setIsSavingOfficer] = useState(false) const [isSavingStatus, setIsSavingStatus] = useState(false) const [isSendingComment, setIsSendingComment] = useState(false) const [isDeleting, setIsDeleting] = useState(false) const [actionError, setActionError] = useState(null) const handleDeleteReport = async () => { if (!window.confirm(`Meldung "${report.title}" wirklich löschen?`)) return setIsDeleting(true) try { const res = await fetch(`/api/sdk/v1/whistleblower/reports/${report.id}`, { method: 'DELETE' }) if (!res.ok) throw new Error(`Fehler: ${res.status}`) onDeleted ? onDeleted() : onClose() } catch (err: unknown) { setActionError(err instanceof Error ? err.message : 'Löschen fehlgeschlagen.') } finally { setIsDeleting(false) } } const categoryInfo = REPORT_CATEGORY_INFO[report.category] const statusInfo = REPORT_STATUS_INFO[report.status] const statusTransitions: Partial> = { new: [{ label: 'Bestaetigen', next: 'acknowledged' }], acknowledged: [{ label: 'Pruefung starten', next: 'under_review' }], under_review: [{ label: 'Untersuchung starten', next: 'investigation' }], investigation: [{ label: 'Massnahmen eingeleitet', next: 'measures_taken' }], measures_taken: [{ label: 'Abschliessen', next: 'closed' }] } const transitions = statusTransitions[report.status] || [] const handleStatusChange = async (newStatus: string) => { setIsSavingStatus(true) setActionError(null) try { const res = await fetch(`/api/sdk/v1/whistleblower/reports/${report.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }) }) if (!res.ok) { const data = await res.json().catch(() => ({})) throw new Error(data?.detail || data?.message || `Fehler ${res.status}`) } onUpdated() } catch (err: unknown) { setActionError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsSavingStatus(false) } } const handleSaveOfficer = async () => { setIsSavingOfficer(true) setActionError(null) try { const res = await fetch(`/api/sdk/v1/whistleblower/reports/${report.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ assignedTo: officerName }) }) if (!res.ok) { const data = await res.json().catch(() => ({})) throw new Error(data?.detail || data?.message || `Fehler ${res.status}`) } onUpdated() } catch (err: unknown) { setActionError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsSavingOfficer(false) } } const handleSendComment = async () => { if (!commentText.trim()) return setIsSendingComment(true) setActionError(null) try { const res = await fetch(`/api/sdk/v1/whistleblower/reports/${report.id}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ senderRole: 'ombudsperson', message: commentText.trim() }) }) if (!res.ok) { const data = await res.json().catch(() => ({})) throw new Error(data?.detail || data?.message || `Fehler ${res.status}`) } setCommentText('') onUpdated() } catch (err: unknown) { setActionError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsSendingComment(false) } } return ( <> {/* Backdrop */}
{/* Drawer */}
{/* Header */}

{report.referenceNumber}

{report.title}

{actionError && (
{actionError}
)} {/* Badges */}
{categoryInfo.label} {statusInfo.label} {report.isAnonymous && ( Anonym )} {report.priority === 'critical' ? 'Kritisch' : report.priority === 'high' ? 'Hoch' : report.priority === 'normal' ? 'Normal' : 'Niedrig'}
{/* Description */}

Beschreibung

{report.description}

{/* Details */}

Eingegangen am

{new Date(report.receivedAt).toLocaleDateString('de-DE')}

Zugewiesen an

{report.assignedTo || '—'}

{/* Status Transitions */} {transitions.length > 0 && (

Status aendern

{transitions.map((t) => ( ))}
)} {/* Assign Officer */}

Zuweisen an:

setOfficerName(e.target.value)} className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="Name der zustaendigen Person" />
{/* Comment Section */}

Kommentar senden