From 503ffc229fe5a701626dee8247a97033b3e10ad3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Sigler Priego Date: Thu, 31 Oct 2024 00:50:47 -0400 Subject: [PATCH] Usar lazy fetch en /mentorias (#101) * use swr in getMentorAvailabilities * dejar de usar hidden * mas feedback --- package-lock.json | 22 ++ package.json | 1 + src/components/mentorias/index.tsx | 335 +++++++++++++++++------------ src/pages/mentorias.tsx | 55 +---- src/types/mentor.schema.ts | 22 +- 5 files changed, 242 insertions(+), 193 deletions(-) diff --git a/package-lock.json b/package-lock.json index e264f89..2ccc490 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "remark-gfm": "^4.0.0", "remark-mdx-frontmatter": "^4.0.0", "sharp": "^0.33.5", + "swr": "^2.2.5", "tailwindest": "^2.2.1", "typescript": "5.2.2" }, @@ -10726,6 +10727,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", + "dependencies": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -19729,6 +19742,15 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "swr": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", + "requires": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 26971f7..c949c9c 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "remark-gfm": "^4.0.0", "remark-mdx-frontmatter": "^4.0.0", "sharp": "^0.33.5", + "swr": "^2.2.5", "tailwindest": "^2.2.1", "typescript": "5.2.2" }, diff --git a/src/components/mentorias/index.tsx b/src/components/mentorias/index.tsx index c9ac568..faef210 100644 --- a/src/components/mentorias/index.tsx +++ b/src/components/mentorias/index.tsx @@ -1,47 +1,109 @@ -import { UserAvailability } from "@/types/mentor.schema"; +import useSWR from "swr"; +import { + type GetAvailabilitiesRequest, + UserAvailability, + GetAvailabilitiesResponseSchema, +} from "@/types/mentor.schema"; import Calendar from "react-calendar"; import { useState } from "react"; import { InlineWidget } from "react-calendly"; import { Link } from "../link"; -import { getLocalDateTimeWithOffset } from "@/utils/time"; +import { getLocalDateTimeWithOffset, nextHalfHour } from "@/utils/time"; +import { Value } from "@sinclair/typebox/value"; + +const fetcher = (args: RequestInfo): Promise => + fetch(args).then((res) => res.json()); + +function useGetMentorAvailabilities({ + ofmiEdition, + startTimeISOString, + endTimeISOString, +}: { + ofmiEdition: number; + startTimeISOString: string; + endTimeISOString: string; +}): Array | null { + const request: GetAvailabilitiesRequest = { + startTime: startTimeISOString, + endTime: endTimeISOString, + ofmiEdition, + }; + const { data } = useSWR( + `/api/volunteer/getMentorAvailabilities?${new URLSearchParams({ + ...request, + ofmiEdition: request.ofmiEdition.toString(), + }).toString()}`, + fetcher, + ); + if (Value.Check(GetAvailabilitiesResponseSchema, data)) { + return data.availabilities; + } + return null; +} + +function Loading(): JSX.Element { + return ( +
+ + + + + Loading... +
+ ); +} // Receives a list of connected providers export default function Mentorias({ - startTime, - endTime, - availabilities, + ofmiEdition, }: { - startTime: Date; - endTime: Date; - availabilities: Array; + ofmiEdition: number; }): JSX.Element { + const startTime = nextHalfHour(new Date(Date.now())); + const endTime = new Date(startTime.getTime() + 7 * 24 * 60 * 60 * 1000); + const availabilities = useGetMentorAvailabilities({ + ofmiEdition, + startTimeISOString: startTime.toISOString(), + endTimeISOString: endTime.toISOString(), + }); const [selectedDay, setSelectedDay] = useState(); const [selectedStartTime, setSelectedStartTime] = useState(); const [schedulingUrlToShow, setSchedulingUrlToShow] = useState(); const showFilterCalendar = schedulingUrlToShow === undefined; const fullSchedulingUrlToShow = (schedulingUrlToShow: string): string => { - return ( - schedulingUrlToShow && - (selectedStartTime - ? `${schedulingUrlToShow}/${getLocalDateTimeWithOffset(selectedStartTime)}` - : selectedDay - ? `${schedulingUrlToShow}/?date=${selectedDay.toLocaleDateString()}?` - : schedulingUrlToShow) - ); + return selectedStartTime + ? `${schedulingUrlToShow}/${getLocalDateTimeWithOffset(selectedStartTime)}` + : selectedDay + ? `${schedulingUrlToShow}/?date=${selectedDay.toLocaleDateString()}?` + : schedulingUrlToShow; }; - const availableLocalDates = new Set( - availabilities - .map((v) => - v.availableStartTimes.map((startTime) => { - const time = new Date(startTime); - return time.toLocaleDateString(); - }), - ) - .flat(), - ); + const availableLocalDates = + availabilities && + new Set( + availabilities + .map((v) => + v.availableStartTimes.map((startTime) => { + const time = new Date(startTime); + return time.toLocaleDateString(); + }), + ) + .flat(), + ); const availableLocalStartTimes = + availabilities && selectedDay && Array.from( new Set( @@ -64,47 +126,47 @@ export default function Mentorias({ .map((v) => new Date(v)); return ( -
+
{/* Filter calendar */} -
- - {availableLocalStartTimes && ( -