'use client'; import { useState } from 'react'; import { Plus, Minus, ChevronDown, ChevronRight } from 'lucide-react'; import { Button } from './ui/button'; import { Input } from './ui/input'; import { Card } from './ui/card'; export interface SchemaField { id: string; name: string; type: 'field' | 'group'; description: string; fields?: SchemaField[]; } const defaultSchema: SchemaField[] = [ { id: '1', name: 'company', type: 'field', description: 'name of company' }, { id: '2', name: 'address', type: 'field', description: 'address of company' }, { id: '3', name: 'total_sum', type: 'field', description: 'total amount we purchased' }, { id: '4', name: 'items', type: 'group', description: 'list of items purchased', fields: [ { id: '4.1', name: 'item', type: 'field', description: 'name of item' }, { id: '4.2', name: 'unit_price', type: 'field', description: 'unit price of item' }, { id: '4.3', name: 'quantity', type: 'field', description: 'quantity we purchased' }, { id: '4.4', name: 'sum', type: 'field', description: 'total amount we purchased' } ] } ]; interface SchemaDefinitionProps { onSchemaChange: (schema: SchemaField[]) => void; } export function SchemaDefinition({ onSchemaChange }: SchemaDefinitionProps) { const [schema, setSchema] = useState(defaultSchema); const [expandedGroups, setExpandedGroups] = useState>(new Set(['4'])); const toggleGroup = (id: string) => { setExpandedGroups(prev => { const next = new Set(prev); if (next.has(id)) { next.delete(id); } else { next.add(id); } return next; }); }; const addField = (parentId?: string) => { const newField: SchemaField = { id: Date.now().toString(), name: '', type: 'field', description: '' }; if (parentId) { setSchema(prev => { const updateFields = (fields: SchemaField[]): SchemaField[] => { return fields.map(field => { if (field.id === parentId) { return { ...field, fields: [...(field.fields || []), newField] }; } if (field.fields) { return { ...field, fields: updateFields(field.fields) }; } return field; }); }; return updateFields(prev); }); } else { setSchema(prev => [...prev, newField]); } }; const addGroup = (parentId?: string) => { const newGroup: SchemaField = { id: Date.now().toString(), name: '', type: 'group', description: '', fields: [] }; if (parentId) { setSchema(prev => { const updateFields = (fields: SchemaField[]): SchemaField[] => { return fields.map(field => { if (field.id === parentId) { return { ...field, fields: [...(field.fields || []), newGroup] }; } if (field.fields) { return { ...field, fields: updateFields(field.fields) }; } return field; }); }; return updateFields(prev); }); } else { setSchema(prev => [...prev, newGroup]); } setExpandedGroups(prev => new Set([...prev, newGroup.id])); }; const removeField = (id: string) => { const removeFieldFromArray = (fields: SchemaField[]): SchemaField[] => { return fields.filter(field => { if (field.id === id) return false; if (field.fields) { field.fields = removeFieldFromArray(field.fields); } return true; }); }; setSchema(prev => removeFieldFromArray(prev)); }; const updateField = (id: string, updates: Partial) => { const updateFieldInArray = (fields: SchemaField[]): SchemaField[] => { return fields.map(field => { if (field.id === id) { return { ...field, ...updates }; } if (field.fields) { return { ...field, fields: updateFieldInArray(field.fields) }; } return field; }); }; const updatedSchema = updateFieldInArray(schema); setSchema(updatedSchema); onSchemaChange(updatedSchema); }; const renderField = (field: SchemaField, depth = 0) => { const isExpanded = expandedGroups.has(field.id); return (
{field.type === 'group' && ( )} updateField(field.id, { name: e.target.value })} className="flex-1" /> updateField(field.id, { description: e.target.value })} className="flex-1" />
{field.type === 'group' && isExpanded && (
{field.fields?.map(subField => renderField(subField, depth + 1))}
)}
); }; return (

Schema Definition

{schema.map(field => renderField(field))}
); }