Campos faltantes
This commit is contained in:
7
apps/api/src/database/migrations/0009_eminent_ares.sql
Normal file
7
apps/api/src/database/migrations/0009_eminent_ares.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE "training_surveys" ADD COLUMN "state" integer;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD COLUMN "municipality" integer;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD COLUMN "parish" integer;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD COLUMN "osp_responsible_email" text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_state_states_id_fk" FOREIGN KEY ("state") REFERENCES "public"."states"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_municipality_municipalities_id_fk" FOREIGN KEY ("municipality") REFERENCES "public"."municipalities"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_parish_parishes_id_fk" FOREIGN KEY ("parish") REFERENCES "public"."parishes"("id") ON DELETE set null ON UPDATE no action;
|
||||
1842
apps/api/src/database/migrations/meta/0009_snapshot.json
Normal file
1842
apps/api/src/database/migrations/meta/0009_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,13 @@
|
||||
"when": 1764623430844,
|
||||
"tag": "0008_plain_scream",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1764883378610,
|
||||
"tag": "0009_eminent_ares",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import * as t from 'drizzle-orm/pg-core';
|
||||
import { eq, lt, gte, ne, sql } from 'drizzle-orm';
|
||||
import { timestamps } from '../timestamps';
|
||||
import { users } from './auth';
|
||||
import { states, municipalities, parishes } from './general';
|
||||
|
||||
|
||||
// Tabla surveys
|
||||
@@ -48,37 +49,47 @@ export const answersSurveys = t.pgTable(
|
||||
export const trainingSurveys = t.pgTable(
|
||||
'training_surveys',
|
||||
{
|
||||
// Datos basicos
|
||||
id: t.serial('id').primaryKey(),
|
||||
firstname: t.text('firstname').notNull(),
|
||||
lastname: t.text('lastname').notNull(),
|
||||
visitDate: t.timestamp('visit_date').notNull(),
|
||||
productiveActivity: t.text('productive_activity').notNull(),
|
||||
financialRequirementDescription: t.text('financial_requirement_description').notNull(),
|
||||
// ubicacion
|
||||
state: t.integer('state').references(() => states.id, { onDelete: 'set null' }),
|
||||
municipality: t.integer('municipality').references(() => municipalities.id, { onDelete: 'set null' }),
|
||||
parish: t.integer('parish').references(() => parishes.id, { onDelete: 'set null' }),
|
||||
siturCodeCommune: t.text('situr_code_commune').notNull(),
|
||||
communalCouncil: t.text('communal_council').notNull(),
|
||||
siturCodeCommunalCouncil: t.text('situr_code_communal_council').notNull(),
|
||||
// datos del OSP (ORGANIZACIÓN SOCIOPRODUCTIVA)
|
||||
ospName: t.text('osp_name').notNull(),
|
||||
ospAddress: t.text('osp_address').notNull(),
|
||||
ospRif: t.text('osp_rif').notNull(),
|
||||
ospType: t.text('osp_type').notNull(),
|
||||
productiveActivity: t.text('productive_activity').notNull(),
|
||||
financialRequirementDescription: t.text('financial_requirement_description').notNull(),
|
||||
currentStatus: t.text('current_status').notNull(),
|
||||
companyConstitutionYear: t.integer('company_constitution_year').notNull(),
|
||||
producerCount: t.integer('producer_count').notNull(),
|
||||
productDescription: t.text('product_description').notNull(),
|
||||
installedCapacity: t.text('installed_capacity').notNull(),
|
||||
operationalCapacity: t.text('operational_capacity').notNull(),
|
||||
// datos del responsable
|
||||
ospResponsibleFullname: t.text('osp_responsible_fullname').notNull(),
|
||||
ospResponsibleCedula: t.text('osp_responsible_cedula').notNull(),
|
||||
ospResponsibleRif: t.text('osp_responsible_rif').notNull(),
|
||||
ospResponsiblePhone: t.text('osp_responsible_phone').notNull(),
|
||||
ospResponsibleEmail: t.text('osp_responsible_email').notNull(),
|
||||
civilState: t.text('civil_state').notNull(),
|
||||
familyBurden: t.integer('family_burden').notNull(),
|
||||
numberOfChildren: t.integer('number_of_children').notNull(),
|
||||
// datos adicionales
|
||||
generalObservations: t.text('general_observations').notNull(),
|
||||
paralysisReason: t.text('paralysis_reason').notNull(),
|
||||
// fotos
|
||||
photo1: t.text('photo1').notNull(),
|
||||
photo2: t.text('photo2').notNull(),
|
||||
photo3: t.text('photo3').notNull(),
|
||||
paralysisReason: t.text('paralysis_reason').notNull(),
|
||||
...timestamps,
|
||||
},
|
||||
(trainingSurveys) => ({
|
||||
|
||||
@@ -22,6 +22,18 @@ export class CreateTrainingDto {
|
||||
@IsString()
|
||||
financialRequirementDescription: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsInt()
|
||||
state: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsInt()
|
||||
municipality: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsInt()
|
||||
parish: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
siturCodeCommune: string;
|
||||
@@ -90,6 +102,10 @@ export class CreateTrainingDto {
|
||||
@IsString()
|
||||
ospResponsiblePhone: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
ospResponsibleEmail: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
civilState: string;
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
'use server';
|
||||
import { safeFetchApi } from '@/lib/fetch.api';
|
||||
import {
|
||||
surveysApiResponseSchema,
|
||||
CreateUser,
|
||||
UsersMutate,
|
||||
UpdateUser
|
||||
} from '../schemas/users';
|
||||
|
||||
import { auth } from '@/lib/auth';
|
||||
|
||||
|
||||
export const getProfileAction = async () => {
|
||||
const session = await auth()
|
||||
const id = session?.user?.id
|
||||
|
||||
const [error, response] = await safeFetchApi(
|
||||
UsersMutate,
|
||||
`/users/${id}`,
|
||||
'GET'
|
||||
);
|
||||
if (error) throw new Error(error.message);
|
||||
return response;
|
||||
};
|
||||
|
||||
export const updateProfileAction = async (payload: UpdateUser) => {
|
||||
const { id, ...payloadWithoutId } = payload;
|
||||
|
||||
const [error, data] = await safeFetchApi(
|
||||
UsersMutate,
|
||||
`/users/profile/${id}`,
|
||||
'PATCH',
|
||||
payloadWithoutId,
|
||||
);
|
||||
|
||||
console.log(payload);
|
||||
if (error) {
|
||||
if (error.message === 'Email already exists') {
|
||||
throw new Error('Ese correo ya está en uso');
|
||||
}
|
||||
// console.error('Error:', error);
|
||||
throw new Error('Error al crear el usuario');
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getUsersAction = async (params: {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
search?: string;
|
||||
sortBy?: string;
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
}) => {
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
page: (params.page || 1).toString(),
|
||||
limit: (params.limit || 10).toString(),
|
||||
...(params.search && { search: params.search }),
|
||||
...(params.sortBy && { sortBy: params.sortBy }),
|
||||
...(params.sortOrder && { sortOrder: params.sortOrder }),
|
||||
});
|
||||
|
||||
const [error, response] = await safeFetchApi(
|
||||
surveysApiResponseSchema,
|
||||
`/users?${searchParams}`,
|
||||
'GET',
|
||||
);
|
||||
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
// const transformedData = response?.data ? transformSurvey(response?.data) : undefined;
|
||||
|
||||
return {
|
||||
data: response?.data || [],
|
||||
meta: response?.meta || {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
totalCount: 0,
|
||||
totalPages: 1,
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
nextPage: null,
|
||||
previousPage: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const createUserAction = async (payload: CreateUser) => {
|
||||
const { id, confirmPassword, ...payloadWithoutId } = payload;
|
||||
|
||||
const [error, data] = await safeFetchApi(
|
||||
UsersMutate,
|
||||
'/users',
|
||||
'POST',
|
||||
payloadWithoutId,
|
||||
);
|
||||
|
||||
if (error) {
|
||||
if (error.message === 'Username already exists') {
|
||||
throw new Error('Ese usuario ya existe');
|
||||
}
|
||||
if (error.message === 'Email already exists') {
|
||||
throw new Error('Ese correo ya está en uso');
|
||||
}
|
||||
// console.error('Error:', error);
|
||||
throw new Error('Error al crear el usuario');
|
||||
}
|
||||
|
||||
return payloadWithoutId;
|
||||
};
|
||||
|
||||
export const updateUserAction = async (payload: UpdateUser) => {
|
||||
try {
|
||||
const { id, ...payloadWithoutId } = payload;
|
||||
|
||||
const [error, data] = await safeFetchApi(
|
||||
UsersMutate,
|
||||
`/users/${id}`,
|
||||
'PATCH',
|
||||
payloadWithoutId,
|
||||
);
|
||||
|
||||
// console.log(data);
|
||||
if (error) {
|
||||
console.error(error);
|
||||
|
||||
throw new Error(error?.message || 'Error al actualizar el usuario');
|
||||
}
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteUserAction = async (id: Number) => {
|
||||
const [error] = await safeFetchApi(
|
||||
UsersMutate,
|
||||
`/users/${id}`,
|
||||
'DELETE'
|
||||
)
|
||||
|
||||
console.log(error);
|
||||
|
||||
|
||||
// if (error) throw new Error(error.message || 'Error al eliminar el usuario')
|
||||
|
||||
return true;
|
||||
}
|
||||
41
apps/web/feactures/training/columnas del excel.sql
Normal file
41
apps/web/feactures/training/columnas del excel.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
-- datos basicos
|
||||
nombre,
|
||||
apellido,
|
||||
fecha de la visita,
|
||||
-->Falta
|
||||
hora de la visita,
|
||||
-- datos de la ubicacion
|
||||
estado,
|
||||
municipio,
|
||||
parroquia,
|
||||
nombre de la comuna,
|
||||
CODIGO SITUR COMUNA,
|
||||
CONSEJO COMUNAL,
|
||||
CODIGO SITUR CONSEJO COMUNAL,
|
||||
-- datos de la osp
|
||||
actividad productiva (agricola,textil,bloquera,carpinteria,unidad de suministro),
|
||||
realice una breve descripcion del requerimiento financiero,
|
||||
NOMBRE DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
|
||||
DIRECCIÓN DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
|
||||
RIF DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
|
||||
TIPO DE ORGANIZACIÓN SOCIOPRODUCTIVA,
|
||||
ESTATUS ACTUAL,
|
||||
AÑO DE CONSTITUCIÓN DE LA EMPRESA ,
|
||||
CANTIDAD DE PRODUCTORES QUE LA CONFORMAN,
|
||||
BREVE DESCRIPCIÓN DEL PRODUCTO O SERVICIO QUE OFRECE,
|
||||
CAPACIDAD INSTALADA,
|
||||
CAPACIDAD OPERATIVA,
|
||||
¿EXPLIQUE LAS RAZONES GENERALES POR LAS CUALES LA UNIDAD DE PRODUCCIÓN TUVO QUE PARALIZARSE?
|
||||
-- datos del responsable
|
||||
NOMBRE Y APELLIDO DEL RESPONSABLE DE LA OSP,
|
||||
CÉDULA DEL RESPONSABLE (SIN PUNTOS),
|
||||
RIF DEL RESPONSABLE (SIN PUNTOS),
|
||||
TELÉFONOS (COLOQUE 2 NUMEROS DE TELEFONOS),
|
||||
CORREO ELECTRÓNICO,
|
||||
ESTADO CIVIL DEL PRODUCTOR,
|
||||
CARGA FAMILIAR,
|
||||
NUMERO DE HIJOS,
|
||||
-- datos adicionales
|
||||
OBSERVACIONES GENERALES,
|
||||
-- fotos
|
||||
COLOCAR TRES (3) REGISTROS FOTOGRÁFICOS VISIBLES DEL ESPACIO Y MAQUINARIAS ACTUALMENTE (OBLIGATORIO),
|
||||
@@ -52,23 +52,23 @@ export function CreateTrainingForm({
|
||||
} = useCreateTraining();
|
||||
|
||||
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 [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 { data: dataState } = useStateQuery()
|
||||
const { data: dataMunicipality } = useMunicipalityQuery(state)
|
||||
const { data: dataParish } = useParishQuery(municipality)
|
||||
|
||||
const stateOptions = dataState?.data || [{id:0,name:'Sin estados'}]
|
||||
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 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 form = useForm<TrainingSchema>({
|
||||
resolver: zodResolver(trainingSchema),
|
||||
@@ -99,6 +99,7 @@ export function CreateTrainingForm({
|
||||
familyBurden: defaultValues?.familyBurden || 0,
|
||||
numberOfChildren: defaultValues?.numberOfChildren || 0,
|
||||
generalObservations: defaultValues?.generalObservations || '',
|
||||
ospResponsibleEmail: defaultValues?.ospResponsibleEmail || '',
|
||||
photo1: defaultValues?.photo1 || '',
|
||||
photo2: defaultValues?.photo2 || '',
|
||||
photo3: defaultValues?.photo3 || '',
|
||||
@@ -171,82 +172,80 @@ export function CreateTrainingForm({
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="state"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Estado</FormLabel>
|
||||
control={form.control}
|
||||
name="state"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Estado</FormLabel>
|
||||
|
||||
<SelectSearchable
|
||||
options={
|
||||
<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>
|
||||
)}
|
||||
}
|
||||
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>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="municipality"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Municipio</FormLabel>
|
||||
|
||||
<SelectSearchable
|
||||
options={
|
||||
<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>
|
||||
)}
|
||||
}
|
||||
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>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="parish"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Parroquia</FormLabel>
|
||||
|
||||
<SelectSearchable
|
||||
options={
|
||||
<SelectSearchable
|
||||
options={
|
||||
parishOptions?.map((item) => ({
|
||||
value: item.id.toString(),
|
||||
label: item.name,
|
||||
})) || []
|
||||
}
|
||||
onValueChange={(value : any) =>
|
||||
}
|
||||
onValueChange={(value: any) =>
|
||||
field.onChange(Number(value))
|
||||
}
|
||||
placeholder="Selecciona una Parroquia"
|
||||
defaultValue={field.value?.toString()}
|
||||
disabled={disabledParish}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
}
|
||||
placeholder="Selecciona una Parroquia"
|
||||
defaultValue={field.value?.toString()}
|
||||
disabled={disabledParish}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* <FormField control={form.control} name="state" render={({ field }) => (
|
||||
<FormItem>
|
||||
@@ -463,6 +462,14 @@ export function CreateTrainingForm({
|
||||
</FormItem>
|
||||
)} />
|
||||
|
||||
<FormField control={form.control} name="ospResponsibleEmail" render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Correo Electrónico</FormLabel>
|
||||
<FormControl><Input type="email" {...field} /></FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)} />
|
||||
|
||||
<FormField control={form.control} name="familyBurden" render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Carga Familiar</FormLabel>
|
||||
@@ -479,6 +486,11 @@ export function CreateTrainingForm({
|
||||
</FormItem>
|
||||
)} />
|
||||
|
||||
{/* datos adicionales */}
|
||||
<div className="col-span-2">
|
||||
<h3 className="text-lg font-medium mb-2 mt-4">Datos Adicionales</h3>
|
||||
</div>
|
||||
|
||||
<FormField control={form.control} name="generalObservations" render={({ field }) => (
|
||||
<FormItem className="col-span-2">
|
||||
<FormLabel>Observaciones Generales</FormLabel>
|
||||
|
||||
@@ -27,6 +27,7 @@ export const trainingSchema = z.object({
|
||||
civilState: z.string().min(1, { message: "Estado civil es requerido" }),
|
||||
familyBurden: z.coerce.number().min(0, { message: "Carga familiar requerida" }),
|
||||
numberOfChildren: z.coerce.number().min(0, { message: "Número de hijos requerido" }),
|
||||
ospResponsibleEmail: z.string().email({ message: "Correo electrónico inválido" }),
|
||||
generalObservations: z.string().optional().default(''),
|
||||
photo1: z.string().optional().default(''),
|
||||
photo2: z.string().optional().default(''),
|
||||
|
||||
Reference in New Issue
Block a user