Merged develop into feat/SW-92-room-card
This commit is contained in:
@@ -1,8 +1,3 @@
|
|||||||
.header {
|
|
||||||
margin-top: var(--Spacing-x2);
|
|
||||||
margin-bottom: var(--Spacing-x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hotelInfo {
|
.hotelInfo {
|
||||||
margin-bottom: 64px;
|
margin-bottom: 64px;
|
||||||
}
|
}
|
||||||
@@ -20,22 +15,3 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page input[type="radio"] {
|
|
||||||
opacity: 0;
|
|
||||||
position: fixed;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.roomList {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
.roomList > li {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import RoomCard from "@/components/HotelReservation/SelectRate/RoomCard"
|
import FlexibilitySelection from "@/components/HotelReservation/SelectRate/FlexibilitySelection"
|
||||||
import Header from "@/components/Section/Header"
|
import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default async function SelectRate() {
|
export default async function SelectRate() {
|
||||||
const { formatMessage } = await getIntl()
|
|
||||||
const rooms = await serverClient().hotel.getRates({
|
const rooms = await serverClient().hotel.getRates({
|
||||||
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
||||||
hotelId: "1",
|
hotelId: "1",
|
||||||
@@ -17,34 +15,8 @@ export default async function SelectRate() {
|
|||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
<main className={styles.content}>
|
<main className={styles.content}>
|
||||||
<div className={styles.hotelInfo}>Hotel info TBI</div>
|
<div className={styles.hotelInfo}>Hotel info TBI</div>
|
||||||
<div className={styles.header}>
|
<RoomSelection rooms={rooms} />
|
||||||
<Header
|
<FlexibilitySelection />
|
||||||
title={formatMessage({ id: "Choose room" })}
|
|
||||||
subtitle={formatMessage({
|
|
||||||
id: "Which room class suits you the best?",
|
|
||||||
})}
|
|
||||||
link={{
|
|
||||||
href: "#",
|
|
||||||
text: formatMessage({
|
|
||||||
id: "All rooms comes with standard amenities",
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul className={styles.roomList}>
|
|
||||||
{rooms.map((room) => (
|
|
||||||
<li key={room.id}>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="room"
|
|
||||||
value={room.id}
|
|
||||||
id={`room-${room.id}`}
|
|
||||||
/>
|
|
||||||
<RoomCard room={room} />
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
.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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
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 (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<Header title={formatMessage({ id: "Flexibility" })} subtitle={null} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className={styles.list}>
|
||||||
|
{choices.map((choice) => (
|
||||||
|
<li key={choice.value}>
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="flexibility" value={choice.value} />
|
||||||
|
<SelectionCard
|
||||||
|
title={choice.name}
|
||||||
|
subtext={choice.payment}
|
||||||
|
price={choice.pricePerNight}
|
||||||
|
membersPrice={choice.membersPricePerNight}
|
||||||
|
currency={choice.currency}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
border: 1px solid rgba(77, 0, 27, 0.1);
|
border: 1px solid rgba(77, 0, 27, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="radio"]:checked + .card {
|
||||||
|
border: 3px solid var(--Scandic-Brand-Scandic-Red);
|
||||||
|
}
|
||||||
|
|
||||||
.cardBody {
|
.cardBody {
|
||||||
padding: var(--Spacing-x2);
|
padding: var(--Spacing-x2);
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import Header from "@/components/Section/Header"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
|
import RoomCard from "./RoomCard"
|
||||||
|
|
||||||
|
import styles from "./roomSelection.module.css"
|
||||||
|
|
||||||
|
import { RoomSelectionProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
|
||||||
|
|
||||||
|
export default async function RoomSelection({ rooms }: RoomSelectionProps) {
|
||||||
|
const { formatMessage } = await getIntl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<Header
|
||||||
|
title={formatMessage({ id: "Choose room" })}
|
||||||
|
subtitle={formatMessage({
|
||||||
|
id: "Which room class suits you the best?",
|
||||||
|
})}
|
||||||
|
link={{
|
||||||
|
href: "#",
|
||||||
|
text: formatMessage({
|
||||||
|
id: "All rooms comes with standard amenities",
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className={styles.roomList}>
|
||||||
|
{rooms.map((room) => (
|
||||||
|
<li key={room.id}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="room"
|
||||||
|
value={room.id}
|
||||||
|
id={`room-${room.id}`}
|
||||||
|
/>
|
||||||
|
<RoomCard room={room} />
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomList {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomList > li {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomList input[type="radio"] {
|
||||||
|
opacity: 0;
|
||||||
|
position: fixed;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
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({
|
||||||
|
price,
|
||||||
|
membersPrice,
|
||||||
|
currency,
|
||||||
|
title,
|
||||||
|
subtext,
|
||||||
|
}: SelectionCardProps) {
|
||||||
|
const { formatMessage } = await getIntl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.card}>
|
||||||
|
<div>
|
||||||
|
<Title className={styles.name} as="h5" level="h3">
|
||||||
|
{title}
|
||||||
|
</Title>
|
||||||
|
<div className={styles.nameInfo}>i</div>
|
||||||
|
</div>
|
||||||
|
<Caption color="burgundy">{subtext}</Caption>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Caption color="burgundy" className={styles.price}>
|
||||||
|
{/* TODO: Handle currency and this whole line of text in a better way through intl */}
|
||||||
|
{price} {currency}/{formatMessage({ id: "night" })}
|
||||||
|
</Caption>
|
||||||
|
|
||||||
|
<Caption color="burgundy" className={styles.membersPrice}>
|
||||||
|
{/* TODO: Handle currency and this whole line of text in a better way through intl */}
|
||||||
|
{formatMessage({ id: "Members" })} {membersPrice} {currency}/
|
||||||
|
{formatMessage({ id: "night" })}
|
||||||
|
</Caption>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
.card {
|
||||||
|
padding: var(--Spacing-x2);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: var(--Corner-radius-Small);
|
||||||
|
border: 1px solid rgba(77, 0, 27, 0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"]:checked + .card {
|
||||||
|
border: 3px solid var(--Scandic-Brand-Scandic-Red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.nameInfo {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: var(--typography-Body-Bold-fontSize);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.membersPrice {
|
||||||
|
font-size: var(--typography-Footnote-Regular-fontSize);
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
|
"Flexibility": "Fleksibilitet",
|
||||||
"From": "Fra",
|
"From": "Fra",
|
||||||
"Get inspired": "Blive inspireret",
|
"Get inspired": "Blive inspireret",
|
||||||
"Go back to overview": "Gå tilbage til oversigten",
|
"Go back to overview": "Gå tilbage til oversigten",
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
"Log in": "Log på",
|
"Log in": "Log på",
|
||||||
"Log in here": "Log ind her",
|
"Log in here": "Log ind her",
|
||||||
"Log out": "Log ud",
|
"Log out": "Log ud",
|
||||||
|
"Members": "Medlemmer",
|
||||||
"Membership cards": "Medlemskort",
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-id",
|
"Membership ID": "Medlems-id",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
||||||
"Find booking": "Buchung finden",
|
"Find booking": "Buchung finden",
|
||||||
|
"Flexibility": "Flexibilität",
|
||||||
"From": "Fromm",
|
"From": "Fromm",
|
||||||
"Get inspired": "Lass dich inspirieren",
|
"Get inspired": "Lass dich inspirieren",
|
||||||
"Go back to overview": "Zurück zur Übersicht",
|
"Go back to overview": "Zurück zur Übersicht",
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
"Log in": "Anmeldung",
|
"Log in": "Anmeldung",
|
||||||
"Log in here": "Hier anmelden",
|
"Log in here": "Hier anmelden",
|
||||||
"Log out": "Ausloggen",
|
"Log out": "Ausloggen",
|
||||||
|
"Members": "Mitglieder",
|
||||||
"Membership cards": "Mitgliedskarten",
|
"Membership cards": "Mitgliedskarten",
|
||||||
"Membership ID": "Mitglieds-ID",
|
"Membership ID": "Mitglieds-ID",
|
||||||
"Month": "Monat",
|
"Month": "Monat",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Explore all levels and benefits": "Explore all levels and benefits",
|
"Explore all levels and benefits": "Explore all levels and benefits",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
|
"Flexibility": "Flexibility",
|
||||||
"From": "From",
|
"From": "From",
|
||||||
"Get inspired": "Get inspired",
|
"Get inspired": "Get inspired",
|
||||||
"Go back to overview": "Go back to overview",
|
"Go back to overview": "Go back to overview",
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
"Log in": "Log in",
|
"Log in": "Log in",
|
||||||
"Log in here": "Log in here",
|
"Log in here": "Log in here",
|
||||||
"Log out": "Log out",
|
"Log out": "Log out",
|
||||||
|
"Members": "Members",
|
||||||
"Membership cards": "Membership cards",
|
"Membership cards": "Membership cards",
|
||||||
"Membership ID": "Membership ID",
|
"Membership ID": "Membership ID",
|
||||||
"Month": "Month",
|
"Month": "Month",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
||||||
"Find booking": "Etsi varaus",
|
"Find booking": "Etsi varaus",
|
||||||
|
"Flexibility": "Joustavuus",
|
||||||
"From": "From",
|
"From": "From",
|
||||||
"Get inspired": "Inspiroidu",
|
"Get inspired": "Inspiroidu",
|
||||||
"Go back to overview": "Palaa yleiskatsaukseen",
|
"Go back to overview": "Palaa yleiskatsaukseen",
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
"Log in": "Kirjaudu sisään",
|
"Log in": "Kirjaudu sisään",
|
||||||
"Log in here": "Kirjaudu sisään tästä",
|
"Log in here": "Kirjaudu sisään tästä",
|
||||||
"Log out": "Kirjautua ulos",
|
"Log out": "Kirjautua ulos",
|
||||||
|
"Members": "Jäsenet",
|
||||||
"Membership cards": "Jäsenkortit",
|
"Membership cards": "Jäsenkortit",
|
||||||
"Membership ID": "Jäsentunnus",
|
"Membership ID": "Jäsentunnus",
|
||||||
"Month": "Kuukausi",
|
"Month": "Kuukausi",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
||||||
"Find booking": "Finn booking",
|
"Find booking": "Finn booking",
|
||||||
|
"Flexibility": "Fleksibilitet",
|
||||||
"From": "Fra",
|
"From": "Fra",
|
||||||
"Get inspired": "Bli inspirert",
|
"Get inspired": "Bli inspirert",
|
||||||
"Go back to overview": "Gå tilbake til oversikten",
|
"Go back to overview": "Gå tilbake til oversikten",
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
"Log in": "Logg Inn",
|
"Log in": "Logg Inn",
|
||||||
"Log in here": "Logg inn her",
|
"Log in here": "Logg inn her",
|
||||||
"Log out": "Logg ut",
|
"Log out": "Logg ut",
|
||||||
|
"Members": "Medlemmer",
|
||||||
"Membership cards": "Medlemskort",
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"Empty": "Tom",
|
"Empty": "Tom",
|
||||||
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
||||||
"Find booking": "Hitta bokning",
|
"Find booking": "Hitta bokning",
|
||||||
|
"Flexibility": "Flexibilitet",
|
||||||
"From": "Från",
|
"From": "Från",
|
||||||
"Get inspired": "Bli inspirerad",
|
"Get inspired": "Bli inspirerad",
|
||||||
"Go back to overview": "Gå tillbaka till översikten",
|
"Go back to overview": "Gå tillbaka till översikten",
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
"Log in": "Logga in",
|
"Log in": "Logga in",
|
||||||
"Log in here": "Logga in här",
|
"Log in here": "Logga in här",
|
||||||
"Log out": "Logga ut",
|
"Log out": "Logga ut",
|
||||||
|
"Members": "Medlemmar",
|
||||||
"Membership cards": "Medlemskort",
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Month": "Månad",
|
"Month": "Månad",
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { Rate } from "@/server/routers/hotels/output"
|
||||||
|
|
||||||
|
export type RoomSelectionProps = {
|
||||||
|
rooms: Rate[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export type SelectionCardProps = {
|
||||||
|
title: string
|
||||||
|
subtext: string
|
||||||
|
price: number
|
||||||
|
membersPrice?: number
|
||||||
|
currency: string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user