'use client' import React, { useState, useEffect, useCallback } from 'react' import { useRouter } from 'next/navigation' import { ClassificationBadge } from './_components/ClassificationBadge' interface CRAProject { id: string name: string description: string cra_classification: string | null conformity_path: string | null status: string created_at: string } const PATH_LABEL: Record = { self_assessment: 'Modul A (Self-Assessment)', harmonized_standard: 'Modul B (Harmonized)', eucc: 'Modul H (EUCC)', notified_body: 'Modul C (Notified Body)', } const STATUS_LABEL: Record = { draft: 'Entwurf', scoped: 'Intake erfasst', classified: 'Klassifiziert', path_selected: 'Pfad gewaehlt', requirements_mapped: 'Requirements', evidence_pending: 'Evidence', gaps_open: 'Gaps offen', remediation: 'Remediation', ready_for_review: 'In Pruefung', declaration_ready: 'DoC bereit', post_market: 'Post-Market', archived: 'Archiviert', } export default function CRAProjectsPage() { const router = useRouter() const [projects, setProjects] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [showModal, setShowModal] = useState(false) const [newName, setNewName] = useState('') const [newDescription, setNewDescription] = useState('') const [creating, setCreating] = useState(false) const tenantHeader = '00000000-0000-0000-0000-000000000001' const loadProjects = useCallback(async () => { try { const res = await fetch('/api/sdk/v1/cra/projects', { headers: { 'X-Tenant-ID': tenantHeader }, }) if (!res.ok) throw new Error(await res.text()) const data = await res.json() setProjects(data.projects || []) } catch (e) { setError(e instanceof Error ? e.message : 'Fehler beim Laden') } finally { setLoading(false) } }, []) useEffect(() => { loadProjects() }, [loadProjects]) const createProject = async () => { if (!newName.trim()) return setCreating(true) setError('') try { const res = await fetch('/api/sdk/v1/cra/projects', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Tenant-ID': tenantHeader }, body: JSON.stringify({ name: newName, description: newDescription }), }) if (!res.ok) throw new Error(await res.text()) const project = await res.json() router.push(`/sdk/cra/${project.id}/intake`) } catch (e) { setError(e instanceof Error ? e.message : 'Anlegen fehlgeschlagen') } finally { setCreating(false) } } return (

CRA Compliance

Cyber Resilience Act — Konformitaets-Workflow fuer Produkte mit digitalen Elementen.

Fuer Entwickler / Tech-Experten. Hardware-CE-Risikobeurteilung siehe{' '} iACE.

Quellen & Lizenz: Inhalte gemaess EU-Verordnung 2024/2847 (Cyber Resilience Act) — Lizenzregel R1 (EU_LAW, woertlich uebernehmbar). ENISA-Implementation-Guidance ergaenzend (R1 EU_PUBLIC).{' '} Quellenverzeichnis
{error && (
{error}
)} {loading ? (
Laedt...
) : projects.length === 0 ? (

Noch keine Projekte. Starten Sie Ihre erste CRA-Konformitaetsanalyse.

) : ( )} {showModal && (

Neues CRA-Projekt anlegen

setNewName(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-red-500" />