From 63c39e399ec52b3b0c71e3aa99e82fada6f53485 Mon Sep 17 00:00:00 2001 From: Sergio Ramirez Date: Tue, 3 Feb 2026 14:19:57 -0400 Subject: [PATCH] corrreciones al formulario de las osp --- .../training/dto/create-training.dto.ts | 17 +++ .../src/features/training/training.service.ts | 5 +- apps/web/components/layout/app-sidebar.tsx | 12 +- .../feactures/training/components/form.tsx | 125 +++++++++++++++--- .../training-tables/cell-action.tsx | 4 +- .../components/training-view-modal.tsx | 20 +++ 6 files changed, 157 insertions(+), 26 deletions(-) diff --git a/apps/api/src/features/training/dto/create-training.dto.ts b/apps/api/src/features/training/dto/create-training.dto.ts index 375634e..3cf3c55 100644 --- a/apps/api/src/features/training/dto/create-training.dto.ts +++ b/apps/api/src/features/training/dto/create-training.dto.ts @@ -213,6 +213,8 @@ export class CreateTrainingDto { @IsString() communalCouncilEmail: string; + + // === 6. LISTAS (Arrays JSON) === // Reciben un string JSON '[{...}]' y lo convierten a Objeto JS real @@ -260,4 +262,19 @@ export class CreateTrainingDto { return value; }) productList?: any[]; + + + //ubicacion + @ApiProperty() + @IsString() + state: string; + + + @ApiProperty() + @IsString() + municipality: string; + + @ApiProperty() + @IsString() + parish: string; } diff --git a/apps/api/src/features/training/training.service.ts b/apps/api/src/features/training/training.service.ts index f6d0641..9941144 100644 --- a/apps/api/src/features/training/training.service.ts +++ b/apps/api/src/features/training/training.service.ts @@ -271,7 +271,7 @@ export class TrainingService { // 2. Extraer solo visitDate para formatearlo. // Ya NO extraemos state, municipality, etc. porque no vienen en el DTO. - const { visitDate, ...rest } = createTrainingDto; + const { visitDate, state, municipality, parish, ...rest } = createTrainingDto; const [newRecord] = await this.drizzle .insert(trainingSurveys) @@ -286,6 +286,9 @@ export class TrainingService { photo1: photoPaths[0] ?? null, photo2: photoPaths[1] ?? null, photo3: photoPaths[2] ?? null, + state: Number(state) ?? null, + municipality: Number(municipality) ?? null, + parish: Number(parish) ?? null, }) .returning(); diff --git a/apps/web/components/layout/app-sidebar.tsx b/apps/web/components/layout/app-sidebar.tsx index f41b3bc..cd4f787 100644 --- a/apps/web/components/layout/app-sidebar.tsx +++ b/apps/web/components/layout/app-sidebar.tsx @@ -42,15 +42,17 @@ export function AppSidebar({ ...props }: React.ComponentProps) { - - + {AdministrationItems[0]?.role?.includes(userRole) && + + } {StatisticsItems[0]?.role?.includes(userRole) && } - {AdministrationItems[0]?.role?.includes(userRole) && - - } + + + + {/* */} diff --git a/apps/web/feactures/training/components/form.tsx b/apps/web/feactures/training/components/form.tsx index 3a0e461..08d5116 100644 --- a/apps/web/feactures/training/components/form.tsx +++ b/apps/web/feactures/training/components/form.tsx @@ -45,6 +45,7 @@ import { CardTitle, } from '@repo/shadcn/components/ui/card'; import React from 'react'; +import { SelectSearchable } from '@repo/shadcn/components/ui/select-searchable'; const OSP_TYPES = ['EPSIC', 'EPSDC', 'UPF', 'OTROS', 'COOPERATIVA']; const STATUS_OPTIONS = ['ACTIVA', 'INACTIVA']; @@ -158,10 +159,14 @@ export function CreateTrainingForm({ equipmentList: defaultValues?.equipmentList || [], productionList: defaultValues?.productionList || [], productList: defaultValues?.productList || [], + state: defaultValues?.state || undefined, + municipality: defaultValues?.municipality || undefined, + parish: defaultValues?.parish || undefined, }, mode: 'onChange', }); + // Cascading Select Logic const ecoSector = useWatch({ control: form.control, name: 'ecoSector' }); const productiveSector = useWatch({ @@ -217,7 +222,7 @@ export function CreateTrainingForm({ : [{ id: 0, stateId: 0, name: 'Sin Municipios' }]; const coorParishOptions = - Array.isArray(dataCoorParish?.data) && dataCoorParish.data.length > 0 + Array.isArray(dataCoorParish?.data) && dataCoorParish?.data.length > 0 ? dataCoorParish.data : [{ id: 0, stateId: 0, name: 'Sin Parroquias' }]; @@ -263,7 +268,7 @@ export function CreateTrainingForm({ // 1. Definimos las claves que NO queremos enviar en el bucle general // 'files' se procesa aparte. // 'photo1/2/3' son strings (urls viejas) que no queremos reenviar como texto. - const excludedKeys = ['files', 'photo1', 'photo2', 'photo3']; + const excludedKeys = ['files', 'photo1', 'photo2', 'photo3', 'coorState', 'coorMunicipality', 'coorParish']; Object.entries(formData).forEach(([key, value]) => { // 2. Condición actualizada: Si la key está en la lista de excluidos, la saltamos @@ -282,6 +287,17 @@ export function CreateTrainingForm({ } }); + + // 2. Mapeo manual y conversión a numérico + // if (formData.state) { + // data.append('state', Number(formData.state).toString()); + // } + // if (formData.municipality) { + // data.append('municipality', Number(formData.municipality).toString()); + // } + // if (formData.parish) { + // data.append('parish', Number(formData.parish).toString()); + // } if (defaultValues?.id) { data.append('id', defaultValues.id.toString()); } @@ -289,24 +305,24 @@ export function CreateTrainingForm({ // 4. Aquí se agregan las NUEVAS fotos (binary) si el usuario seleccionó alguna selectedFiles.forEach((file) => { data.append('files', file); - }); - + }); + console.log(data); const mutation = defaultValues?.id ? updateTraining : createTraining; - mutation(data as any, { - onSuccess: () => { - form.reset(); - setSelectedFiles([]); - onSuccess?.(); - }, - onError: (e) => { - console.error(e); - form.setError('root', { - type: 'manual', - message: 'Error al guardar el registro', - }); - }, - }); + // mutation(data as any, { + // onSuccess: () => { + // form.reset(); + // setSelectedFiles([]); + // onSuccess?.(); + // }, + // onError: (e) => { + // console.error(e); + // form.setError('root', { + // type: 'manual', + // message: 'Error al guardar el registro', + // }); + // }, + // }); }; return ( @@ -382,6 +398,8 @@ export function CreateTrainingForm({ )} /> + + )} /> + ( + + Estado + ({ + value: item.id.toString(), + label: item.name, + }))} + onValueChange={(value) => { + field.onChange(Number(value)); + setState(Number(value)); + setDisabledMunicipality(false); + setDisabledParish(true); + }} + placeholder="Selecciona un estado" + defaultValue={field.value?.toString()} + /> + + + )} + /> + + ( + + Municipio + ({ + value: item.id.toString(), + label: item.name, + }))} + onValueChange={(value) => { + field.onChange(Number(value)); + setMunicipality(Number(value)); + setDisabledParish(false); + }} + placeholder="Selecciona un municipio" + disabled={disabledMunicipality} + defaultValue={field.value?.toString()} + /> + + + )} + /> + + ( + + Parroquia + ({ + value: item.id.toString(), + label: item.name, + }))} + onValueChange={(value) => field.onChange(Number(value))} + placeholder="Selecciona una parroquia" + disabled={disabledParish} + defaultValue={field.value?.toString()} + /> + + + )} + /> @@ -833,6 +921,7 @@ export function CreateTrainingForm({ 3. Detalles de la ubicación + = ({ data, apiUrl }) => { - + {/*