From 7480b212e2050cb344037afd0ab6d8b0249a0e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matilda=20Landstr=C3=B6m?= Date: Fri, 26 Apr 2024 10:51:05 +0200 Subject: [PATCH 1/4] chore: add load more functionality, with refactored css --- .gitignore | 3 + .../Blocks/Overview/UpcomingStays/index.tsx | 11 +- .../Stays/Container/container.module.css | 10 ++ .../MyPages/Blocks/Stays/Container/index.tsx | 5 + .../Blocks/Stays/Header/header.module.css | 13 +- .../MyPages/Blocks/Stays/Header/index.tsx | 6 +- .../Stays/ListContainer/container.module.css | 4 + .../Blocks/Stays/ListContainer/index.tsx | 5 + .../emptyPreviousStays.module.css | 0 .../EmptyPreviousStays/index.tsx | 4 +- .../MyPages/Blocks/Stays/Previous/index.tsx | 50 ++++++-- .../Blocks/Stays/Previous/previous.module.css | 3 - .../Stays/ShowMoreButton/button.module.css | 4 + .../Blocks/Stays/ShowMoreButton/index.tsx | 24 ++++ .../MyPages/Blocks/Stays/StayCard/index.tsx | 6 +- .../MyPages/Blocks/Stays/StayList/index.tsx | 24 +--- .../Blocks/Stays/StayList/stayList.module.css | 10 -- .../emptyUpcomingStays.module.css | 4 +- .../EmptyUpcomingStays/index.tsx | 18 +-- .../MyPages/Blocks/Stays/Upcoming/index.tsx | 51 +++++--- .../Blocks/Stays/Upcoming/upcoming.module.css | 3 - server/routers/user/query.ts | 77 +++++++++--- server/routers/user/temp.ts | 116 ++++++++++-------- types/components/myPages/myPage/stay.ts | 4 +- types/components/myPages/myStays/button.ts | 4 + types/components/myPages/myStays/page.ts | 6 + types/components/myPages/myStays/stayCard.ts | 8 ++ types/components/myPages/myStays/stayList.ts | 7 ++ .../myPages/{stays => myStays}/title.ts | 0 types/components/myPages/stays/stayCard.ts | 8 -- types/components/myPages/stays/stayList.ts | 7 -- 31 files changed, 326 insertions(+), 169 deletions(-) create mode 100644 components/MyPages/Blocks/Stays/Container/container.module.css create mode 100644 components/MyPages/Blocks/Stays/Container/index.tsx create mode 100644 components/MyPages/Blocks/Stays/ListContainer/container.module.css create mode 100644 components/MyPages/Blocks/Stays/ListContainer/index.tsx rename components/MyPages/Blocks/Stays/{ => Previous}/EmptyPreviousStays/emptyPreviousStays.module.css (100%) rename components/MyPages/Blocks/Stays/{ => Previous}/EmptyPreviousStays/index.tsx (76%) delete mode 100644 components/MyPages/Blocks/Stays/Previous/previous.module.css create mode 100644 components/MyPages/Blocks/Stays/ShowMoreButton/button.module.css create mode 100644 components/MyPages/Blocks/Stays/ShowMoreButton/index.tsx rename components/MyPages/Blocks/Stays/{ => Upcoming}/EmptyUpcomingStays/emptyUpcomingStays.module.css (88%) rename components/MyPages/Blocks/Stays/{ => Upcoming}/EmptyUpcomingStays/index.tsx (60%) delete mode 100644 components/MyPages/Blocks/Stays/Upcoming/upcoming.module.css create mode 100644 types/components/myPages/myStays/button.ts create mode 100644 types/components/myPages/myStays/page.ts create mode 100644 types/components/myPages/myStays/stayCard.ts create mode 100644 types/components/myPages/myStays/stayList.ts rename types/components/myPages/{stays => myStays}/title.ts (100%) delete mode 100644 types/components/myPages/stays/stayCard.ts delete mode 100644 types/components/myPages/stays/stayList.ts diff --git a/.gitignore b/.gitignore index 533cf75ab..1e2395721 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ next-env.d.ts certificates # Local Netlify folder .netlify + +#vscode +.vscode/ \ No newline at end of file diff --git a/components/MyPages/Blocks/Overview/UpcomingStays/index.tsx b/components/MyPages/Blocks/Overview/UpcomingStays/index.tsx index 6a3bfff33..699dd24e0 100644 --- a/components/MyPages/Blocks/Overview/UpcomingStays/index.tsx +++ b/components/MyPages/Blocks/Overview/UpcomingStays/index.tsx @@ -1,10 +1,11 @@ +import { _ } from "@/lib/translation" import { serverClient } from "@/lib/trpc/server" import Title from "@/components/MyPages/Title" import Link from "@/components/TempDesignSystem/Link" -import EmptyUpcomingStaysBlock from "../../Stays/EmptyUpcomingStays" import StayCard from "../../Stays/StayCard" +import EmptyUpcomingStaysBlock from "../../Stays/Upcoming/EmptyUpcomingStays" import styles from "./upcoming.module.css" @@ -19,15 +20,15 @@ export default async function UpcomingStays({ lang }: LangParams) {
- Your upcoming stays + {_("Your upcoming stays")} - See all + {_("See all")}
- {stays.length ? ( + {stays.data.length ? (
- {stays.map((stay) => ( + {stays.data.map((stay) => ( ))}
diff --git a/components/MyPages/Blocks/Stays/Container/container.module.css b/components/MyPages/Blocks/Stays/Container/container.module.css new file mode 100644 index 000000000..0a8e6cdac --- /dev/null +++ b/components/MyPages/Blocks/Stays/Container/container.module.css @@ -0,0 +1,10 @@ +.container { + max-width: var(--max-width); + display: grid; + gap: 2rem; +} +@media screen and (min-width: 950px) { + .container { + gap: 7rem; + } +} diff --git a/components/MyPages/Blocks/Stays/Container/index.tsx b/components/MyPages/Blocks/Stays/Container/index.tsx new file mode 100644 index 000000000..db08a3348 --- /dev/null +++ b/components/MyPages/Blocks/Stays/Container/index.tsx @@ -0,0 +1,5 @@ +import styles from "./container.module.css" + +export default function Container({ children }: React.PropsWithChildren) { + return
{children}
+} diff --git a/components/MyPages/Blocks/Stays/Header/header.module.css b/components/MyPages/Blocks/Stays/Header/header.module.css index f16c5f6d3..a308f6fcc 100644 --- a/components/MyPages/Blocks/Stays/Header/header.module.css +++ b/components/MyPages/Blocks/Stays/Header/header.module.css @@ -1,13 +1,18 @@ .subtitle { - padding-top: 0.5rem; - padding-bottom: 2.5rem; margin: 0; } +.header { + display: grid; + gap: 0.5rem; +} + @media screen and (min-width: 950px) { .subtitle { width: 60%; - padding-top: 2.5rem; - padding-bottom: 5rem; + } + + .header { + gap: 2rem; } } diff --git a/components/MyPages/Blocks/Stays/Header/index.tsx b/components/MyPages/Blocks/Stays/Header/index.tsx index 6d7ea5bca..2dbe2056f 100644 --- a/components/MyPages/Blocks/Stays/Header/index.tsx +++ b/components/MyPages/Blocks/Stays/Header/index.tsx @@ -2,15 +2,15 @@ import Title from "@/components/MyPages/Title" import styles from "./header.module.css" -import { HeaderProps } from "@/types/components/myPages/stays/title" +import type { HeaderProps } from "@/types/components/myPages/myStays/title" export default function Header({ title, subtitle }: HeaderProps) { return (
- + <Title as="h3" level="h2" weight="semiBold" uppercase> {title} - + <Title as="h5" level="h3" weight="regular" className={styles.subtitle}> {subtitle}
diff --git a/components/MyPages/Blocks/Stays/ListContainer/container.module.css b/components/MyPages/Blocks/Stays/ListContainer/container.module.css new file mode 100644 index 000000000..966cd1208 --- /dev/null +++ b/components/MyPages/Blocks/Stays/ListContainer/container.module.css @@ -0,0 +1,4 @@ +.container { + display: grid; + gap: 3rem; +} diff --git a/components/MyPages/Blocks/Stays/ListContainer/index.tsx b/components/MyPages/Blocks/Stays/ListContainer/index.tsx new file mode 100644 index 000000000..5908c0ff0 --- /dev/null +++ b/components/MyPages/Blocks/Stays/ListContainer/index.tsx @@ -0,0 +1,5 @@ +import styles from "./container.module.css" + +export default function ListContainer({ children }: React.PropsWithChildren) { + return
{children}
+} diff --git a/components/MyPages/Blocks/Stays/EmptyPreviousStays/emptyPreviousStays.module.css b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css similarity index 100% rename from components/MyPages/Blocks/Stays/EmptyPreviousStays/emptyPreviousStays.module.css rename to components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css diff --git a/components/MyPages/Blocks/Stays/EmptyPreviousStays/index.tsx b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx similarity index 76% rename from components/MyPages/Blocks/Stays/EmptyPreviousStays/index.tsx rename to components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx index c773ced0d..d2c9b517a 100644 --- a/components/MyPages/Blocks/Stays/EmptyPreviousStays/index.tsx +++ b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx @@ -1,3 +1,5 @@ +import { _ } from "@/lib/translation" + import Title from "@/components/MyPages/Title" import styles from "./emptyPreviousStays.module.css" @@ -6,7 +8,7 @@ export default function EmptyPreviousStaysBlock() { return (
- You have no previous stays. + {_("You have no previous stays.")}{" "}
) diff --git a/components/MyPages/Blocks/Stays/Previous/index.tsx b/components/MyPages/Blocks/Stays/Previous/index.tsx index d5e6ab44b..1069d2223 100644 --- a/components/MyPages/Blocks/Stays/Previous/index.tsx +++ b/components/MyPages/Blocks/Stays/Previous/index.tsx @@ -1,28 +1,52 @@ -import { serverClient } from "@/lib/trpc/server" +"use client" -import EmptyPreviousStaysBlock from "../EmptyPreviousStays" +import { _ } from "@/lib/translation" +import { trpc } from "@/lib/trpc/client" + +import Container from "../Container" import Header from "../Header" +import ListContainer from "../ListContainer" +import ShowMoreButton from "../ShowMoreButton" import StayList from "../StayList" +import EmptyPreviousStaysBlock from "./EmptyPreviousStays" -import styles from "./previous.module.css" - +import type { Page } from "@/types/components/myPages/myStays/page" import type { LangParams } from "@/types/params" -export default async function PreviousStays({ lang }: LangParams) { - const stays = await serverClient().user.stays.previous() +export default function PreviousStays({ lang }: LangParams) { + const { data, isFetching, fetchNextPage, hasNextPage } = + trpc.user.stays.previous.useInfiniteQuery( + {}, + { + getNextPageParam: (lastPage: Page) => lastPage.nextCursor, + } + ) + + function loadMoreData() { + fetchNextPage() + } return ( -
+
- - {stays.length ? ( - + {data?.pages.length ? ( + + page.data) ?? []} + /> + {hasNextPage ? ( + + ) : null} + ) : ( )} -
+ ) } diff --git a/components/MyPages/Blocks/Stays/Previous/previous.module.css b/components/MyPages/Blocks/Stays/Previous/previous.module.css deleted file mode 100644 index 020f53751..000000000 --- a/components/MyPages/Blocks/Stays/Previous/previous.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.container { - max-width: var(--max-width); -} diff --git a/components/MyPages/Blocks/Stays/ShowMoreButton/button.module.css b/components/MyPages/Blocks/Stays/ShowMoreButton/button.module.css new file mode 100644 index 000000000..f55557f33 --- /dev/null +++ b/components/MyPages/Blocks/Stays/ShowMoreButton/button.module.css @@ -0,0 +1,4 @@ +.container { + display: flex; + justify-content: center; +} diff --git a/components/MyPages/Blocks/Stays/ShowMoreButton/index.tsx b/components/MyPages/Blocks/Stays/ShowMoreButton/index.tsx new file mode 100644 index 000000000..cd9a3a8d9 --- /dev/null +++ b/components/MyPages/Blocks/Stays/ShowMoreButton/index.tsx @@ -0,0 +1,24 @@ +import Button from "@/components/TempDesignSystem/Button" + +import styles from "./button.module.css" + +import type { ShowMoreButtonParams } from "@/types/components/myPages/myStays/button" + +export default function ShowMoreButton({ + disabled, + loadMoreData, +}: ShowMoreButtonParams) { + return ( +
+ +
+ ) +} diff --git a/components/MyPages/Blocks/Stays/StayCard/index.tsx b/components/MyPages/Blocks/Stays/StayCard/index.tsx index a6c6ba44a..bb7a89a9b 100644 --- a/components/MyPages/Blocks/Stays/StayCard/index.tsx +++ b/components/MyPages/Blocks/Stays/StayCard/index.tsx @@ -5,12 +5,12 @@ import Title from "@/components/MyPages/Title" import styles from "./stay.module.css" -import type { StayCardProps } from "@/types/components/myPages/stays/stayCard" +import type { StayCardProps } from "@/types/components/myPages/myStays/stayCard" export default function StayCard({ stay, lang, - showDayCount = false, + shouldShowDayCount = false, }: StayCardProps) { const { dateArrive, dateDepart, guests, hotel } = stay @@ -25,7 +25,7 @@ export default function StayCard({ return (
- {showDayCount ? ( + {shouldShowDayCount ? (
diff --git a/components/MyPages/Blocks/Stays/StayList/index.tsx b/components/MyPages/Blocks/Stays/StayList/index.tsx index a46296209..08efae29b 100644 --- a/components/MyPages/Blocks/Stays/StayList/index.tsx +++ b/components/MyPages/Blocks/Stays/StayList/index.tsx @@ -1,29 +1,15 @@ -import Button from "@/components/TempDesignSystem/Button" - import StayCard from "../StayCard" import styles from "./stayList.module.css" -import { StayListProps } from "@/types/components/myPages/stays/stayList" +import { StayListProps } from "@/types/components/myPages/myStays/stayList" export default function StayList({ lang, stays }: StayListProps) { return ( -
-
- {stays.map((stay) => ( - - ))} -
-
- -
+
+ {stays.map((stay) => ( + + ))}
) } diff --git a/components/MyPages/Blocks/Stays/StayList/stayList.module.css b/components/MyPages/Blocks/Stays/StayList/stayList.module.css index b44aae5ca..7a2ac7401 100644 --- a/components/MyPages/Blocks/Stays/StayList/stayList.module.css +++ b/components/MyPages/Blocks/Stays/StayList/stayList.module.css @@ -15,18 +15,8 @@ display: none; } -.buttonContainer { - display: flex; - justify-content: center; - margin-top: 2rem; -} - @media screen and (min-width: 950px) { .stays { grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr)); } - - .buttonContainer { - margin-top: 4rem; - } } diff --git a/components/MyPages/Blocks/Stays/EmptyUpcomingStays/emptyUpcomingStays.module.css b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css similarity index 88% rename from components/MyPages/Blocks/Stays/EmptyUpcomingStays/emptyUpcomingStays.module.css rename to components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css index 76d189ba0..04c306c0e 100644 --- a/components/MyPages/Blocks/Stays/EmptyUpcomingStays/emptyUpcomingStays.module.css +++ b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css @@ -6,8 +6,8 @@ text-decoration: none; } -.redTitle { - color: var(--some-red-color, #ed2027); +.grayTitle { + color: var(--some-grey-color, #727272); display: block; } diff --git a/components/MyPages/Blocks/Stays/EmptyUpcomingStays/index.tsx b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx similarity index 60% rename from components/MyPages/Blocks/Stays/EmptyUpcomingStays/index.tsx rename to components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx index 7b7019855..665631207 100644 --- a/components/MyPages/Blocks/Stays/EmptyUpcomingStays/index.tsx +++ b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx @@ -1,5 +1,7 @@ import Link from "next/link" +import { _ } from "@/lib/translation" + import Title from "@/components/MyPages/Title" import Button from "@/components/TempDesignSystem/Button" @@ -9,17 +11,15 @@ export default function EmptyUpcomingStaysBlock() { return (
- You have no upcoming stays. - <span className={styles.redTitle}> Where should you go next?</span> + {_(" You have no upcoming stays.")} + <span className={styles.grayTitle}> + {" "} + {_("Where should you go next?")} + </span> -
diff --git a/components/MyPages/Blocks/Stays/Upcoming/index.tsx b/components/MyPages/Blocks/Stays/Upcoming/index.tsx index c6d05853d..ee06df0ae 100644 --- a/components/MyPages/Blocks/Stays/Upcoming/index.tsx +++ b/components/MyPages/Blocks/Stays/Upcoming/index.tsx @@ -1,29 +1,52 @@ -import { serverClient } from "@/lib/trpc/server" +"use client" -import EmptyUpcomingStaysBlock from "../EmptyUpcomingStays" +import { _ } from "@/lib/translation" +import { trpc } from "@/lib/trpc/client" + +import Container from "../Container" import Header from "../Header" +import ListContainer from "../ListContainer" +import ShowMoreButton from "../ShowMoreButton" import StayList from "../StayList" +import EmptyUpcomingStaysBlock from "./EmptyUpcomingStays" -import styles from "./upcoming.module.css" - +import type { Page } from "@/types/components/myPages/myStays/page" import type { LangParams } from "@/types/params" -export default async function UpcomingStays({ lang }: LangParams) { - const stays = await serverClient().user.stays.upcoming() +export default function UpcomingStays({ lang }: LangParams) { + const { data, hasNextPage, isFetching, fetchNextPage } = + trpc.user.stays.upcoming.useInfiniteQuery( + {}, + { + getNextPageParam: (lastPage: Page) => lastPage.nextCursor, + } + ) + + function loadMoreData() { + fetchNextPage() + } return ( -
+
- {stays.length ? ( - + {data?.pages.length ? ( + + page.data) ?? []} + /> + {hasNextPage ? ( + + ) : null} + ) : ( )} -
+ ) } diff --git a/components/MyPages/Blocks/Stays/Upcoming/upcoming.module.css b/components/MyPages/Blocks/Stays/Upcoming/upcoming.module.css deleted file mode 100644 index 020f53751..000000000 --- a/components/MyPages/Blocks/Stays/Upcoming/upcoming.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.container { - max-width: var(--max-width); -} diff --git a/server/routers/user/query.ts b/server/routers/user/query.ts index 94b66ab7a..3d5f7ea18 100644 --- a/server/routers/user/query.ts +++ b/server/routers/user/query.ts @@ -1,11 +1,6 @@ +import { z } from "zod" + import * as api from "@/lib/api" -import { - benefits, - extendedUser, - nextLevelPerks, - previousStays, - upcomingStays, -} from "./temp" import { badRequestError, forbiddenError, @@ -13,9 +8,15 @@ import { unauthorizedError, } from "@/server/errors/trpc" import { protectedProcedure, router } from "@/server/trpc" -import { z } from "zod" import { getUserSchema } from "./output" +import { + benefits, + extendedUser, + nextLevelPerks, + previousStays, + upcomingStays, +} from "./temp" function fakingRequest(payload: T): Promise { return new Promise((resolve) => { @@ -34,7 +35,6 @@ export const userQueryRouter = router({ Authorization: `Bearer ${ctx.session.token.access_token}`, }, }) - if (!apiResponse.ok) { switch (apiResponse.status) { case 400: @@ -67,7 +67,7 @@ export const userQueryRouter = router({ name: `${verifiedData.data.name} ${verifiedData.data.lastName}`, } } catch (error) { - console.info(`GEt User Error`) + console.info(`Get User Error`) console.error(error) throw internalServerError() } @@ -90,25 +90,74 @@ export const userQueryRouter = router({ .object({ perPage: z.number().min(0).default(6), page: z.number().min(0).default(0), + cursor: z.number().nullish(), }) .default({}) ) .query(async (opts) => { - const { perPage, page } = opts.input - return previousStays.slice(page * perPage, page * perPage + perPage) + const { perPage, page, cursor } = opts.input + let nextCursor: typeof cursor | undefined = undefined + const nrPages = Math.ceil(previousStays.length / perPage) + + let stays, nextPage + if (cursor) { + stays = previousStays.slice(cursor, perPage + cursor + 1) + nextPage = cursor / perPage + 1 + } else { + stays = previousStays.slice( + page * perPage, + page * perPage + perPage + 1 + ) + } + + if ( + (nextPage && nextPage < nrPages && stays.length == perPage + 1) || + (!nextPage && nrPages > 1) + ) { + const nextItem = stays.pop() + if (nextItem) { + nextCursor = previousStays.indexOf(nextItem) + } + } // TODO: Make request to get user data from Scandic API + return { data: stays, nextCursor } }), + upcoming: protectedProcedure .input( z .object({ perPage: z.number().min(0).default(6), page: z.number().min(0).default(0), + cursor: z.number().nullish(), }) .default({}) ) .query(async (opts) => { - const { perPage, page } = opts.input - return upcomingStays.slice(page * perPage, page * perPage + perPage) + const { perPage, page, cursor } = opts.input + let nextCursor: typeof cursor | undefined = undefined + const nrPages = Math.ceil(upcomingStays.length / perPage) + + let stays, nextPage + if (cursor) { + stays = upcomingStays.slice(cursor, perPage + cursor + 1) + nextPage = cursor / perPage + 1 + } else { + stays = upcomingStays.slice( + page * perPage, + page * perPage + perPage + 1 + ) + } + + if ( + (nextPage && nextPage < nrPages && stays.length == perPage + 1) || + (!nextPage && nrPages > 1) + ) { + const nextItem = stays.pop() + if (nextItem) { + nextCursor = upcomingStays.indexOf(nextItem) + } + } // TODO: Make request to get user data from Scandic API + return { data: stays, nextCursor } }), }), }) diff --git a/server/routers/user/temp.ts b/server/routers/user/temp.ts index 08b6c3609..110db45c5 100644 --- a/server/routers/user/temp.ts +++ b/server/routers/user/temp.ts @@ -1,3 +1,5 @@ +import { randomUUID } from "crypto" + import { dt } from "@/lib/dt" export const benefits = [ @@ -115,168 +117,182 @@ export const shortcuts = [ export const previousStays = [ { - uid: "0", + uid: randomUUID(), dateArrive: new Date("04 27 2024"), dateDepart: new Date("04 28 2024"), guests: 2, hotel: "Scandic Helsinki Hub", }, { - uid: "1", + uid: randomUUID(), dateArrive: new Date("05 27 2024"), dateDepart: new Date("05 28 2024"), guests: 2, hotel: "Scandic Örebro Central", }, { - uid: "2", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Oslo City", }, { - uid: "3", + uid: randomUUID(), dateArrive: new Date("04 27 2024"), dateDepart: new Date("04 28 2024"), guests: 2, hotel: "Scandic Lorem", }, { - uid: "4", + uid: randomUUID(), dateArrive: new Date("05 27 2024"), dateDepart: new Date("05 28 2024"), guests: 2, hotel: "Scandic Ipsum", }, { - uid: "5", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Dolor Sin Amet", }, { - uid: "6", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Anglais", }, { - uid: "7", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Park", }, { - uid: "8", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Klara", }, { - uid: "9", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, - hotel: "Scandic Dolor A", + hotel: "Scandic Järva Krog", }, { - uid: "10", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, - hotel: "Scandic B", + hotel: "Scandic Kiruna", }, { - uid: "11", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, - hotel: "Scandic C", - }, - { - uid: "12", - dateArrive: new Date("06 27 2024"), - dateDepart: new Date("06 28 2024"), - guests: 2, - hotel: "Scandic D", - }, - { - uid: "13", - dateArrive: new Date("06 27 2024"), - dateDepart: new Date("06 28 2024"), - guests: 2, - hotel: "Scandic E", - }, - { - uid: "14", - dateArrive: new Date("06 27 2024"), - dateDepart: new Date("06 28 2024"), - guests: 2, - hotel: "Scandic F", - }, - { - uid: "15", - dateArrive: new Date("06 27 2024"), - dateDepart: new Date("06 28 2024"), - guests: 2, - hotel: "Scandic G", + hotel: "Scandic Umeå", }, ] export const upcomingStays = [ { - uid: "0", + uid: randomUUID(), dateArrive: new Date("04 27 2024"), dateDepart: new Date("04 28 2024"), guests: 2, hotel: "Scandic Helsinki Hub", }, { - uid: "1", + uid: randomUUID(), dateArrive: new Date("05 27 2024"), dateDepart: new Date("05 28 2024"), guests: 2, hotel: "Scandic Örebro Central", }, { - uid: "2", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Oslo City", }, { - uid: "3", + uid: randomUUID(), dateArrive: new Date("04 27 2024"), dateDepart: new Date("04 28 2024"), guests: 2, hotel: "Scandic Lorem", }, { - uid: "4", + uid: randomUUID(), dateArrive: new Date("05 27 2024"), dateDepart: new Date("05 28 2024"), guests: 2, hotel: "Scandic Ipsum", }, { - uid: "5", + uid: randomUUID(), dateArrive: new Date("06 27 2024"), dateDepart: new Date("06 28 2024"), guests: 2, hotel: "Scandic Dolor Sin Amet", }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Anglais", + }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Park", + }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Klara", + }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Järva Krog", + }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Kiruna", + }, + { + uid: randomUUID(), + dateArrive: new Date("06 27 2024"), + dateDepart: new Date("06 28 2024"), + guests: 2, + hotel: "Scandic Umeå", + }, ] export const extendedUser = { + dob: dt("1977-07-05").format("YYYY-MM-DD"), journeys: challenges.journeys, nights: 14, shortcuts, - upcomingStays, victories: challenges.victories, } diff --git a/types/components/myPages/myPage/stay.ts b/types/components/myPages/myPage/stay.ts index bb97adae2..ec73f6ae1 100644 --- a/types/components/myPages/myPage/stay.ts +++ b/types/components/myPages/myPage/stay.ts @@ -1,5 +1,7 @@ +import { UUID } from "crypto" + export type Stay = { - uid: string + uid: UUID dateArrive: Date dateDepart: Date guests: number diff --git a/types/components/myPages/myStays/button.ts b/types/components/myPages/myStays/button.ts new file mode 100644 index 000000000..f661c7642 --- /dev/null +++ b/types/components/myPages/myStays/button.ts @@ -0,0 +1,4 @@ +export type ShowMoreButtonParams = { + loadMoreData: () => void + disabled: boolean +} diff --git a/types/components/myPages/myStays/page.ts b/types/components/myPages/myStays/page.ts new file mode 100644 index 000000000..c7f05a80f --- /dev/null +++ b/types/components/myPages/myStays/page.ts @@ -0,0 +1,6 @@ +import type { Stay } from "../myPage/stay" + +export type Page = { + data: Stay[] + nextCursor?: number +} diff --git a/types/components/myPages/myStays/stayCard.ts b/types/components/myPages/myStays/stayCard.ts new file mode 100644 index 000000000..9edcc307d --- /dev/null +++ b/types/components/myPages/myStays/stayCard.ts @@ -0,0 +1,8 @@ +import type { Lang } from "@/constants/languages" +import type { Stay } from "../myPage/stay" + +export type StayCardProps = { + lang: Lang + shouldShowDayCount?: boolean + stay: Stay +} diff --git a/types/components/myPages/myStays/stayList.ts b/types/components/myPages/myStays/stayList.ts new file mode 100644 index 000000000..d76b035d8 --- /dev/null +++ b/types/components/myPages/myStays/stayList.ts @@ -0,0 +1,7 @@ +import type { Lang } from "@/constants/languages" +import type { Stay } from "../myPage/stay" + +export type StayListProps = { + stays: Stay[] + lang: Lang +} diff --git a/types/components/myPages/stays/title.ts b/types/components/myPages/myStays/title.ts similarity index 100% rename from types/components/myPages/stays/title.ts rename to types/components/myPages/myStays/title.ts diff --git a/types/components/myPages/stays/stayCard.ts b/types/components/myPages/stays/stayCard.ts deleted file mode 100644 index d2a70d677..000000000 --- a/types/components/myPages/stays/stayCard.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Stay } from "../myPage/stay" -import { Lang } from "@/constants/languages" - -export type StayCardProps = { - lang: Lang - showDayCount?: boolean - stay: Stay -} diff --git a/types/components/myPages/stays/stayList.ts b/types/components/myPages/stays/stayList.ts deleted file mode 100644 index 6b31f3de5..000000000 --- a/types/components/myPages/stays/stayList.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Lang } from "@/constants/languages" -import { Stay } from "../myPage/stay" - -export type StayListProps = { - stays: Stay[] - lang: Lang -} From 38d65f7b37439f5c8efa330d51ba36da56d559f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matilda=20Landstr=C3=B6m?= Date: Fri, 26 Apr 2024 13:12:40 +0200 Subject: [PATCH 2/4] refactor: refactor according to PR comments --- .../(protected)/my-pages/stays/page.tsx | 5 +- .../Stays/Container/container.module.css | 1 - .../emptyPreviousStays.module.css | 1 - .../Previous/EmptyPreviousStays/index.tsx | 2 +- .../MyPages/Blocks/Stays/Previous/index.tsx | 2 +- .../emptyUpcomingStays.module.css | 1 - .../Upcoming/EmptyUpcomingStays/index.tsx | 4 +- .../MyPages/Blocks/Stays/Upcoming/index.tsx | 2 +- server/routers/user/input.ts | 12 +- server/routers/user/query.ts | 119 ++++++++---------- server/routers/user/temp.ts | 3 - 11 files changed, 67 insertions(+), 85 deletions(-) diff --git a/app/[lang]/(live)/(protected)/my-pages/stays/page.tsx b/app/[lang]/(live)/(protected)/my-pages/stays/page.tsx index 575a6767d..c6fe2ad06 100644 --- a/app/[lang]/(live)/(protected)/my-pages/stays/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/stays/page.tsx @@ -1,3 +1,4 @@ +import MaxWidth from "@/components/MaxWidth" import PreviousStays from "@/components/MyPages/Blocks/Stays/Previous" import UpcomingStays from "@/components/MyPages/Blocks/Stays/Upcoming" @@ -7,9 +8,9 @@ import { LangParams, PageArgs } from "@/types/params" export default async function MyStays({ params }: PageArgs) { return ( -
+ -
+ ) } diff --git a/components/MyPages/Blocks/Stays/Container/container.module.css b/components/MyPages/Blocks/Stays/Container/container.module.css index 0a8e6cdac..f4a93c4e0 100644 --- a/components/MyPages/Blocks/Stays/Container/container.module.css +++ b/components/MyPages/Blocks/Stays/Container/container.module.css @@ -1,5 +1,4 @@ .container { - max-width: var(--max-width); display: grid; gap: 2rem; } diff --git a/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css index 44999673c..72e8229d0 100644 --- a/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css +++ b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/emptyPreviousStays.module.css @@ -5,5 +5,4 @@ min-height: 25rem; background-color: var(--some-grey-color, #f2f2f2); border-radius: 0.8rem; - max-width: var(--max-width); } diff --git a/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx index d2c9b517a..1d7675412 100644 --- a/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx +++ b/components/MyPages/Blocks/Stays/Previous/EmptyPreviousStays/index.tsx @@ -8,7 +8,7 @@ export default function EmptyPreviousStaysBlock() { return (
- {_("You have no previous stays.")}{" "} + {_("You have no previous stays.")}
) diff --git a/components/MyPages/Blocks/Stays/Previous/index.tsx b/components/MyPages/Blocks/Stays/Previous/index.tsx index 1069d2223..e6c03eb4c 100644 --- a/components/MyPages/Blocks/Stays/Previous/index.tsx +++ b/components/MyPages/Blocks/Stays/Previous/index.tsx @@ -33,7 +33,7 @@ export default function PreviousStays({ lang }: LangParams) { subtitle={_( "Revisit your stays and rekindle those our moments together, with ease." )} - > + /> {data?.pages.length ? ( - diff --git a/components/MyPages/Blocks/Stays/Upcoming/index.tsx b/components/MyPages/Blocks/Stays/Upcoming/index.tsx index ee06df0ae..441710fd3 100644 --- a/components/MyPages/Blocks/Stays/Upcoming/index.tsx +++ b/components/MyPages/Blocks/Stays/Upcoming/index.tsx @@ -33,7 +33,7 @@ export default function UpcomingStays({ lang }: LangParams) { subtitle={_( "Excited about your next trip? So are we. Below are your upcoming stays with us, complete with all the details you need to make each visit perfect. Can't wait to welcome you back, friend!" )} - > + /> {data?.pages.length ? ( { - const { perPage, page, cursor } = opts.input - let nextCursor: typeof cursor | undefined = undefined - const nrPages = Math.ceil(previousStays.length / perPage) + previous: protectedProcedure.input(staysInput).query(async (opts) => { + const { perPage, page, cursor } = opts.input + let nextCursor: typeof cursor | undefined = undefined + const nrPages = Math.ceil(previousStays.length / perPage) - let stays, nextPage - if (cursor) { - stays = previousStays.slice(cursor, perPage + cursor + 1) - nextPage = cursor / perPage + 1 - } else { - stays = previousStays.slice( - page * perPage, - page * perPage + perPage + 1 - ) + let stays, nextPage + if (cursor) { + stays = previousStays.slice(cursor, perPage + cursor + 1) + nextPage = cursor / perPage + 1 + } else { + stays = previousStays.slice( + page * perPage, + page * perPage + perPage + 1 + ) + } + + if ( + (nextPage && nextPage < nrPages && stays.length == perPage + 1) || + (!nextPage && nrPages > 1) + ) { + const nextItem = stays.pop() + if (nextItem) { + nextCursor = previousStays.indexOf(nextItem) } + } // TODO: Make request to get user data from Scandic API + return { data: stays, nextCursor } + }), - if ( - (nextPage && nextPage < nrPages && stays.length == perPage + 1) || - (!nextPage && nrPages > 1) - ) { - const nextItem = stays.pop() - if (nextItem) { - nextCursor = previousStays.indexOf(nextItem) - } - } // TODO: Make request to get user data from Scandic API - return { data: stays, nextCursor } - }), + upcoming: protectedProcedure.input(staysInput).query(async (opts) => { + const { perPage, page, cursor } = opts.input + let nextCursor: typeof cursor | undefined = undefined + const nrPages = Math.ceil(upcomingStays.length / perPage) - upcoming: protectedProcedure - .input( - z - .object({ - perPage: z.number().min(0).default(6), - page: z.number().min(0).default(0), - cursor: z.number().nullish(), - }) - .default({}) - ) - .query(async (opts) => { - const { perPage, page, cursor } = opts.input - let nextCursor: typeof cursor | undefined = undefined - const nrPages = Math.ceil(upcomingStays.length / perPage) + let stays, nextPage + if (cursor) { + stays = upcomingStays.slice(cursor, perPage + cursor + 1) + nextPage = cursor / perPage + 1 + } else { + stays = upcomingStays.slice( + page * perPage, + page * perPage + perPage + 1 + ) + } - let stays, nextPage - if (cursor) { - stays = upcomingStays.slice(cursor, perPage + cursor + 1) - nextPage = cursor / perPage + 1 - } else { - stays = upcomingStays.slice( - page * perPage, - page * perPage + perPage + 1 - ) + if ( + (nextPage && nextPage < nrPages && stays.length == perPage + 1) || + (!nextPage && nrPages > 1) + ) { + const nextItem = stays.pop() + if (nextItem) { + nextCursor = upcomingStays.indexOf(nextItem) } - - if ( - (nextPage && nextPage < nrPages && stays.length == perPage + 1) || - (!nextPage && nrPages > 1) - ) { - const nextItem = stays.pop() - if (nextItem) { - nextCursor = upcomingStays.indexOf(nextItem) - } - } // TODO: Make request to get user data from Scandic API - return { data: stays, nextCursor } - }), + } // TODO: Make request to get user data from Scandic API + return { data: stays, nextCursor } + }), }), }) diff --git a/server/routers/user/temp.ts b/server/routers/user/temp.ts index 110db45c5..1d10371fc 100644 --- a/server/routers/user/temp.ts +++ b/server/routers/user/temp.ts @@ -1,7 +1,5 @@ import { randomUUID } from "crypto" -import { dt } from "@/lib/dt" - export const benefits = [ { id: 1, @@ -290,7 +288,6 @@ export const upcomingStays = [ ] export const extendedUser = { - dob: dt("1977-07-05").format("YYYY-MM-DD"), journeys: challenges.journeys, nights: 14, shortcuts, From 861ad26f21784d869e37a23f668dfe50b31c9541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matilda=20Landstr=C3=B6m?= Date: Fri, 26 Apr 2024 14:53:17 +0200 Subject: [PATCH 3/4] chore: update my stays to new MVP design --- .../my-pages/stays/page.module.css | 2 +- .../Stays/Container/container.module.css | 2 +- .../Blocks/Stays/Header/header.module.css | 14 ----- .../MyPages/Blocks/Stays/Header/index.tsx | 2 +- .../MyPages/Blocks/Stays/StayCard/index.tsx | 28 +++------- .../Blocks/Stays/StayCard/stay.module.css | 52 ++++++------------- .../Blocks/Stays/StayList/stayList.module.css | 5 +- types/components/myPages/myStays/stayCard.ts | 1 - 8 files changed, 30 insertions(+), 76 deletions(-) diff --git a/app/[lang]/(live)/(protected)/my-pages/stays/page.module.css b/app/[lang]/(live)/(protected)/my-pages/stays/page.module.css index 0902c782c..85483cea5 100644 --- a/app/[lang]/(live)/(protected)/my-pages/stays/page.module.css +++ b/app/[lang]/(live)/(protected)/my-pages/stays/page.module.css @@ -9,7 +9,7 @@ @media screen and (min-width: 950px) { .container { - gap: 10rem; + gap: 6rem; padding-left: 0; padding-right: 0; margin: 0; diff --git a/components/MyPages/Blocks/Stays/Container/container.module.css b/components/MyPages/Blocks/Stays/Container/container.module.css index f4a93c4e0..00ad315a8 100644 --- a/components/MyPages/Blocks/Stays/Container/container.module.css +++ b/components/MyPages/Blocks/Stays/Container/container.module.css @@ -4,6 +4,6 @@ } @media screen and (min-width: 950px) { .container { - gap: 7rem; + gap: 3.5rem; } } diff --git a/components/MyPages/Blocks/Stays/Header/header.module.css b/components/MyPages/Blocks/Stays/Header/header.module.css index a308f6fcc..680a68d4a 100644 --- a/components/MyPages/Blocks/Stays/Header/header.module.css +++ b/components/MyPages/Blocks/Stays/Header/header.module.css @@ -1,18 +1,4 @@ -.subtitle { - margin: 0; -} - .header { display: grid; gap: 0.5rem; } - -@media screen and (min-width: 950px) { - .subtitle { - width: 60%; - } - - .header { - gap: 2rem; - } -} diff --git a/components/MyPages/Blocks/Stays/Header/index.tsx b/components/MyPages/Blocks/Stays/Header/index.tsx index 2dbe2056f..d4fbeee68 100644 --- a/components/MyPages/Blocks/Stays/Header/index.tsx +++ b/components/MyPages/Blocks/Stays/Header/index.tsx @@ -10,7 +10,7 @@ export default function Header({ title, subtitle }: HeaderProps) { {title} - + <Title as="h5" level="h3" weight="regular"> {subtitle} diff --git a/components/MyPages/Blocks/Stays/StayCard/index.tsx b/components/MyPages/Blocks/Stays/StayCard/index.tsx index bb7a89a9b..459f7fb6e 100644 --- a/components/MyPages/Blocks/Stays/StayCard/index.tsx +++ b/components/MyPages/Blocks/Stays/StayCard/index.tsx @@ -7,14 +7,9 @@ import styles from "./stay.module.css" import type { StayCardProps } from "@/types/components/myPages/myStays/stayCard" -export default function StayCard({ - stay, - lang, - shouldShowDayCount = false, -}: StayCardProps) { +export default function StayCard({ stay, lang }: StayCardProps) { const { dateArrive, dateDepart, guests, hotel } = stay - const daysUntilArrival = dt(dateArrive).diff(dt(), "days") const arrival = dt(dateArrive).locale(lang) const arrivalDate = arrival.format("DD MMM") const arrivalDateTime = arrival.format("YYYY-MM-DD") @@ -24,21 +19,14 @@ export default function StayCard({ return (
-
- {shouldShowDayCount ? ( -
- -
- ) : null} - Placeholder image flower -