refactor(SW-96): use images from API & reduce data returned in getHotel

This commit is contained in:
Chuma McPhoy
2024-08-21 14:52:13 +02:00
parent 6456be95b2
commit 7d47994539
9 changed files with 71 additions and 56 deletions

View File

@@ -11,11 +11,11 @@ export default async function PreviewImages({ images }: PreviewImagesProps) {
const intl = await getIntl() const intl = await getIntl()
return ( return (
<Lightbox images={images}> <Lightbox images={images}>
{/*TODO: Replace with images from API once SW-188 is merged. */}
<div className={styles.mobileWrapper}> <div className={styles.mobileWrapper}>
<Image <Image
src={images[0].url} src={images[0].url}
alt={images[0].alt} alt={images[0].alt}
title={images[0].title}
width={752} width={752}
height={540} height={540}
objectFit="cover" objectFit="cover"
@@ -37,6 +37,7 @@ export default async function PreviewImages({ images }: PreviewImagesProps) {
key={index} key={index}
src={image.url} src={image.url}
alt={image.alt} alt={image.alt}
title={image.title}
width={index === 0 ? 752 : 292} width={index === 0 ? 752 : 292}
height={index === 0 ? 540 : 266} height={index === 0 ? 540 : 266}
objectFit="cover" objectFit="cover"

View File

@@ -22,44 +22,3 @@ export function mapFacilityToIcon(facilityName: string): FC<IconProps> | null {
const iconName = facilityToIconMap[facilityName] const iconName = facilityToIconMap[facilityName]
return getIconByIconName(iconName) || null return getIconByIconName(iconName) || null
} }
/**
* NOTE:
* Images from the test API are hosted on test3.scandichotels.com,
* which can't be accessed unless on Scandic's Wifi or using Citrix.
* So I've added some placeholder images here for use when running the app locally.
*/
export const tempHotelLightboxImage: ImageItem[] = [
{
url: "https://www.scandichotels.com/imagevault/publishedmedia/kd4e35n41mrqinfrkzok/scandic-continental-entrance-vasagatan.jpg",
alt: "Hotel entrance",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/ip4a2rc93qda3aq9ph73/scandic-continental-room-standard.jpg",
alt: "Standard room",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/75y2b2x8uvma4s7zvy50/scandic-continental-room-juniorsuite-detail-1.jpg",
alt: "Junior suite",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/pwotq99pbr68djxnym4a/scandic-continental-diningroom-themarket.jpg",
alt: "Dining room, The Market",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/yc2cjoxq2j01gp0f80gt/scandic-continental-room-juniorsuite-bathroom-1.jpg",
alt: "Junior suite bathroom",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/xocam1f69h7lh57u8f9v/scandic-continental-themarket-detail.jpg",
alt: "The Market detail",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/0nnwt72vwzfvkkx5whf0/scandic-continental-caldo.jpg",
alt: "Caldo",
},
{
url: "https://www.scandichotels.com/imageVault/publishedmedia/mg9bbtbumfxbfjhovk2e/Scandic_Continental_Capitol_The_View_6.jpg",
alt: "Rooftop bar",
},
]

View File

@@ -4,7 +4,6 @@ import { MOCK_FACILITIES } from "./Facilities/mockData"
import Facilities from "./Facilities" import Facilities from "./Facilities"
import AmenitiesList from "./AmenitiesList" import AmenitiesList from "./AmenitiesList"
import { tempHotelLightboxImage } from "./data"
import IntroSection from "./IntroSection" import IntroSection from "./IntroSection"
import PreviewImages from "./PreviewImages" import PreviewImages from "./PreviewImages"
import { Rooms } from "./Rooms" import { Rooms } from "./Rooms"
@@ -20,23 +19,32 @@ export default async function HotelPage() {
if (!hotelData) { if (!hotelData) {
return null return null
} }
const { hotel, roomCategories } = hotelData const {
hotelName,
hotelDescription,
hotelLocation,
hotelAddress,
hotelRatings,
hotelDetailedFacilities,
hotelImages,
roomCategories,
} = hotelData
return ( return (
<div className={styles.pageContainer}> <div className={styles.pageContainer}>
<PreviewImages images={tempHotelLightboxImage} /> <PreviewImages images={hotelImages} />
<TabNavigation /> <TabNavigation />
<main className={styles.mainSection}> <main className={styles.mainSection}>
<div className={styles.introContainer}> <div className={styles.introContainer}>
<IntroSection <IntroSection
hotelName={hotel.name} hotelName={hotelName}
hotelDescription={hotel.hotelContent.texts.descriptions.short} hotelDescription={hotelDescription}
location={hotel.location} location={hotelLocation}
address={hotel.address} address={hotelAddress}
tripAdvisor={hotel.ratings?.tripAdvisor} tripAdvisor={hotelRatings?.tripAdvisor}
/> />
<SidePeeks /> <SidePeeks />
<AmenitiesList detailedFacilities={hotel.detailedFacilities} /> <AmenitiesList detailedFacilities={hotelDetailedFacilities} />
</div> </div>
<Rooms rooms={roomCategories} /> <Rooms rooms={roomCategories} />
<Facilities facilities={MOCK_FACILITIES} /> <Facilities facilities={MOCK_FACILITIES} />

View File

@@ -61,7 +61,7 @@ export default function FullView({
/> />
<div className={styles.fullViewFooter}> <div className={styles.fullViewFooter}>
<Body color="white">{image.alt}</Body> <Body color="white">{image.title}</Body>
</div> </div>
</motion.div> </motion.div>
</AnimatePresence> </AnimatePresence>

View File

@@ -56,7 +56,7 @@ export default function Gallery({
<div className={styles.desktopGallery}> <div className={styles.desktopGallery}>
<div className={styles.galleryHeader}> <div className={styles.galleryHeader}>
<div className={styles.imageCaption}> <div className={styles.imageCaption}>
<Caption color="textMediumContrast">{mainImage.alt}</Caption> <Caption color="textMediumContrast">{mainImage.title}</Caption>
</div> </div>
</div> </div>
<div className={styles.mainImageWrapper}> <div className={styles.mainImageWrapper}>

View File

@@ -5,7 +5,6 @@
.mobileGallery { .mobileGallery {
margin-top: 70.047px; margin-top: 70.047px;
height: 100%; height: 100%;
overflow-y: auto;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -51,6 +50,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
overflow-y: auto;
} }
.galleryHeader { .galleryHeader {
@@ -60,6 +60,10 @@
margin-bottom: var(--Spacing-x1); margin-bottom: var(--Spacing-x1);
} }
.desktopGalleryCloseButton {
display: none;
}
.imageCaption { .imageCaption {
background-color: var(--Base-Surface-Subtle-Normal); background-color: var(--Base-Surface-Subtle-Normal);
padding: var(--Spacing-x-half) var(--Spacing-x1); padding: var(--Spacing-x-half) var(--Spacing-x1);
@@ -187,6 +191,7 @@
} }
.desktopGalleryCloseButton { .desktopGalleryCloseButton {
display: block;
position: absolute; position: absolute;
top: var(--Spacing-x-one-and-half); top: var(--Spacing-x-one-and-half);
right: var(--Spacing-x-half); right: var(--Spacing-x-half);

View File

@@ -13,6 +13,7 @@ import {
publicProcedure, publicProcedure,
router, router,
} from "@/server/trpc" } from "@/server/trpc"
import { extractHotelImages } from "@/server/routers/utils/hotels"
import { toApiLang } from "@/server/utils" import { toApiLang } from "@/server/utils"
import { import {
@@ -153,6 +154,10 @@ export const hotelQueryRouter = router({
const included = validatedHotelData.data.included || [] const included = validatedHotelData.data.included || []
const hotelAttributes = validatedHotelData.data.data.attributes
const images = extractHotelImages(hotelAttributes)
const roomCategories = included const roomCategories = included
? included ? included
.filter((item) => item.type === "roomcategories") .filter((item) => item.type === "roomcategories")
@@ -193,8 +198,14 @@ export const hotelQueryRouter = router({
}) })
) )
return { return {
hotel: validatedHotelData.data.data.attributes, hotelName: hotelAttributes.name,
roomCategories: roomCategories, hotelDescription: hotelAttributes.hotelContent.texts.descriptions.short,
hotelLocation: hotelAttributes.location,
hotelAddress: hotelAttributes.address,
hotelRatings: hotelAttributes.ratings,
hotelDetailedFacilities: hotelAttributes.detailedFacilities,
hotelImages: images,
roomCategories,
} }
}), }),
rates: router({ rates: router({

View File

@@ -0,0 +1,30 @@
import { ImageItem } from "@/types/components/lightbox/lightbox"
import { Hotel } from "@/types/hotel"
export function extractHotelImages(hotelData: Hotel): ImageItem[] {
const images: ImageItem[] = []
if (hotelData.hotelContent?.images) {
images.push({
url: hotelData.hotelContent.images.imageSizes.large,
alt: hotelData.hotelContent.images.metaData.altText,
title:
hotelData.hotelContent.images.metaData.title ||
hotelData.hotelContent.images.metaData.altText,
})
}
if (hotelData.healthFacilities) {
hotelData.healthFacilities.forEach((facility: any) => {
facility.content.images.forEach((image: any) => {
images.push({
url: image.imageSizes.large,
alt: image.metaData.altText,
title: image.metaData.title || image.metaData.altText,
})
})
})
}
return images
}

View File

@@ -1,6 +1,7 @@
export interface ImageItem { export interface ImageItem {
url: string url: string
alt: string alt: string
title: string
} }
export interface LightboxProps { export interface LightboxProps {