From 4450fcde9d1f0c5db0da3b86b3d885d25aad0f77 Mon Sep 17 00:00:00 2001 From: Roberto Milla Martinez Date: Sun, 17 Nov 2024 00:05:08 +0100 Subject: [PATCH] feat: use same query to avoid spinners --- src/app/casos-activos/solicitudes/index.tsx | 8 ++-- src/app/casos-activos/solicitudes/page.tsx | 6 +-- src/app/solicitudes/[id]/page.tsx | 10 ++--- src/app/solicitudes/page.tsx | 8 ++-- src/components/AsignarSolicitudButton.tsx | 16 ++++---- src/components/PhoneInfo.tsx | 24 +++++++----- src/components/map/map.tsx | 9 ++--- src/components/solicitudes/SolicitudCard.tsx | 13 ++++--- .../solicitudes/SolicitudHelpCount.tsx | 38 ------------------- src/components/solicitudes/SolicitudList.tsx | 6 +-- src/components/solicitudes/SolicitudMap.tsx | 4 +- src/helpers/format.tsx | 38 ------------------- src/lib/actions.ts | 25 ++++++++++++ src/types/Requests.ts | 9 +++++ 14 files changed, 89 insertions(+), 125 deletions(-) delete mode 100644 src/components/solicitudes/SolicitudHelpCount.tsx delete mode 100644 src/helpers/format.tsx diff --git a/src/app/casos-activos/solicitudes/index.tsx b/src/app/casos-activos/solicitudes/index.tsx index 369270f..f79da44 100644 --- a/src/app/casos-activos/solicitudes/index.tsx +++ b/src/app/casos-activos/solicitudes/index.tsx @@ -8,7 +8,7 @@ import { useTowns } from '@/context/TownProvider'; import { TabNavigationCount } from '@/components/TabNavigation'; import Modal from '@/components/Modal'; import { MAP_MODAL_NAME } from '@/components/map/map'; -import { HelpRequestData } from '@/types/Requests'; +import { HelpRequestData, HelpRequestWAssignments } from '@/types/Requests'; import SolicitudCard from '@/components/solicitudes/SolicitudCard'; import SolicitudList, { isStringTrue } from '@/components/solicitudes/SolicitudList'; import SolicitudMap from '@/components/solicitudes/SolicitudMap'; @@ -28,14 +28,14 @@ function getDataFiltered(data: HelpRequestData[], filters: DataFilter[]) { type SolicitudesProps = { count: TabNavigationCount; - data: HelpRequestData[]; + data: HelpRequestWAssignments[]; }; export function Solicitudes({ data, count }: SolicitudesProps) { const { towns } = useTowns(); const searchParams = useSearchParams(); const router = useRouter(); - const [selectedMarker, setSelectedMarker] = useState(null); + const [selectedMarker, setSelectedMarker] = useState(null); const [dataFiltered, setDataFiltered] = useState(data); @@ -98,7 +98,7 @@ export function Solicitudes({ data, count }: SolicitudesProps) {
{ // Remove unused properties to reduce the payload size const { coordinates, location, ...rest } = d; @@ -17,7 +17,7 @@ function parseData(data: Database['public']['Tables']['help_requests']['Row'][]) // Fix the coordinates to 3 decimals so locations have a 100m precision latitude: Number(d.latitude?.toFixed(3)), longitude: Number(d.longitude?.toFixed(3)), - } as HelpRequestData; + } as HelpRequestWAssignments; }); } diff --git a/src/app/solicitudes/[id]/page.tsx b/src/app/solicitudes/[id]/page.tsx index 037fc3b..0c3a6a0 100644 --- a/src/app/solicitudes/[id]/page.tsx +++ b/src/app/solicitudes/[id]/page.tsx @@ -5,12 +5,12 @@ import SolicitudCard from '@/components/solicitudes/SolicitudCard'; import { useParams } from 'next/navigation'; import SolicitudComments from '@/components/Comments/SolicitudComments'; import { useEffect, useState } from 'react'; -import { SelectedHelpData } from '../../../types/Requests'; -import { getOne } from '@/lib/actions'; +import { SelectedHelpDataWAssignment } from '../../../types/Requests'; +import { getOneWithAssignments } from '@/lib/actions'; export default function CasoDetalle() { const [loading, setLoading] = useState(true); - const [data, setData] = useState(null); + const [data, setData] = useState(null); const { id } = useParams<{ id: string }>(); useEffect(() => { @@ -18,8 +18,8 @@ export default function CasoDetalle() { try { setLoading(true); - const requestResponse = await getOne(Number(id)); - setData(requestResponse as SelectedHelpData); + const requestResponse = await getOneWithAssignments(Number(id)); + setData(requestResponse as SelectedHelpDataWAssignment); setLoading(false); } catch (err) { diff --git a/src/app/solicitudes/page.tsx b/src/app/solicitudes/page.tsx index 1db4296..45b197c 100644 --- a/src/app/solicitudes/page.tsx +++ b/src/app/solicitudes/page.tsx @@ -5,8 +5,8 @@ import SolicitudCard from '@/components/solicitudes/SolicitudCard'; import { useSession } from '@/context/SessionProvider'; import Link from 'next/link'; import { useQuery } from '@tanstack/react-query'; -import { SelectedHelpData } from '@/types/Requests'; -import { getSolicitudesByUser } from '@/lib/actions'; +import { SelectedHelpDataWAssignment } from '@/types/Requests'; +import { getSolicitudesWAssignemntsByUser } from '@/lib/actions'; export const dynamic = 'force-dynamic'; @@ -18,9 +18,9 @@ export default function ListaSolicitudes() { data: requests, isLoading, error, - } = useQuery({ + } = useQuery({ queryKey: ['help_requests', { user_id: userId, type: 'necesita' }], - queryFn: () => getSolicitudesByUser(userId || ''), + queryFn: () => getSolicitudesWAssignemntsByUser(userId || ''), }); if (isLoading) { diff --git a/src/components/AsignarSolicitudButton.tsx b/src/components/AsignarSolicitudButton.tsx index 12103eb..1455367 100644 --- a/src/components/AsignarSolicitudButton.tsx +++ b/src/components/AsignarSolicitudButton.tsx @@ -1,8 +1,8 @@ 'use client'; import { useSession } from '@/context/SessionProvider'; -import { HelpRequestAssignmentData, SelectedHelpData } from '@/types/Requests'; -import { getAssignments, assign, unassign } from '@/lib/actions'; +import { SelectedHelpData, SelectedHelpDataWAssignment } from '@/types/Requests'; +import { assign, unassign, getSolicitudesWAssignemntsByUser } from '@/lib/actions'; import { MouseEvent } from 'react'; import { Spinner } from '@/components/Spinner'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; @@ -23,12 +23,12 @@ export default function AsignarSolicitudButton({ helpRequest }: AsignarSolicitud const router = useRouter(); const { - data: assignments, + data: solicitudesUser, isLoading, error, - } = useQuery({ - queryKey: ['help_request_assignments', { id: helpRequest.id }], - queryFn: () => getAssignments(helpRequest.id), + } = useQuery({ + queryKey: ['help_requests', { user_id: userId, type: 'necesita' }], + queryFn: () => getSolicitudesWAssignemntsByUser(userId || ''), }); const queryClient = useQueryClient(); @@ -84,9 +84,9 @@ export default function AsignarSolicitudButton({ helpRequest }: AsignarSolicitud } if (isLoading) return ; - if (error || assignments === undefined) return <>; + if (error || solicitudesUser === undefined) return <>; - const userAssignment = assignments.find((x) => x.user_id === session.user?.id); + const userAssignment = solicitudesUser.find((x) => x.id === helpRequest.id); const userIsAssigned = !!userAssignment; if (!session || !session.user) diff --git a/src/components/PhoneInfo.tsx b/src/components/PhoneInfo.tsx index a0338ed..39243bb 100644 --- a/src/components/PhoneInfo.tsx +++ b/src/components/PhoneInfo.tsx @@ -1,27 +1,31 @@ import { useQuery } from '@tanstack/react-query'; import { useSession } from '@/context/SessionProvider'; -import { getAssignments } from '@/lib/actions'; -import { SelectedHelpData } from '@/types/Requests'; +import { getSolicitudesWAssignemntsByUser } from '@/lib/actions'; +import { SelectedHelpDataWAssignment } from '@/types/Requests'; type PhoneInfoProps = { - caseInfo: SelectedHelpData; + caseInfo: SelectedHelpDataWAssignment; isAdmin: boolean; }; export default function PhoneInfo({ caseInfo, isAdmin }: PhoneInfoProps) { const session = useSession(); + const userId = session?.user?.id; const { - data: assignments, + data: solicitudesUser, isLoading, error, - } = useQuery({ - queryKey: ['help_request_assignments', { id: caseInfo.id }], - queryFn: () => getAssignments(caseInfo.id), + } = useQuery({ + queryKey: ['help_requests', { user_id: userId, type: 'necesita' }], + queryFn: () => getSolicitudesWAssignemntsByUser(userId || ''), + staleTime: Infinity, + gcTime: Infinity, }); - if (error || isLoading) return <>; + if (error || isLoading || !solicitudesUser) return <>; - const userAssignment = assignments?.find((x) => x.user_id === session.user?.id); + const userAssignment = solicitudesUser.find((x) => x.id === caseInfo.id); + const userIsAssigned = !!userAssignment; return ( @@ -29,7 +33,7 @@ export default function PhoneInfo({ caseInfo, isAdmin }: PhoneInfoProps) { {session && session.user ? isAdmin ? caseInfo.contact_info - : !!userAssignment + : !!userIsAssigned ? caseInfo.contact_info : 'Dale al botón "Quiero ayudar" para ver sus datos de contacto.' : 'Inicia sesion para ver este dato'} diff --git a/src/components/map/map.tsx b/src/components/map/map.tsx index 1dae55d..b6e6383 100644 --- a/src/components/map/map.tsx +++ b/src/components/map/map.tsx @@ -1,17 +1,16 @@ 'use client'; -import { Dispatch, FC, ReactNode, SetStateAction, useState } from 'react'; +import { Dispatch, FC, SetStateAction, useState } from 'react'; import InteractiveMap, { Layer, MapLayerMouseEvent, Source } from 'react-map-gl/maplibre'; import 'maplibre-gl/dist/maplibre-gl.css'; import { useModal } from '@/context/ModalProvider'; -import { HelpRequestData } from '@/types/Requests'; -import { InterpolationSpecification } from 'maplibre-gl'; +import { HelpRequestWAssignments } from '@/types/Requests'; export const MAP_MODAL_NAME = `map-marker`; type MapProps = { solicitudes?: GeoJSON.FeatureCollection; - setSelectedMarker: Dispatch>; + setSelectedMarker: Dispatch>; }; const PAIPORTA_LAT = 39.42333; @@ -30,7 +29,7 @@ const Map: FC = ({ solicitudes, setSelectedMarker }) => { const onClickHandler = (e: MapLayerMouseEvent) => { if (e.features?.[0]) { toggleModal(MAP_MODAL_NAME, true); - setSelectedMarker(e.features?.[0].properties as HelpRequestData); + setSelectedMarker(e.features?.[0].properties as HelpRequestWAssignments); } }; diff --git a/src/components/solicitudes/SolicitudCard.tsx b/src/components/solicitudes/SolicitudCard.tsx index 01c988d..57b30ee 100644 --- a/src/components/solicitudes/SolicitudCard.tsx +++ b/src/components/solicitudes/SolicitudCard.tsx @@ -1,10 +1,9 @@ -import { AlertTriangle, MapPin, MapPinned, Megaphone, Phone, Users } from 'lucide-react'; +import { AlertTriangle, MapPinned, Megaphone, Phone, Users } from 'lucide-react'; import { tiposAyudaOptions } from '@/helpers/constants'; import Link from 'next/link'; import { useSession } from '@/context/SessionProvider'; -import { HelpRequestAdditionalInfo, HelpRequestData, SelectedHelpData } from '@/types/Requests'; +import { HelpRequestAdditionalInfo, SelectedHelpDataWAssignment } from '@/types/Requests'; import AsignarSolicitudButton from '@/components/AsignarSolicitudButton'; -import SolicitudHelpCount from '@/components/solicitudes/SolicitudHelpCount'; import PhoneInfo from '@/components/PhoneInfo'; import DeleteHelpRequest from '../DeleteHelpRequest'; import { textWithEllipsis } from '@/helpers/utils'; @@ -38,7 +37,7 @@ export const getHighlightedText = (text: string, highlight: string) => { }; type SolicitudCardProps = { - caso: SelectedHelpData; + caso: SelectedHelpDataWAssignment; showLink?: boolean; showEdit?: boolean; format?: 'small' | 'large'; @@ -97,7 +96,11 @@ export default function SolicitudCard({
- +
+ {caso.assignments_count} VOLUNTARIOS +
({ - queryKey: ['help_request_assignments', { id: id }], - queryFn: () => getAssignments(id), - }); - - if (isLoading) return ; - - if (error || assignments === undefined) return <>; - - const volunteers = assignments.length; - - let colorClass: string; - - if (volunteers === 0) { - colorClass = 'bg-red-100 text-red-800'; - } else { - colorClass = 'bg-green-100 text-green-800'; - } - return ( -
- {volunteers} VOLUNTARIOS -
- ); -} diff --git a/src/components/solicitudes/SolicitudList.tsx b/src/components/solicitudes/SolicitudList.tsx index 4266411..5cde924 100644 --- a/src/components/solicitudes/SolicitudList.tsx +++ b/src/components/solicitudes/SolicitudList.tsx @@ -6,14 +6,14 @@ import { tiposAyudaOptions } from '@/helpers/constants'; import { useTowns } from '@/context/TownProvider'; import { Toggle } from '@/components/Toggle'; import TabNavigation, { TabNavigationCount } from '@/components/TabNavigation'; -import { HelpRequestData } from '@/types/Requests'; +import { SelectedHelpDataWAssignment } from '@/types/Requests'; import { Virtuoso } from 'react-virtuoso'; import { FiltersData, FilterType } from '@/app/casos-activos/solicitudes/types'; export const isStringTrue = (str: string): boolean => str === 'true'; type SolicitudListProps = { - data: HelpRequestData[]; + data: SelectedHelpDataWAssignment[]; count: TabNavigationCount; filtersData: FiltersData; onDataFilterChange: (type: FilterType, newFilter: string) => void; @@ -130,7 +130,7 @@ export default function SolicitudList({ data, count, filtersData, onDataFilterCh format="small" showLink={true} showEdit={true} - caso={caso as HelpRequestData} + caso={caso} highlightedText={filtersData.search} />
diff --git a/src/components/solicitudes/SolicitudMap.tsx b/src/components/solicitudes/SolicitudMap.tsx index 54b50e4..04ddff3 100644 --- a/src/components/solicitudes/SolicitudMap.tsx +++ b/src/components/solicitudes/SolicitudMap.tsx @@ -1,7 +1,7 @@ 'use client'; import Map from '@/components/map/map'; -import { HelpRequestData } from '@/types/Requests'; +import { HelpRequestData, HelpRequestWAssignments } from '@/types/Requests'; import { Dispatch, SetStateAction, useMemo } from 'react'; function transformHelpRequestToPointFeature(request: any): GeoJSON.Feature | [] { @@ -20,7 +20,7 @@ function transformHelpRequestToPointFeature(request: any): GeoJSON.Feature>; + setSelectedMarker: Dispatch>; }; export default function SolicitudList({ data, setSelectedMarker }: SolicitudListProps) { diff --git a/src/helpers/format.tsx b/src/helpers/format.tsx deleted file mode 100644 index 8bb1c0a..0000000 --- a/src/helpers/format.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import ReactDOMServer from 'react-dom/server'; -import { HelpRequestData } from '@/types/Requests'; -import { CollectionPointData } from '@/types/DataPoints'; -import SolicitudCard from '@/components/solicitudes/SolicitudCard'; -import { tiposAyudaOptions } from '@/helpers/constants'; - -export const getMarkerBySolicitud = (solicitud: HelpRequestData) => { - // TODO think if possible getLatLng from a given location - if (!solicitud.latitude || !solicitud.longitude) { - return null; - } - - return { - id: solicitud.id, - coordinates: [solicitud.longitude, solicitud.latitude], - descriptionHTML: getMarkerDescriptionBySolicitudAndTowns(solicitud), - color: getMarkerColorBySolicitud(solicitud), - width: '400px', - }; -}; - -export const getMarkerColorBySolicitud = (solicitud: HelpRequestData) => { - switch (solicitud.urgency) { - case 'baja': - return '#00FF00'; - case 'media': - return '#FFA500'; - case 'alta': - return '#FF0000'; - default: - return '#000000'; - } -}; -export const getMarkerDescriptionBySolicitudAndTowns = (solicitud: HelpRequestData) => { - return ReactDOMServer.renderToString( - , - ); -}; diff --git a/src/lib/actions.ts b/src/lib/actions.ts index c7be33f..df42b6e 100644 --- a/src/lib/actions.ts +++ b/src/lib/actions.ts @@ -3,6 +3,7 @@ import { CRMUsersLogRow, helpDataSelectFields, + helpDataWithAssignmentsSelectFields, HelpRequestAssignmentInsert, HelpRequestData, HelpRequestInsert, @@ -10,6 +11,7 @@ import { PuntoDeEntrega, PuntoDeRecogida, SelectedHelpData, + SelectedHelpDataWAssignment, } from '@/types/Requests'; import { createClient } from './supabase/server'; import { AuthChangeEvent, Session, SignInWithOAuthCredentials, Subscription } from '@supabase/supabase-js'; @@ -117,6 +119,17 @@ export async function getOne(id: number) { return data as SelectedHelpData; } +export async function getOneWithAssignments(id: number) { + const supabase = await createClient(); + const { data, error } = await supabase + .from('help_requests_with_assignment_count') + .select(helpDataSelectFields as '*') + .eq('id', id) + .single(); + if (error) throw error; + return data as SelectedHelpDataWAssignment; +} + export async function getOneWithCoords(id: number) { const supabase = await createClient(); const { data, error } = await supabase.from('help_requests').select('*').eq('id', id).single(); @@ -204,6 +217,18 @@ export async function getSolicitudesByUser(user_id: string | undefined) { return requests as SelectedHelpData[]; } +export async function getSolicitudesWAssignemntsByUser(user_id: string | undefined) { + const supabase = await createClient(); + if (user_id === undefined) return []; + const { data: requests, error: requestsError } = await supabase + .from('help_requests_with_assignment_count') + .select(helpDataWithAssignmentsSelectFields as '*') + .eq('type', 'necesita') + .eq('user_id', user_id); + if (requestsError) throw requestsError; + return requests as SelectedHelpDataWAssignment[]; +} + export async function getAssignments(id: number) { const supabase = await createClient(); const { data, error } = await supabase.from('help_request_assignments').select('*').eq('help_request_id', id); diff --git a/src/types/Requests.ts b/src/types/Requests.ts index 0e4046d..8bada0c 100644 --- a/src/types/Requests.ts +++ b/src/types/Requests.ts @@ -13,6 +13,7 @@ export type HelpRequestData = Omit; export type SelectedHelpData = OmitSelect; +export type SelectedHelpDataWAssignment = OmitSelect< + HelpRequestWAssignments, + 'location' | 'coordinates' | 'latitude' | 'longitude' +>; + export const helpDataSelectFieldsObject: SelectHelpDataStringBuilder = { additional_info: true, asignees_count: true, @@ -89,3 +95,6 @@ export const helpDataSelectFieldsObject: SelectHelpDataStringBuilder = { user_id: true, }; export const helpDataSelectFields = Object.keys(helpDataSelectFieldsObject).join(','); +export const helpDataWithAssignmentsSelectFields = Object.keys(helpDataSelectFieldsObject) + .join(',') + .concat(', assignments_count');