From 38d5618277b59efebb1967b5357d5098633a7dd6 Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Mon, 11 Nov 2024 00:05:14 +0100 Subject: [PATCH 1/5] feat: add info in voluntometro --- src/app/voluntometro/page.tsx | 40 ++++-------- src/components/TownCardInfo.tsx | 28 ++++---- src/lib/service.ts | 65 ++----------------- src/types/Town.ts | 2 + src/types/database.ts | 24 +++++++ ...241110204442_add view for voluntometro.sql | 22 +++++++ 6 files changed, 82 insertions(+), 99 deletions(-) create mode 100644 supabase/migrations/20241110204442_add view for voluntometro.sql 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 (
@@ -51,7 +38,7 @@ export default async function Voluntometro() {
-

{count.ofertas}+

+

{totalOffers}+

Nuevos voluntarios hoy

@@ -60,18 +47,19 @@ export default async function Voluntometro() {
-

{count.solicitudes}+

+

{totalSolicitudes}+

Nuevas solicitudes hoy

- {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 9c4f7c7e..2b838201 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -246,6 +246,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']; @@ -397,6 +404,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']; @@ -406,6 +420,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; From 794c6da40410339b343b826fc7d1bace3c94f52b Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Mon, 11 Nov 2024 16:37:52 +0100 Subject: [PATCH 2/5] feat: update db types --- src/types/database.ts | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/types/database.ts b/src/types/database.ts index 2b838201..5392a3f2 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -73,6 +73,54 @@ export type Database = { }; Relationships: []; }; + comments: { + Row: { + comment: string; + created_at: string | null; + help_request_id: number; + id: number; + is_solved: boolean | null; + user_id: string; + user_name: string; + user_phone: string; + }; + Insert: { + comment: string; + created_at?: string | null; + help_request_id: number; + id?: number; + is_solved?: boolean | null; + user_id: string; + user_name: string; + user_phone: string; + }; + Update: { + comment?: string; + created_at?: string | null; + help_request_id?: number; + id?: number; + is_solved?: boolean | null; + user_id?: string; + user_name?: string; + user_phone?: string; + }; + Relationships: [ + { + foreignKeyName: 'comments_help_request_id_fkey'; + columns: ['help_request_id']; + isOneToOne: false; + referencedRelation: 'help_requests'; + referencedColumns: ['id']; + }, + { + foreignKeyName: 'comments_help_request_id_fkey'; + columns: ['help_request_id']; + isOneToOne: false; + referencedRelation: 'help_requests_with_assignment_count'; + referencedColumns: ['id']; + }, + ]; + }; delivery_points: { Row: { additional_info: string | null; From b789c50e775c7f9471982431a26e722776d23189 Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Mon, 11 Nov 2024 17:00:58 +0100 Subject: [PATCH 3/5] fix: update db types --- src/types/database.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types/database.ts b/src/types/database.ts index 98c82829..5392a3f2 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -245,7 +245,6 @@ export type Database = { town_id: number | null; type: string | null; urgency: string | null; - crm_status: string | null; user_id: string | null; }; Insert: { From ab862bf2464cf938735908d15d2da341298b8ae4 Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Mon, 11 Nov 2024 17:06:01 +0100 Subject: [PATCH 4/5] fix: update db types --- src/types/database.ts | 54 +++++-------------------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/src/types/database.ts b/src/types/database.ts index 5392a3f2..c07b3e20 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -73,54 +73,6 @@ export type Database = { }; Relationships: []; }; - comments: { - Row: { - comment: string; - created_at: string | null; - help_request_id: number; - id: number; - is_solved: boolean | null; - user_id: string; - user_name: string; - user_phone: string; - }; - Insert: { - comment: string; - created_at?: string | null; - help_request_id: number; - id?: number; - is_solved?: boolean | null; - user_id: string; - user_name: string; - user_phone: string; - }; - Update: { - comment?: string; - created_at?: string | null; - help_request_id?: number; - id?: number; - is_solved?: boolean | null; - user_id?: string; - user_name?: string; - user_phone?: string; - }; - Relationships: [ - { - foreignKeyName: 'comments_help_request_id_fkey'; - columns: ['help_request_id']; - isOneToOne: false; - referencedRelation: 'help_requests'; - referencedColumns: ['id']; - }, - { - foreignKeyName: 'comments_help_request_id_fkey'; - columns: ['help_request_id']; - isOneToOne: false; - referencedRelation: 'help_requests_with_assignment_count'; - referencedColumns: ['id']; - }, - ]; - }; delivery_points: { Row: { additional_info: string | null; @@ -230,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; @@ -237,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; @@ -253,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; @@ -260,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; @@ -276,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; @@ -283,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; From 3d07785722bd29d744b3ff1aa095d1f5a9b4ea14 Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Mon, 11 Nov 2024 17:14:06 +0100 Subject: [PATCH 5/5] fix: recreate view to include new fields --- src/types/database.ts | 2 ++ .../20241111161121_fix view with new fields.sql | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 supabase/migrations/20241111161121_fix view with new fields.sql diff --git a/src/types/database.ts b/src/types/database.ts index c07b3e20..26cb238b 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -392,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; @@ -399,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; 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;