feat(SW-201): Refactoring how we fetch hotel page data
This commit is contained in:
@@ -3,6 +3,7 @@ import { notFound } from "next/navigation"
|
|||||||
|
|
||||||
import { isSignupPage } from "@/constants/routes/signup"
|
import { isSignupPage } from "@/constants/routes/signup"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
import { getHotelPage } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import HotelPage from "@/components/ContentType/HotelPage"
|
import HotelPage from "@/components/ContentType/HotelPage"
|
||||||
import LoyaltyPage from "@/components/ContentType/LoyaltyPage"
|
import LoyaltyPage from "@/components/ContentType/LoyaltyPage"
|
||||||
@@ -19,7 +20,7 @@ import {
|
|||||||
|
|
||||||
export { generateMetadata } from "@/utils/generateMetadata"
|
export { generateMetadata } from "@/utils/generateMetadata"
|
||||||
|
|
||||||
export default function ContentTypePage({
|
export default async function ContentTypePage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
@@ -57,7 +58,12 @@ export default function ContentTypePage({
|
|||||||
if (env.HIDE_FOR_NEXT_RELEASE) {
|
if (env.HIDE_FOR_NEXT_RELEASE) {
|
||||||
return notFound()
|
return notFound()
|
||||||
}
|
}
|
||||||
return <HotelPage />
|
const hotelPageData = await getHotelPage()
|
||||||
|
return hotelPageData ? (
|
||||||
|
<HotelPage hotelId={hotelPageData.hotel_page_id} />
|
||||||
|
) : (
|
||||||
|
notFound()
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
const type: never = params.contentType
|
const type: never = params.contentType
|
||||||
console.error(`Unsupported content type given: ${type}`)
|
console.error(`Unsupported content type given: ${type}`)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import hotelPageParams from "@/constants/routes/hotelPageParams"
|
import hotelPageParams from "@/constants/routes/hotelPageParams"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getHotelData, getHotelPage } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import AccordionSection from "@/components/Blocks/Accordion"
|
import AccordionSection from "@/components/Blocks/Accordion"
|
||||||
import HotelReservationSidePeek from "@/components/HotelReservation/SidePeek"
|
import HotelReservationSidePeek from "@/components/HotelReservation/SidePeek"
|
||||||
@@ -16,65 +18,96 @@ import MapCard from "./Map/MapCard"
|
|||||||
import MapWithCardWrapper from "./Map/MapWithCard"
|
import MapWithCardWrapper from "./Map/MapWithCard"
|
||||||
import MobileMapToggle from "./Map/MobileMapToggle"
|
import MobileMapToggle from "./Map/MobileMapToggle"
|
||||||
import StaticMap from "./Map/StaticMap"
|
import StaticMap from "./Map/StaticMap"
|
||||||
|
import WellnessAndExerciseSidePeek from "./SidePeeks/WellnessAndExercise"
|
||||||
import AmenitiesList from "./AmenitiesList"
|
import AmenitiesList from "./AmenitiesList"
|
||||||
import Facilities from "./Facilities"
|
import Facilities from "./Facilities"
|
||||||
import IntroSection from "./IntroSection"
|
import IntroSection from "./IntroSection"
|
||||||
import PreviewImages from "./PreviewImages"
|
import PreviewImages from "./PreviewImages"
|
||||||
import { Rooms } from "./Rooms"
|
import { Rooms } from "./Rooms"
|
||||||
import { AboutTheHotelSidePeek, WellnessAndExerciseSidePeek } from "./SidePeeks"
|
import { AboutTheHotelSidePeek } from "./SidePeeks"
|
||||||
import TabNavigation from "./TabNavigation"
|
import TabNavigation from "./TabNavigation"
|
||||||
|
|
||||||
import styles from "./hotelPage.module.css"
|
import styles from "./hotelPage.module.css"
|
||||||
|
|
||||||
|
import { FacilityCardTypeEnum } from "@/types/components/hotelPage/facilities"
|
||||||
|
import { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
|
||||||
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
||||||
|
import { Facility } from "@/types/hotel"
|
||||||
|
|
||||||
export default async function HotelPage() {
|
export default async function HotelPage({ hotelId }: HotelPageProps) {
|
||||||
const intl = await getIntl()
|
|
||||||
const lang = getLang()
|
|
||||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||||
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
||||||
const hotelData = await serverClient().hotel.get()
|
const lang = getLang()
|
||||||
if (!hotelData) {
|
const [intl, hotelPageData, hotelData] = await Promise.all([
|
||||||
return null
|
getIntl(),
|
||||||
|
getHotelPage(),
|
||||||
|
getHotelData({ hotelId, language: lang }),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (!hotelData?.data || !hotelPageData) {
|
||||||
|
return notFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { faq, content } = hotelPageData
|
||||||
const {
|
const {
|
||||||
hotelId,
|
name,
|
||||||
hotelName,
|
address,
|
||||||
hotelDescriptions,
|
|
||||||
hotelLocation,
|
|
||||||
hotelAddress,
|
|
||||||
hotelRatings,
|
|
||||||
hotelDetailedFacilities,
|
|
||||||
hotelImages,
|
|
||||||
roomCategories,
|
|
||||||
activitiesCard,
|
|
||||||
pointsOfInterest,
|
pointsOfInterest,
|
||||||
facilities,
|
gallery,
|
||||||
faq,
|
specialAlerts,
|
||||||
alerts,
|
healthAndWellness,
|
||||||
|
restaurantImages,
|
||||||
|
conferencesAndMeetings,
|
||||||
|
hotelContent,
|
||||||
|
detailedFacilities,
|
||||||
healthFacilities,
|
healthFacilities,
|
||||||
contact,
|
contactInformation,
|
||||||
socials,
|
socialMedia,
|
||||||
ecoLabels,
|
hotelFacts,
|
||||||
} = hotelData
|
location,
|
||||||
|
ratings,
|
||||||
|
} = hotelData.data.attributes
|
||||||
|
const roomCategories =
|
||||||
|
hotelData.included?.filter((item) => item.type === "roomcategories") || []
|
||||||
|
const images = gallery?.smallerImages
|
||||||
|
const description = hotelContent.texts.descriptions.short
|
||||||
|
const activitiesCard = content?.[0]?.upcoming_activities_card || null
|
||||||
|
|
||||||
|
const facilities: Facility[] = [
|
||||||
|
{
|
||||||
|
...restaurantImages,
|
||||||
|
id: FacilityCardTypeEnum.restaurant,
|
||||||
|
headingText: restaurantImages?.headingText ?? "",
|
||||||
|
heroImages: restaurantImages?.heroImages ?? [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...conferencesAndMeetings,
|
||||||
|
id: FacilityCardTypeEnum.conference,
|
||||||
|
headingText: conferencesAndMeetings?.headingText ?? "",
|
||||||
|
heroImages: conferencesAndMeetings?.heroImages ?? [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...healthAndWellness,
|
||||||
|
id: FacilityCardTypeEnum.wellness,
|
||||||
|
headingText: healthAndWellness?.headingText ?? "",
|
||||||
|
heroImages: healthAndWellness?.heroImages ?? [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
const topThreePois = pointsOfInterest.slice(0, 3)
|
const topThreePois = pointsOfInterest.slice(0, 3)
|
||||||
|
|
||||||
const coordinates = {
|
const coordinates = {
|
||||||
lat: hotelLocation.latitude,
|
lat: location.latitude,
|
||||||
lng: hotelLocation.longitude,
|
lng: location.longitude,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.pageContainer}>
|
<div className={styles.pageContainer}>
|
||||||
<div className={styles.hotelImages}>
|
<div className={styles.hotelImages}>
|
||||||
{hotelImages?.length && (
|
{images?.length && <PreviewImages images={images} hotelName={name} />}
|
||||||
<PreviewImages images={hotelImages} hotelName={hotelName} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<TabNavigation
|
<TabNavigation
|
||||||
restaurantTitle={getRestaurantHeading(hotelDetailedFacilities)}
|
restaurantTitle={getRestaurantHeading(detailedFacilities)}
|
||||||
hasActivities={!!activitiesCard}
|
hasActivities={!!activitiesCard}
|
||||||
hasFAQ={!!faq.accordions.length}
|
hasFAQ={!!faq.accordions.length}
|
||||||
/>
|
/>
|
||||||
@@ -82,18 +115,18 @@ export default async function HotelPage() {
|
|||||||
<div id={HotelHashValues.overview} className={styles.overview}>
|
<div id={HotelHashValues.overview} className={styles.overview}>
|
||||||
<div className={styles.introContainer}>
|
<div className={styles.introContainer}>
|
||||||
<IntroSection
|
<IntroSection
|
||||||
hotelName={hotelName}
|
hotelName={name}
|
||||||
hotelDescription={hotelDescriptions.descriptions.short}
|
hotelDescription={description}
|
||||||
location={hotelLocation}
|
location={location}
|
||||||
address={hotelAddress}
|
address={address}
|
||||||
tripAdvisor={hotelRatings?.tripAdvisor}
|
tripAdvisor={ratings?.tripAdvisor}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AmenitiesList detailedFacilities={hotelDetailedFacilities} />
|
<AmenitiesList detailedFacilities={detailedFacilities} />
|
||||||
</div>
|
</div>
|
||||||
{alerts.length ? (
|
{specialAlerts.length ? (
|
||||||
<div className={styles.alertsContainer}>
|
<div className={styles.alertsContainer}>
|
||||||
{alerts.map((alert) => (
|
{specialAlerts.map((alert) => (
|
||||||
<Alert
|
<Alert
|
||||||
key={alert.id}
|
key={alert.id}
|
||||||
type={alert.type}
|
type={alert.type}
|
||||||
@@ -114,14 +147,14 @@ export default async function HotelPage() {
|
|||||||
<>
|
<>
|
||||||
<aside className={styles.mapContainer}>
|
<aside className={styles.mapContainer}>
|
||||||
<MapWithCardWrapper>
|
<MapWithCardWrapper>
|
||||||
<StaticMap coordinates={coordinates} hotelName={hotelName} />
|
<StaticMap coordinates={coordinates} hotelName={name} />
|
||||||
<MapCard hotelName={hotelName} pois={topThreePois} />
|
<MapCard hotelName={name} pois={topThreePois} />
|
||||||
</MapWithCardWrapper>
|
</MapWithCardWrapper>
|
||||||
</aside>
|
</aside>
|
||||||
<MobileMapToggle />
|
<MobileMapToggle />
|
||||||
<DynamicMap
|
<DynamicMap
|
||||||
apiKey={googleMapsApiKey}
|
apiKey={googleMapsApiKey}
|
||||||
hotelName={hotelName}
|
hotelName={name}
|
||||||
coordinates={coordinates}
|
coordinates={coordinates}
|
||||||
pointsOfInterest={pointsOfInterest}
|
pointsOfInterest={pointsOfInterest}
|
||||||
mapId={googleMapId}
|
mapId={googleMapId}
|
||||||
@@ -138,12 +171,12 @@ export default async function HotelPage() {
|
|||||||
Read more about the amenities here
|
Read more about the amenities here
|
||||||
</SidePeek>
|
</SidePeek>
|
||||||
<AboutTheHotelSidePeek
|
<AboutTheHotelSidePeek
|
||||||
hotelAddress={hotelAddress}
|
hotelAddress={address}
|
||||||
coordinates={hotelLocation}
|
coordinates={location}
|
||||||
contact={contact}
|
contact={contactInformation}
|
||||||
socials={socials}
|
socials={socialMedia}
|
||||||
ecoLabels={ecoLabels}
|
ecoLabels={hotelFacts.ecoLabels}
|
||||||
descriptions={hotelDescriptions}
|
descriptions={hotelContent.texts}
|
||||||
/>
|
/>
|
||||||
<SidePeek
|
<SidePeek
|
||||||
contentKey={hotelPageParams.restaurantAndBar[lang]}
|
contentKey={hotelPageParams.restaurantAndBar[lang]}
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ export const getHotelData = cache(function getMemoizedHotelData(
|
|||||||
return serverClient().hotel.hotelData.get(props)
|
return serverClient().hotel.hotelData.get(props)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const getHotelPage = cache(async function getMemoizedHotelPage() {
|
||||||
|
return serverClient().contentstack.hotelPage.get()
|
||||||
|
})
|
||||||
|
|
||||||
export const getRoomsAvailability = cache(function getMemoizedRoomAvailability(
|
export const getRoomsAvailability = cache(function getMemoizedRoomAvailability(
|
||||||
args: GetRoomsAvailabilityInput
|
args: GetRoomsAvailabilityInput
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export async function getDescription(data: RawMetadataSchema) {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getImages(data: RawMetadataSchema) {
|
export function getImage(data: RawMetadataSchema) {
|
||||||
const metadataImage = data.web?.seo_metadata?.seo_image
|
const metadataImage = data.web?.seo_metadata?.seo_image
|
||||||
const heroImage = data.hero_image
|
const heroImage = data.hero_image
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
import { metrics } from "@opentelemetry/api"
|
import { metrics } from "@opentelemetry/api"
|
||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
|
||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
import { GetHotelPage } from "@/lib/graphql/Query/HotelPage/HotelPage.graphql"
|
import { badRequestError } from "@/server/errors/trpc"
|
||||||
import { request } from "@/lib/graphql/request"
|
|
||||||
import { badRequestError, notFound } from "@/server/errors/trpc"
|
|
||||||
import {
|
import {
|
||||||
contentStackUidWithServiceProcedure,
|
|
||||||
publicProcedure,
|
publicProcedure,
|
||||||
router,
|
router,
|
||||||
safeProtectedServiceProcedure,
|
safeProtectedServiceProcedure,
|
||||||
@@ -17,13 +13,6 @@ import { toApiLang } from "@/server/utils"
|
|||||||
|
|
||||||
import { cache } from "@/utils/cache"
|
import { cache } from "@/utils/cache"
|
||||||
|
|
||||||
import { hotelPageSchema } from "../contentstack/hotelPage/output"
|
|
||||||
import {
|
|
||||||
fetchHotelPageRefs,
|
|
||||||
generatePageTags,
|
|
||||||
getHotelPageCounter,
|
|
||||||
validateHotelPageRefs,
|
|
||||||
} from "../contentstack/hotelPage/utils"
|
|
||||||
import { getVerifiedUser, parsedUser } from "../user/query"
|
import { getVerifiedUser, parsedUser } from "../user/query"
|
||||||
import {
|
import {
|
||||||
getBreakfastPackageInputSchema,
|
getBreakfastPackageInputSchema,
|
||||||
@@ -52,13 +41,10 @@ import {
|
|||||||
TWENTYFOUR_HOURS,
|
TWENTYFOUR_HOURS,
|
||||||
} from "./utils"
|
} from "./utils"
|
||||||
|
|
||||||
import { FacilityCardTypeEnum } from "@/types/components/hotelPage/facilities"
|
|
||||||
import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType"
|
import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||||
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
|
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
|
||||||
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
||||||
import type { RequestOptionsWithOutBody } from "@/types/fetch"
|
import type { RequestOptionsWithOutBody } from "@/types/fetch"
|
||||||
import type { Facility } from "@/types/hotel"
|
|
||||||
import type { GetHotelPageData } from "@/types/trpc/routers/contentstack/hotelPage"
|
|
||||||
|
|
||||||
const meter = metrics.getMeter("trpc.hotels")
|
const meter = metrics.getMeter("trpc.hotels")
|
||||||
const getHotelCounter = meter.createCounter("trpc.hotel.get")
|
const getHotelCounter = meter.createCounter("trpc.hotel.get")
|
||||||
@@ -111,55 +97,6 @@ const breakfastPackagesFailCounter = meter.createCounter(
|
|||||||
"trpc.package.breakfast-fail"
|
"trpc.package.breakfast-fail"
|
||||||
)
|
)
|
||||||
|
|
||||||
async function getContentstackData(lang: Lang, uid?: string | null) {
|
|
||||||
if (!uid) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const contentPageRefsData = await fetchHotelPageRefs(lang, uid)
|
|
||||||
const contentPageRefs = validateHotelPageRefs(contentPageRefsData, lang, uid)
|
|
||||||
if (!contentPageRefs) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const tags = generatePageTags(contentPageRefs, lang)
|
|
||||||
|
|
||||||
getHotelPageCounter.add(1, { lang, uid })
|
|
||||||
console.info(
|
|
||||||
"contentstack.hotelPage start",
|
|
||||||
JSON.stringify({
|
|
||||||
query: { lang, uid },
|
|
||||||
})
|
|
||||||
)
|
|
||||||
const response = await request<GetHotelPageData>(
|
|
||||||
GetHotelPage,
|
|
||||||
{
|
|
||||||
locale: lang,
|
|
||||||
uid,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cache: "force-cache",
|
|
||||||
next: {
|
|
||||||
tags,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!response.data) {
|
|
||||||
throw notFound(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
const hotelPageData = hotelPageSchema.safeParse(response.data)
|
|
||||||
if (!hotelPageData.success) {
|
|
||||||
console.error(
|
|
||||||
`Failed to validate Hotel Page - (uid: ${uid}, lang: ${lang})`
|
|
||||||
)
|
|
||||||
console.error(hotelPageData.error)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return hotelPageData.data.hotel_page
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getHotelData = cache(
|
export const getHotelData = cache(
|
||||||
async (input: HotelDataInput, serviceToken: string) => {
|
async (input: HotelDataInput, serviceToken: string) => {
|
||||||
const { hotelId, language, isCardOnlyPayment } = input
|
const { hotelId, language, isCardOnlyPayment } = input
|
||||||
@@ -273,90 +210,6 @@ export const getHotelData = cache(
|
|||||||
)
|
)
|
||||||
|
|
||||||
export const hotelQueryRouter = router({
|
export const hotelQueryRouter = router({
|
||||||
get: contentStackUidWithServiceProcedure.query(async ({ ctx }) => {
|
|
||||||
const { lang, uid } = ctx
|
|
||||||
|
|
||||||
const contentstackData = await getContentstackData(lang, uid)
|
|
||||||
const hotelId = contentstackData?.hotel_page_id
|
|
||||||
|
|
||||||
if (!hotelId) {
|
|
||||||
throw notFound(`Hotel not found for uid: ${uid}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const hotelData = await getHotelData(
|
|
||||||
{
|
|
||||||
hotelId,
|
|
||||||
language: ctx.lang,
|
|
||||||
},
|
|
||||||
ctx.serviceToken
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!hotelData) {
|
|
||||||
throw notFound()
|
|
||||||
}
|
|
||||||
|
|
||||||
const included = hotelData.included || []
|
|
||||||
|
|
||||||
const hotelAttributes = hotelData.data.attributes
|
|
||||||
const images = hotelAttributes.gallery?.smallerImages
|
|
||||||
const hotelAlerts = hotelAttributes.specialAlerts
|
|
||||||
|
|
||||||
const roomCategories = included
|
|
||||||
? included.filter((item) => item.type === "roomcategories")
|
|
||||||
: []
|
|
||||||
|
|
||||||
const activities = contentstackData?.content
|
|
||||||
? contentstackData?.content[0]
|
|
||||||
: null
|
|
||||||
|
|
||||||
const facilities: Facility[] = [
|
|
||||||
{
|
|
||||||
...hotelData.data.attributes.restaurantImages,
|
|
||||||
id: FacilityCardTypeEnum.restaurant,
|
|
||||||
headingText:
|
|
||||||
hotelData?.data.attributes.restaurantImages?.headingText ?? "",
|
|
||||||
heroImages:
|
|
||||||
hotelData?.data.attributes.restaurantImages?.heroImages ?? [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...hotelData.data.attributes.conferencesAndMeetings,
|
|
||||||
id: FacilityCardTypeEnum.conference,
|
|
||||||
headingText:
|
|
||||||
hotelData?.data.attributes.conferencesAndMeetings?.headingText ?? "",
|
|
||||||
heroImages:
|
|
||||||
hotelData?.data.attributes.conferencesAndMeetings?.heroImages ?? [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...hotelData.data.attributes.healthAndWellness,
|
|
||||||
id: FacilityCardTypeEnum.wellness,
|
|
||||||
headingText:
|
|
||||||
hotelData?.data.attributes.healthAndWellness?.headingText ?? "",
|
|
||||||
heroImages:
|
|
||||||
hotelData?.data.attributes.healthAndWellness?.heroImages ?? [],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return {
|
|
||||||
hotelId,
|
|
||||||
hotelName: hotelAttributes.name,
|
|
||||||
hotelDescriptions: hotelAttributes.hotelContent.texts,
|
|
||||||
hotelLocation: hotelAttributes.location,
|
|
||||||
hotelAddress: hotelAttributes.address,
|
|
||||||
hotelRatings: hotelAttributes.ratings,
|
|
||||||
hotelDetailedFacilities: hotelAttributes.detailedFacilities,
|
|
||||||
hotelImages: images,
|
|
||||||
pointsOfInterest: hotelAttributes.pointsOfInterest,
|
|
||||||
roomCategories,
|
|
||||||
activitiesCard: activities?.upcoming_activities_card,
|
|
||||||
facilities,
|
|
||||||
alerts: hotelAlerts,
|
|
||||||
faq: contentstackData?.faq,
|
|
||||||
healthFacilities: hotelAttributes.healthFacilities,
|
|
||||||
contact: hotelAttributes.contactInformation,
|
|
||||||
socials: hotelAttributes.socialMedia,
|
|
||||||
ecoLabels: hotelAttributes.hotelFacts.ecoLabels,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
availability: router({
|
availability: router({
|
||||||
hotels: serviceProcedure
|
hotels: serviceProcedure
|
||||||
.input(getHotelsAvailabilityInputSchema)
|
.input(getHotelsAvailabilityInputSchema)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { CardProps } from "@/components/TempDesignSystem/Card/card"
|
|||||||
|
|
||||||
export type FacilitiesProps = {
|
export type FacilitiesProps = {
|
||||||
facilities: Facility[]
|
facilities: Facility[]
|
||||||
activitiesCard?: ActivityCard
|
activitiesCard: ActivityCard | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FacilityImage = {
|
export type FacilityImage = {
|
||||||
|
|||||||
3
types/components/hotelPage/hotelPage.ts
Normal file
3
types/components/hotelPage/hotelPage.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface HotelPageProps {
|
||||||
|
hotelId: string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user