cambios en el formulario osp: rol autoridad, campos responsable cambiados, esquema cambiado, añadida columna fecha de creacion a la tabla

This commit is contained in:
2026-03-04 15:07:31 -04:00
parent f910aea3cc
commit d6de7527e4
13 changed files with 4916 additions and 125 deletions

View File

@@ -0,0 +1 @@
CREATE VIEW "public"."v_training_surveys" AS (select "id", "osp_name", "osp_rif", "osp_type", "current_status", "visit_date" from "training_surveys");

View File

@@ -0,0 +1,2 @@
DROP VIEW "public"."v_training_surveys";--> statement-breakpoint
CREATE VIEW "public"."v_training_surveys" AS (select "id", "coor_full_name", "visit_date", "coor_phone", "state", "municipality", "parish", "osp_type", "eco_sector", "productive_sector", "central_productive_activity", "main_productive_activity", "productive_activity", "osp_rif", "osp_name", "company_constitution_year", "current_status", "infrastructure_mt2", "has_transport", "structure_type", "is_open_space", "paralysis_reason", "equipment_list", "production_list", "product_list", "osp_address", "osp_google_maps_link", "commune_name", "situr_code_commune", "commune_rif", "commune_spokesperson_name", "commune_spokesperson_cedula", "commune_spokesperson_rif", "commune_spokesperson_phone", "commune_email", "communal_council", "situr_code_communal_council", "communal_council_rif", "communal_council_spokesperson_name", "communal_council_spokesperson_cedula", "communal_council_spokesperson_rif", "communal_council_spokesperson_phone", "communal_council_email", "osp_responsible_fullname", "osp_responsible_cedula", "osp_responsible_rif", "civil_state", "osp_responsible_phone", "osp_responsible_email", "family_burden", "number_of_children", "general_observations", "internal_distribution_zone", "is_exporting", "external_country", "external_city", "external_description", "external_quantity", "external_unit", "women_count", "men_count", "photo1", "photo2", "photo3", "created_by", "updated_by", "created_at", "updated_at" from "training_surveys");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -169,6 +169,20 @@
"when": 1772032122473, "when": 1772032122473,
"tag": "0023_sticky_slayback", "tag": "0023_sticky_slayback",
"breakpoints": true "breakpoints": true
},
{
"idx": 24,
"version": "7",
"when": 1772642460042,
"tag": "0024_petite_sabra",
"breakpoints": true
},
{
"idx": 25,
"version": "7",
"when": 1772643066120,
"tag": "0025_funny_makkari",
"breakpoints": true
} }
] ]
} }

View File

@@ -21,14 +21,12 @@ export default function EditTrainingPage() {
} }
return ( return (
<PageContainer scrollable> <div className="p-6 space-y-6">
<div className="flex-1 space-y-4"> <CreateTrainingForm
<CreateTrainingForm defaultValues={training}
defaultValues={training} onSuccess={() => router.push('/dashboard/formulario')}
onSuccess={() => router.push('/dashboard/formulario')} onCancel={() => router.back()}
onCancel={() => router.back()} />
/> </div>
</div>
</PageContainer>
); );
} }

View File

@@ -1,4 +1,4 @@
import PageContainer from '@/components/layout/page-container'; // import PageContainer from '@/components/layout/page-container';
import { TrainingHeader } from '@/feactures/training/components/training-header'; import { TrainingHeader } from '@/feactures/training/components/training-header';
import TrainingList from '@/feactures/training/components/training-list'; import TrainingList from '@/feactures/training/components/training-list';
import TrainingTableAction from '@/feactures/training/components/training-tables/training-table-action'; import TrainingTableAction from '@/feactures/training/components/training-tables/training-table-action';
@@ -23,17 +23,17 @@ export default async function Page({ searchParams }: PageProps) {
} = searchParamsCache.parse(await searchParams); } = searchParamsCache.parse(await searchParams);
return ( return (
<PageContainer> // <PageContainer>
<div className="flex flex-1 flex-col space-y-6"> <div className="flex flex-1 flex-col space-y-6 p-6">
<TrainingHeader /> <TrainingHeader />
<TrainingTableAction /> <TrainingTableAction />
<TrainingList <TrainingList
initialPage={page} initialPage={page}
initialSearch={searchQuery} initialSearch={searchQuery}
initialLimit={limit || 10} initialLimit={limit || 10}
apiUrl={env.API_URL} apiUrl={env.API_URL}
/> />
</div> </div>
</PageContainer> // </PageContainer>
); );
} }

