'use client' import React, { useState, useEffect, useMemo, useCallback } from 'react' import { useSDK } from '@/lib/sdk' import { StepHeader, STEP_EXPLANATIONS } from '@/components/sdk/StepHeader' import { DSRRequest, DSRType, DSRStatus, DSRStatistics, DSR_TYPE_INFO, DSR_STATUS_INFO, getDaysRemaining, isOverdue, isUrgent } from '@/lib/sdk/dsr/types' import { fetchSDKDSRList, createSDKDSR, updateSDKDSRStatus } from '@/lib/sdk/dsr/api' import { DSRWorkflowStepperCompact } from '@/components/sdk/dsr' // ============================================================================= // TYPES // ============================================================================= type TabId = 'overview' | 'intake' | 'processing' | 'completed' | 'settings' interface Tab { id: TabId label: string count?: number countColor?: string } // ============================================================================= // COMPONENTS // ============================================================================= function TabNavigation({ tabs, activeTab, onTabChange }: { tabs: Tab[] activeTab: TabId onTabChange: (tab: TabId) => void }) { return (
) } function StatCard({ label, value, color = 'gray', icon, trend }: { label: string value: number | string color?: 'gray' | 'blue' | 'yellow' | 'red' | 'green' | 'purple' icon?: React.ReactNode trend?: { value: number; label: string } }) { const colorClasses = { gray: 'border-gray-200 text-gray-900', blue: 'border-blue-200 text-blue-600', yellow: 'border-yellow-200 text-yellow-600', red: 'border-red-200 text-red-600', green: 'border-green-200 text-green-600', purple: 'border-purple-200 text-purple-600' } return (
{label}
{value}
{trend && (
= 0 ? 'text-green-600' : 'text-red-600'}`}> {trend.value >= 0 ? '+' : ''}{trend.value} {trend.label}
)}
{icon && (
{icon}
)}
) } function RequestCard({ request, onClick }: { request: DSRRequest; onClick?: () => void }) { const typeInfo = DSR_TYPE_INFO[request.type] const statusInfo = DSR_STATUS_INFO[request.status] const daysRemaining = getDaysRemaining(request.deadline.currentDeadline) const overdue = isOverdue(request) const urgent = isUrgent(request) return (
{/* Header Badges */}
{request.referenceNumber} {typeInfo.article} {typeInfo.labelShort} {!request.identityVerification.verified && request.status !== 'completed' && request.status !== 'rejected' && ( ID fehlt )}
{/* Requester Info */}

{request.requester.name}

{request.requester.email}

{/* Workflow Status */}
{/* Right Side - Deadline */}
{request.status === 'completed' || request.status === 'rejected' || request.status === 'cancelled' ? statusInfo.label : overdue ? `${Math.abs(daysRemaining)} Tage ueberfaellig` : `${daysRemaining} Tage` }
{new Date(request.receivedAt).toLocaleDateString('de-DE')}
{/* Notes Preview */} {request.notes && (
{request.notes}
)} {/* Footer */}
{request.assignment.assignedTo ? `Zugewiesen: ${request.assignment.assignedTo}` : 'Nicht zugewiesen' }
{request.status !== 'completed' && request.status !== 'rejected' && request.status !== 'cancelled' && ( <> {!request.identityVerification.verified && ( ID pruefen )} Bearbeiten )} {request.status === 'completed' && ( Details )}
) } function FilterBar({ selectedType, selectedStatus, selectedPriority, onTypeChange, onStatusChange, onPriorityChange, onClear }: { selectedType: DSRType | 'all' selectedStatus: DSRStatus | 'all' selectedPriority: string onTypeChange: (type: DSRType | 'all') => void onStatusChange: (status: DSRStatus | 'all') => void onPriorityChange: (priority: string) => void onClear: () => void }) { const hasFilters = selectedType !== 'all' || selectedStatus !== 'all' || selectedPriority !== 'all' return (
Filter: {/* Type Filter */} {/* Status Filter */} {/* Priority Filter */} {/* Clear Filters */} {hasFilters && ( )}
) } // ============================================================================= // DSR CREATE MODAL // ============================================================================= function DSRCreateModal({ onClose, onSuccess }: { onClose: () => void onSuccess: () => void }) { const [type, setType] = useState('access') const [subjectName, setSubjectName] = useState('') const [subjectEmail, setSubjectEmail] = useState('') const [description, setDescription] = useState('') const [source, setSource] = useState('web_form') const [isSaving, setIsSaving] = useState(false) const [error, setError] = useState(null) const deadline = new Date() deadline.setDate(deadline.getDate() + 30) const deadlineStr = deadline.toLocaleDateString('de-DE') const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!subjectName.trim() || !subjectEmail.trim()) return setIsSaving(true) setError(null) try { await createSDKDSR({ type, requester: { name: subjectName.trim(), email: subjectEmail.trim() }, requestText: description.trim(), source }) onSuccess() } catch (err: unknown) { setError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsSaving(false) } } return (
{/* Backdrop */}
{/* Modal */}

Neue Anfrage anlegen

{error && (
{error}
)}
{/* Type */}
{/* Subject Name */}
setSubjectName(e.target.value)} required className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="Vor- und Nachname" />
{/* Subject Email */}
setSubjectEmail(e.target.value)} required className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm" placeholder="email@beispiel.de" />
{/* Description */}