diff --git a/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx b/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx index ed4f704..90db017 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/hazards/_components/RiskAssessmentTable.tsx @@ -80,6 +80,25 @@ export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, const [mitCounts, setMitCounts] = useState>({}) const [edits, setEdits] = useState>({}) const [saving, setSaving] = useState(null) + const [normsByCategory, setNormsByCategory] = useState>({}) + + // Fetch norms library and build category→norm-numbers map + useEffect(() => { + fetch(`/api/sdk/v1/iace/norms-library`) + .then(r => r.ok ? r.json() : null) + .then(json => { + if (!json?.norms) return + const map: Record = {} + for (const n of json.norms) { + for (const cat of (n.hazard_cats || [])) { + if (!map[cat]) map[cat] = [] + if (map[cat].length < 3) map[cat].push(n.number) + } + } + setNormsByCategory(map) + }) + .catch(() => {}) + }, []) // Fetch mitigation counts per hazard useEffect(() => { @@ -226,6 +245,11 @@ export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, {CATEGORY_LABELS[h.category] || h.category} + {normsByCategory[h.category]?.length > 0 && ( +
+ {normsByCategory[h.category].slice(0, 2).join(', ')} +
+ )} {/* Initial S/E/P/RPZ/Risk */} {initS} diff --git a/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx b/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx index b88f2f2..8332891 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/mitigations/page.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' import { useParams } from 'next/navigation' import { REDUCTION_TYPES, Mitigation } from './_components/types' import { HierarchyWarning } from './_components/HierarchyWarning' @@ -21,6 +21,24 @@ export default function MitigationsPage() { fetchMeasuresLibrary, handleSubmit, handleAddSuggestedMeasure, handleVerify, handleDelete, } = useMitigations(projectId) + const [measureNorms, setMeasureNorms] = useState>({}) + + useEffect(() => { + fetch('/api/sdk/v1/iace/protective-measures-library') + .then(r => r.ok ? r.json() : null) + .then(json => { + if (!json?.protective_measures) return + const map: Record = {} + for (const m of json.protective_measures) { + if (m.norm_references?.length > 0) { + map[(m.name || '').toLowerCase()] = m.norm_references + } + } + setMeasureNorms(map) + }) + .catch(() => {}) + }, []) + const [showForm, setShowForm] = useState(false) const [preselectedType, setPreselectedType] = useState<'design' | 'protection' | 'information' | undefined>() const [showLibrary, setShowLibrary] = useState(false) @@ -195,6 +213,12 @@ export default function MitigationsPage() {
{m.title || ''}
{m.description &&
{m.description}
} + {(() => { + const refs = measureNorms[(m.title || '').toLowerCase()] + return refs?.length > 0 ? ( +
Normen: {refs.join(', ')}
+ ) : null + })()}
{(m.linked_hazard_names || []).join(', ') || '-'} diff --git a/admin-compliance/app/sdk/iace/[projectId]/norms/page.tsx b/admin-compliance/app/sdk/iace/[projectId]/norms/page.tsx new file mode 100644 index 0000000..4f210e1 --- /dev/null +++ b/admin-compliance/app/sdk/iace/[projectId]/norms/page.tsx @@ -0,0 +1,39 @@ +'use client' + +import { useParams } from 'next/navigation' +import { SuggestedNorms } from '../_components/SuggestedNorms' + +export default function NormsPage() { + const params = useParams() + const projectId = params.projectId as string + + return ( +
+ {/* Page header */} +
+

Normenrecherche

+

+ Relevante Normen fuer Ihr Produkt, automatisch ermittelt aus Maschinentyp, Gefaehrdungen + und Komponenten. Ergaenzen Sie bei Bedarf weitere Normen manuell. +

+
+ + {/* Info banner */} +
+
+ + + +
+ A-Normen (z.B. ISO 12100) gelten fuer alle Maschinen.{' '} + B-Normen decken Sicherheitsaspekte ab (B1: Grundnormen, B2: Schutzeinrichtungen).{' '} + C-Normen sind maschinenspezifisch und erzeugen eine Konformitaetsvermutung. +
+
+
+ + {/* Suggested norms component — rendered expanded (not collapsed by default) */} + +
+ ) +} diff --git a/admin-compliance/app/sdk/iace/layout.tsx b/admin-compliance/app/sdk/iace/layout.tsx index d14bff8..0adc87a 100644 --- a/admin-compliance/app/sdk/iace/layout.tsx +++ b/admin-compliance/app/sdk/iace/layout.tsx @@ -9,6 +9,7 @@ const IACE_NAV_ITEMS = [ { id: 'overview', label: 'Uebersicht', href: '', icon: 'grid' }, { id: 'order', label: 'Auftrag', href: '/order', icon: 'briefcase' }, { id: 'interview', label: 'Grenzen & Verwendung', href: '/interview', icon: 'chat' }, + { id: 'norms', label: 'Normenrecherche', href: '/norms', icon: 'book' }, { id: 'components', label: 'Komponenten', href: '/components', icon: 'cube' }, { id: 'hazards', label: 'Hazard Log', href: '/hazards', icon: 'warning' }, { id: 'mitigations', label: 'Massnahmen', href: '/mitigations', icon: 'shield' }, @@ -91,6 +92,12 @@ function NavIcon({ icon, className }: { icon: string; className?: string }) { ) + case 'book': + return ( + + + + ) default: return null }