diff --git a/admin-compliance/app/sdk/_components/PresetSection.tsx b/admin-compliance/app/sdk/_components/PresetSection.tsx new file mode 100644 index 0000000..2c882dd --- /dev/null +++ b/admin-compliance/app/sdk/_components/PresetSection.tsx @@ -0,0 +1,131 @@ +'use client' + +import { useState } from 'react' +import Link from 'next/link' +import { COMPANY_PROFILE_PRESETS, type CompanyProfilePreset } from '@/lib/sdk/company-profile-presets' + +const DOC_LABELS: Record = { + privacy_policy: { label: 'Datenschutzerklaerung', category: 'Website' }, + impressum: { label: 'Impressum', category: 'Website' }, + agb: { label: 'AGB', category: 'Vertraege' }, + cookie_policy: { label: 'Cookie-Richtlinie', category: 'Website' }, + cookie_banner: { label: 'Cookie-Banner-Texte', category: 'Website' }, + dpa: { label: 'AVV (Auftragsverarbeitung)', category: 'Vertraege' }, + nda: { label: 'Geheimhaltungsvereinbarung', category: 'Vertraege' }, + sla: { label: 'Service Level Agreement', category: 'Vertraege' }, + terms_of_use: { label: 'Nutzungsbedingungen', category: 'Vertraege' }, + community_guidelines: { label: 'Community Guidelines', category: 'Plattform' }, + acceptable_use: { label: 'Acceptable Use Policy', category: 'Plattform' }, + widerruf: { label: 'Widerrufsbelehrung', category: 'E-Commerce' }, + employee_dsi: { label: 'Mitarbeiter-DSI', category: 'HR' }, + applicant_dsi: { label: 'Bewerber-DSI', category: 'HR' }, + whistleblower_policy: { label: 'Whistleblower-Richtlinie', category: 'HR' }, + tom_documentation: { label: 'TOM-Dokumentation', category: 'Compliance' }, + vvt_register: { label: 'Verarbeitungsverzeichnis', category: 'Compliance' }, + loeschkonzept: { label: 'Loeschkonzept', category: 'Compliance' }, + dsfa: { label: 'Datenschutz-Folgenabschaetzung', category: 'Compliance' }, + pflichtenregister: { label: 'Pflichtenregister', category: 'Compliance' }, + isms_manual: { label: 'ISMS-Handbuch', category: 'Sicherheit' }, + social_media_dsi: { label: 'Social-Media-DSI', category: 'Marketing' }, + transfer_impact_assessment: { label: 'Transfer Impact Assessment', category: 'Drittland' }, + media_content_policy: { label: 'Medien-Richtlinie', category: 'Plattform' }, + cloud_service_agreement: { label: 'Cloud-Vertrag', category: 'Vertraege' }, +} + +const CATEGORY_COLORS: Record = { + Website: 'bg-blue-50 text-blue-700', + Vertraege: 'bg-purple-50 text-purple-700', + Plattform: 'bg-indigo-50 text-indigo-700', + 'E-Commerce': 'bg-green-50 text-green-700', + HR: 'bg-amber-50 text-amber-700', + Compliance: 'bg-red-50 text-red-700', + Sicherheit: 'bg-gray-100 text-gray-700', + Marketing: 'bg-pink-50 text-pink-700', + Drittland: 'bg-orange-50 text-orange-700', +} + +export function PresetSection({ projectId }: { projectId?: string }) { + const [selectedPreset, setSelectedPreset] = useState(null) + + // Group recommended docs by category + const groupedDocs = selectedPreset + ? selectedPreset.recommendedDocs.reduce>((acc, docType) => { + const info = DOC_LABELS[docType] + if (!info) return acc + if (!acc[info.category]) acc[info.category] = [] + acc[info.category].push(info.label) + return acc + }, {}) + : null + + return ( +
+
+

Schnellstart: Welcher Unternehmenstyp sind Sie?

+

+ Waehlen Sie Ihre Branche — wir zeigen Ihnen welche Dokumente Sie benoetigen. +

+
+ + {/* Preset Cards */} +
+ {COMPANY_PROFILE_PRESETS.map((preset) => ( + + ))} +
+ + {/* Document Preview — shown when a preset is selected */} + {selectedPreset && groupedDocs && ( +
+
+
+

+ {selectedPreset.icon} {selectedPreset.label} — Ihre Dokumente +

+

+ {selectedPreset.recommendedDocs.length} Dokumente werden fuer Sie vorbereitet +

+
+ + Jetzt starten + +
+ +
+ {Object.entries(groupedDocs).map(([category, docs]) => ( +
+ + {category} + + {docs.map((doc) => ( +
+ {doc} +
+ ))} +
+ ))} +
+
+ )} +
+ ) +} diff --git a/admin-compliance/app/sdk/page.tsx b/admin-compliance/app/sdk/page.tsx index c6d8dd8..01c9ac0 100644 --- a/admin-compliance/app/sdk/page.tsx +++ b/admin-compliance/app/sdk/page.tsx @@ -2,29 +2,18 @@ import React from 'react' import Link from 'next/link' -import { useRouter } from 'next/navigation' import { useSDK, SDK_PACKAGES, getStepsForPackage } from '@/lib/sdk' import { ProjectSelector } from '@/components/sdk/ProjectSelector/ProjectSelector' import { RegulatoryNewsFeed } from '@/components/sdk/regulatory-news/RegulatoryNewsFeed' -import { COMPANY_PROFILE_PRESETS, type CompanyProfilePreset } from '@/lib/sdk/company-profile-presets' +import { PresetSection } from './_components/PresetSection' import type { SDKPackageId } from '@/lib/sdk/types' // ============================================================================= // DASHBOARD CARDS // ============================================================================= -function StatCard({ - title, - value, - subtitle, - icon, - color, -}: { - title: string - value: string | number - subtitle: string - icon: React.ReactNode - color: string +function StatCard({ title, value, subtitle, icon, color }: { + title: string; value: string | number; subtitle: string; icon: React.ReactNode; color: string }) { return (
@@ -40,18 +29,8 @@ function StatCard({ ) } -function PackageCard({ - pkg, - completion, - stepsCount, - isLocked, - projectId, -}: { - pkg: (typeof SDK_PACKAGES)[number] - completion: number - stepsCount: number - isLocked: boolean - projectId?: string +function PackageCard({ pkg, completion, stepsCount, isLocked, projectId }: { + pkg: (typeof SDK_PACKAGES)[number]; completion: number; stepsCount: number; isLocked: boolean; projectId?: string }) { const steps = getStepsForPackage(pkg.id) const firstStep = steps[0] @@ -59,36 +38,20 @@ function PackageCard({ const href = projectId ? `${baseHref}?project=${projectId}` : baseHref const content = ( -
+
-
+
{isLocked ? ( - - - + ) : completion === 100 ? ( - - - - ) : ( - pkg.icon - )} + + ) : pkg.icon}
@@ -99,61 +62,27 @@ function PackageCard({
{stepsCount} Schritte - - {completion}% - + {completion}%
-
+
- {!isLocked && ( -

- Ergebnis: {pkg.result} -

- )} + {!isLocked &&

Ergebnis: {pkg.result}

}
) - if (isLocked) { - return content - } - - return ( - - {content} - - ) + return isLocked ? content : {content} } -function QuickActionCard({ - title, - description, - icon, - href, - color, - projectId, -}: { - title: string - description: string - icon: React.ReactNode - href: string - color: string - projectId?: string +function QuickActionCard({ title, description, icon, href, color, projectId }: { + title: string; description: string; icon: React.ReactNode; href: string; color: string; projectId?: string }) { const finalHref = projectId ? `${href}?project=${projectId}` : href return ( - +
{icon}

{title}

@@ -172,23 +101,15 @@ function QuickActionCard({ export default function SDKDashboard() { const { state, packageCompletion, completionPercentage, setCustomerType, projectId } = useSDK() - - // customerType is set during project creation — default to 'new' for legacy projects const effectiveCustomerType = state.customerType || 'new' - // No project selected → show project list - if (!projectId) { - return - } + if (!projectId) return - // Calculate total steps const totalSteps = SDK_PACKAGES.reduce((sum, pkg) => { const steps = getStepsForPackage(pkg.id) - // Filter import step for new customers return sum + steps.filter(s => !(s.id === 'import' && effectiveCustomerType === 'new')).length }, 0) - // Calculate stats const completedCheckpoints = Object.values(state.checkpoints).filter(cp => cp.passed).length const totalRisks = state.risks.length const criticalRisks = state.risks.filter(r => r.severity === 'CRITICAL' || r.severity === 'HIGH').length @@ -197,11 +118,8 @@ export default function SDKDashboard() { if (state.preferences?.allowParallelWork) return false const pkg = SDK_PACKAGES.find(p => p.id === packageId) if (!pkg || pkg.order === 1) return false - - // Check if previous package is complete const prevPkg = SDK_PACKAGES.find(p => p.order === pkg.order - 1) if (!prevPkg) return false - return packageCompletion[prevPkg.id] < 100 } @@ -212,109 +130,39 @@ export default function SDKDashboard() {

AI Compliance SDK

- {effectiveCustomerType === 'new' - ? 'Neukunden-Modus: Erstellen Sie alle Compliance-Dokumente von Grund auf.' - : 'Bestandskunden-Modus: Erweitern Sie bestehende Dokumente.'} + {effectiveCustomerType === 'new' ? 'Neukunden-Modus: Erstellen Sie alle Compliance-Dokumente von Grund auf.' : 'Bestandskunden-Modus: Erweitern Sie bestehende Dokumente.'}

-
- {/* Industry Presets — shown when company profile is empty */} - {!state.companyProfile?.companyName && ( -
-

Schnellstart: Welcher Unternehmenstyp sind Sie?

-

- Waehlen Sie Ihre Branche — wir befuellen alle Felder vor und empfehlen die passenden Dokumente. -

-
- {COMPANY_PROFILE_PRESETS.map((preset) => ( - - {preset.icon} - {preset.label} - {preset.description} - - ))} -
-
- )} + {/* Industry Presets with Document Preview */} + {!state.companyProfile?.companyName && } {/* Stats Grid */}
- - - - } - color="bg-purple-50" - /> - - - - } - color="bg-blue-50" - /> - - - - } - color="bg-green-50" - /> - 0 ? `${criticalRisks} kritisch` : 'Keine kritischen'} - icon={ - - - - } - color="bg-orange-50" - /> + } color="bg-purple-50" /> + } color="bg-blue-50" /> + } color="bg-green-50" /> + 0 ? `${criticalRisks} kritisch` : 'Keine kritischen'} + icon={} color="bg-orange-50" />
{/* Bestandskunden: Gap Analysis Banner */} {effectiveCustomerType === 'existing' && state.importedDocuments.length === 0 && (
-
- 📄 -
+
📄

Bestehende Dokumente importieren

-

- Laden Sie Ihre vorhandenen Compliance-Dokumente hoch. Unsere KI analysiert sie und zeigt Ihnen, welche Erweiterungen fuer KI-Compliance erforderlich sind. -

- - - - +

Laden Sie Ihre vorhandenen Compliance-Dokumente hoch. Unsere KI analysiert sie und zeigt Ihnen, welche Erweiterungen erforderlich sind.

+ + Dokumente hochladen
@@ -326,38 +174,21 @@ export default function SDKDashboard() { {state.gapAnalysis && (
-
- 📊 -
+
📊

Gap-Analyse Ergebnis

-

- {state.gapAnalysis.totalGaps} Luecken gefunden -

+

{state.gapAnalysis.totalGaps} Luecken gefunden

-
-
{state.gapAnalysis.criticalGaps}
-
Kritisch
-
-
-
{state.gapAnalysis.highGaps}
-
Hoch
-
-
-
{state.gapAnalysis.mediumGaps}
-
Mittel
-
-
-
{state.gapAnalysis.lowGaps}
-
Niedrig
-
+
{state.gapAnalysis.criticalGaps}
Kritisch
+
{state.gapAnalysis.highGaps}
Hoch
+
{state.gapAnalysis.mediumGaps}
Mittel
+
{state.gapAnalysis.lowGaps}
Niedrig
)} - {/* Regulatory News */} {/* 5 Packages */} @@ -367,17 +198,7 @@ export default function SDKDashboard() { {SDK_PACKAGES.map(pkg => { const steps = getStepsForPackage(pkg.id) const visibleSteps = steps.filter(s => !(s.id === 'import' && effectiveCustomerType === 'new')) - - return ( - - ) + return })}
@@ -386,54 +207,18 @@ export default function SDKDashboard() {

Schnellaktionen

- - - - } - href="/sdk/advisory-board" - color="bg-purple-50" - projectId={projectId} - /> - - - - } - href="/sdk/screening" - color="bg-red-50" - projectId={projectId} - /> - - - - } - href="/sdk/dsfa" - color="bg-blue-50" - projectId={projectId} - /> - - - - } - href="/sdk/rag" - color="bg-green-50" - projectId={projectId} - /> + } + href="/sdk/advisory-board" color="bg-purple-50" projectId={projectId} /> + } + href="/sdk/screening" color="bg-red-50" projectId={projectId} /> + } + href="/sdk/dsfa" color="bg-blue-50" projectId={projectId} /> + } + href="/sdk/rag" color="bg-green-50" projectId={projectId} />
@@ -444,30 +229,15 @@ export default function SDKDashboard() {
{state.commandBarHistory.slice(0, 5).map(entry => (
-
- {entry.success ? ( - - - - ) : ( - - - - )} +
+ {entry.success ? + : }

{entry.query}

-

- {new Date(entry.timestamp).toLocaleString('de-DE')} -

+

{new Date(entry.timestamp).toLocaleString('de-DE')}

- - {entry.type} - + {entry.type}
))}