Merged in fix/book-607-page-not-found-confirmation-page (pull request #3345)
* fix(BOOK-607): updated to read from base URL env and contentstack slug instead * made url optional on interface * added url to findBooking query * added the correct (new) link in the confirmation header, add to calendar Approved-by: Erik Tiekstra
This commit is contained in:
2
packages/booking-flow/env/server.ts
vendored
2
packages/booking-flow/env/server.ts
vendored
@@ -9,12 +9,14 @@ export const env = createEnv({
|
|||||||
*/
|
*/
|
||||||
isServer: typeof window === "undefined" || "Deno" in window,
|
isServer: typeof window === "undefined" || "Deno" in window,
|
||||||
server: {
|
server: {
|
||||||
|
PUBLIC_URL: z.string().default(""),
|
||||||
GOOGLE_STATIC_MAP_KEY: z.string(),
|
GOOGLE_STATIC_MAP_KEY: z.string(),
|
||||||
GOOGLE_STATIC_MAP_SIGNATURE_SECRET: z.string(),
|
GOOGLE_STATIC_MAP_SIGNATURE_SECRET: z.string(),
|
||||||
GOOGLE_DYNAMIC_MAP_ID: z.string(),
|
GOOGLE_DYNAMIC_MAP_ID: z.string(),
|
||||||
},
|
},
|
||||||
emptyStringAsUndefined: true,
|
emptyStringAsUndefined: true,
|
||||||
runtimeEnv: {
|
runtimeEnv: {
|
||||||
|
PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
|
||||||
GOOGLE_STATIC_MAP_KEY: process.env.GOOGLE_STATIC_MAP_KEY,
|
GOOGLE_STATIC_MAP_KEY: process.env.GOOGLE_STATIC_MAP_KEY,
|
||||||
GOOGLE_STATIC_MAP_SIGNATURE_SECRET:
|
GOOGLE_STATIC_MAP_SIGNATURE_SECRET:
|
||||||
process.env.GOOGLE_STATIC_MAP_SIGNATURE_SECRET,
|
process.env.GOOGLE_STATIC_MAP_SIGNATURE_SECRET,
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConf
|
|||||||
|
|
||||||
import type { BookingConfirmationRoom } from "../../../types/components/bookingConfirmation/bookingConfirmation"
|
import type { BookingConfirmationRoom } from "../../../types/components/bookingConfirmation/bookingConfirmation"
|
||||||
|
|
||||||
interface ConfirmationProps
|
interface ConfirmationProps extends Pick<
|
||||||
extends Pick<BookingConfirmation, "booking" | "hotel"> {
|
BookingConfirmation,
|
||||||
|
"booking" | "hotel" | "url"
|
||||||
|
> {
|
||||||
room: BookingConfirmationRoom
|
room: BookingConfirmationRoom
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Confirmation({
|
export function Confirmation({
|
||||||
booking,
|
booking,
|
||||||
|
url,
|
||||||
hotel,
|
hotel,
|
||||||
children,
|
children,
|
||||||
}: React.PropsWithChildren<ConfirmationProps>) {
|
}: React.PropsWithChildren<ConfirmationProps>) {
|
||||||
@@ -24,7 +27,7 @@ export function Confirmation({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={styles.main} ref={mainRef}>
|
<main className={styles.main} ref={mainRef}>
|
||||||
<Header booking={booking} hotel={hotel} mainRef={mainRef} />
|
<Header url={url} booking={booking} hotel={hotel} mainRef={mainRef} />
|
||||||
{children}
|
{children}
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import type { MutableRefObject } from "react"
|
|||||||
|
|
||||||
interface BookingConfirmationHeaderProps extends Pick<
|
interface BookingConfirmationHeaderProps extends Pick<
|
||||||
BookingConfirmation,
|
BookingConfirmation,
|
||||||
"booking" | "hotel"
|
"booking" | "hotel" | "url"
|
||||||
> {
|
> {
|
||||||
mainRef: MutableRefObject<HTMLElement | null>
|
mainRef: MutableRefObject<HTMLElement | null>
|
||||||
}
|
}
|
||||||
@@ -26,6 +26,7 @@ interface BookingConfirmationHeaderProps extends Pick<
|
|||||||
export function Header({
|
export function Header({
|
||||||
booking,
|
booking,
|
||||||
hotel,
|
hotel,
|
||||||
|
url,
|
||||||
// mainRef,
|
// mainRef,
|
||||||
}: BookingConfirmationHeaderProps) {
|
}: BookingConfirmationHeaderProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -52,7 +53,7 @@ export function Header({
|
|||||||
startInputType: "utc",
|
startInputType: "utc",
|
||||||
status: "CONFIRMED",
|
status: "CONFIRMED",
|
||||||
title: hotel.name,
|
title: hotel.name,
|
||||||
url: hotel.contactInformation.websiteUrl,
|
url: url ?? undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,10 +11,13 @@ import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConf
|
|||||||
|
|
||||||
export function HotelDetails({
|
export function HotelDetails({
|
||||||
hotel,
|
hotel,
|
||||||
|
url,
|
||||||
}: {
|
}: {
|
||||||
hotel: BookingConfirmation["hotel"]
|
hotel: BookingConfirmation["hotel"]
|
||||||
|
url: string | null
|
||||||
}) {
|
}) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.details}>
|
<div className={styles.details}>
|
||||||
@@ -62,14 +65,16 @@ export function HotelDetails({
|
|||||||
>
|
>
|
||||||
{hotel.contactInformation.email}
|
{hotel.contactInformation.email}
|
||||||
</Link>
|
</Link>
|
||||||
|
{url && (
|
||||||
<Link
|
<Link
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
color="Text/Interactive/Secondary"
|
color="Text/Interactive/Secondary"
|
||||||
href={hotel.contactInformation.websiteUrl}
|
href={url}
|
||||||
textDecoration="underline"
|
textDecoration="underline"
|
||||||
>
|
>
|
||||||
{hotel.contactInformation.websiteUrl}
|
{url}
|
||||||
</Link>
|
</Link>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Alert } from "@scandic-hotels/design-system/Alert"
|
|||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
|
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
|
||||||
|
|
||||||
|
import { env } from "../../../env/server"
|
||||||
import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
|
import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
|
||||||
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
|
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
|
||||||
import { SidePanel } from "../SidePanel"
|
import { SidePanel } from "../SidePanel"
|
||||||
@@ -41,7 +42,10 @@ export async function BookingConfirmation({
|
|||||||
return notFound()
|
return notFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
const { booking, hotel, room, roomCategories } = bookingConfirmation
|
const { booking, url, hotel, room, roomCategories } = bookingConfirmation
|
||||||
|
|
||||||
|
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
|
||||||
|
const hotelUrl = new URL(`${baseUrl}${url}`)
|
||||||
|
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return notFound()
|
return notFound()
|
||||||
@@ -69,7 +73,12 @@ export async function BookingConfirmation({
|
|||||||
]}
|
]}
|
||||||
vat={booking.vatPercentage}
|
vat={booking.vatPercentage}
|
||||||
>
|
>
|
||||||
<Confirmation booking={booking} hotel={hotel} room={room}>
|
<Confirmation
|
||||||
|
url={hotelUrl.toString()}
|
||||||
|
booking={booking}
|
||||||
|
hotel={hotel}
|
||||||
|
room={room}
|
||||||
|
>
|
||||||
<div className={styles.booking}>
|
<div className={styles.booking}>
|
||||||
{membershipFailedError && (
|
{membershipFailedError && (
|
||||||
<Alert
|
<Alert
|
||||||
@@ -93,7 +102,7 @@ export async function BookingConfirmation({
|
|||||||
/>
|
/>
|
||||||
<PaymentDetails />
|
<PaymentDetails />
|
||||||
<Divider color="Border/Divider/Subtle" />
|
<Divider color="Border/Divider/Subtle" />
|
||||||
<HotelDetails hotel={hotel} />
|
<HotelDetails url={hotelUrl.toString()} hotel={hotel} />
|
||||||
{validAlerts.map((alert) => (
|
{validAlerts.map((alert) => (
|
||||||
<div key={alert.id}>
|
<div key={alert.id}>
|
||||||
<Alert
|
<Alert
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
import { toApiLang } from "../../utils"
|
import { toApiLang } from "../../utils"
|
||||||
import { encrypt } from "../../utils/encryption"
|
import { encrypt } from "../../utils/encryption"
|
||||||
import { isValidSession } from "../../utils/session"
|
import { isValidSession } from "../../utils/session"
|
||||||
|
import { getHotelPageUrls } from "../contentstack/hotelPage/utils"
|
||||||
import { getHotel } from "../hotels/services/getHotel"
|
import { getHotel } from "../hotels/services/getHotel"
|
||||||
import { createBookingSchema } from "./mutation/create/schema"
|
import { createBookingSchema } from "./mutation/create/schema"
|
||||||
import { getHotelRoom } from "./helpers"
|
import { getHotelRoom } from "./helpers"
|
||||||
@@ -62,13 +63,19 @@ export const bookingQueryRouter = router({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const hotelData = await getHotel(
|
const [hotelData, hotelPages] = await Promise.all([
|
||||||
|
getHotel(
|
||||||
{
|
{
|
||||||
hotelId: booking.hotelId,
|
hotelId: booking.hotelId,
|
||||||
isCardOnlyPayment: false,
|
isCardOnlyPayment: false,
|
||||||
language: lang,
|
language: lang,
|
||||||
},
|
},
|
||||||
serviceToken
|
serviceToken
|
||||||
|
),
|
||||||
|
getHotelPageUrls(lang),
|
||||||
|
])
|
||||||
|
const hotelPage = hotelPages.find(
|
||||||
|
(page) => page.hotelId === booking.hotelId
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!hotelData) {
|
if (!hotelData) {
|
||||||
@@ -86,6 +93,7 @@ export const bookingQueryRouter = router({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...hotelData,
|
...hotelData,
|
||||||
|
url: hotelPage?.url || null,
|
||||||
booking,
|
booking,
|
||||||
room: getHotelRoom(hotelData.roomCategories, booking.roomTypeCode),
|
room: getHotelRoom(hotelData.roomCategories, booking.roomTypeCode),
|
||||||
}
|
}
|
||||||
@@ -132,13 +140,19 @@ export const bookingQueryRouter = router({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const hotelData = await getHotel(
|
const [hotelData, hotelPages] = await Promise.all([
|
||||||
|
getHotel(
|
||||||
{
|
{
|
||||||
hotelId: booking.hotelId,
|
hotelId: booking.hotelId,
|
||||||
isCardOnlyPayment: false,
|
isCardOnlyPayment: false,
|
||||||
language: lang,
|
language: lang,
|
||||||
},
|
},
|
||||||
serviceToken
|
serviceToken
|
||||||
|
),
|
||||||
|
getHotelPageUrls(lang),
|
||||||
|
])
|
||||||
|
const hotelPage = hotelPages.find(
|
||||||
|
(page) => page.hotelId === booking.hotelId
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!hotelData) {
|
if (!hotelData) {
|
||||||
@@ -156,6 +170,7 @@ export const bookingQueryRouter = router({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...hotelData,
|
...hotelData,
|
||||||
|
url: hotelPage?.url || null,
|
||||||
booking,
|
booking,
|
||||||
room: getHotelRoom(hotelData.roomCategories, booking.roomTypeCode),
|
room: getHotelRoom(hotelData.roomCategories, booking.roomTypeCode),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ import type {
|
|||||||
} from "../routers/booking/output"
|
} from "../routers/booking/output"
|
||||||
import type { HotelData, Room } from "./hotel"
|
import type { HotelData, Room } from "./hotel"
|
||||||
|
|
||||||
export interface BookingConfirmationSchema
|
export interface BookingConfirmationSchema extends z.output<
|
||||||
extends z.output<typeof bookingConfirmationSchema> {}
|
typeof bookingConfirmationSchema
|
||||||
|
> {}
|
||||||
|
|
||||||
export interface PackageSchema extends z.output<typeof packageSchema> {}
|
export interface PackageSchema extends z.output<typeof packageSchema> {}
|
||||||
|
|
||||||
export interface BookingConfirmation extends HotelData {
|
export interface BookingConfirmation extends HotelData {
|
||||||
|
url: string | null
|
||||||
booking: BookingConfirmationSchema
|
booking: BookingConfirmationSchema
|
||||||
room:
|
room:
|
||||||
| (Room & {
|
| (Room & {
|
||||||
|
|||||||
Reference in New Issue
Block a user