/** * Dynamic custom field renderer. * Renders the appropriate input element based on field_type. */ import React, { useId } from 'react'; import { Input } from '@/components/ui/Input'; import { Select } from '@/components/ui/Select'; import { Badge } from '@/components/ui/Badge'; import { X } from 'lucide-react'; import type { CustomFieldDefinition } from '@/api/customFieldDefinitions'; export interface CustomFieldRendererProps { definition: CustomFieldDefinition; value: any; onChange: (value: any) => void; } export function CustomFieldRenderer({ definition, value, onChange }: CustomFieldRendererProps) { const generatedId = useId(); const fieldId = `cf-${definition.id || generatedId}`; const { field_type, options, required } = definition; // --- Boolean: checkbox --- if (field_type === 'boolean') { return (
); } // --- Multiselect: chips with toggle --- if (field_type === 'multiselect') { const selectedValues: string[] = Array.isArray(value) ? value : value != null && value !== '' ? [String(value)] : []; const availableOptions = options || []; const toggleOption = (opt: string) => { if (selectedValues.includes(opt)) { onChange(selectedValues.filter((v) => v !== opt)); } else { onChange([...selectedValues, opt]); } }; const removeChip = (opt: string) => { onChange(selectedValues.filter((v) => v !== opt)); }; const unselected = availableOptions.filter((o) => !selectedValues.includes(o)); return (
{selectedValues.length > 0 && (
{selectedValues.map((opt) => ( {opt} ))}
)} {unselected.length > 0 ? (
{unselected.map((opt) => ( ))}
) : availableOptions.length === 0 ? (

Keine Optionen verfügbar

) : (

Alle Optionen ausgewählt

)}
); } // --- Select: dropdown --- if (field_type === 'select') { const selectOptions = (options || []).map((opt) => ({ value: opt, label: opt })); return ( { const raw = e.target.value; onChange(raw === '' ? null : Number(raw)); }} /> ); } // --- Date: date input --- if (field_type === 'date') { return ( onChange(e.target.value)} /> ); } // --- Text (default) --- return ( onChange(e.target.value)} /> ); }