feat(LOY-424): Load More Past Stays via Sidepeek * feat(LOY-424): Load More Past Stays via Sidepeek * chore(LOY-424): use new section header * fix(LOY-424): remove uneeded nextCursor check Approved-by: Emma Zettervall
103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
"use client"
|
|
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
|
import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled"
|
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
import { trpc } from "@scandic-hotels/trpc/client"
|
|
|
|
import useLang from "@/hooks/useLang"
|
|
|
|
import ShowMoreButton from "../../ShowMoreButton"
|
|
import { Card } from "../Card"
|
|
import { groupStaysByYear } from "../utils/groupStaysByYear"
|
|
|
|
import styles from "./previousStaysSidePeek.module.css"
|
|
|
|
import type { PreviousStaysNonNullResponseObject } from "@/types/components/myPages/stays/previous"
|
|
|
|
interface PreviousStaysSidePeekProps {
|
|
isOpen: boolean
|
|
onClose: () => void
|
|
}
|
|
|
|
export function PreviousStaysSidePeek({
|
|
isOpen,
|
|
onClose,
|
|
}: PreviousStaysSidePeekProps) {
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
|
|
const { data, isFetching, fetchNextPage, hasNextPage, isLoading } =
|
|
trpc.user.stays.previous.useInfiniteQuery(
|
|
{
|
|
limit: 10,
|
|
lang,
|
|
},
|
|
{
|
|
getNextPageParam: (lastPage) => {
|
|
return lastPage?.nextCursor
|
|
},
|
|
enabled: isOpen,
|
|
}
|
|
)
|
|
|
|
function loadMoreData() {
|
|
if (hasNextPage) {
|
|
fetchNextPage()
|
|
}
|
|
}
|
|
|
|
const stays = data?.pages
|
|
.filter((page): page is PreviousStaysNonNullResponseObject => !!page?.data)
|
|
.flatMap((page) => page.data)
|
|
|
|
const staysByYear = stays ? groupStaysByYear(stays) : []
|
|
|
|
return (
|
|
<SidePeekSelfControlled
|
|
title={intl.formatMessage({
|
|
id: "stays.previous.title",
|
|
defaultMessage: "Previous stays",
|
|
})}
|
|
isOpen={isOpen}
|
|
onClose={onClose}
|
|
>
|
|
<div className={styles.content}>
|
|
{isLoading ? (
|
|
<div className={styles.loadingContainer}>
|
|
<LoadingSpinner />
|
|
</div>
|
|
) : (
|
|
<>
|
|
{staysByYear.map(({ year, stays }) => (
|
|
<section key={year} className={styles.yearSection}>
|
|
<div className={styles.yearHeader}>
|
|
<Typography variant="Title/Overline/sm">
|
|
<span className={styles.yearText}>{year}</span>
|
|
</Typography>
|
|
</div>
|
|
<div className={styles.staysList}>
|
|
{stays.map((stay) => (
|
|
<Card
|
|
key={stay.attributes.confirmationNumber}
|
|
stay={stay}
|
|
/>
|
|
))}
|
|
</div>
|
|
</section>
|
|
))}
|
|
{hasNextPage && (
|
|
<ShowMoreButton
|
|
disabled={isFetching}
|
|
loadMoreData={loadMoreData}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
</SidePeekSelfControlled>
|
|
)
|
|
}
|