From f178f7fde0b37245221ffefa9aa76fc23f8f49e4 Mon Sep 17 00:00:00 2001 From: Niclas Edenvin Date: Thu, 29 Aug 2024 13:38:14 +0000 Subject: [PATCH] Merged in feature/select-room-ux-one-page (pull request #523) This updates the select room page according to the new UX. It has different sections on the same page, but with specific URLs per section. Since neither UX, UI nor API is completely done both design and data structures are a bit temporary. Approved-by: Simon.Emanuelsson --- .../page.module.css | 16 +- .../hotelreservation/[section]/page.tsx | 188 ++++++++++++++++++ .../hotelreservation/select-rate/page.tsx | 39 ---- .../SelectRate/BedSelection/index.tsx | 98 ++++----- .../SelectRate/BreakfastSelection/index.tsx | 87 ++++---- .../SelectRate/Details/details.module.css | 2 + .../SelectRate/Details/index.tsx | 6 + .../flexibilitySelection.module.css | 28 --- .../SelectRate/FlexibilitySelection/index.tsx | 62 ------ .../SelectRate/Payment/index.tsx | 6 + .../SelectRate/Payment/payment.module.css | 2 + .../flexibilityOption.module.css | 15 ++ .../RoomSelection/FlexibilityOption/index.tsx | 45 +++++ .../RoomSelection/RoomCard/index.tsx | 87 ++++++-- .../RoomCard/roomCard.module.css | 23 +-- .../SelectRate/RoomSelection/index.tsx | 66 +++--- .../RoomSelection/roomSelection.module.css | 6 +- .../SelectRate/SectionAccordion/index.tsx | 48 +++++ .../sectionAccordion.module.css | 21 ++ .../SelectRate/SelectionCard/index.tsx | 14 +- .../SelectRate/Summary/index.tsx | 6 + .../SelectRate/Summary/summary.module.css | 2 + i18n/dictionaries/da.json | 22 +- i18n/dictionaries/de.json | 24 ++- i18n/dictionaries/en.json | 22 +- i18n/dictionaries/fi.json | 23 ++- i18n/dictionaries/no.json | 22 +- i18n/dictionaries/sv.json | 23 ++- server/routers/hotels/output.ts | 14 +- server/routers/hotels/tempRatesData.json | 84 ++++++-- .../selectRate/flexibilityOption.ts | 8 + .../hotelReservation/selectRate/roomCard.ts | 7 +- .../selectRate/roomSelection.ts | 5 - .../hotelReservation/selectRate/section.ts | 40 ++++ .../selectRate/sectionAccordion.ts | 5 + 35 files changed, 794 insertions(+), 372 deletions(-) rename app/[lang]/(live)/(public)/hotelreservation/{select-rate => [section]}/page.module.css (61%) create mode 100644 app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/select-rate/page.tsx create mode 100644 components/HotelReservation/SelectRate/Details/details.module.css create mode 100644 components/HotelReservation/SelectRate/Details/index.tsx delete mode 100644 components/HotelReservation/SelectRate/FlexibilitySelection/flexibilitySelection.module.css delete mode 100644 components/HotelReservation/SelectRate/FlexibilitySelection/index.tsx create mode 100644 components/HotelReservation/SelectRate/Payment/index.tsx create mode 100644 components/HotelReservation/SelectRate/Payment/payment.module.css create mode 100644 components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/flexibilityOption.module.css create mode 100644 components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx create mode 100644 components/HotelReservation/SelectRate/SectionAccordion/index.tsx create mode 100644 components/HotelReservation/SelectRate/SectionAccordion/sectionAccordion.module.css create mode 100644 components/HotelReservation/SelectRate/Summary/index.tsx create mode 100644 components/HotelReservation/SelectRate/Summary/summary.module.css create mode 100644 types/components/hotelReservation/selectRate/flexibilityOption.ts delete mode 100644 types/components/hotelReservation/selectRate/roomSelection.ts create mode 100644 types/components/hotelReservation/selectRate/section.ts create mode 100644 types/components/hotelReservation/selectRate/sectionAccordion.ts diff --git a/app/[lang]/(live)/(public)/hotelreservation/select-rate/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.module.css similarity index 61% rename from app/[lang]/(live)/(public)/hotelreservation/select-rate/page.module.css rename to app/[lang]/(live)/(public)/hotelreservation/[section]/page.module.css index d6c36de71..3266c418d 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/select-rate/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.module.css @@ -1,7 +1,3 @@ -.hotelInfo { - margin-bottom: 64px; -} - .page { min-height: 100dvh; padding-top: var(--Spacing-x6); @@ -12,6 +8,18 @@ .content { max-width: 1134px; + margin-top: var(--Spacing-x5); margin-left: auto; margin-right: auto; + display: flex; + justify-content: space-between; + gap: var(--Spacing-x7); +} + +.main { + flex-grow: 1; +} + +.summary { + max-width: 340px; } diff --git a/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx new file mode 100644 index 000000000..93a46d618 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx @@ -0,0 +1,188 @@ +import { notFound } from "next/navigation" + +import { serverClient } from "@/lib/trpc/server" + +import HotelCard from "@/components/HotelReservation/HotelCard" +import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection" +import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection" +import Details from "@/components/HotelReservation/SelectRate/Details" +import Payment from "@/components/HotelReservation/SelectRate/Payment" +import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection" +import SectionAccordion from "@/components/HotelReservation/SelectRate/SectionAccordion" +import Summary from "@/components/HotelReservation/SelectRate/Summary" +import { getIntl } from "@/i18n" +import { setLang } from "@/i18n/serverContext" + +import styles from "./page.module.css" + +import { SectionPageProps } from "@/types/components/hotelReservation/selectRate/section" +import { LangParams, PageArgs } from "@/types/params" + +const bedAlternatives = [ + { + value: "queen", + name: "Queen bed", + payment: "160 cm", + pricePerNight: 0, + membersPricePerNight: 0, + currency: "SEK", + }, + { + value: "king", + name: "King bed", + payment: "160 cm", + pricePerNight: 0, + membersPricePerNight: 0, + currency: "SEK", + }, + { + value: "twin", + name: "Twin bed", + payment: "90 cm + 90 cm", + pricePerNight: 82, + membersPricePerNight: 67, + currency: "SEK", + }, +] + +const breakfastAlternatives = [ + { + value: "no", + name: "No breakfast", + payment: "Always cheeper to get it online", + pricePerNight: 0, + currency: "SEK", + }, + { + value: "buffe", + name: "Breakfast buffé", + payment: "Always cheeper to get it online", + pricePerNight: 150, + currency: "SEK", + }, +] + +const getFlexibilityMessage = (value: string) => { + switch (value) { + case "non-refundable": + return "Non refundable" + case "free-rebooking": + return "Free rebooking" + case "free-cancellation": + return "Free cancellation" + } + return undefined +} + +export default async function SectionsPage({ + params, + searchParams, +}: PageArgs) { + setLang(params.lang) + + // TODO: pass the correct hotel ID + const hotelResponse = await serverClient().hotel.get({ + hotelId: "879", + language: params.lang, + }) + if (!hotelResponse) { + return notFound() + } + const { hotel } = hotelResponse + const rooms = await serverClient().hotel.rates.get({ + // TODO: pass the correct hotel ID and all other parameters that should be included in the search + hotelId: "1", + }) + const intl = await getIntl() + + const selectedBed = searchParams.bed + ? bedAlternatives.find((a) => a.value === searchParams.bed)?.name + : undefined + + const selectedBreakfast = searchParams.breakfast + ? breakfastAlternatives.find((a) => a.value === searchParams.breakfast) + ?.name + : undefined + + const selectedRoom = searchParams.roomClass + ? rooms.find((room) => room.id.toString() === searchParams.roomClass)?.name + : undefined + const selectedFlexibility = searchParams.flexibility + ? getFlexibilityMessage(searchParams.flexibility) + : undefined + + const currentSearchParams = new URLSearchParams(searchParams).toString() + + return ( +
+ + +
+
+ + {params.section === "select-rate" && ( + + )} + + + {params.section === "select-bed" && ( + + )} + + + {params.section === "breakfast" && ( + + )} + + + {params.section === "details" &&
} + + + {params.section === "payment" && } + +
+
+ +
+
+
+ ) +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/select-rate/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/select-rate/page.tsx deleted file mode 100644 index 518fe667c..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/select-rate/page.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { serverClient } from "@/lib/trpc/server" -import tempHotelData from "@/server/routers/hotels/tempHotelData.json" - -import HotelCard from "@/components/HotelReservation/HotelCard" -import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection" -import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection" -import FlexibilitySelection from "@/components/HotelReservation/SelectRate/FlexibilitySelection" -import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection" -import { setLang } from "@/i18n/serverContext" - -import styles from "./page.module.css" - -import { LangParams, PageArgs } from "@/types/params" - -export default async function SelectRate({ params }: PageArgs) { - setLang(params.lang) - - // TODO: Use real endpoint. - const hotel = tempHotelData.data.attributes - - const rooms = await serverClient().hotel.rates.get({ - // TODO: pass the correct hotel ID and all other parameters that should be included in the search - hotelId: "1", - }) - - return ( -
-
-
- -
- - - - -
-
- ) -} diff --git a/components/HotelReservation/SelectRate/BedSelection/index.tsx b/components/HotelReservation/SelectRate/BedSelection/index.tsx index 784150d54..2d2d0d4a8 100644 --- a/components/HotelReservation/SelectRate/BedSelection/index.tsx +++ b/components/HotelReservation/SelectRate/BedSelection/index.tsx @@ -1,70 +1,54 @@ -import Header from "@/components/Section/Header" -import { getIntl } from "@/i18n" +"use client" +import { useRouter, useSearchParams } from "next/navigation" import SelectionCard from "../SelectionCard" import styles from "./bedSelection.module.css" -const choices = [ - { - value: "queen", - name: "Queen bed", - payment: "160 cm", - pricePerNight: 0, - membersPricePerNight: 0, - currency: "SEK", - }, - { - value: "king", - name: "King bed", - payment: "160 cm", - pricePerNight: 0, - membersPricePerNight: 0, - currency: "SEK", - }, - { - value: "twin", - name: "Twin bed", - payment: "90 cm + 90 cm", - pricePerNight: 82, - membersPricePerNight: 67, - currency: "SEK", - }, -] +import { BedSelectionProps } from "@/types/components/hotelReservation/selectRate/section" -export default async function BedSelection() { - const { formatMessage } = await getIntl() +export default function BedSelection({ + alternatives, + nextPath, +}: BedSelectionProps) { + const router = useRouter() + const searchParams = useSearchParams() + + function handleSubmit(e: React.FormEvent) { + e.preventDefault() + const queryParams = new URLSearchParams(searchParams) + queryParams.set("bed", e.currentTarget.bed?.value) + router.push(`${nextPath}?${queryParams}`) + } return (
-
-
-

- {formatMessage({ - id: "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.", - })} -

-
+
+
    + {alternatives.map((alternative) => ( +
  • + +
  • + ))} +
-
    - {choices.map((choice) => ( -
  • - -
  • - ))} -
+ +
) } diff --git a/components/HotelReservation/SelectRate/BreakfastSelection/index.tsx b/components/HotelReservation/SelectRate/BreakfastSelection/index.tsx index 7183d19e8..7cdce91f1 100644 --- a/components/HotelReservation/SelectRate/BreakfastSelection/index.tsx +++ b/components/HotelReservation/SelectRate/BreakfastSelection/index.tsx @@ -1,56 +1,57 @@ -import Header from "@/components/Section/Header" -import { getIntl } from "@/i18n" +"use client" +import { useRouter, useSearchParams } from "next/navigation" import SelectionCard from "../SelectionCard" import styles from "./breakfastSelection.module.css" -const choices = [ - { - value: "no", - name: "No breakfast", - payment: "Always cheeper to get it online", - pricePerNight: 0, - currency: "SEK", - }, - { - value: "buffe", - name: "Breakfast buffé", - payment: "Always cheeper to get it online", - pricePerNight: 150, - currency: "SEK", - }, -] +import { BreakfastSelectionProps } from "@/types/components/hotelReservation/selectRate/section" -export default async function BreakfastSelection() { - const { formatMessage } = await getIntl() +export default function BreakfastSelection({ + alternatives, + nextPath, +}: BreakfastSelectionProps) { + const router = useRouter() + const searchParams = useSearchParams() + + function handleSubmit(e: React.FormEvent) { + e.preventDefault() + const queryParams = new URLSearchParams(searchParams) + queryParams.set("breakfast", e.currentTarget.breakfast?.value) + router.push(`${nextPath}?${queryParams}`) + } return (
-
-
-
+
+
    + {alternatives.map((alternative) => ( +
  • + +
  • + ))} +
-
    - {choices.map((choice) => ( -
  • - -
  • - ))} -
+ +
) } diff --git a/components/HotelReservation/SelectRate/Details/details.module.css b/components/HotelReservation/SelectRate/Details/details.module.css new file mode 100644 index 000000000..ec81ef8e9 --- /dev/null +++ b/components/HotelReservation/SelectRate/Details/details.module.css @@ -0,0 +1,2 @@ +.wrapper { +} diff --git a/components/HotelReservation/SelectRate/Details/index.tsx b/components/HotelReservation/SelectRate/Details/index.tsx new file mode 100644 index 000000000..0b2dee1a1 --- /dev/null +++ b/components/HotelReservation/SelectRate/Details/index.tsx @@ -0,0 +1,6 @@ +"use client" +import styles from "./details.module.css" + +export default function Details() { + return
Details TBI
+} diff --git a/components/HotelReservation/SelectRate/FlexibilitySelection/flexibilitySelection.module.css b/components/HotelReservation/SelectRate/FlexibilitySelection/flexibilitySelection.module.css deleted file mode 100644 index 6c6a80b90..000000000 --- a/components/HotelReservation/SelectRate/FlexibilitySelection/flexibilitySelection.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.wrapper { - border-bottom: 1px solid rgba(17, 17, 17, 0.2); - padding-bottom: var(--Spacing-x3); -} - -.header { - margin-top: var(--Spacing-x2); - margin-bottom: var(--Spacing-x2); -} - -.list { - margin-top: var(--Spacing-x4); - list-style: none; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - column-gap: var(--Spacing-x2); - row-gap: var(--Spacing-x4); -} - -.list > li { - width: 100%; -} - -.list input[type="radio"] { - opacity: 0; - position: fixed; - width: 0; -} diff --git a/components/HotelReservation/SelectRate/FlexibilitySelection/index.tsx b/components/HotelReservation/SelectRate/FlexibilitySelection/index.tsx deleted file mode 100644 index 592732f86..000000000 --- a/components/HotelReservation/SelectRate/FlexibilitySelection/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import Header from "@/components/Section/Header" -import { getIntl } from "@/i18n" - -import SelectionCard from "../SelectionCard" - -import styles from "./flexibilitySelection.module.css" - -const choices = [ - { - value: "non-refundable", - name: "Non refundable", - payment: "Pay now", - pricePerNight: 0, - membersPricePerNight: 0, - currency: "SEK", - }, - { - value: "rebook", - name: "Free rebooking", - payment: "Pay now", - pricePerNight: 77, - membersPricePerNight: 20, - currency: "SEK", - }, - { - value: "cancellation", - name: "Free cancellation", - payment: "Pay later", - pricePerNight: 132, - membersPricePerNight: 80, - currency: "SEK", - }, -] - -export default async function FlexibilitySelection() { - const { formatMessage } = await getIntl() - - return ( -
-
-
-
- -
    - {choices.map((choice) => ( -
  • - -
  • - ))} -
-
- ) -} diff --git a/components/HotelReservation/SelectRate/Payment/index.tsx b/components/HotelReservation/SelectRate/Payment/index.tsx new file mode 100644 index 000000000..a9915a310 --- /dev/null +++ b/components/HotelReservation/SelectRate/Payment/index.tsx @@ -0,0 +1,6 @@ +"use client" +import styles from "./payment.module.css" + +export default function Payment() { + return
Payment TBI
+} diff --git a/components/HotelReservation/SelectRate/Payment/payment.module.css b/components/HotelReservation/SelectRate/Payment/payment.module.css new file mode 100644 index 000000000..ec81ef8e9 --- /dev/null +++ b/components/HotelReservation/SelectRate/Payment/payment.module.css @@ -0,0 +1,2 @@ +.wrapper { +} diff --git a/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/flexibilityOption.module.css b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/flexibilityOption.module.css new file mode 100644 index 000000000..cf6c7b165 --- /dev/null +++ b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/flexibilityOption.module.css @@ -0,0 +1,15 @@ +.card { + font-size: 14px; + border-radius: var(--Corner-radius-Medium); + border: 1px solid var(--Base-Border-Normal); + padding: var(--Spacing-x-one-and-half) var(--Spacing-x2); +} + +input[type="radio"]:checked + .card { + background-color: var(--Base-Surface-Primary-light-Hover-alt); +} + +.header { + display: flex; + justify-content: space-between; +} diff --git a/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx new file mode 100644 index 000000000..5760c219f --- /dev/null +++ b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx @@ -0,0 +1,45 @@ +"use client" +import { useIntl } from "react-intl" + +import Body from "@/components/TempDesignSystem/Text/Body" +import Caption from "@/components/TempDesignSystem/Text/Caption" + +import styles from "./flexibilityOption.module.css" + +import { FlexibilityOptionProps } from "@/types/components/hotelReservation/selectRate/flexibilityOption" + +export default function FlexibilityOption({ + currency, + standardPrice, + memberPrice, + name, + value, + paymentTerm, +}: FlexibilityOptionProps) { + const intl = useIntl() + return ( + + ) +} diff --git a/components/HotelReservation/SelectRate/RoomSelection/RoomCard/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/RoomCard/index.tsx index 38f8bfc55..ea4c0540c 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/RoomCard/index.tsx +++ b/components/HotelReservation/SelectRate/RoomSelection/RoomCard/index.tsx @@ -1,49 +1,92 @@ +"use client" +import { useIntl } from "react-intl" + +import FlexibilityOption from "@/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption" import Button from "@/components/TempDesignSystem/Button" import Caption from "@/components/TempDesignSystem/Text/Caption" -import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" +import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import styles from "./roomCard.module.css" import { RoomCardProps } from "@/types/components/hotelReservation/selectRate/roomCard" -export default async function RoomCard({ room }: RoomCardProps) { - const { formatMessage } = await getIntl() +export default function RoomCard({ + room, + nrOfAdults, + nrOfNights, + breakfastIncluded, +}: RoomCardProps) { + const intl = useIntl() return (
-
- + <div className={styles.specification}> + <Subtitle className={styles.name} type="two"> {room.name} - -
i
+ + {room.size} + + + {/*TODO: Handle pluralisation*/} + {intl.formatMessage( + { + id: "Nr night, nr adult", + defaultMessage: + "{nights, number} night, {adults, number} adult", + }, + { nights: nrOfNights, adults: nrOfAdults } + )} + {" | "} + {breakfastIncluded + ? intl.formatMessage({ + id: "Breakfast included", + }) + : intl.formatMessage({ + id: "Breakfast excluded", + })} +
- {room.size} - {room.description} - - {/* TODO: Handle currency and this whole line of text in a better way through intl */} - {formatMessage({ id: "From" })}{" "} - {room.pricePerNight}{" "} - {room.currency}/{formatMessage({ id: "night" })} - + + +
{/* TODO: maybe use the `Image` component instead of the `img` tag. Waiting until we know how to get the image */} {/* eslint-disable-next-line @next/next/no-img-element */} {formatMessage({
diff --git a/components/HotelReservation/SelectRate/RoomSelection/RoomCard/roomCard.module.css b/components/HotelReservation/SelectRate/RoomSelection/RoomCard/roomCard.module.css index b657f057e..3102b1c3a 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/RoomCard/roomCard.module.css +++ b/components/HotelReservation/SelectRate/RoomSelection/RoomCard/roomCard.module.css @@ -1,6 +1,5 @@ .card { font-size: 14px; - text-align: center; display: flex; flex-direction: column-reverse; background-color: #fff; @@ -8,12 +7,15 @@ border: 1px solid rgba(77, 0, 27, 0.1); } -input[type="radio"]:checked + .card { - border: 3px solid var(--Scandic-Brand-Scandic-Red); +.cardBody { + padding: var(--Spacing-x1); + display: flex; + flex-direction: column; + gap: var(--Spacing-x1); } -.cardBody { - padding: var(--Spacing-x2); +.specification { + padding: var(--Spacing-x1); display: flex; flex-direction: column; gap: var(--Spacing-x1); @@ -22,15 +24,6 @@ input[type="radio"]:checked + .card { .name { display: inline-block; } -.nameInfo { - float: right; -} - -.price { - font-size: 24px; - font-weight: 600; - text-align: center; -} .card .button { display: inline; @@ -38,6 +31,6 @@ input[type="radio"]:checked + .card { .card img { max-width: 100%; - aspect-ratio: 2.45; + aspect-ratio: 1.5; object-fit: cover; } diff --git a/components/HotelReservation/SelectRate/RoomSelection/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/index.tsx index 4e6588fa3..d1be37221 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/index.tsx +++ b/components/HotelReservation/SelectRate/RoomSelection/index.tsx @@ -1,42 +1,52 @@ -import Header from "@/components/Section/Header" -import { getIntl } from "@/i18n" +"use client" +import { useRouter, useSearchParams } from "next/navigation" import RoomCard from "./RoomCard" import styles from "./roomSelection.module.css" -import { RoomSelectionProps } from "@/types/components/hotelReservation/selectRate/roomSelection" +import { RoomSelectionProps } from "@/types/components/hotelReservation/selectRate/section" -export default async function RoomSelection({ rooms }: RoomSelectionProps) { - const { formatMessage } = await getIntl() +export default function RoomSelection({ + alternatives, + nextPath, + nrOfNights, + nrOfAdults, +}: RoomSelectionProps) { + const router = useRouter() + const searchParams = useSearchParams() + + function handleSubmit(e: React.FormEvent) { + e.preventDefault() + const queryParams = new URLSearchParams(searchParams) + queryParams.set("roomClass", e.currentTarget.roomClass?.value) + queryParams.set("flexibility", e.currentTarget.flexibility?.value) + router.push(`${nextPath}?${queryParams}`) + } return (
-
-
-
-
    - {rooms.map((room) => ( + {alternatives.map((room) => (
  • - - +
    + + +
  • ))}
diff --git a/components/HotelReservation/SelectRate/RoomSelection/roomSelection.module.css b/components/HotelReservation/SelectRate/RoomSelection/roomSelection.module.css index 259232c67..5a1dfd7c8 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/roomSelection.module.css +++ b/components/HotelReservation/SelectRate/RoomSelection/roomSelection.module.css @@ -2,16 +2,12 @@ border-bottom: 1px solid rgba(17, 17, 17, 0.2); padding-bottom: var(--Spacing-x3); } -.header { - margin-top: var(--Spacing-x2); - margin-bottom: var(--Spacing-x2); -} .roomList { margin-top: var(--Spacing-x4); list-style: none; display: grid; - grid-template-columns: 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: var(--Spacing-x2); row-gap: var(--Spacing-x4); } diff --git a/components/HotelReservation/SelectRate/SectionAccordion/index.tsx b/components/HotelReservation/SelectRate/SectionAccordion/index.tsx new file mode 100644 index 000000000..94ae62f21 --- /dev/null +++ b/components/HotelReservation/SelectRate/SectionAccordion/index.tsx @@ -0,0 +1,48 @@ +import { CheckCircleIcon, ChevronDownIcon } from "@/components/Icons" +import Button from "@/components/TempDesignSystem/Button" +import Link from "@/components/TempDesignSystem/Link" +import Body from "@/components/TempDesignSystem/Text/Body" +import Caption from "@/components/TempDesignSystem/Text/Caption" +import { getIntl } from "@/i18n" + +import styles from "./sectionAccordion.module.css" + +import { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion" + +export default async function SectionAccordion({ + header, + selection, + path, + children, +}: React.PropsWithChildren) { + const intl = await getIntl() + + return ( +
+
+
+ +
+
+ +

{header}

+ + {(Array.isArray(selection) ? selection : [selection]).map((s) => ( + + {s} + + ))} +
+ {selection && ( + + )} +
+ +
+
+ {children} +
+ ) +} diff --git a/components/HotelReservation/SelectRate/SectionAccordion/sectionAccordion.module.css b/components/HotelReservation/SelectRate/SectionAccordion/sectionAccordion.module.css new file mode 100644 index 000000000..ce9dec013 --- /dev/null +++ b/components/HotelReservation/SelectRate/SectionAccordion/sectionAccordion.module.css @@ -0,0 +1,21 @@ +.wrapper { + border-bottom: 1px solid var(--Base-Border-Normal); +} + +.top { + padding-bottom: var(--Spacing-x3); + padding-top: var(--Spacing-x3); + display: flex; + justify-content: space-between; + align-items: center; + gap: var(--Spacing-x2); +} + +.header { + flex-grow: 1; +} + +.selection { + font-weight: 450; + font-size: var(--typography-Title-4-fontSize); +} diff --git a/components/HotelReservation/SelectRate/SelectionCard/index.tsx b/components/HotelReservation/SelectRate/SelectionCard/index.tsx index 144a164a0..bf3b8caeb 100644 --- a/components/HotelReservation/SelectRate/SelectionCard/index.tsx +++ b/components/HotelReservation/SelectRate/SelectionCard/index.tsx @@ -1,19 +1,21 @@ +"use client" +import { useIntl } from "react-intl" + import Caption from "@/components/TempDesignSystem/Text/Caption" import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" import styles from "./selectionCard.module.css" import { SelectionCardProps } from "@/types/components/hotelReservation/selectRate/selectionCard" -export default async function SelectionCard({ +export default function SelectionCard({ price, membersPrice, currency, title, subtext, }: SelectionCardProps) { - const { formatMessage } = await getIntl() + const intl = useIntl() return (
@@ -28,13 +30,13 @@ export default async function SelectionCard({
{/* TODO: Handle currency and this whole line of text in a better way through intl */} - {price} {currency}/{formatMessage({ id: "night" })} + {price} {currency}/{intl.formatMessage({ id: "night" })} {/* TODO: Handle currency and this whole line of text in a better way through intl */} - {formatMessage({ id: "Members" })} {membersPrice} {currency}/ - {formatMessage({ id: "night" })} + {intl.formatMessage({ id: "Members" })} {membersPrice} {currency}/ + {intl.formatMessage({ id: "night" })}
diff --git a/components/HotelReservation/SelectRate/Summary/index.tsx b/components/HotelReservation/SelectRate/Summary/index.tsx new file mode 100644 index 000000000..1cff67248 --- /dev/null +++ b/components/HotelReservation/SelectRate/Summary/index.tsx @@ -0,0 +1,6 @@ +"use client" +import styles from "./summary.module.css" + +export default function Summary() { + return
Summary TBI
+} diff --git a/components/HotelReservation/SelectRate/Summary/summary.module.css b/components/HotelReservation/SelectRate/Summary/summary.module.css new file mode 100644 index 000000000..ec81ef8e9 --- /dev/null +++ b/components/HotelReservation/SelectRate/Summary/summary.module.css @@ -0,0 +1,2 @@ +.wrapper { +} diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index dcef5e33c..c5efa0a8d 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -4,8 +4,6 @@ "Add code": "Tilføj kode", "Add new card": "Tilføj nyt kort", "Address": "Adresse", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "Alle vores senge er fra Bliss, så du kan justere fastheden til din perfekte komfort.", - "All rooms comes with standard amenities": "Alle værelser er udstyret med standardfaciliteter", "Already a friend?": "Allerede en ven?", "Amenities": "Faciliteter", "An error occurred when adding a credit card, please try again later.": "Der opstod en fejl under tilføjelse af et kreditkort. Prøv venligst igen senere.", @@ -17,11 +15,14 @@ "As our Close Friend": "Som vores nære ven", "At latest": "Senest", "At the hotel": "På hotellet", + "Bed type": "Seng type", "Book": "Book", "Book reward night": "Book bonusnat", "Booking codes and vouchers": "Bookingkoder og vouchers", "Booking number": "Bookingnummer", "Breakfast": "Morgenmad", + "Breakfast excluded": "Morgenmad ikke inkluderet", + "Breakfast included": "Morgenmad inkluderet", "by": "inden", "Cancel": "Afbestille", "characters": "tegn", @@ -29,7 +30,6 @@ "Check out": "Check ud", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.", "Choose room": "Vælg rum", - "Choose type of bed": "Vælg type seng", "City": "By", "City/State": "By/Stat", "Click here to log in": "Klik her for at logge ind", @@ -47,7 +47,6 @@ "Day": "Dag", "Description": "Beskrivelse", "Discard changes": "Kassér ændringer", - "Do you want to start the day with Scandics famous breakfast buffé?": "Vil du starte dagen med Scandics berømte morgenbuffet?", "Download the Scandic app": "Download Scandic-appen", "Edit": "Redigere", "Edit profile": "Rediger profil", @@ -59,6 +58,8 @@ "Find hotels": "Find hotel", "Flexibility": "Fleksibilitet", "Former Scandic Hotel": "Tidligere Scandic Hotel", + "Free cancellation": "Gratis afbestilling", + "Free rebooking": "Gratis ombooking", "From": "Fra", "from your member profile?": "fra din medlemsprofil?", "Get inspired": "Bliv inspireret", @@ -66,7 +67,6 @@ "Highest level": "Højeste niveau", "Hotel facilities": "Hotel faciliteter", "Hotel surroundings": "Hotel omgivelser", - "How do you want to sleep?": "Hvordan vil du sove?", "How it works": "Hvordan det virker", "Join Scandic Friends": "Tilmeld dig Scandic Friends", "Language": "Sprog", @@ -84,9 +84,11 @@ "Log out": "Log ud", "Manage preferences": "Administrer præferencer", "Meetings & Conferences": "Møder & Konferencer", + "Member price": "Medlemspris", "Members": "Medlemmer", "Membership cards": "Medlemskort", "Membership ID": "Medlems-id", + "Modify": "Ændre", "Month": "Måned", "My communication preferences": "Mine kommunikationspræferencer", "My credit cards": "Mine kreditkort", @@ -102,13 +104,19 @@ "No content published": "Intet indhold offentliggjort", "No transactions available": "Ingen tilgængelige transaktioner", "No, keep card": "Nej, behold kortet", + "Non refundable": "Ikke-refunderbart", + "Non-refundable": "Ikke-refunderbart", "Not found": "Ikke fundet", + "Nr night, nr adult": "{nights, number} nat, {adults, number} voksen", "number": "nummer", "On your journey": "På din rejse", "Open": "Åben", "or": "eller", "Overview": "Oversigt", "Password": "Adgangskode", + "Pay later": "Betal senere", + "Pay now": "Betal nu", + "Payment info": "Betalingsoplysninger", "Phone": "Telefon", "Phone is required": "Telefonnummer er påkrævet", "Phone number": "Telefonnummer", @@ -126,6 +134,7 @@ "Remove card from member profile": "Fjern kortet fra medlemsprofilen", "Restaurant & Bar": "Restaurant & Bar", "Retype new password": "Gentag den nye adgangskode", + "Room & Terms": "Værelse & Vilkår", "Room facilities": "Værelsesfaciliteter", "Rooms": "Værelser", "Rooms & Guests": "Værelser & gæster", @@ -147,6 +156,7 @@ "Something went wrong!": "Noget gik galt!", "special character": "speciel karakter", "spendable points expiring by": "{points} Brugbare point udløber den {date}", + "Standard price": "Standardpris", "Street": "Gade", "Successfully updated profile!": "Profilen er opdateret med succes!", "Summary": "Opsummering", @@ -177,7 +187,6 @@ "When": "Hvornår", "Where should you go next?": "Find inspiration til dit næste ophold", "Where to": "Hvor", - "Which room class suits you the best?": "Hvilken rumklasse passer bedst til dig", "Year": "År", "Yes, remove my card": "Ja, fjern mit kort", "You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.", @@ -187,6 +196,7 @@ "Your card was successfully saved!": "Dit kort blev gemt!", "Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!", "Your current level": "Dit nuværende niveau", + "Your details": "Dine oplysninger", "Your level": "Dit niveau", "Your points to spend": "Dine brugbare point", "Zip code": "Postnummer" diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index c5d3ef573..9de24aa0a 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -3,8 +3,6 @@ "Add code": "Code hinzufügen", "Add new card": "Neue Karte hinzufügen", "Address": "Adresse", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "Alle unsere Betten sind von Bliss, sodass Sie die Festigkeit für Ihren perfekten Komfort anpassen können.", - "All rooms comes with standard amenities": "Alle Zimmer sind mit den üblichen Annehmlichkeiten ausgestattet", "Already a friend?": "Sind wir schon Freunde?", "Amenities": "Annehmlichkeiten", "An error occurred when adding a credit card, please try again later.": "Beim Hinzufügen einer Kreditkarte ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.", @@ -16,11 +14,14 @@ "As our Close Friend": "Als unser enger Freund", "At latest": "Spätestens", "At the hotel": "Im Hotel", + "Bed type": "Bettentyp", "Book": "Buchen", "Book reward night": "Bonusnacht buchen", "Booking codes and vouchers": "Buchungscodes und Gutscheine", "Booking number": "Buchungsnummer", "Breakfast": "Frühstück", + "Breakfast excluded": "Frühstück nicht inbegriffen", + "Breakfast included": "Frühstück inbegriffen", "by": "bis", "Cancel": "Stornieren", "characters": "figuren", @@ -28,7 +29,6 @@ "Check out": "Auschecken", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.", "Choose room": "Zimmer wählen", - "Choose type of bed": "Wählen Sie den Bettentyp", "City": "Stadt", "City/State": "Stadt/Zustand", "Click here to log in": "Klicken Sie hier, um sich einzuloggen", @@ -46,7 +46,6 @@ "Day": "Tag", "Description": "Beschreibung", "Discard changes": "Änderungen verwerfen", - "Do you want to start the day with Scandics famous breakfast buffé?": "Möchten Sie den Tag mit Scandics berühmtem Frühstücksbuffet beginnen?", "Download the Scandic app": "Laden Sie die Scandic-App herunter", "Edit": "Bearbeiten", "Edit profile": "Profil bearbeiten", @@ -58,6 +57,8 @@ "Find hotels": "Hotels finden", "Flexibility": "Flexibilität", "Former Scandic Hotel": "Ehemaliges Scandic Hotel", + "Free cancellation": "Kostenlose Stornierung", + "Free rebooking": "Kostenlose Umbuchung", "From": "Fromm", "from your member profile?": "wirklich aus Ihrem Mitgliedsprofil entfernen?", "Get inspired": "Lassen Sie sich inspieren", @@ -65,7 +66,6 @@ "Highest level": "Höchstes Level", "Hotel facilities": "Hotel-Infos", "Hotel surroundings": "Umgebung des Hotels", - "How do you want to sleep?": "Wie möchtest du schlafen?", "How it works": "Wie es funktioniert", "Join Scandic Friends": "Treten Sie Scandic Friends bei", "Language": "Sprache", @@ -82,9 +82,11 @@ "Log in here": "Hier einloggen", "Log out": "Ausloggen", "Manage preferences": "Verwalten von Voreinstellungen", + "Member price": "Mitgliederpreis", "Members": "Mitglieder", "Membership cards": "Mitgliedskarten", "Membership ID": "Mitglieds-ID", + "Modify": "Ändern", "Month": "Monat", "My communication preferences": "Meine Kommunikationseinstellungen", "My credit cards": "Meine Kreditkarten", @@ -100,12 +102,18 @@ "No content published": "Kein Inhalt veröffentlicht", "No transactions available": "Keine Transaktionen verfügbar", "No, keep card": "Nein, Karte behalten", + "Non refundable": "Nicht erstattungsfähig", + "Non-refundable": "Nicht erstattungsfähig", "Not found": "Nicht gefunden", + "Nr night, nr adult": "{nights, number} Nacht, {adults, number} Erwachsener", "number": "nummer", "On your journey": "Auf deiner Reise", "Open": "Offen", "or": "oder", "Password": "Passwort", + "Pay later": "Später bezahlen", + "Pay now": "Jetzt bezahlen", + "Payment info": "Zahlungsinformationen", "Phone": "Telefon", "Phone is required": "Telefon ist erforderlich", "Phone number": "Telefonnummer", @@ -122,6 +130,7 @@ "Read more about the hotel": "Lesen Sie mehr über das Hotel", "Remove card from member profile": "Karte aus dem Mitgliedsprofil entfernen", "Retype new password": "Neues Passwort erneut eingeben", + "Room & Terms": "Zimmer & Bedingungen", "Room facilities": "Zimmerausstattung", "Rooms & Guests": "Zimmer & Gäste", "Save": "Speichern", @@ -142,6 +151,7 @@ "Something went wrong!": "Etwas ist schief gelaufen!", "special character": "sonderzeichen", "spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}", + "Standard price": "Standardpreis", "Street": "Straße", "Successfully updated profile!": "Profil erfolgreich aktualisiert!", "Summary": "Zusammenfassung", @@ -171,7 +181,6 @@ "When": "Wann", "Where should you go next?": "Wo geht es als Nächstes hin?", "Where to": "Wohin", - "Which room class suits you the best?": "Welche Zimmerklasse passt am besten zu Ihnen?", "Year": "Jahr", "Yes, remove my card": "Ja, meine Karte entfernen", "You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.", @@ -181,7 +190,8 @@ "Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!", "Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!", "Your current level": "Ihr aktuelles Level", + "Your details": "Ihre Angaben", "Your level": "Dein level", "Your points to spend": "Meine Punkte", "Zip code": "PLZ" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 9d10d7855..e93e834d1 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -4,8 +4,6 @@ "Add code": "Add code", "Add new card": "Add new card", "Address": "Address", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.", - "All rooms comes with standard amenities": "All rooms comes with standard amenities", "Already a friend?": "Already a friend?", "Amenities": "Amenities", "An error occurred when adding a credit card, please try again later.": "An error occurred when adding a credit card, please try again later.", @@ -17,11 +15,14 @@ "As our Close Friend": "As our Close Friend", "At latest": "At latest", "At the hotel": "At the hotel", + "Bed type": "Bed type", "Book": "Book", "Book reward night": "Book reward night", "Booking codes and vouchers": "Booking codes and vouchers", "Booking number": "Booking number", "Breakfast": "Breakfast", + "Breakfast excluded": "Breakfast excluded", + "Breakfast included": "Breakfast included", "by": "by", "Cancel": "Cancel", "characters": "characters", @@ -29,7 +30,6 @@ "Check out": "Check out", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.", "Choose room": "Choose room", - "Choose type of bed": "Choose type of bed", "City": "City", "City/State": "City/State", "Click here to log in": "Click here to log in", @@ -48,7 +48,6 @@ "Description": "Description", "Discard changes": "Discard changes", "Distance to city centre": "{number}km to city centre", - "Do you want to start the day with Scandics famous breakfast buffé?": "Do you want to start the day with Scandics famous breakfast buffé?", "Download the Scandic app": "Download the Scandic app", "Edit": "Edit", "Edit profile": "Edit profile", @@ -61,6 +60,8 @@ "Find hotels": "Find hotels", "Flexibility": "Flexibility", "Former Scandic Hotel": "Former Scandic Hotel", + "Free cancellation": "Free cancellation", + "Free rebooking": "Free rebooking", "From": "From", "from your member profile?": "from your member profile?", "Get inspired": "Get inspired", @@ -71,7 +72,6 @@ "hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "persons", "hotelPages.rooms.roomCard.seeRoomDetails": "See room details", - "How do you want to sleep?": "How do you want to sleep?", "How it works": "How it works", "Join Scandic Friends": "Join Scandic Friends", "Language": "Language", @@ -89,9 +89,11 @@ "Log out": "Log out", "Manage preferences": "Manage preferences", "Meetings & Conferences": "Meetings & Conferences", + "Member price": "Member price", "Members": "Members", "Membership cards": "Membership cards", "Membership ID": "Membership ID", + "Modify": "Modify", "Month": "Month", "My communication preferences": "My communication preferences", "My credit cards": "My credit cards", @@ -107,13 +109,19 @@ "No content published": "No content published", "No transactions available": "No transactions available", "No, keep card": "No, keep card", + "Non refundable": "Non refundable", + "Non-refundable": "Non-refundable", "Not found": "Not found", + "Nr night, nr adult": "{nights, number} night, {adults, number} adult", "number": "number", "On your journey": "On your journey", "Open": "Open", "or": "or", "Overview": "Overview", "Password": "Password", + "Pay later": "Pay later", + "Pay now": "Pay now", + "Payment info": "Payment info", "Phone": "Phone", "Phone is required": "Phone is required", "Phone number": "Phone number", @@ -131,6 +139,7 @@ "Remove card from member profile": "Remove card from member profile", "Restaurant & Bar": "Restaurant & Bar", "Retype new password": "Retype new password", + "Room & Terms": "Room & Terms", "Room facilities": "Room facilities", "Rooms": "Rooms", "Rooms & Guests": "Rooms & Guests", @@ -153,6 +162,7 @@ "Something went wrong!": "Something went wrong!", "special character": "special character", "spendable points expiring by": "{points} spendable points expiring by {date}", + "Standard price": "Standard price", "Street": "Street", "Successfully updated profile!": "Successfully updated profile!", "Summary": "Summary", @@ -183,7 +193,6 @@ "When": "When", "Where should you go next?": "Where should you go next?", "Where to": "Where to", - "Which room class suits you the best?": "Which room class suits you the best?", "Year": "Year", "Yes, remove my card": "Yes, remove my card", "You canceled adding a new credit card.": "You canceled adding a new credit card.", @@ -193,6 +202,7 @@ "Your card was successfully saved!": "Your card was successfully saved!", "Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!", "Your current level": "Your current level", + "Your details": "Your details", "Your level": "Your level", "Your points to spend": "Your points to spend", "Zip code": "Zip code" diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index d421d976a..1a24a14ab 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -4,8 +4,6 @@ "Add code": "Lisää koodi", "Add new card": "Lisää uusi kortti", "Address": "Osoite", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "Kaikki sänkymme ovat Bliss, joten voit säätää kiinteyttä täydelliseen mukavuuteen.", - "All rooms comes with standard amenities": "Kaikissa huoneissa on perusmukavuudet", "Already a friend?": "Oletko jo ystävä?", "Amenities": "Mukavuudet", "An error occurred when adding a credit card, please try again later.": "Luottokorttia lisättäessä tapahtui virhe. Yritä myöhemmin uudelleen.", @@ -17,11 +15,14 @@ "As our Close Friend": "Läheisenä ystävänämme", "At latest": "Viimeistään", "At the hotel": "Hotellissa", + "Bed type": "Vuodetyyppi", "Book": "Varaa", "Book reward night": "Kirjapalkinto-ilta", "Booking codes and vouchers": "Varauskoodit ja kupongit", "Booking number": "Varausnumero", "Breakfast": "Aamiainen", + "Breakfast excluded": "Aamiainen ei sisälly", + "Breakfast included": "Aamiainen sisältyy", "by": "mennessä", "Cancel": "Peruuttaa", "characters": "hahmoja", @@ -29,7 +30,6 @@ "Check out": "Uloskirjautuminen", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.", "Choose room": "Valitse huone", - "Choose type of bed": "Valitse sänkytyyppi", "City": "Kaupunki", "City/State": "Kaupunki/Osavaltio", "Click here to log in": "Napsauta tästä kirjautuaksesi sisään", @@ -47,7 +47,6 @@ "Day": "Päivä", "Description": "Kuvaus", "Discard changes": "Hylkää muutokset", - "Do you want to start the day with Scandics famous breakfast buffé?": "Haluatko aloittaa päiväsi Scandicsin kuuluisalla aamiaisbuffella?", "Download the Scandic app": "Lataa Scandic-sovellus", "Edit": "Muokata", "Edit profile": "Muokkaa profiilia", @@ -59,6 +58,8 @@ "Find hotels": "Etsi hotelleja", "Flexibility": "Joustavuus", "Former Scandic Hotel": "Entinen Scandic-hotelli", + "Free cancellation": "Ilmainen peruutus", + "Free rebooking": "Ilmainen uudelleenvaraus", "From": "From", "from your member profile?": "jäsenprofiilistasi?", "Get inspired": "Inspiroidu", @@ -66,7 +67,6 @@ "Highest level": "Korkein taso", "Hotel facilities": "Hotellin palvelut", "Hotel surroundings": "Hotellin ympäristö", - "How do you want to sleep?": "Kuinka haluat nukkua?", "How it works": "Kuinka se toimii", "Join Scandic Friends": "Liity jäseneksi", "Language": "Kieli", @@ -84,9 +84,11 @@ "Log out": "Kirjaudu ulos", "Manage preferences": "Asetusten hallinta", "Meetings & Conferences": "Kokoukset & Konferenssit", + "Member price": "Jäsenhinta", "Members": "Jäsenet", "Membership cards": "Jäsenkortit", "Membership ID": "Jäsentunnus", + "Modify": "Muokkaa", "Month": "Kuukausi", "My communication preferences": "Viestintämieltymykseni", "My credit cards": "Luottokorttini", @@ -102,13 +104,19 @@ "No content published": "Ei julkaistua sisältöä", "No transactions available": "Ei tapahtumia saatavilla", "No, keep card": "Ei, pidä kortti", + "Non refundable": "Ei palautettavissa", + "Non-refundable": "Ei palautettavissa", "Not found": "Ei löydetty", + "Nr night, nr adult": "{nights, number} yö, {adults, number} aikuinen", "number": "määrä", "On your journey": "Matkallasi", "Open": "Avata", "or": "tai", "Overview": "Yleiskatsaus", "Password": "Salasana", + "Pay later": "Maksa myöhemmin", + "Pay now": "Maksa nyt", + "Payment info": "Maksutiedot", "Phone": "Puhelin", "Phone is required": "Puhelin vaaditaan", "Phone number": "Puhelinnumero", @@ -120,11 +128,13 @@ "Points may take up to 10 days to be displayed.": "Pisteiden näyttäminen voi kestää jopa 10 päivää.", "Points needed to level up": "Tarvitset vielä", "Points needed to stay on level": "Tällä tasolla pysymiseen tarvittavat pisteet", + "Previous victories": "Edelliset voitot", "Read more": "Lue lisää", "Read more about the hotel": "Lue lisää hotellista", "Remove card from member profile": "Poista kortti jäsenprofiilista", "Restaurant & Bar": "Ravintola & Baari", "Retype new password": "Kirjoita uusi salasana uudelleen", + "Room & Terms": "Huone & Ehdot", "Room facilities": "Huoneen varustelu", "Rooms": "Huoneet", "Rooms & Guestss": "Huoneet & Vieraat", @@ -146,6 +156,7 @@ "Something went wrong!": "Jotain meni pieleen!", "special character": "erikoishahmo", "spendable points expiring by": "{points} pistettä vanhenee {date} mennessä", + "Standard price": "Normaali hinta", "Street": "Katu", "Successfully updated profile!": "Profiilin päivitys onnistui!", "Summary": "Yhteenveto", @@ -176,7 +187,6 @@ "When": "Kun", "Where should you go next?": "Mihin menisit seuraavaksi?", "Where to": "Minne", - "Which room class suits you the best?": "Mikä huoneluokka sopii sinulle parhaiten?", "Year": "Vuosi", "Yes, remove my card": "Kyllä, poista korttini", "You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.", @@ -186,6 +196,7 @@ "Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!", "Your Challenges Conquer & Earn!": "Voita ja ansaitse haasteesi!", "Your current level": "Nykyinen tasosi", + "Your details": "Tietosi", "Your level": "Tasosi", "Your points to spend": "Käytettävissä olevat pisteesi", "Zip code": "Postinumero" diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index 5fc40010e..0f669ed51 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -4,8 +4,6 @@ "Add code": "Legg til kode", "Add new card": "Legg til nytt kort", "Address": "Adresse", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "Alle sengene våre er fra Bliss, slik at du kan justere fastheten for din perfekte komfort.", - "All rooms comes with standard amenities": "Alle rommene har standard fasiliteter", "Already a friend?": "Allerede Friend?", "Amenities": "Fasiliteter", "An error occurred when adding a credit card, please try again later.": "Det oppstod en feil ved å legge til et kredittkort. Prøv igjen senere.", @@ -17,11 +15,14 @@ "As our Close Friend": "Som vår nære venn", "At latest": "Senest", "At the hotel": "På hotellet", + "Bed type": "Seng type", "Book": "Bestill", "Book reward night": "Bestill belønningskveld", "Booking codes and vouchers": "Bestillingskoder og kuponger", "Booking number": "Bestillingsnummer", "Breakfast": "Frokost", + "Breakfast excluded": "Frokost ekskludert", + "Breakfast included": "Frokost inkludert", "by": "innen", "Cancel": "Avbryt", "characters": "tegn", @@ -29,7 +30,6 @@ "Check out": "Sjekk ut", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.", "Choose room": "Velg rom", - "Choose type of bed": "Velg type seng", "City": "By", "City/State": "By/Stat", "Click here to log in": "Klikk her for å logge inn", @@ -47,7 +47,6 @@ "Day": "Dag", "Description": "Beskrivelse", "Discard changes": "Forkaste endringer", - "Do you want to start the day with Scandics famous breakfast buffé?": "Vil du starte dagen med Scandics berømte frokostbuffé?", "Download the Scandic app": "Last ned Scandic-appen", "Edit": "Redigere", "Edit profile": "Rediger profil", @@ -59,6 +58,8 @@ "Find hotels": "Finn hotell", "Flexibility": "Fleksibilitet", "Former Scandic Hotel": "Tidligere Scandic-hotell", + "Free cancellation": "Gratis avbestilling", + "Free rebooking": "Gratis ombooking", "From": "Fra", "from your member profile?": "fra medlemsprofilen din?", "Get inspired": "Bli inspirert", @@ -66,7 +67,6 @@ "Highest level": "Høyeste nivå", "Hotel facilities": "Hotelfaciliteter", "Hotel surroundings": "Hotellomgivelser", - "How do you want to sleep?": "Hvordan vil du sove?", "How it works": "Hvordan det fungerer", "Join Scandic Friends": "Bli med i Scandic Friends", "Language": "Språk", @@ -84,9 +84,11 @@ "Log out": "Logg ut", "Manage preferences": "Administrer preferanser", "Meetings & Conferences": "Møter & Konferanser", + "Member price": "Medlemspris", "Members": "Medlemmer", "Membership cards": "Medlemskort", "Membership ID": "Medlems-ID", + "Modify": "Endre", "Month": "Måned", "My communication preferences": "Mine kommunikasjonspreferanser", "My credit cards": "Kredittkortene mine", @@ -102,13 +104,19 @@ "No content published": "Ingen innhold publisert", "No transactions available": "Ingen transaksjoner tilgjengelig", "No, keep card": "Nei, behold kortet", + "Non refundable": "Ikke-refunderbart", + "Non-refundable": "Ikke-refunderbart", "Not found": "Ikke funnet", + "Nr night, nr adult": "{nights, number} natt, {adults, number} voksen", "number": "antall", "On your journey": "På reisen din", "Open": "Åpen", "or": "eller", "Overview": "Oversikt", "Password": "Passord", + "Pay later": "Betal senere", + "Pay now": "Betal nå", + "Payment info": "Betalingsinformasjon", "Phone": "Telefon", "Phone is required": "Telefon kreves", "Phone number": "Telefonnummer", @@ -126,6 +134,7 @@ "Remove card from member profile": "Fjern kortet fra medlemsprofilen", "Restaurant & Bar": "Restaurant & Bar", "Retype new password": "Skriv inn nytt passord på nytt", + "Room & Terms": "Rom & Vilkår", "Room facilities": "Romfasiliteter", "Rooms": "Rom", "Rooms & Guests": "Rom og gjester", @@ -147,6 +156,7 @@ "Something went wrong!": "Noe gikk galt!", "special character": "spesiell karakter", "spendable points expiring by": "{points} Brukbare poeng utløper innen {date}", + "Standard price": "Standardpris", "Street": "Gate", "Successfully updated profile!": "Vellykket oppdatert profil!", "Summary": "Sammendrag", @@ -177,7 +187,6 @@ "When": "Når", "Where should you go next?": "Hvor ønsker du å reise neste gang?", "Where to": "Hvor skal du", - "Which room class suits you the best?": "Hvilken romklasse passer deg best?", "Year": "År", "Yes, remove my card": "Ja, fjern kortet mitt", "You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.", @@ -187,6 +196,7 @@ "Your card was successfully saved!": "Kortet ditt ble lagret!", "Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!", "Your current level": "Ditt nåværende nivå", + "Your details": "Dine detaljer", "Your level": "Ditt nivå", "Your points to spend": "Dine brukbare poeng", "Zip code": "Post kode" diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 9fdf157d8..7b7f17465 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -4,8 +4,6 @@ "Add code": "Lägg till kod", "Add new card": "Lägg till nytt kort", "Address": "Adress", - "All our beds are from Bliss, allowing you to adjust the firmness for your perfect comfort.": "Alla våra sängar är från Bliss, med möjlighet att justera fastheten för perfekt komfort.", - "All rooms comes with standard amenities": "Alla rum har standardbekvämligheter", "Already a friend?": "Är du redan en vän?", "Amenities": "Bekvämligheter", "An error occurred when adding a credit card, please try again later.": "Ett fel uppstod när ett kreditkort lades till, försök igen senare.", @@ -17,11 +15,14 @@ "As our Close Friend": "Som vår nära vän", "At latest": "Senast", "At the hotel": "På hotellet", + "Bed type": "Sängtyp", "Book": "Boka", "Book reward night": "Boka frinatt", "Booking codes and vouchers": "Bokningskoder och kuponger", "Booking number": "Bokningsnummer", "Breakfast": "Frukost", + "Breakfast excluded": "Frukost ingår ej", + "Breakfast included": "Frukost ingår", "by": "innan", "Cancel": "Avbryt", "characters": "tecken", @@ -29,7 +30,6 @@ "Check out": "Checka ut", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.", "Choose room": "Välj rum", - "Choose type of bed": "Välj typ av säng", "City": "Ort", "City/State": "Ort", "Click here to log in": "Klicka här för att logga in", @@ -47,7 +47,6 @@ "Day": "Dag", "Description": "Beskrivning", "Discard changes": "Ignorera ändringar", - "Do you want to start the day with Scandics famous breakfast buffé?": "Vill du starta dagen med Scandics berömda frukostbuffé?", "Download the Scandic app": "Ladda ner Scandic-appen", "Edit": "Redigera", "Edit profile": "Redigera profil", @@ -59,6 +58,8 @@ "Find hotels": "Hitta hotell", "Flexibility": "Flexibilitet", "Former Scandic Hotel": "Tidigare Scandichotell", + "Free cancellation": "Fri avbokning", + "Free rebooking": "Fri ombokning", "From": "Från", "from your member profile?": "från din medlemsprofil?", "Get inspired": "Bli inspirerad", @@ -68,7 +69,6 @@ "Hotel surroundings": "Hotellomgivning", "hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "personer", - "How do you want to sleep?": "Hur vill du sova?", "How it works": "Hur det fungerar", "Join Scandic Friends": "Gå med i Scandic Friends", "Language": "Språk", @@ -86,9 +86,11 @@ "Log out": "Logga ut", "Manage preferences": "Hantera inställningar", "Meetings & Conferences": "Möten & Konferenser", + "Member price": "Medlemspris", "Members": "Medlemmar", "Membership cards": "Medlemskort", "Membership ID": "Medlems-ID", + "Modify": "Ändra", "Month": "Månad", "My communication preferences": "Mina kommunikationspreferenser", "My credit cards": "Mina kreditkort", @@ -104,13 +106,19 @@ "No content published": "Inget innehåll publicerat", "No transactions available": "Inga transaktioner tillgängliga", "No, keep card": "Nej, behåll kortet", + "Non refundable": "Ej återbetalningsbar", + "Non-refundable": "Ej återbetalningsbar", "Not found": "Hittades inte", + "Nr night, nr adult": "{nights, number} natt, {adults, number} vuxen", "number": "nummer", "On your journey": "På din resa", "Open": "Öppna", "or": "eller", "Overview": "Översikt", "Password": "Lösenord", + "Pay later": "Betala senare", + "Pay now": "Betala nu", + "Payment info": "Betalningsinformation", "Phone": "Telefon", "Phone is required": "Telefonnummer är obligatorisk", "Phone number": "Telefonnummer", @@ -128,6 +136,7 @@ "Remove card from member profile": "Ta bort kortet från medlemsprofilen", "Restaurant & Bar": "Restaurang & Bar", "Retype new password": "Upprepa nytt lösenord", + "Room & Terms": "Rum & Villkor", "Room facilities": "Rumfaciliteter", "Rooms": "Rum", "Rooms & Guests": "Rum och gäster", @@ -150,6 +159,7 @@ "Something went wrong!": "Något gick fel!", "special character": "speciell karaktär", "spendable points expiring by": "{points} poäng förfaller {date}", + "Standard price": "Standardpris", "Street": "Gata", "Successfully updated profile!": "Profilen har uppdaterats framgångsrikt!", "Summary": "Sammanfattning", @@ -158,6 +168,7 @@ "There are no transactions to display": "Det finns inga transaktioner att visa", "to": "till", "Total Points": "Poäng totalt", + "Transaction date": "Transaktionsdatum", "Transactions": "Transaktioner", "Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)", "TUI Points": "TUI Points", @@ -178,7 +189,6 @@ "When": "När", "Where should you go next?": "Låter inte en spontanweekend härligt?", "Where to": "Vart", - "Which room class suits you the best?": "Vilken rumsklass passar dig bäst?", "Year": "År", "Yes, remove my card": "Ja, ta bort mitt kort", "You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.", @@ -188,6 +198,7 @@ "Your card was successfully saved!": "Ditt kort har sparats!", "Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!", "Your current level": "Din nuvarande nivå", + "Your details": "Dina uppgifter", "Your level": "Din nivå", "Your points to spend": "Dina spenderbara poäng", "Zip code": "Postnummer" diff --git a/server/routers/hotels/output.ts b/server/routers/hotels/output.ts index b11189d2e..e7b85f7a3 100644 --- a/server/routers/hotels/output.ts +++ b/server/routers/hotels/output.ts @@ -468,14 +468,24 @@ export const getHotelDataSchema = z.object({ included: z.array(roomSchema).optional(), }) +const flexibilityPrice = z.object({ + standard: z.number(), + member: z.number(), +}) + const rate = z.object({ id: z.number(), name: z.string(), description: z.string(), size: z.string(), - pricePerNight: z.number(), - currency: z.string(), imageSrc: z.string(), + breakfastIncluded: z.boolean(), + prices: z.object({ + currency: z.string(), + nonRefundable: flexibilityPrice, + freeRebooking: flexibilityPrice, + freeCancellation: flexibilityPrice, + }), }) export const getRatesSchema = z.array(rate) diff --git a/server/routers/hotels/tempRatesData.json b/server/routers/hotels/tempRatesData.json index 4bd00d0be..4cdf68cdd 100644 --- a/server/routers/hotels/tempRatesData.json +++ b/server/routers/hotels/tempRatesData.json @@ -4,53 +4,101 @@ "name": "Cabin", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "17 - 24 m² (1 - 2 persons)", - "pricePerNight": 1348, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } }, { "id": 2, "name": "Standard", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "19 - 30 m² (1 - 2 persons)", - "pricePerNight": 1548, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } }, { "id": 3, "name": "Superior", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "22 - 40 m² (1 - 3 persons)", - "pricePerNight": 1744, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } }, { "id": 4, "name": "Superior Family", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "29 - 49 m² (3 - 4 persons)", - "pricePerNight": 2032, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } }, { "id": 5, "name": "Superior PLUS", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "21 - 28 m² (2 - 3 persons)", - "pricePerNight": 2065, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } }, { "id": 6, "name": "Junior Suite", "description": "Stylish, peaceful and air-conditioned room. The rooms have small clerestory windows.", "size": "35 - 43 m² (2 - 4 persons)", - "pricePerNight": 3012, - "currency": "SEK", - "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg" + "imageSrc": "https://www.scandichotels.se/imageVault/publishedmedia/xnmqnmz6mz0uhuat0917/scandic-helsinki-hub-room-standard-KR-7.jpg", + "breakfastIncluded": false, + "prices": { + "currency": "SEK", + "nonRefundable": { + "standard": 2315, + "member": 2247 + }, + "freeRebooking": { "standard": 2437, "member": 2365 }, + "freeCancellation": { "standard": 2620, "member": 2542 } + } } ] diff --git a/types/components/hotelReservation/selectRate/flexibilityOption.ts b/types/components/hotelReservation/selectRate/flexibilityOption.ts new file mode 100644 index 000000000..c61c09e94 --- /dev/null +++ b/types/components/hotelReservation/selectRate/flexibilityOption.ts @@ -0,0 +1,8 @@ +export type FlexibilityOptionProps = { + name: string + value: string + paymentTerm: string + standardPrice: number + memberPrice: number + currency: string +} diff --git a/types/components/hotelReservation/selectRate/roomCard.ts b/types/components/hotelReservation/selectRate/roomCard.ts index 7be2ae91d..ae9528b10 100644 --- a/types/components/hotelReservation/selectRate/roomCard.ts +++ b/types/components/hotelReservation/selectRate/roomCard.ts @@ -1,3 +1,8 @@ import { Rate } from "@/server/routers/hotels/output" -export type RoomCardProps = { room: Rate } +export type RoomCardProps = { + room: Rate + nrOfNights: number + nrOfAdults: number + breakfastIncluded: boolean +} diff --git a/types/components/hotelReservation/selectRate/roomSelection.ts b/types/components/hotelReservation/selectRate/roomSelection.ts deleted file mode 100644 index be21abaed..000000000 --- a/types/components/hotelReservation/selectRate/roomSelection.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Rate } from "@/server/routers/hotels/output" - -export type RoomSelectionProps = { - rooms: Rate[] -} diff --git a/types/components/hotelReservation/selectRate/section.ts b/types/components/hotelReservation/selectRate/section.ts new file mode 100644 index 000000000..bec7f57e5 --- /dev/null +++ b/types/components/hotelReservation/selectRate/section.ts @@ -0,0 +1,40 @@ +import { Rate } from "@/server/routers/hotels/output" + +export interface SectionProps { + nextPath: string +} + +export interface BedSelectionProps extends SectionProps { + alternatives: { + value: string + name: string + payment: string + pricePerNight: number + membersPricePerNight: number + currency: string + }[] +} + +export interface BreakfastSelectionProps extends SectionProps { + alternatives: { + value: string + name: string + payment: string + pricePerNight: number + currency: string + }[] +} + +export interface RoomSelectionProps extends SectionProps { + alternatives: Rate[] + nrOfAdults: number + nrOfNights: number +} + +export interface SectionPageProps { + breakfast?: string + bed?: string + fromDate: string + toDate: string + room: { adults: number; child: { age: number; bed: number }[] }[] +} diff --git a/types/components/hotelReservation/selectRate/sectionAccordion.ts b/types/components/hotelReservation/selectRate/sectionAccordion.ts new file mode 100644 index 000000000..19d13f836 --- /dev/null +++ b/types/components/hotelReservation/selectRate/sectionAccordion.ts @@ -0,0 +1,5 @@ +export interface SectionAccordionProps { + header: string + selection?: string | string[] + path: string +}