Merged develop into feat/SW-92-room-card

This commit is contained in:
Chuma Mcphoy (We Ahead)
2024-07-11 08:06:59 +00:00
18 changed files with 266 additions and 56 deletions

View File

@@ -1,8 +1,3 @@
.header {
margin-top: var(--Spacing-x2);
margin-bottom: var(--Spacing-x2);
}
.hotelInfo {
margin-bottom: 64px;
}
@@ -20,22 +15,3 @@
margin-left: 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%;
}

View File

@@ -1,13 +1,11 @@
import { serverClient } from "@/lib/trpc/server"
import RoomCard from "@/components/HotelReservation/SelectRate/RoomCard"
import Header from "@/components/Section/Header"
import { getIntl } from "@/i18n"
import FlexibilitySelection from "@/components/HotelReservation/SelectRate/FlexibilitySelection"
import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection"
import styles from "./page.module.css"
export default async function SelectRate() {
const { formatMessage } = await getIntl()
const rooms = await serverClient().hotel.getRates({
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
hotelId: "1",
@@ -17,34 +15,8 @@ export default async function SelectRate() {
<div className={styles.page}>
<main className={styles.content}>
<div className={styles.hotelInfo}>Hotel info TBI</div>
<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>
<RoomSelection rooms={rooms} />
<FlexibilitySelection />
</main>
</div>
)

View File

@@ -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;
}

View File

@@ -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>
)
}

View File

@@ -8,6 +8,10 @@
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-x2);
display: flex;

View File

@@ -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>
)
}

View File

@@ -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;
}

View File

@@ -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>
)
}

View File

@@ -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);
}

View File

@@ -37,6 +37,7 @@
"Empty": "Empty",
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
"Find booking": "Find booking",
"Flexibility": "Fleksibilitet",
"From": "Fra",
"Get inspired": "Blive inspireret",
"Go back to overview": "Gå tilbage til oversigten",
@@ -48,6 +49,7 @@
"Log in": "Log på",
"Log in here": "Log ind her",
"Log out": "Log ud",
"Members": "Medlemmer",
"Membership cards": "Medlemskort",
"Membership ID": "Medlems-id",
"Month": "Måned",

View File

@@ -37,6 +37,7 @@
"Empty": "Empty",
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
"Find booking": "Buchung finden",
"Flexibility": "Flexibilität",
"From": "Fromm",
"Get inspired": "Lass dich inspirieren",
"Go back to overview": "Zurück zur Übersicht",
@@ -48,6 +49,7 @@
"Log in": "Anmeldung",
"Log in here": "Hier anmelden",
"Log out": "Ausloggen",
"Members": "Mitglieder",
"Membership cards": "Mitgliedskarten",
"Membership ID": "Mitglieds-ID",
"Month": "Monat",

View File

@@ -38,6 +38,7 @@
"Empty": "Empty",
"Explore all levels and benefits": "Explore all levels and benefits",
"Find booking": "Find booking",
"Flexibility": "Flexibility",
"From": "From",
"Get inspired": "Get inspired",
"Go back to overview": "Go back to overview",
@@ -53,6 +54,7 @@
"Log in": "Log in",
"Log in here": "Log in here",
"Log out": "Log out",
"Members": "Members",
"Membership cards": "Membership cards",
"Membership ID": "Membership ID",
"Month": "Month",

View File

@@ -37,6 +37,7 @@
"Empty": "Empty",
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
"Find booking": "Etsi varaus",
"Flexibility": "Joustavuus",
"From": "From",
"Get inspired": "Inspiroidu",
"Go back to overview": "Palaa yleiskatsaukseen",
@@ -48,6 +49,7 @@
"Log in": "Kirjaudu sisään",
"Log in here": "Kirjaudu sisään tästä",
"Log out": "Kirjautua ulos",
"Members": "Jäsenet",
"Membership cards": "Jäsenkortit",
"Membership ID": "Jäsentunnus",
"Month": "Kuukausi",

View File

@@ -37,6 +37,7 @@
"Empty": "Empty",
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
"Find booking": "Finn booking",
"Flexibility": "Fleksibilitet",
"From": "Fra",
"Get inspired": "Bli inspirert",
"Go back to overview": "Gå tilbake til oversikten",
@@ -48,6 +49,7 @@
"Log in": "Logg Inn",
"Log in here": "Logg inn her",
"Log out": "Logg ut",
"Members": "Medlemmer",
"Membership cards": "Medlemskort",
"Membership ID": "Medlems-ID",
"Month": "Måned",

View File

@@ -37,6 +37,7 @@
"Empty": "Tom",
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
"Find booking": "Hitta bokning",
"Flexibility": "Flexibilitet",
"From": "Från",
"Get inspired": "Bli inspirerad",
"Go back to overview": "Gå tillbaka till översikten",
@@ -52,6 +53,7 @@
"Log in": "Logga in",
"Log in here": "Logga in här",
"Log out": "Logga ut",
"Members": "Medlemmar",
"Membership cards": "Medlemskort",
"Membership ID": "Medlems-ID",
"Month": "Månad",

View File

@@ -0,0 +1,5 @@
import { Rate } from "@/server/routers/hotels/output"
export type RoomSelectionProps = {
rooms: Rate[]
}

View File

@@ -0,0 +1,7 @@
export type SelectionCardProps = {
title: string
subtext: string
price: number
membersPrice?: number
currency: string
}