feat: add summary card
This commit is contained in:
165
components/HotelReservation/EnterDetails/Summary/index.tsx
Normal file
165
components/HotelReservation/EnterDetails/Summary/index.tsx
Normal file
@@ -0,0 +1,165 @@
|
||||
import { dt } from "@/lib/dt"
|
||||
|
||||
import { ArrowRightIcon, ChevronRightSmallIcon } from "@/components/Icons"
|
||||
import Divider from "@/components/TempDesignSystem/Divider"
|
||||
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 { getLang } from "@/i18n/serverContext"
|
||||
|
||||
import styles from "./summary.module.css"
|
||||
|
||||
// TEMP
|
||||
const rooms = [
|
||||
{
|
||||
adults: 1,
|
||||
type: "Cozy cabin",
|
||||
},
|
||||
]
|
||||
|
||||
export default async function Summary() {
|
||||
const intl = await getIntl()
|
||||
const lang = getLang()
|
||||
|
||||
const fromDate = dt().locale(lang).format("ddd, D MMM")
|
||||
const toDate = dt().add(1, "day").locale(lang).format("ddd, D MMM")
|
||||
const diff = dt(toDate).diff(fromDate, "days")
|
||||
|
||||
const totalAdults = rooms.reduce((total, room) => total + room.adults, 0)
|
||||
|
||||
const adults = intl.formatMessage(
|
||||
{ id: "booking.adults" },
|
||||
{ totalAdults: totalAdults }
|
||||
)
|
||||
const nights = intl.formatMessage(
|
||||
{ id: "booking.nights" },
|
||||
{ totalNights: diff }
|
||||
)
|
||||
|
||||
const addOns = [
|
||||
{
|
||||
price: intl.formatMessage({ id: "Included" }),
|
||||
title: intl.formatMessage({ id: "King bed" }),
|
||||
},
|
||||
{
|
||||
price: intl.formatMessage({ id: "Included" }),
|
||||
title: intl.formatMessage({ id: "Breakfast buffet" }),
|
||||
},
|
||||
]
|
||||
|
||||
const mappedRooms = Array.from(
|
||||
rooms
|
||||
.reduce((acc, room) => {
|
||||
const currentRoom = acc.get(room.type)
|
||||
acc.set(room.type, {
|
||||
total: currentRoom ? currentRoom.total + 1 : 1,
|
||||
type: room.type,
|
||||
})
|
||||
return acc
|
||||
}, new Map())
|
||||
.values()
|
||||
)
|
||||
|
||||
return (
|
||||
<section className={styles.summary}>
|
||||
<header>
|
||||
<Body textTransform="bold">
|
||||
{mappedRooms.map(
|
||||
(room, idx) =>
|
||||
`${room.total} x ${room.type}${mappedRooms.length > 1 && idx + 1 !== mappedRooms.length ? ", " : ""}`
|
||||
)}
|
||||
</Body>
|
||||
<Body className={styles.date} color="textMediumContrast">
|
||||
{fromDate}
|
||||
<ArrowRightIcon color="uiTextMediumContrast" height={15} width={15} />
|
||||
{toDate}
|
||||
</Body>
|
||||
<Link
|
||||
className={styles.link}
|
||||
color="baseButtonTextOnFillNormal"
|
||||
href="#"
|
||||
variant="icon"
|
||||
>
|
||||
{intl.formatMessage({ id: "See room details" })}
|
||||
<ChevronRightSmallIcon
|
||||
color="baseButtonTextOnFillNormal"
|
||||
height={20}
|
||||
width={20}
|
||||
/>
|
||||
</Link>
|
||||
</header>
|
||||
<Divider color="primaryLightSubtle" />
|
||||
<div className={styles.addOns}>
|
||||
<div className={styles.entry}>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{`${nights}, ${adults}`}
|
||||
</Caption>
|
||||
<Caption color="uiTextHighContrast">
|
||||
{intl.formatMessage(
|
||||
{ id: "{amount} {currency}" },
|
||||
{ amount: "4536", currency: "SEK" }
|
||||
)}
|
||||
</Caption>
|
||||
</div>
|
||||
{addOns.map((addOn) => (
|
||||
<div className={styles.entry} key={addOn.title}>
|
||||
<Caption color="uiTextMediumContrast">{addOn.title}</Caption>
|
||||
<Caption color="uiTextHighContrast">{addOn.price}</Caption>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Divider color="primaryLightSubtle" />
|
||||
<div className={styles.total}>
|
||||
<div>
|
||||
<div className={styles.entry}>
|
||||
<Body textTransform="bold">
|
||||
{intl.formatMessage({ id: "Total incl VAT" })}
|
||||
</Body>
|
||||
<Body textTransform="bold">
|
||||
{intl.formatMessage(
|
||||
{ id: "{amount} {currency}" },
|
||||
{ amount: "4686", currency: "SEK" }
|
||||
)}
|
||||
</Body>
|
||||
</div>
|
||||
<div className={styles.entry}>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{intl.formatMessage({ id: "Approx." })}
|
||||
</Caption>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{intl.formatMessage(
|
||||
{ id: "{amount} {currency}" },
|
||||
{ amount: "455", currency: "EUR" }
|
||||
)}
|
||||
</Caption>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.entry}>
|
||||
<Body color="red" textTransform="bold">
|
||||
{intl.formatMessage({ id: "Member price" })}
|
||||
</Body>
|
||||
<Body color="red" textTransform="bold">
|
||||
{intl.formatMessage(
|
||||
{ id: "{amount} {currency}" },
|
||||
{ amount: "4219", currency: "SEK" }
|
||||
)}
|
||||
</Body>
|
||||
</div>
|
||||
<div className={styles.entry}>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{intl.formatMessage({ id: "Approx." })}
|
||||
</Caption>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{intl.formatMessage(
|
||||
{ id: "{amount} {currency}" },
|
||||
{ amount: "412", currency: "EUR" }
|
||||
)}
|
||||
</Caption>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
.summary {
|
||||
background-color: var(--Main-Grey-White);
|
||||
border: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
|
||||
border-radius: var(--Corner-radius-Large);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x2);
|
||||
padding: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.date {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: var(--Spacing-x1);
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.link {
|
||||
margin-top: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.addOns {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.entry {
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.total {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
Reference in New Issue
Block a user