Files
sistema_base/apps/web/feactures/training/components/form.tsx
2025-12-01 18:23:18 -04:00

432 lines
19 KiB
TypeScript

'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@repo/shadcn/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@repo/shadcn/form';
import { Input } from '@repo/shadcn/input';
import { Textarea } from '@repo/shadcn/textarea';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@repo/shadcn/select';
import { useForm } from 'react-hook-form';
import { useCreateTraining } from "../hooks/use-training";
import { TrainingSchema, trainingSchema } from '../schemas/training';
const PRODUCTIVE_ACTIVITIES = [
'Agricola',
'Textil',
'Bloquera',
'Carpinteria',
'Unidad de suministro'
];
interface CreateTrainingFormProps {
onSuccess?: () => void;
onCancel?: () => void;
defaultValues?: Partial<TrainingSchema>;
}
export function CreateTrainingForm({
onSuccess,
onCancel,
defaultValues,
}: CreateTrainingFormProps) {
const {
mutate: saveTraining,
isPending: isSaving,
} = useCreateTraining();
const form = useForm<TrainingSchema>({
resolver: zodResolver(trainingSchema),
defaultValues: {
firstname: defaultValues?.firstname || '',
lastname: defaultValues?.lastname || '',
visitDate: defaultValues?.visitDate || new Date().toISOString().split('T')[0],
productiveActivity: defaultValues?.productiveActivity || '',
financialRequirementDescription: defaultValues?.financialRequirementDescription || '',
siturCodeCommune: defaultValues?.siturCodeCommune || '',
communalCouncil: defaultValues?.communalCouncil || '',
siturCodeCommunalCouncil: defaultValues?.siturCodeCommunalCouncil || '',
ospName: defaultValues?.ospName || '',
ospAddress: defaultValues?.ospAddress || '',
ospRif: defaultValues?.ospRif || '',
ospType: defaultValues?.ospType || '',
currentStatus: defaultValues?.currentStatus || '',
companyConstitutionYear: defaultValues?.companyConstitutionYear || new Date().getFullYear(),
producerCount: defaultValues?.producerCount || 0,
productDescription: defaultValues?.productDescription || '',
installedCapacity: defaultValues?.installedCapacity || '',
operationalCapacity: defaultValues?.operationalCapacity || '',
ospResponsibleFullname: defaultValues?.ospResponsibleFullname || '',
ospResponsibleCedula: defaultValues?.ospResponsibleCedula || '',
ospResponsibleRif: defaultValues?.ospResponsibleRif || '',
ospResponsiblePhone: defaultValues?.ospResponsiblePhone || '',
civilState: defaultValues?.civilState || '',
familyBurden: defaultValues?.familyBurden || 0,
numberOfChildren: defaultValues?.numberOfChildren || 0,
generalObservations: defaultValues?.generalObservations || '',
photo1: defaultValues?.photo1 || '',
photo2: defaultValues?.photo2 || '',
photo3: defaultValues?.photo3 || '',
paralysisReason: defaultValues?.paralysisReason || '',
state: defaultValues?.state || '',
municipality: defaultValues?.municipality || '',
parish: defaultValues?.parish || '',
},
mode: 'onChange',
});
const onSubmit = async (formData: TrainingSchema) => {
saveTraining(formData, {
onSuccess: () => {
form.reset();
onSuccess?.();
},
onError: (e) => {
console.error(e);
form.setError('root', {
type: 'manual',
message: 'Error al guardar el registro',
});
},
});
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
{form.formState.errors.root && (
<div className="text-destructive text-sm">
{form.formState.errors.root.message}
</div>
)}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* Datos Personales */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2">Datos Básicos</h3>
</div>
<FormField control={form.control} name="firstname" render={({ field }) => (
<FormItem>
<FormLabel>Nombre</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="lastname" render={({ field }) => (
<FormItem>
<FormLabel>Apellido</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="visitDate" render={({ field }) => (
<FormItem>
<FormLabel>Fecha de la visita</FormLabel>
<FormControl><Input type="date" {...field} value={field.value ? new Date(field.value).toISOString().split('T')[0] : ''} /></FormControl>
<FormMessage />
</FormItem>
)} />
{/* Ubicación */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2 mt-4">Ubicación</h3>
</div>
<FormField control={form.control} name="state" render={({ field }) => (
<FormItem>
<FormLabel>Estado</FormLabel>
<FormControl><Input {...field} value={field.value || ''} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="municipality" render={({ field }) => (
<FormItem>
<FormLabel>Municipio</FormLabel>
<FormControl><Input {...field} value={field.value || ''} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="parish" render={({ field }) => (
<FormItem>
<FormLabel>Parroquia</FormLabel>
<FormControl><Input {...field} value={field.value || ''} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="siturCodeCommune" render={({ field }) => (
<FormItem>
<FormLabel>Código SITUR Comuna</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="communalCouncil" render={({ field }) => (
<FormItem>
<FormLabel>Consejo Comunal</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="siturCodeCommunalCouncil" render={({ field }) => (
<FormItem>
<FormLabel>Código SITUR Consejo Comunal</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
{/* Datos de la OSP */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2 mt-4">Datos de la Organización Socioproductiva (OSP)</h3>
</div>
<FormField control={form.control} name="ospName" render={({ field }) => (
<FormItem>
<FormLabel>Nombre de la Organización</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospAddress" render={({ field }) => (
<FormItem>
<FormLabel>Dirección</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospRif" render={({ field }) => (
<FormItem>
<FormLabel>RIF</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospType" render={({ field }) => (
<FormItem>
<FormLabel>Tipo de Organización</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="productiveActivity" render={({ field }) => (
<FormItem>
<FormLabel>Actividad Productiva</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Seleccione actividad" />
</SelectTrigger>
</FormControl>
<SelectContent>
{PRODUCTIVE_ACTIVITIES.map((activity) => (
<SelectItem key={activity} value={activity}>
{activity}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="currentStatus" render={({ field }) => (
<FormItem>
<FormLabel>Estatus Actual</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="companyConstitutionYear" render={({ field }) => (
<FormItem>
<FormLabel>Año de Constitución</FormLabel>
<FormControl><Input type="number" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="producerCount" render={({ field }) => (
<FormItem>
<FormLabel>Cantidad de Productores</FormLabel>
<FormControl><Input type="number" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="productDescription" render={({ field }) => (
<FormItem className="col-span-2">
<FormLabel>Breve descripción del producto o servicio</FormLabel>
<FormControl><Textarea {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="installedCapacity" render={({ field }) => (
<FormItem>
<FormLabel>Capacidad Instalada</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="operationalCapacity" render={({ field }) => (
<FormItem>
<FormLabel>Capacidad Operativa</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="financialRequirementDescription" render={({ field }) => (
<FormItem className="col-span-2">
<FormLabel>Descripción del Requerimiento Financiero</FormLabel>
<FormControl><Textarea {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="paralysisReason" render={({ field }) => (
<FormItem className="col-span-2">
<FormLabel>Razones de paralización (si aplica)</FormLabel>
<FormControl><Textarea {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
{/* Responsable */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2 mt-4">Datos del Responsable</h3>
</div>
<FormField control={form.control} name="ospResponsibleFullname" render={({ field }) => (
<FormItem>
<FormLabel>Nombre y Apellido</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospResponsibleCedula" render={({ field }) => (
<FormItem>
<FormLabel>Cédula (sin puntos)</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospResponsibleRif" render={({ field }) => (
<FormItem>
<FormLabel>RIF (sin puntos)</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="ospResponsiblePhone" render={({ field }) => (
<FormItem>
<FormLabel>Teléfonos (2 números)</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="civilState" render={({ field }) => (
<FormItem>
<FormLabel>Estado Civil</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="familyBurden" render={({ field }) => (
<FormItem>
<FormLabel>Carga Familiar</FormLabel>
<FormControl><Input type="number" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="numberOfChildren" render={({ field }) => (
<FormItem>
<FormLabel>Número de Hijos</FormLabel>
<FormControl><Input type="number" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="generalObservations" render={({ field }) => (
<FormItem className="col-span-2">
<FormLabel>Observaciones Generales</FormLabel>
<FormControl><Textarea {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
{/* Fotos */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2 mt-4">Registro Fotográfico (URLs)</h3>
</div>
<FormField control={form.control} name="photo1" render={({ field }) => (
<FormItem>
<FormLabel>Foto 1</FormLabel>
<FormControl><Input {...field} placeholder="URL de la imagen" /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="photo2" render={({ field }) => (
<FormItem>
<FormLabel>Foto 2</FormLabel>
<FormControl><Input {...field} placeholder="URL de la imagen" /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="photo3" render={({ field }) => (
<FormItem>
<FormLabel>Foto 3</FormLabel>
<FormControl><Input {...field} placeholder="URL de la imagen" /></FormControl>
<FormMessage />
</FormItem>
)} />
</div>
<div className="flex justify-end gap-4 mt-6">
<Button variant="outline" type="button" onClick={onCancel}>
Cancelar
</Button>
<Button type="submit" disabled={isSaving}>
{isSaving ? 'Guardando...' : 'Guardar'}
</Button>
</div>
</form>
</Form>
);
}