feat: add summary card

This commit is contained in:
Simon Emanuelsson
2024-10-09 12:44:00 +02:00
parent 491253d866
commit a84940aa8f
19 changed files with 253 additions and 18 deletions

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

View File

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