feat: booking confirmation page with hardcoded data

This commit is contained in:
Simon Emanuelsson
2024-10-22 11:43:08 +02:00
parent 445bde8e2e
commit 2d23f9bbf3
42 changed files with 859 additions and 533 deletions
@@ -1,58 +0,0 @@
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import styles from "./introSection.module.css"
import { IntroSectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
export default function IntroSection({ email }: IntroSectionProps) {
const intl = useIntl()
return (
<section className={styles.section}>
<div>
<Title textAlign="center" as="h2">
{intl.formatMessage({ id: "Thank you" })}
</Title>
<Subtitle textAlign="center" textTransform="uppercase">
{intl.formatMessage({ id: "We look forward to your visit!" })}
</Subtitle>
</div>
<Body color="burgundy" textAlign="center">
{intl.formatMessage({
id: "We have sent a detailed confirmation of your booking to your email: ",
})}
{email}
</Body>
<div className={styles.buttons}>
<Button
asChild
size="small"
theme="base"
intent="secondary"
className={styles.button}
>
<Link href="#" color="none">
{intl.formatMessage({ id: "Download the Scandic app" })}
</Link>
</Button>
<Button
asChild
size="small"
theme="base"
intent="secondary"
className={styles.button}
>
<Link href="#" color="none">
{intl.formatMessage({ id: "View your booking" })}
</Link>
</Button>
</div>
</section>
)
}
@@ -1,26 +0,0 @@
.section {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
width: 100%;
}
.buttons {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--Spacing-x2);
}
.button {
width: 100%;
max-width: 240px;
justify-content: center;
}
@media screen and (min-width: 1367px) {
.buttons {
flex-direction: row;
justify-content: space-around;
}
}
@@ -1,81 +0,0 @@
import { useIntl } from "react-intl"
import { ArrowRightIcon, ScandicLogoIcon } from "@/components/Icons"
import Image from "@/components/Image"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import styles from "./staySection.module.css"
import { StaySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
export default function StaySection({ hotel, stay }: StaySectionProps) {
const intl = useIntl()
const nightsText =
stay.nights > 1
? intl.formatMessage({ id: "nights" })
: intl.formatMessage({ id: "night" })
return (
<>
<section className={styles.card}>
<Image
src={hotel.image}
alt=""
height={400}
width={200}
className={styles.image}
/>
<div className={styles.info}>
<div className={styles.hotel}>
<ScandicLogoIcon color="red" />
<Title as="h5" textTransform="capitalize">
{hotel.name}
</Title>
<Caption color="burgundy" className={styles.caption}>
<span>{hotel.address}</span>
<span>{hotel.phone}</span>
</Caption>
</div>
<Body className={styles.stay}>
<span>{`${stay.nights} ${nightsText}`}</span>
<span className={styles.dates}>
<span>{stay.start}</span>
<ArrowRightIcon height={15} width={15} />
<span>{stay.end}</span>
</span>
</Body>
</div>
</section>
<section className={styles.table}>
<div className={styles.breakfast}>
<Body color="burgundy">
{intl.formatMessage({ id: "Breakfast" })}
</Body>
<Caption className={styles.caption}>
<span>{`${intl.formatMessage({ id: "Weekdays" })} ${hotel.breakfast.start}-${hotel.breakfast.end}`}</span>
<span>{`${intl.formatMessage({ id: "Weekends" })} ${hotel.breakfast.start}-${hotel.breakfast.end}`}</span>
</Caption>
</div>
<div className={styles.checkIn}>
<Body color="burgundy">{intl.formatMessage({ id: "Check in" })}</Body>
<Caption className={styles.caption}>
<span>{intl.formatMessage({ id: "From" })}</span>
<span>{hotel.checkIn}</span>
</Caption>
</div>
<div className={styles.checkOut}>
<Body color="burgundy">
{intl.formatMessage({ id: "Check out" })}
</Body>
<Caption className={styles.caption}>
<span>{intl.formatMessage({ id: "At latest" })}</span>
<span>{hotel.checkOut}</span>
</Caption>
</div>
</section>
</>
)
}
@@ -1,78 +0,0 @@
.card {
display: flex;
width: 100%;
background-color: var(--Base-Surface-Primary-light-Normal);
border: 1px solid var(--Base-Border-Subtle);
border-radius: var(--Corner-radius-Small);
overflow: hidden;
}
.image {
height: 100%;
width: 105px;
object-fit: cover;
}
.info {
display: flex;
flex-direction: column;
width: 100%;
gap: var(--Spacing-x1);
padding: var(--Spacing-x2);
}
.hotel,
.stay {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-half);
}
.caption {
display: flex;
flex-direction: column;
}
.dates {
display: flex;
align-items: center;
gap: var(--Spacing-x-half);
}
.table {
display: flex;
justify-content: space-between;
padding: var(--Spacing-x2);
border-radius: var(--Corner-radius-Small);
background-color: var(--Base-Surface-Primary-dark-Normal);
width: 100%;
}
.breakfast,
.checkIn,
.checkOut {
display: flex;
flex-direction: column;
gap: var(--Spacing-x-half);
}
@media screen and (min-width: 1367px) {
.card {
flex-direction: column;
}
.image {
width: 100%;
max-height: 195px;
}
.info {
flex-direction: row;
justify-content: space-between;
}
.hotel,
.stay {
width: 100%;
max-width: 230px;
}
}
@@ -1,40 +0,0 @@
import { useIntl } from "react-intl"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import styles from "./summarySection.module.css"
import { SummarySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
export default function SummarySection({ summary }: SummarySectionProps) {
const intl = useIntl()
const roomType = `${intl.formatMessage({ id: "Type of room" })}: ${summary.roomType}`
const bedType = `${intl.formatMessage({ id: "Type of bed" })}: ${summary.bedType}`
const breakfast = `${intl.formatMessage({ id: "Breakfast" })}: ${summary.breakfast}`
const flexibility = `${intl.formatMessage({ id: "Flexibility" })}: ${summary.flexibility}`
return (
<section className={styles.section}>
<Title as="h4" textAlign="center">
{intl.formatMessage({ id: "Summary" })}
</Title>
<Caption className={styles.summary}>
<span>{roomType}</span>
<span>1648 SEK</span>
</Caption>
<Caption className={styles.summary}>
<span>{bedType}</span>
<span>0 SEK</span>
</Caption>
<Caption className={styles.summary}>
<span>{breakfast}</span>
<span>198 SEK</span>
</Caption>
<Caption className={styles.summary}>
<span>{flexibility}</span>
<span>200 SEK</span>
</Caption>
</section>
)
}
@@ -1,13 +0,0 @@
.section {
width: 100%;
}
.summary {
display: flex;
justify-content: space-between;
border-bottom: 1px solid var(--Base-Border-Subtle);
}
.summary span {
padding: var(--Spacing-x2) var(--Spacing-x0);
}
@@ -1,27 +0,0 @@
import { BookingConfirmation } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
export const tempConfirmationData: BookingConfirmation = {
email: "lisa.andersson@outlook.com",
hotel: {
name: "Helsinki Hub",
address: "Kaisaniemenkatu 7, Helsinki",
location: "Helsinki",
phone: "+358 300 870680",
image:
"https://test3.scandichotels.com/imagevault/publishedmedia/i11isd60bh119s9486b7/downtown-camper-by-scandic-lobby-reception-desk-ch.jpg?w=640",
checkIn: "15.00",
checkOut: "12.00",
breakfast: { start: "06:30", end: "10:00" },
},
stay: {
nights: 1,
start: "2024.03.09",
end: "2024.03.10",
},
summary: {
roomType: "Standard Room",
bedType: "King size",
breakfast: "Yes",
flexibility: "Yes",
},
}
@@ -66,7 +66,7 @@ export default function Payment({
resolver: zodResolver(paymentSchema),
})
const initiateBooking = trpc.booking.booking.create.useMutation({
const initiateBooking = trpc.booking.create.useMutation({
onSuccess: (result) => {
if (result?.confirmationNumber) {
setConfirmationNumber(result.confirmationNumber)