import { useState, useCallback } from "react"; import type { XOTemplate } from "@xo-cash/types"; import type { VariableInput } from "../types.js"; /** * Manages the variable input state for the wizard's variables step. * * Populates variables from the template's action/role requirements * and provides validation + update helpers. */ export function useVariableInputs() { const [variables, setVariables] = useState([]); /** * Populate the variable list from the template's role requirements. * Calling this again replaces the current variables entirely. */ const initFromTemplate = useCallback( ( template: XOTemplate, actionIdentifier: string, roleIdentifier: string, ) => { const action = template.actions?.[actionIdentifier]; const role = action?.roles?.[roleIdentifier]; const varIds = role?.requirements?.variables ?? []; const varInputs: VariableInput[] = varIds.map((varId) => { const varDef = template.variables?.[varId]; return { id: varId, name: varDef?.name || varId, type: varDef?.type || "string", hint: varDef?.hint, value: "", }; }); setVariables(varInputs); }, [], ); /** Update a single variable's value by index. */ const updateVariable = useCallback((index: number, value: string) => { setVariables((prev) => { const updated = [...prev]; const variable = updated[index]; if (variable) { updated[index] = { ...variable, value }; } return updated; }); }, []); /** Returns an error message if any required variable is empty, or null if valid. */ const validate = useCallback((): string | null => { const emptyVars = variables.filter( (v) => !v.value || v.value.trim() === "", ); if (emptyVars.length > 0) { return `Please enter values for: ${emptyVars.map((v) => v.name).join(", ")}`; } return null; }, [variables]); return { variables, setVariables, initFromTemplate, updateVariable, validate, } as const; } export type VariableInputsState = ReturnType;