diff --git a/src/app/voluntometro/page.tsx b/src/app/voluntometro/page.tsx
index 91687af0..da47ae4c 100644
--- a/src/app/voluntometro/page.tsx
+++ b/src/app/voluntometro/page.tsx
@@ -5,8 +5,7 @@ import { helpRequestService } from '@/lib/service';
export const dynamic = 'force-dynamic';
export default async function Voluntometro() {
- const pueblos = await helpRequestService.getTodaysCountByTown();
- const count = await helpRequestService.getTodaysCount();
+ const towns = await helpRequestService.getTodaysCountByTown();
const getFechaHoy = () => {
const fecha = new Date();
@@ -17,23 +16,11 @@ export default async function Voluntometro() {
});
};
- const getTopAndBottomPueblos = () => {
- const sortedPueblos = [...pueblos].sort((a, b) => {
- const volunteersDiffA = a.count - a.needHelp;
- const volunteersDiffB = b.count - b.needHelp;
- if (volunteersDiffA !== volunteersDiffB) {
- return volunteersDiffB - volunteersDiffA;
- } else {
- return b.count - a.count;
- }
- });
+ const totalOffers = towns.reduce((sum, pueblo) => sum + (pueblo.offers_last_24h ?? 0), 0);
+ const totalSolicitudes = towns.reduce((sum, pueblo) => sum + (pueblo.needs_last_24h ?? 0), 0);
+
+ const sortedTowns = towns.sort((a, b) => (b.unassigned_needs ?? 0) - (a.unassigned_needs ?? 0));
- return {
- top: sortedPueblos.slice(0, 2),
- bottom: sortedPueblos.slice(-2).reverse(),
- all: sortedPueblos.reverse(),
- };
- };
return (
- {getTopAndBottomPueblos().all.map(
- (pueblo) =>
- pueblo.needHelp > 0 && (
-
- ),
- )}
+ {sortedTowns.map((townSummary) => (
+
+ ))}
);
diff --git a/src/components/TownCardInfo.tsx b/src/components/TownCardInfo.tsx
index 291595c2..51800eca 100644
--- a/src/components/TownCardInfo.tsx
+++ b/src/components/TownCardInfo.tsx
@@ -1,42 +1,44 @@
'use client';
import { useRouter } from 'next/navigation';
import React from 'react';
+import { TownSummary } from '@/types/Town';
type PuebloInfo = {
- pueblo: {
- id: number;
- name: string;
- count: number;
- needHelp: string;
- };
+ townSummary: TownSummary;
route: string;
};
-export default function TownCardInfo({ pueblo, route }: PuebloInfo) {
+export default function TownCardInfo({ townSummary, route }: PuebloInfo) {
const router = useRouter();
return (
-
+
-
{pueblo.name}
+
{townSummary.town_name}
- {pueblo.count}
+ {townSummary.offers_last_24h}
voluntarios
|
- {pueblo.needHelp}
+ {townSummary.needs_last_24h}
solicitudes de ayuda
+
+
+ {townSummary.unassigned_needs}
+ solicitudes sin atender
+
+
);
diff --git a/src/lib/service.ts b/src/lib/service.ts
index 31fd0bad..987de2f7 100644
--- a/src/lib/service.ts
+++ b/src/lib/service.ts
@@ -125,75 +125,20 @@ export const helpRequestService = {
if (error) throw error;
return data;
},
- async getTodaysCount() {
- const today = new Date().toISOString().split('T')[0];
- const supabase = await getSupabaseClient();
- const { count: solicitaCount, error: solicitaError } = await supabase
- .from('help_requests')
- .select('id', { count: 'exact' })
- .eq('type', 'necesita')
- .gte('created_at', today)
- .lte('created_at', `${today}T23:59:59.999Z`);
-
- const { count: ofreceCount, error: ofreceError } = await supabase
- .from('help_requests')
- .select('id', { count: 'exact' })
- .eq('type', 'ofrece')
- .gte('created_at', today)
- .lte('created_at', `${today}T23:59:59.999Z`);
-
- if (solicitaError) {
- throw new Error('Error fetching solicita:', solicitaError);
- }
- if (ofreceError) {
- throw new Error('Error fetching ofrece:', ofreceError);
- }
- return {
- solicitudes: solicitaCount || 0,
- ofertas: ofreceCount || 0,
- };
- },
async getTodaysCountByTown() {
const supabase = await getSupabaseClient();
- const today = new Date().toISOString().split('T')[0];
- const { data: towns, error: townError } = await supabase.from('towns').select('id, name');
+ const { data: towns, error: townError } = await supabase
+ .from('town_help_request_summary')
+ .select('*')
+ .or('offers_last_24h.gt.0,needs_last_24h.gt.0,unassigned_needs.gt.0');
if (townError) {
console.log('Error fetching towns:', townError);
throw townError;
}
- const { data, error } = await supabase
- .from('help_requests')
- .select('*')
- .in('type', ['ofrece', 'necesita'])
- .gte('created_at', today)
- .lte('created_at', `${today}T23:59:59.999Z`);
-
- if (error) {
- console.log('Error fetching help requests:', error);
- throw error;
- }
-
- const volunteersCount = new Map();
- const needHelpCount = new Map();
-
- data.forEach((person) => {
- const townId = person.town_id;
- if (person.type === 'ofrece') {
- volunteersCount.set(townId, (volunteersCount.get(townId) || 0) + 1);
- } else if (person.type === 'necesita') {
- needHelpCount.set(townId, (needHelpCount.get(townId) || 0) + 1);
- }
- });
-
- return towns.map((town) => ({
- id: town.id,
- name: town.name ?? 'N/A',
- count: volunteersCount.get(town.id) || 0,
- needHelp: needHelpCount.get(town.id) || 0,
- }));
+ return towns;
},
};
diff --git a/src/types/Town.ts b/src/types/Town.ts
index 160382a6..1696fc8c 100644
--- a/src/types/Town.ts
+++ b/src/types/Town.ts
@@ -1,3 +1,5 @@
import { Database } from '@/types/database';
export type Town = Database['public']['Tables']['towns']['Row'];
+
+export type TownSummary = Database['public']['Views']['town_help_request_summary']['Row'];
diff --git a/src/types/database.ts b/src/types/database.ts
index a863b045..26cb238b 100644
--- a/src/types/database.ts
+++ b/src/types/database.ts
@@ -182,6 +182,7 @@ export type Database = {
contact_info: string | null;
coordinates: unknown | null;
created_at: string | null;
+ crm_status: string | null;
description: string | null;
help_type: Database['public']['Enums']['help_type_enum'][] | null;
id: number;
@@ -189,6 +190,7 @@ export type Database = {
location: string | null;
longitude: number | null;
name: string | null;
+ notes: string | null;
number_of_people: number | null;
other_help: string | null;
people_needed: number | null;
@@ -197,7 +199,6 @@ export type Database = {
town_id: number | null;
type: string | null;
urgency: string | null;
- crm_status: string | null;
user_id: string | null;
};
Insert: {
@@ -206,6 +207,7 @@ export type Database = {
contact_info?: string | null;
coordinates?: unknown | null;
created_at?: string | null;
+ crm_status?: string | null;
description?: string | null;
help_type?: Database['public']['Enums']['help_type_enum'][] | null;
id?: number;
@@ -213,6 +215,7 @@ export type Database = {
location?: string | null;
longitude?: number | null;
name?: string | null;
+ notes?: string | null;
number_of_people?: number | null;
other_help?: string | null;
people_needed?: number | null;
@@ -229,6 +232,7 @@ export type Database = {
contact_info?: string | null;
coordinates?: unknown | null;
created_at?: string | null;
+ crm_status?: string | null;
description?: string | null;
help_type?: Database['public']['Enums']['help_type_enum'][] | null;
id?: number;
@@ -236,6 +240,7 @@ export type Database = {
location?: string | null;
longitude?: number | null;
name?: string | null;
+ notes?: string | null;
number_of_people?: number | null;
other_help?: string | null;
people_needed?: number | null;
@@ -247,6 +252,13 @@ export type Database = {
user_id?: string | null;
};
Relationships: [
+ {
+ foreignKeyName: 'help_requests_town_id_fkey';
+ columns: ['town_id'];
+ isOneToOne: false;
+ referencedRelation: 'town_help_request_summary';
+ referencedColumns: ['town_id'];
+ },
{
foreignKeyName: 'help_requests_town_id_fkey';
columns: ['town_id'];
@@ -380,6 +392,7 @@ export type Database = {
contact_info: string | null;
coordinates: unknown | null;
created_at: string | null;
+ crm_status: string | null;
description: string | null;
help_type: Database['public']['Enums']['help_type_enum'][] | null;
id: number | null;
@@ -387,6 +400,7 @@ export type Database = {
location: string | null;
longitude: number | null;
name: string | null;
+ notes: string | null;
number_of_people: number | null;
other_help: string | null;
people_needed: number | null;
@@ -398,6 +412,13 @@ export type Database = {
user_id: string | null;
};
Relationships: [
+ {
+ foreignKeyName: 'help_requests_town_id_fkey';
+ columns: ['town_id'];
+ isOneToOne: false;
+ referencedRelation: 'town_help_request_summary';
+ referencedColumns: ['town_id'];
+ },
{
foreignKeyName: 'help_requests_town_id_fkey';
columns: ['town_id'];
@@ -407,6 +428,16 @@ export type Database = {
},
];
};
+ town_help_request_summary: {
+ Row: {
+ needs_last_24h: number | null;
+ offers_last_24h: number | null;
+ town_id: number | null;
+ town_name: string | null;
+ unassigned_needs: number | null;
+ };
+ Relationships: [];
+ };
};
Functions: {
[_ in never]: never;
diff --git a/supabase/migrations/20241110204442_add view for voluntometro.sql b/supabase/migrations/20241110204442_add view for voluntometro.sql
new file mode 100644
index 00000000..1f22a3a7
--- /dev/null
+++ b/supabase/migrations/20241110204442_add view for voluntometro.sql
@@ -0,0 +1,22 @@
+create view town_help_request_summary as
+select
+ t.id as town_id,
+ t.name as town_name,
+
+ -- Número de help_requests de type = "ofrece" en las últimas 24 horas
+ coalesce(sum(case when hr.type = 'ofrece' and hr.created_at >= now() - interval '24 hours' then 1 else 0 end), 0) as offers_last_24h,
+
+ -- Número de help_requests de type = "necesita" en las últimas 24 horas
+ coalesce(sum(case when hr.type = 'necesita' and hr.created_at >= now() - interval '24 hours' then 1 else 0 end), 0) as needs_last_24h,
+
+ -- Número de help_requests de type = "necesita" sin help_request_assignments
+ coalesce(sum(case when hr.type = 'necesita' and hr.status <> 'finished' and hra.help_request_id is null then 1 else 0 end), 0) as unassigned_needs
+
+from
+ towns t
+left join
+ help_requests hr on t.id = hr.town_id
+left join
+ help_request_assignments hra on hr.id = hra.help_request_id
+group by
+ t.id, t.name;
diff --git a/supabase/migrations/20241111161121_fix view with new fields.sql b/supabase/migrations/20241111161121_fix view with new fields.sql
new file mode 100644
index 00000000..6c12ec9c
--- /dev/null
+++ b/supabase/migrations/20241111161121_fix view with new fields.sql
@@ -0,0 +1,12 @@
+drop view if exists help_requests_with_assignment_count;
+
+create view help_requests_with_assignment_count as
+select
+ hr.*,
+ coalesce(count(hra.id), 0) as assignments_count
+from
+ help_requests hr
+left join
+ help_request_assignments hra on hr.id = hra.help_request_id
+group by
+ hr.id;