diff --git a/apps/api/src/features/training/training.service.ts b/apps/api/src/features/training/training.service.ts index a568a51..84a79f7 100644 --- a/apps/api/src/features/training/training.service.ts +++ b/apps/api/src/features/training/training.service.ts @@ -105,13 +105,21 @@ export class TrainingService { // Ejecutamos todas las consultas en paralelo con Promise.all para mayor velocidad const [ totalOspsResult, - totalProducersResult, - totalProductsResult, // Nuevo: Calculado desde el JSON + // totalProducersResult, + totalProductsResult, statusDistribution, activityDistribution, typeDistribution, stateDistribution, yearDistribution, + ecoSectorDistribution, + productiveSectorDistribution, + centralActivityDistribution, + mainActivityDistribution, + structureTypeDistribution, + isOpenSpaceDistribution, + hasTransportDistribution, + genderResult, ] = await Promise.all([ // 1. Total OSPs this.drizzle @@ -120,12 +128,12 @@ export class TrainingService { .where(whereCondition), // 2. Total Productores (Columna plana que mantuviste) - this.drizzle - .select({ - sum: sql`SUM(${trainingSurveys.womenCount} + ${trainingSurveys.menCount})`, - }) - .from(trainingSurveys) - .where(whereCondition), + // this.drizzle + // .select({ + // sum: sql`SUM(${trainingSurveys.womenCount} + ${trainingSurveys.menCount})`, + // }) + // .from(trainingSurveys) + // .where(whereCondition), // 3. NUEVO: Total Productos (Contamos el largo del array JSON productList) this.drizzle @@ -145,7 +153,7 @@ export class TrainingService { .where(whereCondition) .groupBy(trainingSurveys.currentStatus), - // 5. Distribución por Actividad + // 5. Distribución por Actividad (General) this.drizzle .select({ name: trainingSurveys.productiveActivity, @@ -188,11 +196,90 @@ export class TrainingService { .where(whereCondition) .groupBy(trainingSurveys.companyConstitutionYear) .orderBy(trainingSurveys.companyConstitutionYear), + + // 9. Distribución por Sector Económico + this.drizzle + .select({ + name: trainingSurveys.ecoSector, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.ecoSector), + + // 10. Distribución por Sector Productivo + this.drizzle + .select({ + name: trainingSurveys.productiveSector, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.productiveSector), + + // 11. Distribución por Actividad Central Productiva + this.drizzle + .select({ + name: trainingSurveys.centralProductiveActivity, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.centralProductiveActivity), + + // 12. Distribución por Actividad Productiva Principal + this.drizzle + .select({ + name: trainingSurveys.mainProductiveActivity, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.mainProductiveActivity), + + // 13. Distribución por Tipo de Estructura + this.drizzle + .select({ + name: trainingSurveys.structureType, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.structureType), + + // 14. Distribución por Espacio Abierto + this.drizzle + .select({ + name: sql`case when ${trainingSurveys.isOpenSpace} then 'Sí' else 'No' end`, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.isOpenSpace), + + // 15. Distribución por Transporte + this.drizzle + .select({ + name: sql`case when ${trainingSurveys.hasTransport} then 'Sí' else 'No' end`, + value: sql`count(*)`, + }) + .from(trainingSurveys) + .where(whereCondition) + .groupBy(trainingSurveys.hasTransport), + + // 16. Distribución por Género + this.drizzle + .select({ + women: sql`sum(${trainingSurveys.womenCount})`, + men: sql`sum(${trainingSurveys.menCount})`, + }) + .from(trainingSurveys) + .where(whereCondition), ]); return { totalOsps: Number(totalOspsResult[0]?.count || 0), - totalProducers: Number(totalProducersResult[0]?.sum || 0), + // totalProducers: Number(totalProducersResult[0]?.sum || 0), totalProducts: Number(totalProductsResult[0]?.sum || 0), // Dato extraído del JSON statusDistribution: statusDistribution.map((item) => ({ @@ -215,6 +302,38 @@ export class TrainingService { ...item, value: Number(item.value), })), + ecoSectorDistribution: ecoSectorDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + productiveSectorDistribution: productiveSectorDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + centralActivityDistribution: centralActivityDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + mainActivityDistribution: mainActivityDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + structureTypeDistribution: structureTypeDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + isOpenSpaceDistribution: isOpenSpaceDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + hasTransportDistribution: hasTransportDistribution.map((item) => ({ + ...item, + value: Number(item.value), + })), + genderDistribution: [ + { name: 'Mujeres', value: Number(genderResult[0]?.women || 0) }, + { name: 'Hombres', value: Number(genderResult[0]?.men || 0) }, + ], }; } diff --git a/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx b/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx index 4cbc28c..6d949f5 100644 --- a/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx +++ b/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx @@ -9,11 +9,11 @@ export const metadata: Metadata = { export default function SocioproductivaStatisticsPage() { return ( - -
-

Estadísticas Socioproductivas

- -
-
+ // +
+

Estadísticas Socioproductivas

+ +
+ //
); } diff --git a/apps/web/feactures/training/components/training-statistics.tsx b/apps/web/feactures/training/components/training-statistics.tsx index e2cd34c..9317efe 100644 --- a/apps/web/feactures/training/components/training-statistics.tsx +++ b/apps/web/feactures/training/components/training-statistics.tsx @@ -103,12 +103,20 @@ export function TrainingStatistics() { const { totalOsps, - totalProducers, + // totalProducers, statusDistribution, activityDistribution, typeDistribution, stateDistribution, yearDistribution, + ecoSectorDistribution, + productiveSectorDistribution, + centralActivityDistribution, + mainActivityDistribution, + structureTypeDistribution, + isOpenSpaceDistribution, + hasTransportDistribution, + genderDistribution, } = data; const COLORS = [ @@ -230,7 +238,8 @@ export function TrainingStatistics() {

- + + {/* Total de Productores @@ -242,7 +251,8 @@ export function TrainingStatistics() { Productores asociados

-
+
*/} + @@ -367,6 +377,223 @@ export function TrainingStatistics() { + + {/* ECO SECTOR DISTRIBUTION */} + + + Sector Económico + + Distribución por sector económico + + + + + + + + + + + + + + + + + {/* PRODUCTIVE SECTOR DISTRIBUTION */} + + + Sector Productivo + + Distribución por sector productivo + + + + + + + + + + + + + + + + + {/* CENTRAL PRODUCTIVE ACTIVITY DISTRIBUTION */} + + + Actividad Central Productiva + + Distribución por actividad central productiva + + + + + + + + + + + + + + + + + {/* MAIN PRODUCTIVE ACTIVITY DISTRIBUTION */} + + + Actividad Productiva Principal + + Distribución por actividad productiva principal + + + + + + + + + + + + + + + + + {/* STRUCTURE TYPE DISTRIBUTION */} + + + Tipo de Estructura + Distribución física + + + + + + + + + + + + + + + + {/* GENDER DISTRIBUTION */} + + + Distribución de Género + Conteo total por género + + + + + + + + + + + + + + + + {/* OPEN SPACE AND TRANSPORT (PIE CHARTS) */} +
+ + + Espacio Abierto + ¿Poseen áreas libres? + + + + + + {isOpenSpaceDistribution.map((entry, index) => ( + + ))} + + + + + + + + + + + Transporte + ¿Tienen vehículo propio? + + + + + + {hasTransportDistribution.map((entry, index) => ( + + ))} + + + + + + + +
); diff --git a/apps/web/feactures/training/schemas/statistics.ts b/apps/web/feactures/training/schemas/statistics.ts index 3edf814..7eeb775 100644 --- a/apps/web/feactures/training/schemas/statistics.ts +++ b/apps/web/feactures/training/schemas/statistics.ts @@ -10,13 +10,21 @@ export const statisticsItemSchema = z.object({ export const trainingStatisticsSchema = z.object({ totalOsps: z.number(), - totalProducers: z.number(), + // totalProducers: z.number(), totalProducts: z.number(), statusDistribution: z.array(statisticsItemSchema), activityDistribution: z.array(statisticsItemSchema), typeDistribution: z.array(statisticsItemSchema), stateDistribution: z.array(statisticsItemSchema), yearDistribution: z.array(statisticsItemSchema), + ecoSectorDistribution: z.array(statisticsItemSchema), + productiveSectorDistribution: z.array(statisticsItemSchema), + centralActivityDistribution: z.array(statisticsItemSchema), + mainActivityDistribution: z.array(statisticsItemSchema), + structureTypeDistribution: z.array(statisticsItemSchema), + isOpenSpaceDistribution: z.array(statisticsItemSchema), + hasTransportDistribution: z.array(statisticsItemSchema), + genderDistribution: z.array(statisticsItemSchema), }); export type TrainingStatisticsData = z.infer;