View File

@@ -76,11 +76,10 @@ export function CreateTrainingForm({
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true); const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
const [disabledParish, setDisabledParish] = React.useState(true); const [disabledParish, setDisabledParish] = React.useState(true);
const [coorState, setcoorState] = React.useState(0); // const [coorState, setcoorState] = React.useState(0);
const [coorMunicipality, setcoorMunicipality] = React.useState(0); // const [coorMunicipality, setcoorMunicipality] = React.useState(0);
const [disabledCoorMunicipality, setDisabledCoorMunicipality] = // const [disabledCoorMunicipality, setDisabledCoorMunicipality] = React.useState(true);
React.useState(true); // const [disabledCoorParish, setDisabledCoorParish] = React.useState(true);
const [disabledCoorParish, setDisabledCoorParish] = React.useState(true);
const [selectedFiles, setSelectedFiles] = React.useState<File[]>([]); const [selectedFiles, setSelectedFiles] = React.useState<File[]>([]);
@@ -107,11 +106,11 @@ export function CreateTrainingForm({
coorParish: defaultValues?.coorParish || undefined, coorParish: defaultValues?.coorParish || undefined,
coorPhone: defaultValues?.coorPhone || '', coorPhone: defaultValues?.coorPhone || '',
visitDate: formatToLocalISO(defaultValues?.visitDate), visitDate: formatToLocalISO(defaultValues?.visitDate),
productiveActivity: defaultValues?.productiveActivity || '', productiveActivity: defaultValues?.productiveActivity || undefined,
ecoSector: defaultValues?.ecoSector || undefined, ecoSector: defaultValues?.ecoSector || undefined,
productiveSector: defaultValues?.productiveSector || undefined, productiveSector: defaultValues?.productiveSector || undefined,
centralProductiveActivity: defaultValues?.centralProductiveActivity || '', centralProductiveActivity: defaultValues?.centralProductiveActivity || undefined,
mainProductiveActivity: defaultValues?.mainProductiveActivity || '', mainProductiveActivity: defaultValues?.mainProductiveActivity || undefined,
photo1: defaultValues?.photo1 || '', photo1: defaultValues?.photo1 || '',
photo2: defaultValues?.photo2 || '', photo2: defaultValues?.photo2 || '',
@@ -149,9 +148,9 @@ export function CreateTrainingForm({
generalObservations: defaultValues?.generalObservations || '', generalObservations: defaultValues?.generalObservations || '',
ospResponsibleEmail: defaultValues?.ospResponsibleEmail || '', ospResponsibleEmail: defaultValues?.ospResponsibleEmail || '',
paralysisReason: defaultValues?.paralysisReason || '', paralysisReason: defaultValues?.paralysisReason || '',
infrastructureMt2: defaultValues?.infrastructureMt2 || '', infrastructureMt2: defaultValues?.infrastructureMt2 || undefined,
hasTransport: defaultValues?.hasTransport || false, hasTransport: defaultValues?.hasTransport || false,
structureType: defaultValues?.structureType || '', structureType: defaultValues?.structureType || undefined,
isOpenSpace: defaultValues?.isOpenSpace || false, isOpenSpace: defaultValues?.isOpenSpace || false,
equipmentList: defaultValues?.equipmentList || [], equipmentList: defaultValues?.equipmentList || [],
productionList: defaultValues?.productionList || [], productionList: defaultValues?.productionList || [],
@@ -249,14 +248,14 @@ export function CreateTrainingForm({
setDisabledParish(false); setDisabledParish(false);
} }
if (defaultValues.coorState) { // if (defaultValues.coorState) {
setcoorState(Number(defaultValues.coorState)); // setcoorState(Number(defaultValues.coorState));
setDisabledCoorMunicipality(false); // setDisabledCoorMunicipality(false);
} // }
if (defaultValues.coorMunicipality) { // if (defaultValues.coorMunicipality) {
setcoorMunicipality(Number(defaultValues.coorMunicipality)); // setcoorMunicipality(Number(defaultValues.coorMunicipality));
setDisabledCoorParish(false); // setDisabledCoorParish(false);
} // }
} }
}, [defaultValues]); }, [defaultValues]);
@@ -489,13 +488,11 @@ export function CreateTrainingForm({
2. Datos de la Organización Socioproductiva (OSP) 2. Datos de la Organización Socioproductiva (OSP)
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
{/* CAMBIO 1: lg:grid-cols-2 para evitar columnas estrechas en tablets */}
<CardContent className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start"> <CardContent className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
<FormField <FormField
control={form.control} control={form.control}
name="ospType" name="ospType"
render={({ field }) => ( render={({ field }) => (
/* CAMBIO 2: flex flex-col y space-y-3 para forzar separación vertical interna */
<FormItem className="w-full flex flex-col space-y-3"> <FormItem className="w-full flex flex-col space-y-3">
<FormLabel className="whitespace-normal leading-tight font-semibold"> <FormLabel className="whitespace-normal leading-tight font-semibold">
Tipo de Organización Tipo de Organización
@@ -1103,7 +1100,7 @@ export function CreateTrainingForm({
name="womenCount" name="womenCount"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Mujeres (cantidad)</FormLabel> <FormLabel>Mujeres (Cantidad opcional)</FormLabel>
<FormControl> <FormControl>
<Input type="number" {...field} /> <Input type="number" {...field} />
</FormControl> </FormControl>
@@ -1116,7 +1113,7 @@ export function CreateTrainingForm({
name="menCount" name="menCount"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Hombres (cantidad)</FormLabel> <FormLabel>Hombres (Cantidad opcional)</FormLabel>
<FormControl> <FormControl>
<Input type="number" {...field} /> <Input type="number" {...field} />
</FormControl> </FormControl>
@@ -1155,7 +1152,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="col-span-1 lg:col-span-2 flex flex-col space-y-2"> <FormItem className="col-span-1 lg:col-span-2 flex flex-col space-y-2">
<FormLabel> <FormLabel>
Coordenadas de la Ubicación (Google Maps) Coordenadas de la Ubicación (Google Maps. Opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input
@@ -1211,7 +1208,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Rif de la Comuna Rif de la Comuna (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} value={field.value ?? ''} /> <Input {...field} value={field.value ?? ''} />
@@ -1227,7 +1224,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Nombre del Vocero o Vocera Nombre del Vocero o Vocera (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} value={field.value ?? ''} /> <Input {...field} value={field.value ?? ''} />
@@ -1243,7 +1240,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Número de Teléfono del Vocero Número de Teléfono del Vocero (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input
@@ -1325,7 +1322,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Rif del Consejo Comunal Rif del Consejo Comunal (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} value={field.value ?? ''} /> <Input {...field} value={field.value ?? ''} />
@@ -1341,7 +1338,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Nombre del Vocero o Vocera Nombre del Vocero o Vocera (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} value={field.value ?? ''} /> <Input {...field} value={field.value ?? ''} />
@@ -1357,7 +1354,7 @@ export function CreateTrainingForm({
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-2"> <FormItem className="w-full flex flex-col space-y-2">
<FormLabel className="font-semibold"> <FormLabel className="font-semibold">
Número de Teléfono del Vocero Número de Teléfono del Vocero (opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input
@@ -1419,9 +1416,31 @@ export function CreateTrainingForm({
<FormField <FormField
control={form.control} control={form.control}
name="ospResponsibleFullname" name="ospResponsiblePhone"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Teléfono</FormLabel>
<FormControl>
<Input
{...field}
value={field.value ?? ''}
placeholder="Ej. 04121234567"
onChange={(e) => {
const val = e.target.value.replace(/\D/g, '');
field.onChange(val.slice(0, 11));
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="ospResponsibleFullname"
render={({ field }) => (
<FormItem className="col-span-2">
<FormLabel>Nombre y apellido</FormLabel> <FormLabel>Nombre y apellido</FormLabel>
<FormControl> <FormControl>
<Input {...field} /> <Input {...field} />
@@ -1431,7 +1450,7 @@ export function CreateTrainingForm({
)} )}
/> />
<FormField {/* <FormField
control={form.control} control={form.control}
name="ospResponsibleRif" name="ospResponsibleRif"
render={({ field }) => ( render={({ field }) => (
@@ -1443,9 +1462,9 @@ export function CreateTrainingForm({
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> /> */}
<FormField {/* <FormField
control={form.control} control={form.control}
name="civilState" name="civilState"
render={({ field }) => ( render={({ field }) => (
@@ -1471,31 +1490,9 @@ export function CreateTrainingForm({
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> /> */}
<FormField {/* <FormField
control={form.control}
name="ospResponsiblePhone"
render={({ field }) => (
<FormItem>
<FormLabel>Teléfono</FormLabel>
<FormControl>
<Input
{...field}
value={field.value ?? ''}
placeholder="Ej. 04121234567"
onChange={(e) => {
const val = e.target.value.replace(/\D/g, '');
field.onChange(val.slice(0, 11));
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control} control={form.control}
name="ospResponsibleEmail" name="ospResponsibleEmail"
render={({ field }) => ( render={({ field }) => (
@@ -1511,9 +1508,9 @@ export function CreateTrainingForm({
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> /> */}
<FormField {/* <FormField
control={form.control} control={form.control}
name="familyBurden" name="familyBurden"
render={({ field }) => ( render={({ field }) => (
@@ -1529,9 +1526,9 @@ export function CreateTrainingForm({
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> /> */}
<FormField {/* <FormField
control={form.control} control={form.control}
name="numberOfChildren" name="numberOfChildren"
render={({ field }) => ( render={({ field }) => (
@@ -1547,7 +1544,7 @@ export function CreateTrainingForm({
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> /> */}
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -22,6 +22,15 @@ export function columns({ apiUrl }: ColumnsProps): ColumnDef<TrainingSchema>[] {
accessorKey: 'ospType', accessorKey: 'ospType',
header: 'Tipo', header: 'Tipo',
}, },
{
accessorKey: 'created_at',
header: 'Fecha de creación',
cell: ({ row }) => {
// console.log(row.getValue('created_at'));
const date = row.getValue('created_at') as string;
return date ? new Date(date).toLocaleString() : 'N/A';
},
},
{ {
accessorKey: 'currentStatus', accessorKey: 'currentStatus',
header: 'Estatus', header: 'Estatus',

View File

@@ -22,17 +22,17 @@ export default function TrainingTableAction() {
setPage={setPage} setPage={setPage}
/> />
</div>{' '} </div>{' '}
{['superadmin', 'admin', 'manager', 'coordinators'].includes( {['superadmin', 'autoridad', 'admin', 'manager', 'coordinators'].includes(
role ?? '', role ?? '',
) && ( ) && (
<Button <Button
onClick={() => router.push(`/dashboard/formulario/nuevo`)} onClick={() => router.push(`/dashboard/formulario/nuevo`)}
size="sm" size="sm"
> >
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
<span className="hidden md:inline">Nuevo Registro</span> <span className="hidden md:inline">Nuevo Registro</span>
</Button> </Button>
)} )}
</div> </div>
); );
} }

View File

@@ -356,10 +356,10 @@ export function TrainingViewModal({
))} ))}
{(!data.equipmentList || {(!data.equipmentList ||
data.equipmentList.length === 0) && ( data.equipmentList.length === 0) && (
<p className="text-sm text-muted-foreground italic"> <p className="text-sm text-muted-foreground italic">
No hay equipamiento registrado. No hay equipamiento registrado.
</p> </p>
)} )}
</CardContent> </CardContent>
</Card> </Card>
@@ -389,10 +389,10 @@ export function TrainingViewModal({
))} ))}
{(!data.productionList || {(!data.productionList ||
data.productionList.length === 0) && ( data.productionList.length === 0) && (
<p className="text-sm text-muted-foreground italic"> <p className="text-sm text-muted-foreground italic">
No hay materia prima registrada. No hay materia prima registrada.
</p> </p>
)} )}
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
@@ -438,12 +438,12 @@ export function TrainingViewModal({
label="Teléfono" label="Teléfono"
value={data.ospResponsiblePhone} value={data.ospResponsiblePhone}
/> />
<DetailItem label="Email" value={data.ospResponsibleEmail} /> {/* <DetailItem label="Email" value={data.ospResponsibleEmail} />
<DetailItem <DetailItem
label="Carga Familiar" label="Carga Familiar"
value={data.familyBurden} value={data.familyBurden}
/> />
<DetailItem label="Hijos" value={data.numberOfChildren} /> <DetailItem label="Hijos" value={data.numberOfChildren} /> */}
</Section> </Section>
</div> </div>

View File

@@ -28,7 +28,7 @@ export const ACTIVIDAD_PRINCIPAL = {
PATIOS_PRODUCTIVOS: 'PATIOS PRODUCTIVOS O CONUCOS', PATIOS_PRODUCTIVOS: 'PATIOS PRODUCTIVOS O CONUCOS',
TRANSFORMACION_MATERIA: 'TRANSFORMACION DE LA MATERIA PRIMA', TRANSFORMACION_MATERIA: 'TRANSFORMACION DE LA MATERIA PRIMA',
TEXTIL: 'TALLER DE COFECCION TEXTIL', TEXTIL: 'TALLER DE COFECCION TEXTIL',
CONSTRUCCION: 'CONSTRUCION', CONSTRUCCION: 'CONSTRUCCION',
BIENES_SERVICIOS: 'OFRECER PRODUCTOS DE BIENES Y SERVICIOS', BIENES_SERVICIOS: 'OFRECER PRODUCTOS DE BIENES Y SERVICIOS',
VISITAS_GUIADAS: 'VISITAS GUIADAS', VISITAS_GUIADAS: 'VISITAS GUIADAS',
ALOJAMIENTO: 'ALOJAMIENTO', ALOJAMIENTO: 'ALOJAMIENTO',

View File

@@ -28,9 +28,7 @@ export const trainingSchema = z.object({
.min(1, { message: 'Nombre del coordinador es requerido' }), .min(1, { message: 'Nombre del coordinador es requerido' }),
coorPhone: z coorPhone: z
.string() .string()
.optional() .refine((val) => /^(04|02)\d{9}$/.test(val), {
.nullable()
.refine((val) => !val || /^(04|02)\d{9}$/.test(val), {
message: 'El teléfono debe tener 11 dígitos y comenzar con 04 o 02', message: 'El teléfono debe tener 11 dígitos y comenzar con 04 o 02',
}), }),
visitDate: z visitDate: z
@@ -39,13 +37,11 @@ export const trainingSchema = z.object({
//Datos de la organización socioproductiva (OSP) //Datos de la organización socioproductiva (OSP)
ospType: z.string().min(1, { message: 'Tipo de OSP es requerido' }), ospType: z.string().min(1, { message: 'Tipo de OSP es requerido' }),
ecoSector: z.string().optional().or(z.literal('')).nullable(), ecoSector: z.string({ message: 'Sector Económico es requerido' }),
productiveSector: z.string().optional().or(z.literal('')).nullable(), productiveSector: z.string({ message: 'Sector Productivo es requerido' }),
centralProductiveActivity: z.string().optional().or(z.literal('')).nullable(), centralProductiveActivity: z.string({ message: 'Actividad Central Productiva es requerido' }),
mainProductiveActivity: z.string().optional().or(z.literal('')).nullable(), mainProductiveActivity: z.string({ message: 'Actividad Productiva Principal es requerida' }),
productiveActivity: z productiveActivity: z.string({ message: 'Actividad Productiva es requerida' }),
.string()
.min(1, { message: 'Actividad productiva es requerida' }),
ospRif: z.string().optional().or(z.literal('')).nullable(), ospRif: z.string().optional().or(z.literal('')).nullable(),
ospName: z.string().optional().or(z.literal('')).nullable(), ospName: z.string().optional().or(z.literal('')).nullable(),
companyConstitutionYear: z.coerce companyConstitutionYear: z.coerce
@@ -56,7 +52,7 @@ export const trainingSchema = z.object({
.string() .string()
.min(1, { message: 'Estatus actual es requerido' }) .min(1, { message: 'Estatus actual es requerido' })
.default('ACTIVA'), .default('ACTIVA'),
infrastructureMt2: z.string().optional().or(z.literal('')).nullable(), infrastructureMt2: z.string({ message: 'Infraestructura es requerida' }),
hasTransport: z hasTransport: z
.preprocess( .preprocess(
(val) => val === 'true' || val === true || val === 1 || val === '1', (val) => val === 'true' || val === true || val === 1 || val === '1',
@@ -65,7 +61,7 @@ export const trainingSchema = z.object({
.optional() .optional()
.nullable() .nullable()
.default(false), .default(false),
structureType: z.string().optional().or(z.literal('')).nullable(), structureType: z.string({ message: 'Tipo de estructura es requerido' }),
isOpenSpace: z isOpenSpace: z
.preprocess( .preprocess(
(val) => val === 'true' || val === true || val === 1 || val === '1', (val) => val === 'true' || val === true || val === 1 || val === '1',
@@ -115,8 +111,8 @@ export const trainingSchema = z.object({
.string() .string()
.min(1, { message: 'Dirección de la OSP es requerida' }), .min(1, { message: 'Dirección de la OSP es requerida' }),
ospGoogleMapsLink: z.string().optional().or(z.literal('')).nullable(), ospGoogleMapsLink: z.string().optional().or(z.literal('')).nullable(),
communeName: z.string().optional().or(z.literal('')).nullable(), communeName: z.string().min(1, { message: 'Nombre de la comuna es requerida' }),
siturCodeCommune: z.string().optional().or(z.literal('')).nullable(), siturCodeCommune: z.string().min(1, { message: 'Código SITUR de la comuna es requerida' }),
communeRif: z.string().optional().or(z.literal('')).nullable(), communeRif: z.string().optional().or(z.literal('')).nullable(),
communeSpokespersonName: z.string().optional().or(z.literal('')).nullable(), communeSpokespersonName: z.string().optional().or(z.literal('')).nullable(),
communeSpokespersonPhone: z communeSpokespersonPhone: z
@@ -135,7 +131,7 @@ export const trainingSchema = z.object({
communalCouncil: z communalCouncil: z
.string() .string()
.min(1, { message: 'Consejo Comunal es requerido' }), .min(1, { message: 'Consejo Comunal es requerido' }),
siturCodeCommunalCouncil: z.string().optional().or(z.literal('')).nullable(), siturCodeCommunalCouncil: z.string().min(1, { message: 'Código SITUR del Consejo Comunal es requerido' }),
communalCouncilRif: z.string().optional().or(z.literal('')).nullable(), communalCouncilRif: z.string().optional().or(z.literal('')).nullable(),
communalCouncilSpokespersonName: z communalCouncilSpokespersonName: z
.string() .string()
@@ -188,9 +184,9 @@ export const trainingSchema = z.object({
files: z.any().optional(), files: z.any().optional(),
//no se envia la backend al crear ni editar el formulario //no se envia la backend al crear ni editar el formulario
state: z.number().optional().nullable(), state: z.number({ message: 'El estado es requerido' }).nullable(),
municipality: z.number().optional().nullable(), municipality: z.number({ message: 'Municipio es requerido' }).nullable(),
parish: z.number().optional().nullable(), parish: z.number({ message: 'Parroquia es requerido' }).nullable(),
coorState: z.number().optional().nullable(), coorState: z.number().optional().nullable(),
coorMunicipality: z.number().optional().nullable(), coorMunicipality: z.number().optional().nullable(),
coorParish: z.number().optional().nullable(), coorParish: z.number().optional().nullable(),
@@ -199,15 +195,117 @@ export const trainingSchema = z.object({
photo3: z.string().optional().nullable(), photo3: z.string().optional().nullable(),
createdBy: z.number().optional().nullable(), createdBy: z.number().optional().nullable(),
updatedBy: z.number().optional().nullable(), updatedBy: z.number().optional().nullable(),
createdAt: z.string().optional().nullable(), created_at: z.string().optional().nullable(),
updatedAt: z.string().optional().nullable(), updated_at: z.string().optional().nullable(),
}); });
export type TrainingSchema = z.infer<typeof trainingSchema>; export type TrainingSchema = z.infer<typeof trainingSchema>;
export const getTrainingSchema = z.object({
//Datos de la visita
id: z.number().optional(),
coorFullName: z.string(),
coorPhone: z.string(),
visitDate: z.string(),
//Datos de la organización socioproductiva (OSP)
ospType: z.string(),
ecoSector: z.string(),
productiveSector: z.string(),
centralProductiveActivity: z.string(),
mainProductiveActivity: z.string(),
productiveActivity: z.string(),
ospRif: z.string().optional().or(z.literal('')).nullable(),
ospName: z.string().optional().or(z.literal('')).nullable(),
companyConstitutionYear: z.coerce.number(),
currentStatus: z.string(),
infrastructureMt2: z.string(),
hasTransport: z
.preprocess(
(val) => val === 'true' || val === true || val === 1 || val === '1',
z.boolean(),
)
.optional()
.nullable()
.default(false),
structureType: z.string(),
isOpenSpace: z
.preprocess(
(val) => val === 'true' || val === true || val === 1 || val === '1',
z.boolean(),
)
.optional()
.nullable()
.default(false),
paralysisReason: z.string().optional().nullable(),
//Datos del Equipamiento
equipmentList: z.array(equipmentItemSchema).optional().default([]),
//Datos de Producción
productionList: z.array(productionItemSchema).optional().default([]),
// Datos de Actividad Productiva
productList: z.array(productItemSchema).optional().default([]),
// Distribución y Exportación
internalDistributionZone: z.string(),
isExporting: z
.preprocess(
(val) => val === 'true' || val === true || val === 1 || val === '1',
z.boolean(),
)
.optional()
.default(false),
externalCountry: z.string().optional().nullable(),
externalCity: z.string().optional().nullable(),
externalDescription: z.string().optional().nullable(),
externalQuantity: z.coerce.string().or(z.number()).optional().nullable(),
externalUnit: z.string().optional().nullable(),
// Mano de obra
womenCount: z.coerce.number(),
menCount: z.coerce.number(),
//Detalles de la ubicación
ospAddress: z.string(),
ospGoogleMapsLink: z.string().optional().or(z.literal('')).nullable(),
communeName: z.string(),
siturCodeCommune: z.string(),
communeRif: z.string().optional().or(z.literal('')).nullable(),
communeSpokespersonName: z.string().optional().or(z.literal('')).nullable(),
communeSpokespersonPhone: z.string(),
communeEmail: z.string(),
communalCouncil: z.string(),
siturCodeCommunalCouncil: z.string(),
communalCouncilRif: z.string().optional(),
communalCouncilSpokespersonName: z.string(),
communalCouncilSpokespersonPhone: z.string(),
communalCouncilEmail: z.string(),
//Datos del Responsable OSP
ospResponsibleCedula: z.string(),
ospResponsibleFullname: z.string(),
ospResponsibleRif: z.string().optional().nullable(),
civilState: z.string().optional().nullable(),
ospResponsiblePhone: z.string(),
ospResponsibleEmail: z.string(),
familyBurden: z.coerce.number().optional(),
numberOfChildren: z.coerce.number().optional(),
//Datos adicionales
generalObservations: z.string().optional().nullable(),
//no se envia la backend al crear ni editar el formulario
state: z.number().nullable(),
municipality: z.number().nullable(),
parish: z.number().nullable(),
coorState: z.number().optional().nullable(),
coorMunicipality: z.number().optional().nullable(),
coorParish: z.number().optional().nullable(),
photo1: z.string().optional().nullable(),
photo2: z.string().optional().nullable(),
photo3: z.string().optional().nullable(),
createdBy: z.number().optional().nullable(),
updatedBy: z.number().optional().nullable(),
created_at: z.string().optional().nullable(),
updated_at: z.string().optional().nullable(),
});
export const trainingApiResponseSchema = z.object({ export const trainingApiResponseSchema = z.object({
message: z.string(), message: z.string(),
data: z.array(trainingSchema), data: z.array(getTrainingSchema),
meta: z.object({ meta: z.object({
page: z.number(), page: z.number(),
limit: z.number(), limit: z.number(),