mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 23:12:35 +00:00
#591 - sites [wip]
This commit is contained in:
82
resources/js/components/ui/dynamic-field.tsx
Normal file
82
resources/js/components/ui/dynamic-field.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import { InputHTMLAttributes } from 'react';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DynamicFieldConfig } from '@/types/dynamic-field-config';
|
||||
import InputError from '@/components/ui/input-error';
|
||||
import { FormField } from '@/components/ui/form';
|
||||
|
||||
interface DynamicFieldProps {
|
||||
value: string | number | boolean | string[] | undefined;
|
||||
onChange: (value: string | number | boolean | string[]) => void;
|
||||
config: DynamicFieldConfig;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export default function DynamicField({ value, onChange, config, error }: DynamicFieldProps) {
|
||||
const defaultLabel = config.name.replaceAll('_', ' ');
|
||||
const label = config?.label || defaultLabel;
|
||||
|
||||
if (!value) {
|
||||
value = config?.default || '';
|
||||
}
|
||||
|
||||
// Handle checkbox
|
||||
if (config?.type === 'checkbox') {
|
||||
return (
|
||||
<FormField>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch id={`switch-${config.name}`} checked={value as boolean} onCheckedChange={onChange} />
|
||||
<Label htmlFor={`switch-${config.name}`}>{label}</Label>
|
||||
{config.description && <p className="text-muted-foreground text-xs">{config.description}</p>}
|
||||
<InputError message={error} />
|
||||
</div>
|
||||
</FormField>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle select
|
||||
if (config?.type === 'select' && config.options) {
|
||||
return (
|
||||
<FormField>
|
||||
<Label htmlFor={config.name} className="capitalize">
|
||||
{label}
|
||||
</Label>
|
||||
<Select value={value as string} onValueChange={onChange}>
|
||||
<SelectTrigger id={config.name}>
|
||||
<SelectValue placeholder={config.placeholder || `Select ${label}`} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
{config.options.map((item) => (
|
||||
<SelectItem key={`${config.name}-${item}`} value={item}>
|
||||
{item}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{config.description && <p className="text-muted-foreground text-xs">{config.description}</p>}
|
||||
<InputError message={error} />
|
||||
</FormField>
|
||||
);
|
||||
}
|
||||
|
||||
// Default to text input
|
||||
const props: InputHTMLAttributes<HTMLInputElement> = {};
|
||||
if (config?.placeholder) {
|
||||
props.placeholder = config.placeholder;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormField>
|
||||
<Label htmlFor={config.name} className="capitalize">
|
||||
{label}
|
||||
</Label>
|
||||
<Input type="text" name={config.name} id={config.name} value={(value as string) || ''} onChange={(e) => onChange(e.target.value)} {...props} />
|
||||
{config.description && <p className="text-muted-foreground text-xs">{config.description}</p>}
|
||||
<InputError message={error} />
|
||||
</FormField>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user