'use client' import { useState } from 'react' import { useParams, useRouter } from 'next/navigation' import { useOperationalStates, type OperationalStateInfo } from './_hooks/useOperationalStates' // ── State descriptions for ISO 12100 context ─────────────── const STATE_DESCRIPTIONS: Record = { startup: 'Erstmaliges oder wiederholtes Einschalten der Maschine', homing: 'Referenzfahrt der Achsen nach dem Einschalten', automatic_operation: 'Vollautomatischer Produktionsbetrieb', manual_operation: 'Manuell gesteuerter Betrieb (Handrad, Tippbetrieb)', teach_mode: 'Programmierung und Einrichten bei reduzierter Geschwindigkeit', maintenance: 'Geplante Wartungs- und Instandhaltungsarbeiten', cleaning: 'Reinigung der Maschine und des Arbeitsbereichs', emergency_stop: 'Not-Halt ausgeloest — Maschine im sicheren Zustand', recovery_mode: 'Wiederanlauf nach Not-Halt oder Stoerung', } const STATE_ICONS: Record = { startup: 'M13 10V3L4 14h7v7l9-11h-7z', homing: 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0h4', automatic_operation: 'M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15', manual_operation: 'M7 11.5V14m0-2.5v-6a1.5 1.5 0 113 0m-3 6a1.5 1.5 0 00-3 0v2a7.5 7.5 0 0015 0v-5a1.5 1.5 0 00-3 0m-6-3V11m0-5.5v-1a1.5 1.5 0 013 0v1m0 0V11m0-5.5a1.5 1.5 0 013 0v3m0 0V11', teach_mode: 'M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z', maintenance: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z', cleaning: 'M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z', emergency_stop: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z', recovery_mode: 'M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15', } const STATE_COLORS: Record = { startup: { bg: 'bg-blue-50 dark:bg-blue-900/20', border: 'border-blue-200 dark:border-blue-800', text: 'text-blue-700 dark:text-blue-300' }, homing: { bg: 'bg-indigo-50 dark:bg-indigo-900/20', border: 'border-indigo-200 dark:border-indigo-800', text: 'text-indigo-700 dark:text-indigo-300' }, automatic_operation: { bg: 'bg-green-50 dark:bg-green-900/20', border: 'border-green-200 dark:border-green-800', text: 'text-green-700 dark:text-green-300' }, manual_operation: { bg: 'bg-yellow-50 dark:bg-yellow-900/20', border: 'border-yellow-200 dark:border-yellow-800', text: 'text-yellow-700 dark:text-yellow-300' }, teach_mode: { bg: 'bg-orange-50 dark:bg-orange-900/20', border: 'border-orange-200 dark:border-orange-800', text: 'text-orange-700 dark:text-orange-300' }, maintenance: { bg: 'bg-purple-50 dark:bg-purple-900/20', border: 'border-purple-200 dark:border-purple-800', text: 'text-purple-700 dark:text-purple-300' }, cleaning: { bg: 'bg-cyan-50 dark:bg-cyan-900/20', border: 'border-cyan-200 dark:border-cyan-800', text: 'text-cyan-700 dark:text-cyan-300' }, emergency_stop: { bg: 'bg-red-50 dark:bg-red-900/20', border: 'border-red-200 dark:border-red-800', text: 'text-red-700 dark:text-red-300' }, recovery_mode: { bg: 'bg-amber-50 dark:bg-amber-900/20', border: 'border-amber-200 dark:border-amber-800', text: 'text-amber-700 dark:text-amber-300' }, } export default function OperationalStatesPage() { const { projectId } = useParams<{ projectId: string }>() const router = useRouter() const { allStates, activeTransitions, selectedStates, toggleState, saveSelection, runDeltaAnalysis, loading, saving, saved, deltaResult, deltaLoading, } = useOperationalStates(projectId) const [initStatus, setInitStatus] = useState<'idle' | 'running' | 'done' | 'error'>('idle') const [initResult, setInitResult] = useState<{ steps: { name: string; status: string; count: number; details?: string }[]; summary?: Record } | null>(null) async function handleInitialize(force: boolean) { // Save current selection first await saveSelection(selectedStates) setInitStatus('running') setInitResult(null) try { const url = `/api/sdk/v1/iace/projects/${projectId}/initialize${force ? '?force=true' : ''}` const res = await fetch(url, { method: 'POST' }) if (!res.ok) { const err = await res.json().catch(() => ({})) alert(err.error || 'Initialisierung fehlgeschlagen') setInitStatus('error') return } const data = await res.json() setInitResult(data) setInitStatus('done') } catch { setInitStatus('error') } } if (loading) { return (
) } const hasChanges = true // always allow save (metadata merge is idempotent) return (
{/* Header */}

