'use client' /** * Retention Matrix Page (Loeschfristen) * * Zeigt die Loeschfristen-Matrix fuer alle Datenpunkte nach Kategorien. */ import { useState, useMemo } from 'react' import { useSDK } from '@/lib/sdk' import { StepHeader, STEP_EXPLANATIONS } from '@/components/sdk/StepHeader' import { RetentionMatrix } from '@/components/sdk/einwilligungen' import { EinwilligungenProvider, useEinwilligungen, } from '@/lib/sdk/einwilligungen/context' import { RETENTION_MATRIX } from '@/lib/sdk/einwilligungen/catalog/loader' import { SupportedLanguage, RETENTION_PERIOD_INFO, DataPointCategory, } from '@/lib/sdk/einwilligungen/types' import { Clock, Calendar, AlertTriangle, Info, Download, Filter, ArrowLeft, BarChart3, Shield, Scale, } from 'lucide-react' import Link from 'next/link' // ============================================================================= // RETENTION STATS // ============================================================================= interface RetentionStatsProps { stats: Record } function RetentionStats({ stats }: RetentionStatsProps) { const shortTerm = (stats['24_HOURS'] || 0) + (stats['30_DAYS'] || 0) const mediumTerm = (stats['90_DAYS'] || 0) + (stats['12_MONTHS'] || 0) const longTerm = (stats['24_MONTHS'] || 0) + (stats['36_MONTHS'] || 0) const legalTerm = (stats['6_YEARS'] || 0) + (stats['10_YEARS'] || 0) const variable = (stats['UNTIL_REVOCATION'] || 0) + (stats['UNTIL_PURPOSE_FULFILLED'] || 0) + (stats['UNTIL_ACCOUNT_DELETION'] || 0) const total = shortTerm + mediumTerm + longTerm + legalTerm + variable return (
Kurzfristig
{shortTerm}
≤ 30 Tage ({total > 0 ? Math.round((shortTerm / total) * 100) : 0}%)
Mittelfristig
{mediumTerm}
90 Tage - 12 Monate ({total > 0 ? Math.round((mediumTerm / total) * 100) : 0}%)
Langfristig
{longTerm}
2-3 Jahre ({total > 0 ? Math.round((longTerm / total) * 100) : 0}%)
Gesetzlich
{legalTerm}
6-10 Jahre AO/HGB ({total > 0 ? Math.round((legalTerm / total) * 100) : 0}%)
Variabel
{variable}
Bis Widerruf/Zweck ({total > 0 ? Math.round((variable / total) * 100) : 0}%)
) } // ============================================================================= // LEGAL INFO PANEL // ============================================================================= function LegalInfoPanel() { return (

Rechtliche Grundlagen

Art. 17 DSGVO - Loeschpflicht

Personenbezogene Daten muessen geloescht werden, sobald der Zweck der Verarbeitung entfaellt und keine gesetzlichen Aufbewahrungspflichten entgegenstehen.

§ 147 AO - Steuerliche Aufbewahrung

Buchungsbelege, Rechnungen und geschaeftsrelevante Unterlagen muessen fuer 10 Jahre aufbewahrt werden.

§ 257 HGB - Handelsrechtlich

Handelsbuecher und Inventare: 10 Jahre. Handels- und Geschaeftsbriefe: 6 Jahre.

Hinweis zur Umsetzung

Die Loeschfristen muessen technisch umgesetzt werden. Implementieren Sie automatische Loeschprozesse oder Benachrichtigungen fuer manuelle Pruefungen.

) } // ============================================================================= // RETENTION TIMELINE // ============================================================================= interface RetentionTimelineProps { dataPoints: Array<{ id: string code: string name: { de: string; en: string } retentionPeriod: string }> language: SupportedLanguage } function RetentionTimeline({ dataPoints, language }: RetentionTimelineProps) { // Sort by retention period duration const sortedDataPoints = useMemo(() => { const getPeriodDays = (period: string): number => { const info = RETENTION_PERIOD_INFO[period as keyof typeof RETENTION_PERIOD_INFO] return info?.days ?? 99999 } return [...dataPoints].sort((a, b) => { return getPeriodDays(a.retentionPeriod) - getPeriodDays(b.retentionPeriod) }) }, [dataPoints]) const getColorForPeriod = (period: string): string => { const days = RETENTION_PERIOD_INFO[period as keyof typeof RETENTION_PERIOD_INFO]?.days if (days === null) return 'bg-purple-500' if (days <= 30) return 'bg-green-500' if (days <= 365) return 'bg-blue-500' if (days <= 1095) return 'bg-amber-500' return 'bg-red-500' } return (

Timeline der Loeschfristen

