import React, { useState, useEffect, useCallback } from 'react' import { Link } from 'react-router-dom' import api from '../utils/api' import { notifyOrgInboxChanged, useOrgInbox } from '../context/OrgInboxContext' const CLUB_ROLE_OPTIONS = [ { code: 'club_admin', label: 'Vereinsadmin' }, { code: 'trainer', label: 'Trainer' }, { code: 'division_lead', label: 'Spartenleitung' }, { code: 'content_editor', label: 'Inhalte bearbeiten' }, ] const REASON_LABELS = { copyright: 'Urheberrecht', image_rights: 'Bildrechte', privacy: 'Datenschutz / Persönlichkeitsrecht', minors: 'Minderjährige', illegal_content: 'Rechtswidriger Inhalt', youth_protection: 'Jugendschutz', offensive_content: 'Beleidigender Inhalt', other: 'Sonstiges', } const STATUS_LABELS = { submitted: 'Eingegangen', under_review: 'In Bearbeitung', resolved_no_action: 'Abgeschlossen (kein Handlungsbedarf)', resolved_legal_hold: 'Abgeschlossen (Legal Hold)', rejected_invalid: 'Abgewiesen (ungültig)', } const STATUS_COLORS = { submitted: 'var(--accent)', under_review: '#e8960a', resolved_no_action: 'var(--text3)', resolved_legal_hold: 'var(--danger)', rejected_invalid: 'var(--text3)', } function formatWhen(iso) { if (!iso) return '' const s = String(iso) const d = s.includes('T') ? s.split('T')[0] : s.slice(0, 10) const t = s.includes('T') ? s.split('T')[1] : '' const time = t ? t.slice(0, 5) : '' return time ? `${d} · ${time}` : d } function PriorityBadge({ priority }) { if (priority !== 'high') return null return ( DRINGEND ) } function ReportDetailModal({ report, onClose, onRefresh, isSuperadmin }) { const [resolutionNote, setResolutionNote] = useState('') const [legalHoldNote, setLegalHoldNote] = useState('') const [saving, setSaving] = useState(false) const [error, setError] = useState(null) const [showLegalHoldForm, setShowLegalHoldForm] = useState(false) const isOpen = report.status === 'submitted' || report.status === 'under_review' async function handleStatus(status) { if ((status === 'resolved_no_action' || status === 'rejected_invalid') && !resolutionNote.trim()) { setError('Bitte eine Begründung eingeben.') return } setSaving(true) setError(null) try { await api.patchContentReport(report.id, { status, resolution_note: resolutionNote.trim() || undefined, }) notifyOrgInboxChanged() onRefresh() onClose() } catch (err) { setError(err.message || String(err)) } finally { setSaving(false) } } async function handleUnderReview() { setSaving(true) setError(null) try { await api.patchContentReport(report.id, { status: 'under_review' }) notifyOrgInboxChanged() onRefresh() onClose() } catch (err) { setError(err.message || String(err)) } finally { setSaving(false) } } async function handleLegalHold() { if (!legalHoldNote.trim()) { setError('Begründung für Legal Hold erforderlich.') return } setSaving(true) setError(null) try { await api.setLegalHoldFromReport(report.id, { reason_note: legalHoldNote.trim() }) notifyOrgInboxChanged() onRefresh() onClose() } catch (err) { setError(err.message || String(err)) } finally { setSaving(false) } } return (
{ if (e.target === e.currentTarget) onClose() }} >

Meldung #{report.id}

Status
{STATUS_LABELS[report.status] || report.status}
Ziel
{report.target_type === 'media_asset' ? 'Medium' : 'Übung'} #{report.target_id} {report.target_name ? ` – ${report.target_name}` : ''}
Meldegrund
{REASON_LABELS[report.report_reason] || report.report_reason}
Beschreibung
{report.report_description}
Meldende Person
{report.reporter_name} {report.reporter_email ? ` · ${report.reporter_email}` : ''} {report.reporter_profile_id ? ` · Profil #${report.reporter_profile_id}` : ' · anonym'}
Eingegangen
{formatWhen(report.submitted_at || report.created_at)}
{report.resolution_note && (
Begründung
{report.resolution_note}
)} {report.legal_hold_active && (
Legal Hold aktiv
)}
{error && (
{error}
)} {isOpen && (
{report.status === 'submitted' && ( )}