From ce7deab542aaa65ceef27e8ff2076471b9ec8135 Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 07:55:36 +0100 Subject: [PATCH 1/9] add toggle and filtering capabilities --- src/app/casos-activos/solicitudes/page.js | 157 +++++++++++++--------- src/components/Toggle.tsx | 33 +++++ 2 files changed, 127 insertions(+), 63 deletions(-) create mode 100644 src/components/Toggle.tsx diff --git a/src/app/casos-activos/solicitudes/page.js b/src/app/casos-activos/solicitudes/page.js index 99853cba..05ae3544 100644 --- a/src/app/casos-activos/solicitudes/page.js +++ b/src/app/casos-activos/solicitudes/page.js @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback, useMemo } from 'react'; import { HeartHandshake } from 'lucide-react'; import { supabase } from '@/lib/supabase/client'; import SolicitudCard from '@/components/SolicitudCard'; @@ -11,9 +11,15 @@ import { tiposAyudaOptions } from '@/helpers/constants'; import Modal from '@/components/Modal'; import { useModal } from '@/context/ModalProvider'; import { useTowns } from '@/context/TownProvider'; +import { Toggle } from '@/components/Toggle'; const MODAL_NAME = 'solicitudes'; +const itemsPerPage = 10; +const numPages = (count) => { + return Math.ceil(count / itemsPerPage) || 0; +}; + export default function Solicitudes() { const { getTownById, towns } = useTowns(); const searchParams = useSearchParams(); @@ -27,38 +33,46 @@ export default function Solicitudes() { const [currentCount, setCurrentCount] = useState(0); const { toggleModal } = useModal(); - const closeModal = () => { + const closeModal = useCallback(() => { toggleModal(MODAL_NAME, false); - }; - const itemsPerPage = 10; - const numPages = (count) => { - return Math.ceil(count / itemsPerPage) || 0; - }; - - const updateFilter = (filter, value) => { - const params = new URLSearchParams(searchParams.toString()); - params.set(filter, value); - router.push(`?${params.toString()}`); - }; + }, [toggleModal]); + + const updateFilter = useCallback( + (filter, value) => { + const params = new URLSearchParams(searchParams.toString()); + params.set(filter, value); + router.push(`?${params.toString()}`); + }, + [searchParams, router], + ); const [filtroData, setFiltroData] = useState({ urgencia: searchParams.get('urgencia') || 'todas', tipoAyuda: searchParams.get('tipoAyuda') || 'todas', pueblo: searchParams.get('pueblo') || 'todos', + soloSinVoluntarios: searchParams.get('soloSinVoluntarios') || true, }); - const changeDataFilter = (type, newFilter) => { - setFiltroData((prev) => ({ - ...prev, - [type]: newFilter, - })); - updateFilter(type, newFilter); - }; - - function changePage(newPage) { - setCurrentPage(newPage); - updateFilter('page', newPage); - } + const changeDataFilter = useCallback( + (type, newFilter) => { + setFiltroData((prev) => ({ + ...prev, + [type]: newFilter, + })); + updateFilter(type, newFilter); + }, + [updateFilter, setFiltroData], + ); + + const changePage = useCallback( + (newPage) => { + setCurrentPage(newPage); + updateFilter('page', newPage); + }, + [updateFilter], + ); + + const handleToggleChange = useCallback((e) => changeDataFilter('soloSinVoluntarios', e.target.checked), []); useEffect(() => { async function fetchData() { @@ -83,6 +97,12 @@ export default function Solicitudes() { if (filtroData.urgencia !== 'todas') { query.eq('urgency', filtroData.urgencia); } + + // Solo agregar filtro si es true + if (!!filtroData.soloSinVoluntarios) { + query.eq('asignees_count', 0); + } + query.neq('status', 'finished'); // Ejecutar la consulta con paginación const { data, count, error } = await query @@ -107,6 +127,8 @@ export default function Solicitudes() { fetchData(); }, [filtroData, currentPage]); + const puebloSeleccionado = useMemo(() => getTownById(Number(filtroData.pueblo)), [filtroData, getTownById]); + if (loading) { return (
@@ -123,48 +145,57 @@ export default function Solicitudes() { ); } - const puebloSeleccionado = getTownById(Number(filtroData.pueblo)); - return ( <> {/* FILTROS */}
-

Filtros

-
- - - +
+
+
+

Filtros

+
+ + + +
+
+ +
diff --git a/src/components/Toggle.tsx b/src/components/Toggle.tsx new file mode 100644 index 00000000..77960d80 --- /dev/null +++ b/src/components/Toggle.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +type ToggleProps = { handleChange: React.ChangeEventHandler; checked: boolean; label: string }; + +export const Toggle = ({ checked, handleChange, label }: ToggleProps) => { + return ( +
+ +
+ + +
+
+ ); +}; From 6dce7cfbaa43b2e42096a81a91a6c8b455802d95 Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:00:16 +0100 Subject: [PATCH 2/9] supabase migration --- supabase/config.toml | 2 +- supabase/help_requests.sql | 11 +++++++++++ ...01532_add-number-of-volunteers-in-each-request.sql | 8 ++++++++ supabase/{seed.sql => towns.sql} | 0 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 supabase/help_requests.sql create mode 100644 supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql rename supabase/{seed.sql => towns.sql} (100%) diff --git a/supabase/config.toml b/supabase/config.toml index a79ce9fc..6aa978b8 100644 --- a/supabase/config.toml +++ b/supabase/config.toml @@ -45,7 +45,7 @@ enabled = true # Specifies an ordered list of seed files to load during db reset. # Supports glob patterns relative to supabase directory. For example: # sql_paths = ['./seeds/*.sql', '../project-src/seeds/*-load-testing.sql'] -sql_paths = ['./seed.sql'] +sql_paths = ['./towns.sql', './help_requests.sql'] [realtime] enabled = true diff --git a/supabase/help_requests.sql b/supabase/help_requests.sql new file mode 100644 index 00000000..a37856da --- /dev/null +++ b/supabase/help_requests.sql @@ -0,0 +1,11 @@ +INSERT INTO "public"."help_requests" ("id","created_at","type","name","location","description","urgency","number_of_people","contact_info","additional_info","status","resources","latitude","longitude","help_type","people_needed","town_id","other_help") +VALUES ('10851', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Lorem Ipsum', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10852', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Lorem Ipsum', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10853', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Lorem Ipsum', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10854', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10855', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10856', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10857', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10858', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10859', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null), +('10860', '2024-11-07 18:31:47.83578+00', 'necesita', 'Rocío', '46200, P', 'Me traslado desde r con l', 'alta', '1', '123456789', '{"email": "ptesting@gmail.com", "consent": true, "special_situations": null}', 'active', null, '39.1', '-0.4', '{"alojamiento"}', '1', '17', null); \ No newline at end of file diff --git a/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql b/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql new file mode 100644 index 00000000..b5ee485a --- /dev/null +++ b/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql @@ -0,0 +1,8 @@ +alter table "public"."help_requests" add column "asignees_count" smallint not null default '0'::smallint; + +UPDATE "public"."help_requests" +SET "assignees_count" = ( + SELECT COUNT(*) + FROM "public"."help_request_assignments" + WHERE "public"."help_request_assignments"."help_request_id" = "public"."help_requests"."id" +); \ No newline at end of file diff --git a/supabase/seed.sql b/supabase/towns.sql similarity index 100% rename from supabase/seed.sql rename to supabase/towns.sql From 0db5a825694bb0ada265e17e35f32a2138a636be Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:10:42 +0100 Subject: [PATCH 3/9] Update types and service methods --- src/lib/service.ts | 40 +++++++++++++++++++++++++++++++++++++--- src/types/database.ts | 20 +++++++++++++++----- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/lib/service.ts b/src/lib/service.ts index f0aebddf..5acc7fbf 100644 --- a/src/lib/service.ts +++ b/src/lib/service.ts @@ -70,14 +70,48 @@ export const helpRequestService = { async assign(requestData: HelpRequestAssignmentInsert) { const { data, error } = await supabase.from('help_request_assignments').insert([requestData]).select(); - if (error) throw error; + + const { data: linkedRequestData, error: errorGettingLinkedData } = await supabase + .from('help_requests') + .select('*') + .eq('id', requestData.help_request_id); + if (errorGettingLinkedData) throw errorGettingLinkedData; + if (!linkedRequestData) throw new Error('No se puede encontrar esta tarea'); + + const { error: errorUpdatingAssigneesCount } = await supabase + .from('help_requests') + .update({ asignees_count: linkedRequestData[0].asignees_count + 1 }); + if (errorUpdatingAssigneesCount) throw errorUpdatingAssigneesCount; + return data[0]; }, async unassign(id: number) { - const { error } = await supabase.from('help_request_assignments').delete().eq('id', id); + const { data, error: errorFindingRow } = await supabase.from('help_request_assignments').select('*').eq('id', id); + if (errorFindingRow || !data) { + throw new Error('No se puede encontrar la tarea'); + } - if (error) throw error; + const requestId = data[0].help_request_id; + + const { error: errorDeletingAssignment } = await supabase.from('help_request_assignments').delete().eq('id', id); + if (errorDeletingAssignment) throw errorDeletingAssignment; + + const { data: linkedRequestData, error: errorGettingLinkedData } = await supabase + .from('help_requests') + .select('*') + .eq('id', requestId); + + if (errorGettingLinkedData) throw errorGettingLinkedData; + if (!linkedRequestData) throw new Error('No se puede encontrar esta tarea'); + + const { asignees_count } = linkedRequestData[0]; + const newNumberAssignees = asignees_count <= 0 ? 0 : asignees_count - 1; + + const { error: errorUpdatingAssigneesCount } = await supabase + .from('help_requests') + .update({ asignees_count: newNumberAssignees }); + if (errorUpdatingAssigneesCount) throw errorUpdatingAssigneesCount; }, async getByType(type: any) { diff --git a/src/types/database.ts b/src/types/database.ts index 2a181cf2..bbc0c694 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -171,6 +171,7 @@ export type Database = { help_requests: { Row: { additional_info: Json | null; + asignees_count: number; contact_info: string | null; coordinates: unknown | null; created_at: string | null; @@ -182,16 +183,17 @@ export type Database = { longitude: number | null; name: string | null; number_of_people: number | null; + other_help: string | null; people_needed: number | null; resources: Json | null; status: string | null; town_id: number | null; type: string | null; urgency: string | null; - user_id: string | null; }; Insert: { additional_info?: Json | null; + asignees_count?: number; contact_info?: string | null; coordinates?: unknown | null; created_at?: string | null; @@ -203,16 +205,17 @@ export type Database = { longitude?: number | null; name?: string | null; number_of_people?: number | null; + other_help?: string | null; people_needed?: number | null; resources?: Json | null; status?: string | null; town_id?: number | null; type?: string | null; urgency?: string | null; - user_id?: string | null; }; Update: { additional_info?: Json | null; + asignees_count?: number; contact_info?: string | null; coordinates?: unknown | null; created_at?: string | null; @@ -224,13 +227,13 @@ export type Database = { longitude?: number | null; name?: string | null; number_of_people?: number | null; + other_help?: string | null; people_needed?: number | null; resources?: Json | null; status?: string | null; town_id?: number | null; type?: string | null; urgency?: string | null; - user_id?: string | null; }; Relationships: [ { @@ -331,7 +334,12 @@ export type Database = { }; }; Views: { - [_ in never]: never; + distinct_collection_cities: { + Row: { + city: string | null; + }; + Relationships: []; + }; }; Functions: { [_ in never]: never; @@ -346,7 +354,9 @@ export type Database = { | 'medica' | 'psicologico' | 'logistico' - | 'otros'; + | 'otros' + | 'reparto' + | 'donaciones'; }; CompositeTypes: { [_ in never]: never; From d2465b2f0e2575f6eac00a69dd07e62e5ad023eb Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:24:42 +0100 Subject: [PATCH 4/9] Revert wrong type changes --- src/types/database.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/types/database.ts b/src/types/database.ts index bbc0c694..996026d4 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -190,6 +190,7 @@ export type Database = { town_id: number | null; type: string | null; urgency: string | null; + user_id: string | null; }; Insert: { additional_info?: Json | null; @@ -212,6 +213,7 @@ export type Database = { town_id?: number | null; type?: string | null; urgency?: string | null; + user_id: string | null; }; Update: { additional_info?: Json | null; @@ -234,6 +236,7 @@ export type Database = { town_id?: number | null; type?: string | null; urgency?: string | null; + user_id: string | null; }; Relationships: [ { @@ -334,12 +337,7 @@ export type Database = { }; }; Views: { - distinct_collection_cities: { - Row: { - city: string | null; - }; - Relationships: []; - }; + [_ in never]: never; }; Functions: { [_ in never]: never; @@ -354,9 +352,7 @@ export type Database = { | 'medica' | 'psicologico' | 'logistico' - | 'otros' - | 'reparto' - | 'donaciones'; + | 'otros'; }; CompositeTypes: { [_ in never]: never; From 52a22ee74231d1d8755870e5bb1cbbb9bccc777c Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:29:03 +0100 Subject: [PATCH 5/9] optional type --- src/types/database.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/database.ts b/src/types/database.ts index 996026d4..bed60d5d 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -213,7 +213,7 @@ export type Database = { town_id?: number | null; type?: string | null; urgency?: string | null; - user_id: string | null; + user_id?: string | null; }; Update: { additional_info?: Json | null; @@ -236,7 +236,7 @@ export type Database = { town_id?: number | null; type?: string | null; urgency?: string | null; - user_id: string | null; + user_id?: string | null; }; Relationships: [ { From 63b978cbae53b6ae40ca76501db03e1625066672 Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:30:13 +0100 Subject: [PATCH 6/9] update types --- src/types/database.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/database.ts b/src/types/database.ts index bed60d5d..5a137a4a 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -183,7 +183,6 @@ export type Database = { longitude: number | null; name: string | null; number_of_people: number | null; - other_help: string | null; people_needed: number | null; resources: Json | null; status: string | null; @@ -206,7 +205,6 @@ export type Database = { longitude?: number | null; name?: string | null; number_of_people?: number | null; - other_help?: string | null; people_needed?: number | null; resources?: Json | null; status?: string | null; @@ -229,7 +227,6 @@ export type Database = { longitude?: number | null; name?: string | null; number_of_people?: number | null; - other_help?: string | null; people_needed?: number | null; resources?: Json | null; status?: string | null; From a2130b565c6b78e024b5c5463e649267005f4b4e Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:32:19 +0100 Subject: [PATCH 7/9] Remove population of newly created column --- ...07201532_add-number-of-volunteers-in-each-request.sql | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql b/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql index b5ee485a..b9becac8 100644 --- a/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql +++ b/supabase/migrations/20241107201532_add-number-of-volunteers-in-each-request.sql @@ -1,8 +1 @@ -alter table "public"."help_requests" add column "asignees_count" smallint not null default '0'::smallint; - -UPDATE "public"."help_requests" -SET "assignees_count" = ( - SELECT COUNT(*) - FROM "public"."help_request_assignments" - WHERE "public"."help_request_assignments"."help_request_id" = "public"."help_requests"."id" -); \ No newline at end of file +alter table "public"."help_requests" add column "asignees_count" smallint not null default '0'::smallint; \ No newline at end of file From 55a1460dd9c9fb46ab23bc731d1b9766a0fd03e0 Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:36:33 +0100 Subject: [PATCH 8/9] Add data population as separate migration --- .../migrations/20241108083517_populate_assignments_data.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 supabase/migrations/20241108083517_populate_assignments_data.sql diff --git a/supabase/migrations/20241108083517_populate_assignments_data.sql b/supabase/migrations/20241108083517_populate_assignments_data.sql new file mode 100644 index 00000000..05413116 --- /dev/null +++ b/supabase/migrations/20241108083517_populate_assignments_data.sql @@ -0,0 +1,6 @@ +UPDATE "public"."help_requests" +SET "assignees_count" = ( + SELECT COUNT(*) + FROM "public"."help_request_assignments" + WHERE "public"."help_request_assignments"."help_request_id" = "public"."help_requests"."id" +); \ No newline at end of file From 04f2b0a4534da850aba37f8af6078012205847fc Mon Sep 17 00:00:00 2001 From: Pablo Gracia Gil Date: Fri, 8 Nov 2024 08:38:54 +0100 Subject: [PATCH 9/9] typo --- .../migrations/20241108083517_populate_assignments_data.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supabase/migrations/20241108083517_populate_assignments_data.sql b/supabase/migrations/20241108083517_populate_assignments_data.sql index 05413116..8c5fb791 100644 --- a/supabase/migrations/20241108083517_populate_assignments_data.sql +++ b/supabase/migrations/20241108083517_populate_assignments_data.sql @@ -1,5 +1,5 @@ UPDATE "public"."help_requests" -SET "assignees_count" = ( +SET "asignees_count" = ( SELECT COUNT(*) FROM "public"."help_request_assignments" WHERE "public"."help_request_assignments"."help_request_id" = "public"."help_requests"."id"