42d4b4d9c5
CI / detect-changes (push) Successful in 19s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 7s
CI / validate-canonical-controls (push) Successful in 4s
CI / loc-budget (push) Successful in 21s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m13s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
Schritt A (Tokens): zentrale Design-Sprache aus dem Claude-Design-Handoff —
Tailwind-Tokens (re/geltung/severity/domain) + Fonts (Public Sans / Source
Serif 4 / IBM Plex Mono) + components/redesign/{tokens.ts,Chips.tsx}
(GeltungChip, SeverityChip, DomainTag, MonoId) + Showcase /sdk/design-system.
Bestehende Farben/sans unangetastet.
Schritt B (Ebene 2): CyberMeetsSafety als USP-Hero im CRA/Cyber-Tab
(/sdk/iace/[id]/cra) — Domaenen-Bar, Hazard-Karten (CE-gemildert -> Cyber-Befund
-> Restrisiko, Warum-Box, Pflicht/Empfehlung-Massnahmen, aufklappbarer
Norm-Bezug), Massnahmen-Backlog mit Geltung-Filter. Gebunden an echte
cross_links/findings/open_measures. Bisheriger CRACyberView bleibt eingeklappt
erhalten -> kein Inhaltsverlust.
Guardrail-Doku: design/redesign/ (HANDOFF_README, CONTENT_INVENTORY mit
40-Screen-Mapping + Waisen-Liste, Arbeitsbereich.dc.html-Referenz).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
'use client'
|
||
|
||
import { useParams } from 'next/navigation'
|
||
import { useCRA } from './_hooks/useCRA'
|
||
import { CRACyberView } from './_components/CRACyberView'
|
||
import { CyberMeetsSafety } from './_components/CyberMeetsSafety'
|
||
import { WeightsControl } from './_components/WeightsControl'
|
||
import { SnapshotPanel } from './_components/SnapshotPanel'
|
||
import { ScannerRepoPicker } from './_components/ScannerRepoPicker'
|
||
|
||
export default function CRAPage() {
|
||
const params = useParams()
|
||
const projectId = params?.projectId as string | undefined
|
||
const { data, live, weights, setWeights, snapshots, saveSnapshot, viewSnapshot, scannerRepo, setScannerRepo } = useCRA(projectId)
|
||
if (!data) {
|
||
return <p className="text-sm text-gray-500">CRA-Risikobeurteilung wird geladen …</p>
|
||
}
|
||
return (
|
||
<div className="space-y-6">
|
||
<div className="flex items-center justify-between gap-3">
|
||
<span className="text-sm text-gray-500">
|
||
Projektgebundene CE × Cyber-Analyse
|
||
</span>
|
||
<a href="/sdk/cra" className="text-sm text-purple-600 hover:underline whitespace-nowrap">
|
||
Allgemeiner CRA-Readiness-Check →
|
||
</a>
|
||
</div>
|
||
{!live && (
|
||
<p className="text-sm text-amber-600 dark:text-amber-400">
|
||
Backend nicht erreichbar — statisches Szenario angezeigt.
|
||
</p>
|
||
)}
|
||
<ScannerRepoPicker value={scannerRepo} onChange={setScannerRepo} />
|
||
<WeightsControl weights={weights} onChange={setWeights} />
|
||
|
||
{/* Ebene 2 — Cyber trifft Safety (Redesign, neue Design-Sprache) */}
|
||
<div>
|
||
<h2 className="font-publicSans" style={{ fontSize: 19, fontWeight: 800, letterSpacing: '-0.01em', color: '#1A1D29', marginBottom: 12 }}>
|
||
Cyber trifft Safety
|
||
</h2>
|
||
<CyberMeetsSafety data={data} />
|
||
</div>
|
||
|
||
{/* Bisherige Detailansicht (bleibt erhalten, bis das Redesign 100% abdeckt) */}
|
||
<details className="rounded-lg border border-gray-200 dark:border-gray-700">
|
||
<summary className="cursor-pointer px-4 py-2 text-sm text-gray-500">Bisherige Detailansicht (CRACyberView)</summary>
|
||
<div className="p-1">
|
||
<CRACyberView data={data} scannerRepo={scannerRepo} />
|
||
</div>
|
||
</details>
|
||
<SnapshotPanel snapshots={snapshots} onSave={saveSnapshot} onView={viewSnapshot} />
|
||
</div>
|
||
)
|
||
}
|