Merged develop into feat/SW-92-room-card
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + .card {
|
||||
border: 3px solid var(--Scandic-Brand-Scandic-Red);
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
padding: var(--Spacing-x2);
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user