import type { IntakeFormField } from '@/types' import { InlineVariablePrompt } from './InlineVariablePrompt' interface ResolvedTextProps { text: string variables: Record intakeFields?: IntakeFormField[] onVariableSubmit?: (variableName: string, value: string) => void className?: string } /** * Renders text with resolved variables inline. Unresolved [VAR:x] tokens * are replaced with interactive InlineVariablePrompt components. */ export function ResolvedText({ text, variables, intakeFields, onVariableSubmit, className, }: ResolvedTextProps) { if (!text) return null // Split on variable tokens, keeping the tokens in the result const tokenPattern = /(\[(?:VAR|USER_INPUT):([^\]]+)\])/g const parts: Array<{ type: 'text'; value: string } | { type: 'var'; variableName: string; token: string }> = [] let lastIndex = 0 let match // Remove [SAVE_AS:...] tokens first const cleaned = text.replace(/\[SAVE_AS:[^\]]+\]/g, '') while ((match = tokenPattern.exec(cleaned)) !== null) { // Add text before the token if (match.index > lastIndex) { parts.push({ type: 'text', value: cleaned.slice(lastIndex, match.index) }) } const variableName = match[2].trim() const resolvedValue = variables[variableName] if (resolvedValue && resolvedValue.trim()) { // Variable is resolved — render as plain text parts.push({ type: 'text', value: resolvedValue }) } else { // Variable is unresolved — render as inline prompt parts.push({ type: 'var', variableName, token: match[1] }) } lastIndex = match.index + match[0].length } // Add remaining text if (lastIndex < cleaned.length) { parts.push({ type: 'text', value: cleaned.slice(lastIndex) }) } // If no unresolved variables, just render plain text const hasUnresolved = parts.some(p => p.type === 'var') if (!hasUnresolved) { const fullText = parts.map(p => p.type === 'text' ? p.value : '').join('') return {fullText} } // Find field metadata helper const getFieldMeta = (varName: string) => intakeFields?.find(f => f.variable_name === varName) return ( {parts.map((part, i) => { if (part.type === 'text') { return {part.value} } return ( {})} /> ) })} ) }