/** * FormFieldRenderer - Dynamic form field renderer * Renders form fields based on configuration objects * * Usage: * ```typescript * * ``` */ import React from 'react'; import Input from './input/InputField'; import SelectDropdown from './SelectDropdown'; import Label from './Label'; export interface FormFieldConfig { key: string; label: string; type: 'text' | 'number' | 'email' | 'password' | 'select' | 'textarea'; placeholder?: string; options?: Array<{ value: string; label: string }>; required?: boolean; min?: number; max?: number; rows?: number; className?: string; gridCols?: 1 | 2; // For inline fields (e.g., Volume & Difficulty) } interface FormFieldRendererProps { fields: FormFieldConfig[]; values: Record; onChange: (key: string, value: any) => void; errors?: Record; disabled?: boolean; } export default function FormFieldRenderer({ fields, values, onChange, errors = {}, disabled = false, }: FormFieldRendererProps) { // Group fields by grid layout const fieldGroups: FormFieldConfig[][] = []; let currentGroup: FormFieldConfig[] = []; fields.forEach((field) => { if (field.gridCols === 2) { // Start new group for inline fields if (currentGroup.length > 0) { fieldGroups.push(currentGroup); currentGroup = []; } currentGroup.push(field); if (currentGroup.length === 2) { fieldGroups.push(currentGroup); currentGroup = []; } } else { // Full-width field if (currentGroup.length > 0) { fieldGroups.push(currentGroup); currentGroup = []; } fieldGroups.push([field]); } }); if (currentGroup.length > 0) { fieldGroups.push(currentGroup); } const renderField = (field: FormFieldConfig) => { const value = values[field.key] || ''; const error = errors[field.key]; const fieldId = `field-${field.key}`; return (
{field.type === 'select' ? ( onChange(field.key, val)} className="w-full" /> ) : field.type === 'textarea' ? (