refactor(admin): split AIUseCaseModuleEditor, DataPointCatalog, ProjectSelector components
AIUseCaseModuleEditor (698 LOC) → thin orchestrator (187) + constants (29) + barrel tabs (4) + tabs implementation split into SystemData (261), PurposeAct (149), RisksReview (219). DataPointCatalog (658 LOC) → main (291) + helpers (190) + CategoryGroup (124) + Row (108). ProjectSelector (656 LOC) → main (211) + CreateProjectDialog (169) + ProjectActionDialog (140) + ProjectCard (128). All files now under 300 LOC soft target and 500 LOC hard cap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
'use client'
|
||||
|
||||
import { ChevronDown, ChevronRight } from 'lucide-react'
|
||||
import {
|
||||
DataPoint,
|
||||
DataPointCategory,
|
||||
SupportedLanguage,
|
||||
CATEGORY_METADATA,
|
||||
} from '@/lib/sdk/einwilligungen/types'
|
||||
import { CategoryIcon } from './DataPointCatalogHelpers'
|
||||
import { DataPointRow } from './DataPointRow'
|
||||
|
||||
interface DataPointCategoryGroupProps {
|
||||
category: DataPointCategory
|
||||
categoryDataPoints: DataPoint[]
|
||||
selectedIds: string[]
|
||||
isExpanded: boolean
|
||||
readOnly: boolean
|
||||
language: SupportedLanguage
|
||||
onToggleCategory: (category: DataPointCategory) => void
|
||||
onToggleDataPoint: (id: string) => void
|
||||
}
|
||||
|
||||
export function DataPointCategoryGroup({
|
||||
category,
|
||||
categoryDataPoints,
|
||||
selectedIds,
|
||||
isExpanded,
|
||||
readOnly,
|
||||
language,
|
||||
onToggleCategory,
|
||||
onToggleDataPoint,
|
||||
}: DataPointCategoryGroupProps) {
|
||||
const meta = CATEGORY_METADATA[category]
|
||||
const selectedInCategory = categoryDataPoints.filter((dp) =>
|
||||
selectedIds.includes(dp.id)
|
||||
).length
|
||||
|
||||
return (
|
||||
<div className="border border-slate-200 rounded-xl overflow-hidden bg-white">
|
||||
{/* Category Header */}
|
||||
<button
|
||||
onClick={() => onToggleCategory(category)}
|
||||
className={`w-full flex items-center justify-between px-4 py-3 transition-colors ${
|
||||
category === 'HEALTH_DATA'
|
||||
? 'bg-rose-50 hover:bg-rose-100 border-l-4 border-rose-400'
|
||||
: category === 'EMPLOYEE_DATA'
|
||||
? 'bg-orange-50 hover:bg-orange-100 border-l-4 border-orange-400'
|
||||
: category === 'AI_DATA'
|
||||
? 'bg-fuchsia-50 hover:bg-fuchsia-100 border-l-4 border-fuchsia-400'
|
||||
: 'bg-slate-50 hover:bg-slate-100'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`p-2 rounded-lg ${
|
||||
category === 'HEALTH_DATA' ? 'bg-rose-100' :
|
||||
category === 'EMPLOYEE_DATA' ? 'bg-orange-100' :
|
||||
category === 'AI_DATA' ? 'bg-fuchsia-100' :
|
||||
`bg-${meta.color}-100`
|
||||
}`}>
|
||||
<CategoryIcon
|
||||
category={category}
|
||||
className={`w-5 h-5 ${
|
||||
category === 'HEALTH_DATA' ? 'text-rose-600' :
|
||||
category === 'EMPLOYEE_DATA' ? 'text-orange-600' :
|
||||
category === 'AI_DATA' ? 'text-fuchsia-600' :
|
||||
`text-${meta.color}-600`
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-semibold text-slate-900">
|
||||
{meta.code}. {meta.name[language]}
|
||||
</span>
|
||||
{category === 'HEALTH_DATA' && (
|
||||
<span className="text-xs bg-rose-200 text-rose-700 px-1.5 py-0.5 rounded font-medium">
|
||||
Art. 9 DSGVO
|
||||
</span>
|
||||
)}
|
||||
{category === 'EMPLOYEE_DATA' && (
|
||||
<span className="text-xs bg-orange-200 text-orange-700 px-1.5 py-0.5 rounded font-medium">
|
||||
BDSG § 26
|
||||
</span>
|
||||
)}
|
||||
{category === 'AI_DATA' && (
|
||||
<span className="text-xs bg-fuchsia-200 text-fuchsia-700 px-1.5 py-0.5 rounded font-medium">
|
||||
AI Act
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-xs text-slate-500">{meta.description[language]}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-slate-500">
|
||||
{selectedInCategory}/{categoryDataPoints.length}
|
||||
</span>
|
||||
{isExpanded ? (
|
||||
<ChevronDown className="w-5 h-5 text-slate-400" />
|
||||
) : (
|
||||
<ChevronRight className="w-5 h-5 text-slate-400" />
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* Data Points List */}
|
||||
{isExpanded && (
|
||||
<div className="divide-y divide-slate-100">
|
||||
{categoryDataPoints.map((dp) => (
|
||||
<DataPointRow
|
||||
key={dp.id}
|
||||
dp={dp}
|
||||
isSelected={selectedIds.includes(dp.id)}
|
||||
readOnly={readOnly}
|
||||
language={language}
|
||||
onToggle={onToggleDataPoint}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user