265 lines
8.0 KiB
TypeScript
265 lines
8.0 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 {
|
|
// Select,
|
|
// SelectContent,
|
|
// SelectItem,
|
|
// SelectTrigger,
|
|
// SelectValue,
|
|
// } from '@repo/shadcn/select';
|
|
import { SelectSearchable } from '@repo/shadcn/select-searchable'
|
|
import { useForm } from 'react-hook-form';
|
|
import { useUpdateProfile } from "@/feactures/users/hooks/use-mutation-users";
|
|
import { UpdateUser, updateUser } from '@/feactures/users/schemas/users';
|
|
import { toast } from 'sonner';
|
|
|
|
import React from 'react';
|
|
import { useStateQuery, useMunicipalityQuery, useParishQuery } from '@/feactures/location/hooks/use-query-location';
|
|
|
|
interface UserFormProps {
|
|
onSuccess?: () => void;
|
|
onCancel?: () => void;
|
|
defaultValues?: Partial<UpdateUser>;
|
|
}
|
|
|
|
export function ModalForm({
|
|
onSuccess,
|
|
onCancel,
|
|
defaultValues,
|
|
}: UserFormProps) {
|
|
const {
|
|
mutate: saveAccountingAccounts,
|
|
isPending: isSaving,
|
|
isError,
|
|
} = useUpdateProfile();
|
|
|
|
const [state, setState] = React.useState(0);
|
|
const [municipality, setMunicipality] = React.useState(0);
|
|
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
|
|
const [disabledParish, setDisabledParish] = React.useState(true);
|
|
|
|
const { data : dataState } = useStateQuery()
|
|
const { data : dataMunicipality } = useMunicipalityQuery(state)
|
|
const { data : dataParish } = useParishQuery(municipality)
|
|
|
|
const stateOptions = dataState?.data || [{id:0,name:'Sin estados'}]
|
|
|
|
const municipalityOptions = Array.isArray(dataMunicipality?.data) && dataMunicipality.data.length > 0
|
|
? dataMunicipality.data
|
|
: [{id:0,stateId:0,name:'Sin Municipios'}]
|
|
// const parishOptions = dataParish?.data || [{id:0,municipalityId:0,name:'Sin Parroquias'}]
|
|
const parishOptions = Array.isArray(dataParish?.data) && dataParish.data.length > 0
|
|
? dataParish.data
|
|
: [{id:0,stateId:0,name:'Sin Parroquias'}]
|
|
|
|
|
|
const defaultformValues = {
|
|
username: defaultValues?.username || '',
|
|
fullname: defaultValues?.fullname || '',
|
|
email: defaultValues?.email || '',
|
|
password: '',
|
|
id: defaultValues?.id,
|
|
phone: defaultValues?.phone || '',
|
|
role: undefined,
|
|
isActive: defaultValues?.isActive,
|
|
state: undefined,
|
|
municipality: undefined,
|
|
parish: undefined
|
|
}
|
|
|
|
// console.log(defaultValues);
|
|
|
|
const form = useForm<UpdateUser>({
|
|
resolver: zodResolver(updateUser),
|
|
defaultValues: defaultformValues,
|
|
mode: 'onChange', // Enable real-time validation
|
|
});
|
|
|
|
const onSubmit = async (data: UpdateUser) => {
|
|
|
|
const formData = data
|
|
|
|
saveAccountingAccounts(formData, {
|
|
onSuccess: () => {
|
|
form.reset();
|
|
onSuccess?.();
|
|
toast.success('Actualizado exitosamente!');
|
|
},
|
|
onError: (e) => {
|
|
form.setError('root', {
|
|
type: 'manual',
|
|
message: e.message,
|
|
});
|
|
// toast.error(e.message);
|
|
},
|
|
});
|
|
};
|
|
|
|
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-2 gap-4">
|
|
<FormField
|
|
control={form.control}
|
|
name="fullname"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Nombre completo</FormLabel>
|
|
<FormControl>
|
|
<Input {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="email"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Correo</FormLabel>
|
|
<FormControl>
|
|
<Input {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="phone"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Teléfono</FormLabel>
|
|
<FormControl>
|
|
<Input {...field} value={field.value?.toString() ?? ''}/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="state"
|
|
render={({ field }) => (
|
|
<FormItem className="w-full">
|
|
<FormLabel>Estado</FormLabel>
|
|
|
|
<SelectSearchable
|
|
options={
|
|
stateOptions?.map((item) => ({
|
|
value: item.id.toString(),
|
|
label: item.name,
|
|
})) || []
|
|
}
|
|
onValueChange={(value : any) =>
|
|
{field.onChange(Number(value)); setState(value); setDisabledMunicipality(false); setDisabledParish(true)}
|
|
}
|
|
placeholder="Selecciona un estado"
|
|
defaultValue={field.value?.toString()}
|
|
// disabled={readOnly}
|
|
/>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="municipality"
|
|
render={({ field }) => (
|
|
<FormItem className="w-full">
|
|
<FormLabel>Municipio</FormLabel>
|
|
|
|
<SelectSearchable
|
|
options={
|
|
municipalityOptions?.map((item) => ({
|
|
value: item.id.toString(),
|
|
label: item.name,
|
|
})) || []
|
|
}
|
|
onValueChange={(value : any) =>
|
|
{field.onChange(Number(value)); setMunicipality(value); setDisabledParish(false)}
|
|
}
|
|
placeholder="Selecciona un Municipio"
|
|
defaultValue={field.value?.toString()}
|
|
disabled={disabledMunicipality}
|
|
/>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name="parish"
|
|
render={({ field }) => (
|
|
<FormItem className="w-full">
|
|
<FormLabel>Parroquia</FormLabel>
|
|
|
|
<SelectSearchable
|
|
options={
|
|
parishOptions?.map((item) => ({
|
|
value: item.id.toString(),
|
|
label: item.name,
|
|
})) || []
|
|
}
|
|
onValueChange={(value : any) =>
|
|
field.onChange(Number(value))
|
|
}
|
|
placeholder="Selecciona una Parroquia"
|
|
defaultValue={field.value?.toString()}
|
|
disabled={disabledParish}
|
|
/>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
|
|
<FormField
|
|
control={form.control}
|
|
name='password'
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>Nueva Contraseña</FormLabel>
|
|
<FormControl>
|
|
<Input type="password" {...field}/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-4">
|
|
<Button variant="outline" type="button" onClick={onCancel}>
|
|
Cancelar
|
|
</Button>
|
|
<Button type="submit" disabled={isSaving}>
|
|
{isSaving ? 'Guardando...' : 'Guardar'}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</Form>
|
|
);
|
|
}
|