import React, { useMemo, useState } from 'react' import { archetypeCoachHint, combinationArchetypeLabel } from '../constants/combinationArchetypes' import { METHOD_PROFILE_GUI_FIELDS, parseProfileJson, setFullProfileRawJson, updateProfileGuided, } from '../utils/combinationMethodProfileUi' function clampInt(n, min, max) { if (!Number.isFinite(n)) return null let x = n if (typeof min === 'number' && x < min) x = min if (typeof max === 'number' && x > max) x = max return Math.round(x) } /** * Kombination: geführtes Ablaufprofil + optionales Roh-JSON. */ export default function CombinationMethodProfileEditor({ methodArchetype, methodProfileJson, onChangeMethodProfileJson, }) { const arch = typeof methodArchetype === 'string' ? methodArchetype.trim() : '' const fieldsGui = METHOD_PROFILE_GUI_FIELDS[arch] const fields = Array.isArray(fieldsGui) ? fieldsGui : null const parseState = useMemo(() => parseProfileJson(methodProfileJson || '{}'), [methodProfileJson]) const [rawOpenError, setRawOpenError] = useState(null) const [rawDraft, setRawDraft] = useState(null) const profileObj = parseState.ok ? parseState.obj : {} const applyGuided = (key, value, kind) => { if (kind === 'bool') { const res = updateProfileGuided(arch, methodProfileJson || '{}', key, value, 'bool') if (!res.ok) return onChangeMethodProfileJson(res.json) return } if (value === '' || value === undefined || value === null) { const res = updateProfileGuided(arch, methodProfileJson || '{}', key, '', 'int') if (!res.ok) return onChangeMethodProfileJson(res.json) return } const num = typeof value === 'number' ? value : parseInt(String(value), 10) if (!Number.isFinite(num)) return const def = METHOD_PROFILE_GUI_FIELDS[arch]?.find((f) => f.key === key && f.kind === 'int') const c = clampInt(num, def?.min, def?.max) if (c == null) return const res = updateProfileGuided(arch, methodProfileJson || '{}', key, c, 'int') if (!res.ok) return onChangeMethodProfileJson(res.json) } const archeLabel = arch ? combinationArchetypeLabel(arch) : null const openAdvanced = () => { setRawOpenError(null) const p = parseProfileJson(methodProfileJson || '{}') setRawDraft(p.ok ? JSON.stringify(p.obj, null, 2) : String(methodProfileJson || '')) } return (
{arch ? (

Coach & Planung:{' '} {archeLabel && archeLabel !== arch ? `${archeLabel} · ` : ''} {archetypeCoachHint(arch)}

) : (

Wähle einen Archetyp, um das Ablaufprofil strukturiert zu erfassen — oder nur das JSON weiter unten.

)} {!parseState.ok ? (

{parseState.error}

) : null} {fields && fields.length > 0 ? (
{fields.map((def) => { if (def.kind === 'bool') { const ck = !!profileObj[def.key] return ( ) } const v = profileObj[def.key] const str = v === undefined || v === null ? '' : typeof v === 'number' && Number.isFinite(v) ? String(v) : String(v) return (
{ const t = e.target.value if (t.trim() === '') applyGuided(def.key, '', 'int') else applyGuided(def.key, parseInt(t, 10), 'int') }} />
) })}
) : arch && fields && fields.length === 0 ? (

Für diesen Archetyp gibt es keine vorgegebenen Profilfelder — nutze die Freitexte der Kombination oder Roh‑JSON bei Bedarf.

) : null}
{ if (ev.target.open) openAdvanced() }} > Erweitert: JSON direkt bearbeiten

Zusätzliche Schlüssel (Piloten). Geführte Felder können dieselben Schlüssel beim nächsten Speichern überlagern.