From f9eef8ebd6ac3fc67c024833fb0b19fe1eb85df7 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Thu, 16 Apr 2026 17:08:14 -0400 Subject: [PATCH] estadisticas por estado, municipio y parroquia agregadas --- .../src/features/training/training.service.ts | 37 +++++- .../components/training-statistics.tsx | 110 ++++++++++++++---- .../feactures/training/schemas/statistics.ts | 2 + 3 files changed, 125 insertions(+), 24 deletions(-) diff --git a/apps/api/src/features/training/training.service.ts b/apps/api/src/features/training/training.service.ts index 84a79f7..748a7b0 100644 --- a/apps/api/src/features/training/training.service.ts +++ b/apps/api/src/features/training/training.service.ts @@ -4,7 +4,7 @@ import { and, eq, gte, ilike, lte, or, SQL, sql } from 'drizzle-orm'; import { NodePgDatabase } from 'drizzle-orm/node-postgres'; import { DRIZZLE_PROVIDER } from 'src/database/drizzle-provider'; import * as schema from 'src/database/index'; -import { states, trainingSurveys } from 'src/database/index'; +import { municipalities, parishes, states, trainingSurveys } from 'src/database/index'; import { PaginationDto } from '../../common/dto/pagination.dto'; import { CreateTrainingDto } from './dto/create-training.dto'; @@ -120,6 +120,8 @@ export class TrainingService { isOpenSpaceDistribution, hasTransportDistribution, genderResult, + municipalityDistribution, + parishDistribution, ] = await Promise.all([ // 1. Total OSPs this.drizzle @@ -275,6 +277,31 @@ export class TrainingService { }) .from(trainingSurveys) .where(whereCondition), + + // 17. Distribución por Municipio + this.drizzle + .select({ + name: sql`COALESCE(${municipalities.name}, 'Sin Asignar')`, + value: sql`count(${trainingSurveys.id})`, + }) + .from(trainingSurveys) + .leftJoin( + municipalities, + eq(trainingSurveys.municipality, municipalities.id), + ) + .where(whereCondition) + .groupBy(municipalities.name), + + // 18. Distribución por Parroquia + this.drizzle + .select({ + name: sql`COALESCE(${parishes.name}, 'Sin Asignar')`, + value: sql`count(${trainingSurveys.id})`, + }) + .from(trainingSurveys) + .leftJoin(parishes, eq(trainingSurveys.parish, parishes.id)) + .where(whereCondition) + .groupBy(parishes.name), ]); return { @@ -334,6 +361,14 @@ export class TrainingService { { name: 'Mujeres', value: Number(genderResult[0]?.women || 0) }, { name: 'Hombres', value: Number(genderResult[0]?.men || 0) }, ], + municipalityDistribution: municipalityDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + parishDistribution: parishDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), }; } diff --git a/apps/web/feactures/training/components/training-statistics.tsx b/apps/web/feactures/training/components/training-statistics.tsx index 9317efe..e1563d0 100644 --- a/apps/web/feactures/training/components/training-statistics.tsx +++ b/apps/web/feactures/training/components/training-statistics.tsx @@ -117,6 +117,8 @@ export function TrainingStatistics() { isOpenSpaceDistribution, hasTransportDistribution, genderDistribution, + municipalityDistribution, + parishDistribution, } = data; const COLORS = [ @@ -279,28 +281,90 @@ export function TrainingStatistics() { - {/* State Distribution */} - {/* - - Distribución por Estado - OSP registradas por estado - - - - - - - - - - - - - - */} + {/* Location Distribution (Dynamic) */} + + + Distribución por Estado + OSP registradas por estado + + + + + + + + + + + + + + + + {stateId > 0 ? ( + + + Distribución por Municipio + OSP registradas en este estado + + + + + + + + + + + + + + + ) : ( + + + Distribución por Municipio + Seleccione un estado + + + )} + + {municipalityId > 0 ? ( + + + Distribución por Parroquia + OSP registradas en este municipio + + + + + + + + + + + + + + + ) : ( + + + Distribución por Parroquia + Seleccione un municipio + + + )} {/* Year Distribution */} @@ -483,7 +547,7 @@ export function TrainingStatistics() { {/* STRUCTURE TYPE DISTRIBUTION */} - + Tipo de Estructura Distribución física diff --git a/apps/web/feactures/training/schemas/statistics.ts b/apps/web/feactures/training/schemas/statistics.ts index 7eeb775..29ced24 100644 --- a/apps/web/feactures/training/schemas/statistics.ts +++ b/apps/web/feactures/training/schemas/statistics.ts @@ -25,6 +25,8 @@ export const trainingStatisticsSchema = z.object({ isOpenSpaceDistribution: z.array(statisticsItemSchema), hasTransportDistribution: z.array(statisticsItemSchema), genderDistribution: z.array(statisticsItemSchema), + municipalityDistribution: z.array(statisticsItemSchema), + parishDistribution: z.array(statisticsItemSchema), }); export type TrainingStatisticsData = z.infer;