feat: SW-1182 Implntd rate terms modal in confirmation page and Updated styles

This commit is contained in:
Hrishikesh Vaipurkar
2025-01-08 14:50:27 +01:00
parent 61bd3a2c3e
commit 9a25b3569d
6 changed files with 106 additions and 29 deletions

View File

@@ -2,7 +2,11 @@
import { notFound } from "next/navigation" import { notFound } from "next/navigation"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { ChevronRightSmallIcon, InfoCircleIcon } from "@/components/Icons" import {
CheckIcon,
ChevronRightSmallIcon,
InfoCircleIcon,
} from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider" import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
@@ -11,6 +15,8 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting" import { formatPrice } from "@/utils/numberFormatting"
import Modal from "../../Modal"
import styles from "./receipt.module.css" import styles from "./receipt.module.css"
import type { BookingConfirmationReceiptProps } from "@/types/components/hotelReservation/bookingConfirmation/receipt" import type { BookingConfirmationReceiptProps } from "@/types/components/hotelReservation/bookingConfirmation/receipt"
@@ -64,16 +70,46 @@ export default function Receipt({
<Caption color="uiTextMediumContrast"> <Caption color="uiTextMediumContrast">
{booking.rateDefinition.cancellationText} {booking.rateDefinition.cancellationText}
</Caption> </Caption>
<Link <Modal
color="peach80" trigger={
href="" <Button intent="text" className={styles.termsLink}>
size="small" <Link
textDecoration="underline" color="peach80"
variant="icon" href=""
size="small"
textDecoration="underline"
variant="icon"
>
{intl.formatMessage({ id: "Reservation policy" })}
<InfoCircleIcon color="peach80" />
</Link>
</Button>
}
title={booking.rateDefinition.cancellationText || ""}
subtitle={
booking.rateDefinition.cancellationRule == "CancellableBefore6PM"
? intl.formatMessage({ id: "Pay later" })
: intl.formatMessage({ id: "Pay now" })
}
> >
{intl.formatMessage({ id: "Reservation policy" })} <div className={styles.terms}>
<InfoCircleIcon color="peach80" /> {booking.rateDefinition.generalTerms?.map((info) => (
</Link> <Body
key={info}
color="uiTextHighContrast"
className={styles.termsText}
>
<CheckIcon
color="uiSemanticSuccess"
width={20}
height={20}
className={styles.termsIcon}
></CheckIcon>
{info}
</Body>
))}
</div>
</Modal>
</header> </header>
<div className={styles.entry}> <div className={styles.entry}>
<Body color="uiTextHighContrast">{room.bedType.description}</Body> <Body color="uiTextHighContrast">{room.bedType.description}</Body>

View File

@@ -33,6 +33,22 @@
padding: 0; padding: 0;
} }
.termsLink {
justify-self: flex-start;
}
.terms {
margin-top: var(--Spacing-x3);
margin-bottom: var(--Spacing-x3);
}
.termsText:nth-child(n) {
display: flex;
align-items: center;
margin-bottom: var(--Spacing-x1);
}
.terms .termsIcon {
margin-right: var(--Spacing-x1);
}
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
.receipt { .receipt {
padding: var(--Spacing-x3); padding: var(--Spacing-x3);

View File

@@ -8,12 +8,12 @@ import { useEnterDetailsStore } from "@/stores/enter-details"
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop" import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import { import {
ArrowRightIcon, ArrowRightIcon,
CheckIcon,
ChevronDownSmallIcon, ChevronDownSmallIcon,
ChevronRightSmallIcon, ChevronRightSmallIcon,
} from "@/components/Icons" } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider" import Divider from "@/components/TempDesignSystem/Divider"
import Popover from "@/components/TempDesignSystem/Popover"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
@@ -170,23 +170,34 @@ export default function SummaryUI({
}`} }`}
</Caption> </Caption>
<Caption color="uiTextMediumContrast">{cancellationText}</Caption> <Caption color="uiTextMediumContrast">{cancellationText}</Caption>
<Popover <Modal
placement="bottom left" trigger={
triggerContent={ <Button intent="text">
<Caption color="burgundy" type="underline"> <Caption color="burgundy" type="underline">
{intl.formatMessage({ id: "Rate details" })} {intl.formatMessage({ id: "Rate details" })}
</Caption> </Caption>
</Button>
} }
title={cancellationText}
> >
<aside className={styles.rateDetailsPopover}> <div className={styles.terms}>
<header> {rateDetails?.map((info) => (
<Caption type="bold">{cancellationText}</Caption> <Body
</header> key={info}
{rateDetails?.map((detail, idx) => ( color="uiTextHighContrast"
<Caption key={`rateDetails-${idx}`}>{detail}</Caption> className={styles.termsText}
>
<CheckIcon
color="uiSemanticSuccess"
width={20}
height={20}
className={styles.termsIcon}
></CheckIcon>
{info}
</Body>
))} ))}
</aside> </div>
</Popover> </Modal>
</div> </div>
{packages {packages
? packages.map((roomPackage) => ( ? packages.map((roomPackage) => (

View File

@@ -72,6 +72,19 @@
width: 560px; width: 560px;
} }
.terms {
margin-top: var(--Spacing-x3);
margin-bottom: var(--Spacing-x3);
}
.termsText:nth-child(n) {
display: flex;
align-items: center;
margin-bottom: var(--Spacing-x1);
}
.terms .termsIcon {
margin-right: var(--Spacing-x1);
}
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
.bottomDivider { .bottomDivider {
display: block; display: block;

View File

@@ -77,9 +77,6 @@ input[type="radio"]:checked + .card .checkIcon {
margin: 0 auto var(--Spacing-x2); margin: 0 auto var(--Spacing-x2);
} }
.modal section:focus-visible {
outline: none;
}
.terms { .terms {
margin-top: var(--Spacing-x3); margin-top: var(--Spacing-x3);
margin-bottom: var(--Spacing-x3); margin-bottom: var(--Spacing-x3);
@@ -89,3 +86,6 @@ input[type="radio"]:checked + .card .checkIcon {
align-items: center; align-items: center;
margin-bottom: var(--Spacing-x1); margin-bottom: var(--Spacing-x1);
} }
.termsIcon {
margin-right: var(--Spacing-x1);
}

View File

@@ -4,7 +4,7 @@ import { useSearchParams } from "next/navigation"
import { useEffect, useRef } from "react" import { useEffect, useRef } from "react"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { CheckIcon, InfoCircleIcon } from "@/components/Icons" import { CheckCircleIcon, CheckIcon, InfoCircleIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import Label from "@/components/TempDesignSystem/Form/Label" import Label from "@/components/TempDesignSystem/Form/Label"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
@@ -142,6 +142,7 @@ export default function FlexibilityOption({
color="uiSemanticSuccess" color="uiSemanticSuccess"
width={20} width={20}
height={20} height={20}
className={styles.termsIcon}
></CheckIcon> ></CheckIcon>
{info} {info}
</Body> </Body>