feat: break apart loading of room availability and hotel card

feat: add skeletons
This commit is contained in:
Joakim Jäderberg
2024-11-20 10:17:55 +01:00
parent c4caccae5a
commit dfdbdb7621
8 changed files with 97 additions and 32 deletions

View File

@@ -4,9 +4,9 @@ import { Suspense } from "react"
import { dt } from "@/lib/dt"
import { getHotelData, getLocations } from "@/lib/trpc/memoizedRequests"
import LoadingSpinner from "@/components/Current/LoadingSpinner"
import HotelInfoCard from "@/components/HotelReservation/SelectRate/HotelInfoCard"
import { RoomsContainer } from "@/components/HotelReservation/SelectRate/Rooms/RoomsContainer"
import { RoomsContainerSkeleton } from "@/components/HotelReservation/SelectRate/Rooms/RoomsContainerSkeleton"
import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { setLang } from "@/i18n/serverContext"
import { safeTry } from "@/utils/safeTry"
@@ -71,7 +71,8 @@ export default async function SelectRatePage({
adultCount={adults}
childArray={children ?? []}
/>
<Suspense key={hotelId} fallback={<LoadingSpinner />}>
<Suspense key={hotelId} fallback={<RoomsContainerSkeleton />}>
<RoomsContainer
hotelId={hotelId}
lang={params.lang}

View File

@@ -42,23 +42,10 @@ export default async function HotelInfoCard({
const hotelAttributes = hotelData?.data.attributes
const intl = await getIntl()
// const noRoomsAvailable = useRoomAvailableStore(
// (state) => state.noRoomsAvailable
// )
// const setNoRoomsAvailable = useRoomAvailableStore(
// (state) => state.setNoRoomsAvailable
// )
const sortedFacilities = hotelAttributes?.detailedFacilities
.sort((a, b) => b.sortOrder - a.sortOrder)
.slice(0, 5)
// useEffect(() => {
// if (noAvailability) {
// setNoRoomsAvailable()
// }
// }, [noAvailability, setNoRoomsAvailable])
return (
<article className={styles.container}>
{hotelAttributes && (

View File

@@ -0,0 +1,26 @@
.card {
font-size: 14px;
display: flex;
flex-direction: column;
background-color: #fff;
border-radius: var(--Corner-radius-Large);
border: 1px solid var(--Base-Border-Subtle);
position: relative;
height: 100%;
justify-content: space-between;
min-height: 200px;
flex: 1;
overflow: hidden;
}
.imageContainer {
aspect-ratio: 16/9;
width: 100%;
}
.priceVariants {
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
padding: var(--Spacing-x2);
}

View File

@@ -0,0 +1,21 @@
import SkeletonShimmer from "@/components/SkeletonShimmer"
import styles from "./RoomCardSkeleton.module.css"
export function RoomCardSkeleton() {
return (
<article className={styles.card}>
{/* image container */}
<div className={styles.imageContainer}>
<SkeletonShimmer width={"100%"} height="100%" />
</div>
<div className={styles.priceVariants}>
{/* price variants */}
{Array.from({ length: 3 }).map((_, index) => (
<SkeletonShimmer key={index} height={"100px"} />
))}
</div>
</article>
)
}

View File

@@ -0,0 +1,21 @@
.container {
padding: var(--Spacing-x2);
}
.filterContainer {
height: 38px;
}
.skeletonContainer {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
/* used to hide overflowing rows */
grid-template-rows: auto;
grid-auto-rows: 0;
overflow: hidden;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 20px;
gap: var(--Spacing-x2);
}

View File

@@ -0,0 +1,24 @@
import Body from "@/components/TempDesignSystem/Text/Body"
import { getIntl } from "@/i18n"
import { RoomCardSkeleton } from "../RoomSelection/RoomCard/RoomCardSkeleton"
import styles from "./RoomsContainerSkeleton.module.css"
type Props = {
count?: number
}
export async function RoomsContainerSkeleton({ count = 4 }: Props) {
const intl = await getIntl()
return (
<div className={styles.container}>
<div className={styles.filterContainer}></div>
<div className={styles.skeletonContainer}>
{Array.from({ length: count }).map((_, index) => (
<RoomCardSkeleton key={index} />
))}
</div>
</div>
)
}

View File

@@ -82,6 +82,8 @@ export function getSiteConfigConnections(refs: GetSiteConfigRefData) {
const siteConfigData = refs.all_site_config.items[0]
const connections: System["system"][] = []
if (!siteConfigData) return connections
const alertConnection = siteConfigData.sitewide_alert.alertConnection
alertConnection.edges.forEach(({ node }) => {

View File

@@ -1,17 +0,0 @@
"use client"
import { create } from "zustand"
interface RoomAvailabilityState {
noRoomsAvailable: boolean
setNoRoomsAvailable: () => void
setRoomsAvailable: () => void
}
const useRoomAvailableStore = create<RoomAvailabilityState>((set) => ({
noRoomsAvailable: false,
setNoRoomsAvailable: () => set(() => ({ noRoomsAvailable: true })),
setRoomsAvailable: () => set(() => ({ noRoomsAvailable: false })),
}))
export default useRoomAvailableStore