/** * Renders config fields from an IssuerTypeConfig.configFields definition. * Handles sensitive field masking. M34 will reuse this directly for its * dynamic config wizard. M35 can reuse it for target config forms. */ import type { ConfigField } from '../../config/issuerTypes'; interface ConfigFormProps { fields: ConfigField[]; values: Record; onChange: (key: string, value: unknown) => void; /** When true, sensitive fields show as ******** with a "Change" button. * Used in edit mode — empty value means "keep existing". */ editMode?: boolean; } export default function ConfigForm({ fields, values, onChange, editMode }: ConfigFormProps) { return (
{fields.map((field) => ( onChange(field.key, v)} editMode={editMode} /> ))}
); } function ConfigFieldInput({ field, value, onChange, editMode, }: { field: ConfigField; value: unknown; onChange: (v: unknown) => void; editMode?: boolean; }) { const inputCls = 'w-full px-3 py-2 bg-surface border border-surface-border rounded text-ink placeholder-ink-faint focus:outline-none focus:border-brand-500 transition-colors'; // In edit mode, sensitive fields that haven't been touched show as masked if (editMode && field.sensitive && value === undefined) { return (
********
); } if (field.type === 'select') { return (
); } if (field.type === 'textarea') { return (