{sortedDataPoints.slice(0, 15).map((dp) => { const info = RETENTION_PERIOD_INFO[dp.retentionPeriod as keyof typeof RETENTION_PERIOD_INFO] const maxDays = 3650 // 10 Jahre als Maximum const width = info?.days !== null ? Math.min(100, ((info?.days || 0) / maxDays) * 100) : 100 return (
{dp.code}
{info?.label[language]}
) })} {sortedDataPoints.length > 15 && (

+ {sortedDataPoints.length - 15} weitere Datenpunkte

)}
{/* Legend */}
Legende:
≤ 30 Tage
90T-12M
2-3 Jahre
6-10 Jahre
Variabel
) } // ============================================================================= // EXPORT OPTIONS // ============================================================================= interface ExportOptionsProps { onExport: (format: 'csv' | 'json' | 'pdf') => void } function ExportOptions({ onExport }: ExportOptionsProps) { return (
) } // ============================================================================= // MAIN CONTENT // ============================================================================= function RetentionContent() { const { state } = useSDK() const { allDataPoints } = useEinwilligungen() const [language, setLanguage] = useState('de') const [filterCategory, setFilterCategory] = useState('ALL') // Calculate stats const stats = useMemo(() => { const periodCounts: Record = {} for (const dp of allDataPoints) { periodCounts[dp.retentionPeriod] = (periodCounts[dp.retentionPeriod] || 0) + 1 } return periodCounts }, [allDataPoints]) // Filter data points const filteredDataPoints = useMemo(() => { if (filterCategory === 'ALL') return allDataPoints return allDataPoints.filter((dp) => dp.category === filterCategory) }, [allDataPoints, filterCategory]) // Handle export const handleExport = (format: 'csv' | 'json' | 'pdf') => { if (format === 'csv') { const headers = ['Code', 'Name', 'Kategorie', 'Loeschfrist', 'Rechtsgrundlage'] const rows = allDataPoints.map((dp) => [ dp.code, dp.name[language], dp.category, RETENTION_PERIOD_INFO[dp.retentionPeriod as keyof typeof RETENTION_PERIOD_INFO]?.label[language] || dp.retentionPeriod, dp.legalBasis, ]) const csv = [headers, ...rows].map((row) => row.join(';')).join('\n') downloadFile(csv, 'loeschfristen.csv', 'text/csv') } else if (format === 'json') { const data = allDataPoints.map((dp) => ({ code: dp.code, name: dp.name, category: dp.category, retentionPeriod: dp.retentionPeriod, retentionLabel: RETENTION_PERIOD_INFO[dp.retentionPeriod as keyof typeof RETENTION_PERIOD_INFO]?.label, legalBasis: dp.legalBasis, })) downloadFile(JSON.stringify(data, null, 2), 'loeschfristen.json', 'application/json') } else { alert('PDF-Export wird noch implementiert.') } } const downloadFile = (content: string, filename: string, type: string) => { const blob = new Blob([content], { type }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = filename document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) } // 18 Kategorien (A-R) const categories: Array<{ id: DataPointCategory | 'ALL'; label: string }> = [ { id: 'ALL', label: 'Alle Kategorien' }, { id: 'MASTER_DATA', label: 'A: Stammdaten' }, { id: 'CONTACT_DATA', label: 'B: Kontaktdaten' }, { id: 'AUTHENTICATION', label: 'C: Authentifizierung' }, { id: 'CONSENT', label: 'D: Einwilligung' }, { id: 'COMMUNICATION', label: 'E: Kommunikation' }, { id: 'PAYMENT', label: 'F: Zahlung' }, { id: 'USAGE_DATA', label: 'G: Nutzungsdaten' }, { id: 'LOCATION', label: 'H: Standort' }, { id: 'DEVICE_DATA', label: 'I: Geraetedaten' }, { id: 'MARKETING', label: 'J: Marketing' }, { id: 'ANALYTICS', label: 'K: Analyse' }, { id: 'SOCIAL_MEDIA', label: 'L: Social Media' }, { id: 'HEALTH_DATA', label: 'M: Gesundheit (Art. 9)' }, { id: 'EMPLOYEE_DATA', label: 'N: Beschaeftigte (BDSG § 26)' }, { id: 'CONTRACT_DATA', label: 'O: Vertraege' }, { id: 'LOG_DATA', label: 'P: Protokolle' }, { id: 'AI_DATA', label: 'Q: KI-Daten (AI Act)' }, { id: 'SECURITY', label: 'R: Sicherheit' }, ] return (
{/* Back Link */} Zurueck zum Katalog {/* Header */}

Loeschfristen-Matrix

Uebersicht aller Aufbewahrungsfristen gemaess DSGVO, AO und HGB.

{/* Stats */} {/* Filters */}
{filteredDataPoints.length} Datenpunkte
{/* Two Column Layout */}
{/* Left: Matrix */}
{/* Right: Sidebar */}
) } // ============================================================================= // MAIN PAGE // ============================================================================= export default function RetentionPage() { return ( ) }