'use client' /** * DataPointCatalog Component * * Zeigt den vollstaendigen Datenpunktkatalog an. * Ermoeglicht Filterung, Suche und Auswahl von Datenpunkten. * Unterstützt 18 Kategorien (A-R) inkl. Art. 9 DSGVO Warnungen. */ import { useState, useMemo } from 'react' import { Search } from 'lucide-react' import { DataPoint, DataPointCategory, RiskLevel, LegalBasis, SupportedLanguage, CATEGORY_METADATA, RISK_LEVEL_STYLING, LEGAL_BASIS_INFO, } from '@/lib/sdk/einwilligungen/types' import { searchDataPoints } from '@/lib/sdk/einwilligungen/catalog/loader' import { SpecialCategoryWarning } from './DataPointCatalogHelpers' import { DataPointCategoryGroup } from './DataPointCategoryGroup' // ============================================================================= // TYPES // ============================================================================= interface DataPointCatalogProps { dataPoints: DataPoint[] selectedIds: string[] onToggle: (id: string) => void onSelectAll?: () => void onDeselectAll?: () => void language?: SupportedLanguage showFilters?: boolean readOnly?: boolean } // ============================================================================= // CATEGORY ORDER // ============================================================================= const ALL_CATEGORIES: DataPointCategory[] = [ 'MASTER_DATA', // A 'CONTACT_DATA', // B 'AUTHENTICATION', // C 'CONSENT', // D 'COMMUNICATION', // E 'PAYMENT', // F 'USAGE_DATA', // G 'LOCATION', // H 'DEVICE_DATA', // I 'MARKETING', // J 'ANALYTICS', // K 'SOCIAL_MEDIA', // L 'HEALTH_DATA', // M - Art. 9 DSGVO 'EMPLOYEE_DATA', // N - BDSG § 26 'CONTRACT_DATA', // O 'LOG_DATA', // P 'AI_DATA', // Q - AI Act 'SECURITY', // R ] // ============================================================================= // MAIN COMPONENT // ============================================================================= export function DataPointCatalog({ dataPoints, selectedIds, onToggle, onSelectAll, onDeselectAll, language = 'de', showFilters = true, readOnly = false, }: DataPointCatalogProps) { const [searchQuery, setSearchQuery] = useState('') const [expandedCategories, setExpandedCategories] = useState>( new Set(ALL_CATEGORIES) ) const [filterCategory, setFilterCategory] = useState('ALL') const [filterRisk, setFilterRisk] = useState('ALL') const [filterBasis, setFilterBasis] = useState('ALL') const [dismissedWarnings, setDismissedWarnings] = useState>(new Set()) const filteredDataPoints = useMemo(() => { let result = dataPoints if (searchQuery.trim()) { result = searchDataPoints(result, searchQuery, language) } if (filterCategory !== 'ALL') { result = result.filter((dp) => dp.category === filterCategory) } if (filterRisk !== 'ALL') { result = result.filter((dp) => dp.riskLevel === filterRisk) } if (filterBasis !== 'ALL') { result = result.filter((dp) => dp.legalBasis === filterBasis) } return result }, [dataPoints, searchQuery, filterCategory, filterRisk, filterBasis, language]) const groupedDataPoints = useMemo(() => { const grouped = new Map() for (const cat of ALL_CATEGORIES) { grouped.set(cat, []) } for (const dp of filteredDataPoints) { const existing = grouped.get(dp.category) || [] grouped.set(dp.category, [...existing, dp]) } return grouped }, [filteredDataPoints]) const selectedSpecialCategories = useMemo(() => { const special = new Set() for (const id of selectedIds) { const dp = dataPoints.find(d => d.id === id) if (dp) { if (dp.category === 'HEALTH_DATA' || dp.isSpecialCategory) { special.add('HEALTH_DATA') } if (dp.category === 'EMPLOYEE_DATA') { special.add('EMPLOYEE_DATA') } if (dp.category === 'AI_DATA') { special.add('AI_DATA') } } } return special }, [selectedIds, dataPoints]) const toggleCategory = (category: DataPointCategory) => { setExpandedCategories((prev) => { const next = new Set(prev) if (next.has(category)) { next.delete(category) } else { next.add(category) } return next }) } const totalSelected = selectedIds.length const totalDataPoints = dataPoints.length return (
{/* Header with Stats */}
{totalSelected} von{' '} {totalDataPoints} Datenpunkte ausgewaehlt
{!readOnly && (
|
)}
{/* Art. 9 / BDSG § 26 / AI Act Warnungen */} {selectedSpecialCategories.size > 0 && (
{selectedSpecialCategories.has('HEALTH_DATA') && !dismissedWarnings.has('HEALTH_DATA') && ( setDismissedWarnings(prev => new Set([...prev, 'HEALTH_DATA']))} /> )} {selectedSpecialCategories.has('EMPLOYEE_DATA') && !dismissedWarnings.has('EMPLOYEE_DATA') && ( setDismissedWarnings(prev => new Set([...prev, 'EMPLOYEE_DATA']))} /> )} {selectedSpecialCategories.has('AI_DATA') && !dismissedWarnings.has('AI_DATA') && ( setDismissedWarnings(prev => new Set([...prev, 'AI_DATA']))} /> )}
)} {/* Search and Filters */} {showFilters && (
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" />
)} {/* Data Points by Category */}
{Array.from(groupedDataPoints.entries()).map(([category, categoryDataPoints]) => { if (categoryDataPoints.length === 0) return null return ( ) })}
{/* Empty State */} {filteredDataPoints.length === 0 && (

Keine Datenpunkte gefunden

Versuchen Sie andere Suchbegriffe oder Filter

)}
) } export default DataPointCatalog