corregido estado, estatus osp

This commit is contained in:
2026-04-12 20:59:15 -04:00
parent ce1727525b
commit 8f207e675c
6 changed files with 67 additions and 90 deletions

View File

@@ -158,7 +158,7 @@ export const trainingSurveys = t.pgTable(
updatedBy: t updatedBy: t
.integer('updated_by') .integer('updated_by')
.references(() => users.id, { onDelete: 'cascade' }), .references(() => users.id, { onDelete: 'cascade' }),
surveyStatus: t.text('survey_status').notNull().default('PUBLICADO'), surveyStatus: t.text('survey_status').notNull().default('COMPLETADA'),
...timestamps, ...timestamps,
}, },
(trainingSurveys) => ({ (trainingSurveys) => ({

View File

@@ -2,7 +2,7 @@ import { DRIZZLE_PROVIDER } from '@/database/drizzle-provider';
import * as schema from '@/database/index'; import * as schema from '@/database/index';
import { states } from '@/database/schema/general'; import { states } from '@/database/schema/general';
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { eq } from 'drizzle-orm'; import { and, eq, ne } from 'drizzle-orm';
import { NodePgDatabase } from 'drizzle-orm/node-postgres'; import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { CreateStateDto } from './dto/create-state.dto'; import { CreateStateDto } from './dto/create-state.dto';
import { UpdateStateDto } from './dto/update-state.dto'; import { UpdateStateDto } from './dto/update-state.dto';
@@ -15,14 +15,17 @@ export class StatesService {
) {} ) {}
async findAll(): Promise<State[]> { async findAll(): Promise<State[]> {
return await this.drizzle.select().from(states); return await this.drizzle
.select()
.from(states)
.where(ne(states.name, 'EMBAJADA'));
} }
async findOne(id: number): Promise<State> { async findOne(id: number): Promise<State> {
const state = await this.drizzle const state = await this.drizzle
.select() .select()
.from(states) .from(states)
.where(eq(states.id, id)); .where(and(eq(states.id, id), ne(states.name, 'EMBAJADA')));
if (state.length === 0) { if (state.length === 0) {
throw new HttpException('State not found', HttpStatus.NOT_FOUND); throw new HttpException('State not found', HttpStatus.NOT_FOUND);

View File

@@ -1,29 +1,30 @@
import { DRIZZLE_PROVIDER } from 'src/database/drizzle-provider'; import { DRIZZLE_PROVIDER } from 'src/database/drizzle-provider';
// import { Env, validateString } from '@/common/utils'; // import { Env, validateString } from '@/common/utils';
import { Inject, Injectable, HttpException, HttpStatus, NotFoundException, UnauthorizedException } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { eq, ne } from 'drizzle-orm';
import { NodePgDatabase } from 'drizzle-orm/node-postgres'; import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import * as schema from 'src/database/index'; import * as schema from 'src/database/index';
import { states, municipalities, parishes } from 'src/database/index'; import { municipalities, parishes, states } from 'src/database/index';
import { eq, like, or, SQL, sql, and, not } from 'drizzle-orm';
import * as bcrypt from 'bcryptjs'; import { Municipality, Parish, State } from './entities/user.entity';
import { State, Municipality, Parish } from './entities/user.entity';
// import { PaginationDto } from '../../common/dto/pagination.dto'; // import { PaginationDto } from '../../common/dto/pagination.dto';
@Injectable() @Injectable()
export class UsersService { export class UsersService {
constructor( constructor(
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>, @Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
) { } ) {}
async StateAll(): Promise< State[]> { async StateAll(): Promise<State[]> {
const find = await this.drizzle const find = await this.drizzle
.select() .select()
.from(states) .from(states)
.where(ne(states.name, 'EMBAJADA'));
return find; return find;
} }
async MunicioalityAll(id: string): Promise< Municipality[]> { async MunicioalityAll(id: string): Promise<Municipality[]> {
const find = await this.drizzle const find = await this.drizzle
.select() .select()
.from(municipalities) .from(municipalities)
@@ -32,7 +33,7 @@ export class UsersService {
return find; return find;
} }
async ParishAll(id: string): Promise< Parish[]> { async ParishAll(id: string): Promise<Parish[]> {
const find = await this.drizzle const find = await this.drizzle
.select() .select()
.from(parishes) .from(parishes)
@@ -41,4 +42,3 @@ export class UsersService {
return find; return find;
} }
} }

View File

@@ -107,7 +107,8 @@ export function CreateTrainingForm({
coorPhone: defaultValues?.coorPhone || '', coorPhone: defaultValues?.coorPhone || '',
visitDate: formatToLocalISO(defaultValues?.visitDate), visitDate: formatToLocalISO(defaultValues?.visitDate),
productiveActivity: defaultValues?.productiveActivity || undefined, productiveActivity: defaultValues?.productiveActivity || undefined,
productiveActivityOther: defaultValues?.productiveActivityOther || undefined, productiveActivityOther:
defaultValues?.productiveActivityOther || undefined,
ecoSector: defaultValues?.ecoSector || undefined, ecoSector: defaultValues?.ecoSector || undefined,
productiveSector: defaultValues?.productiveSector || undefined, productiveSector: defaultValues?.productiveSector || undefined,
centralProductiveActivity: centralProductiveActivity:
@@ -172,7 +173,7 @@ export function CreateTrainingForm({
womenCount: defaultValues?.womenCount || 0, womenCount: defaultValues?.womenCount || 0,
menCount: defaultValues?.menCount || 0, menCount: defaultValues?.menCount || 0,
surveyStatus: defaultValues?.surveyStatus || 'BORRADOR' surveyStatus: defaultValues?.surveyStatus || 'BORRADOR',
}, },
mode: 'onChange', mode: 'onChange',
}); });
@@ -240,7 +241,7 @@ export function CreateTrainingForm({
productiveSector, productiveSector,
centralProductiveActivity, centralProductiveActivity,
mainProductiveActivity, mainProductiveActivity,
productiveActivity productiveActivity,
]); ]);
const stateOptions = dataState?.data || [{ id: 0, name: 'Sin estados' }]; const stateOptions = dataState?.data || [{ id: 0, name: 'Sin estados' }];
@@ -690,26 +691,23 @@ export function CreateTrainingForm({
)} )}
/> />
{other && (
{other && (<FormField <FormField
control={form.control} control={form.control}
name="productiveActivityOther" name="productiveActivityOther"
render={({ field }) => ( render={({ field }) => (
<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">
¿Cuál otra Actividad Productiva? ¿Cuál otra Actividad Productiva?
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input {...field} value={field.value} />
{...field} </FormControl>
value={field.value} <FormMessage />
/> </FormItem>
</FormControl> )}
<FormMessage /> />
</FormItem> )}
)}
/>)}
<FormField <FormField
control={form.control} control={form.control}
@@ -756,11 +754,7 @@ export function CreateTrainingForm({
Año de constitución Año de constitución
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input type="number" {...field} value={field.value} />
type="number"
{...field}
value={field.value}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@@ -1291,11 +1285,7 @@ export function CreateTrainingForm({
Correo Electrónico de la Comuna (Opcional) Correo Electrónico de la Comuna (Opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input type="email" {...field} value={field.value} />
type="email"
{...field}
value={field.value}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@@ -1405,11 +1395,7 @@ export function CreateTrainingForm({
Correo Electrónico del Consejo Comunal (Opcional) Correo Electrónico del Consejo Comunal (Opcional)
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input type="email" {...field} value={field.value} />
type="email"
{...field}
value={field.value}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@@ -1555,9 +1541,7 @@ export function CreateTrainingForm({
</div> </div>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<FormLabel> <FormLabel>Subir imágenes (Máximo 3 y opcional)</FormLabel>
Subir imágenes (Máximo 3 y opcional)
</FormLabel>
<Input <Input
type="file" type="file"
multiple multiple
@@ -1643,13 +1627,8 @@ export function CreateTrainingForm({
</CardContent> </CardContent>
</Card> </Card>
<div className="grid grid-cols-2 md:grid-cols-3 justify-items-end gap-3 mt-8"> <div className="flex justify-end gap-4">
<Button <Button variant="outline" type="button" onClick={onCancel}>
variant="outline"
type="button"
onClick={onCancel}
className="w-32 col-span-2 md:col-span-1"
>
Cancelar Cancelar
</Button> </Button>
@@ -1668,8 +1647,10 @@ export function CreateTrainingForm({
</SelectTrigger> </SelectTrigger>
</FormControl> </FormControl>
<SelectContent> <SelectContent>
<SelectItem defaultChecked value="BORRADOR">BORRADOR</SelectItem> <SelectItem defaultChecked value="BORRADOR">
<SelectItem value="PUBLICADO">PUBLICADO</SelectItem> BORRADOR
</SelectItem>
<SelectItem value="COMPLETADA">COMPLETADA</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
<FormMessage /> <FormMessage />

View File

@@ -43,22 +43,13 @@ export function columns({ apiUrl }: ColumnsProps): ColumnDef<TrainingSchema>[] {
return date ? new Date(date).toLocaleString() : 'N/A'; return date ? new Date(date).toLocaleString() : 'N/A';
}, },
}, },
{
accessorKey: 'visitDate',
header: 'Fecha Visita',
cell: ({ row }) => {
const date = row.getValue('visitDate') as string;
return date ? new Date(date).toLocaleString() : 'N/A';
},
},
{ {
accessorKey: 'surveyStatus', accessorKey: 'surveyStatus',
header: '', header: '',
cell: ({ row }) => { cell: ({ row }) => {
const status = row.getValue('surveyStatus') as string; const status = row.getValue('surveyStatus') as string;
return ( return (
<Badge variant={status === 'PUBLICADO' ? 'default' : 'secondary'}> <Badge variant={status === 'COMPLETADA' ? 'success' : 'secondary'}>
{status} {status}
</Badge> </Badge>
); );

View File

@@ -1,38 +1,40 @@
import * as React from "react" import { Slot } from '@radix-ui/react-slot';
import { Slot } from "@radix-ui/react-slot" import { cva, type VariantProps } from 'class-variance-authority';
import { cva, type VariantProps } from "class-variance-authority" import * as React from 'react';
import { cn } from "@repo/shadcn/lib/utils" import { cn } from '@repo/shadcn/lib/utils';
const badgeVariants = cva( const badgeVariants = cva(
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
{ {
variants: { variants: {
variant: { variant: {
default: default:
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
secondary: secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
destructive: destructive:
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70", 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70',
outline: outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
success:
'border-transparent bg-green-500 text-black [a&]:hover:bg-green-300',
}, },
}, },
defaultVariants: { defaultVariants: {
variant: "default", variant: 'default',
}, },
} },
) );
function Badge({ function Badge({
className, className,
variant, variant,
asChild = false, asChild = false,
...props ...props
}: React.ComponentProps<"span"> & }: React.ComponentProps<'span'> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) { VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "span" const Comp = asChild ? Slot : 'span';
return ( return (
<Comp <Comp
@@ -40,7 +42,7 @@ function Badge({
className={cn(badgeVariants({ variant }), className)} className={cn(badgeVariants({ variant }), className)}
{...props} {...props}
/> />
) );
} }
export { Badge, badgeVariants } export { Badge, badgeVariants };