Betriebszustaende

Waehlen Sie die relevanten Betriebszustaende fuer diese Maschine (ISO 12100 Abschnitt 5)

{saved && ( Gespeichert )} {selectedStates.length} / {allStates.length} aktiv
{/* State Selection Grid */}
{allStates.map((state) => ( toggleState(state.id)} /> ))}
{/* Active Transitions */} {selectedStates.length >= 2 && (

Zustandsuebergaenge ({activeTransitions.length})

Gueltige Uebergaenge zwischen den ausgewaehlten Betriebszustaenden gemaess ISO 12100 State Graph

{activeTransitions.length === 0 ? (

Keine direkten Uebergaenge zwischen den ausgewaehlten Zustaenden.

) : (
{activeTransitions.map((t) => { const [from, to] = t.split('\u2192') const fromLabel = allStates.find((s) => s.id === from)?.label_de || from const toLabel = allStates.find((s) => s.id === to)?.label_de || to return (
{fromLabel} {toLabel}
) })}
)}
)} {/* Delta Analysis */}

Delta-Vorschau

Zeigt die Auswirkungen der Zustandsaenderung auf Gefaehrdungen und Massnahmen

{deltaResult && (
{deltaResult.added_hazards.length > 0 && (

+ Neue Gefaehrdungen

    {deltaResult.added_hazards.slice(0, 10).map((h, i) => (
  • + {h}
  • ))} {deltaResult.added_hazards.length > 10 && (
  • ... und {deltaResult.added_hazards.length - 10} weitere
  • )}
)} {deltaResult.added_measures.length > 0 && (

+ Neue Massnahmen ({deltaResult.added_measures.length})

)} {deltaResult.added_patterns === 0 && deltaResult.removed_patterns === 0 && (

Keine Aenderungen erkannt — die Zustandsauswahl hat keinen Einfluss auf die aktuellen Patterns.

)}
)}
{/* Initialize Section */}

Projekt initialisieren

Erzeugt Gefaehrdungen und Massnahmen basierend auf Maschinenbeschreibung, Komponenten und den ausgewaehlten Betriebszustaenden.

{initResult && (

Initialisierung abgeschlossen

{initResult.steps.map((s, i) => (
{s.status === 'done' ? '\u2713' : s.status === 'skipped' ? '\u25CB' : '\u2717'} {s.name} {s.count > 0 && ({s.count})} {s.details && — {s.details}}
))}
)}
{/* Footer Actions */}
) } // ── Sub-components ───────────────────────────────────────── function StateCard({ state, selected, onToggle, }: { state: OperationalStateInfo selected: boolean onToggle: () => void }) { const colors = STATE_COLORS[state.id] || STATE_COLORS.startup const description = STATE_DESCRIPTIONS[state.id] || '' const iconPath = STATE_ICONS[state.id] || STATE_ICONS.startup return ( ) } function DeltaStat({ label, value, positive, }: { label: string value: number positive: boolean }) { const color = value === 0 ? 'text-gray-400' : positive ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' return (
{value > 0 && positive ? '+' : ''}{value}
{label}
) }