Merged in fix/STAY-133 (pull request #3313)
Fix/STAY-133 * fix: Add static summary buttons row on add ancillary flow * fix: refactor handling of modals * fix: refactor file structure for add ancillary flow * Merged in chore/replace-deprecated-body (pull request #3300) Replace deprecated <Body> with <Typography> * chore: replace deprecated body component * refactor: replace Body component with Typography across various components * merge Approved-by: Bianca Widstam Approved-by: Matilda Landström Approved-by: Bianca Widstam Approved-by: Matilda Landström
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
.price {
|
||||
display: flex;
|
||||
gap: var(--Space-x2);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contentContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.description {
|
||||
display: flex;
|
||||
margin: var(--Space-x2) 0;
|
||||
}
|
||||
|
||||
.pointsDivider {
|
||||
display: flex;
|
||||
gap: var(--Space-x2);
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.breakfastPriceList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
height: var(--Space-x4);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.breakfastPriceList {
|
||||
flex-direction: row;
|
||||
gap: var(--Space-x2);
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import {
|
||||
AncillaryStepEnum,
|
||||
useAddAncillaryStore,
|
||||
} from "@/stores/my-stay/add-ancillary-flow"
|
||||
|
||||
import styles from "./description.module.css"
|
||||
|
||||
export default function Description() {
|
||||
const intl = useIntl()
|
||||
const { selectedAncillary, isBreakfast, currentStep } = useAddAncillaryStore(
|
||||
(state) => ({
|
||||
selectedAncillary: state.selectedAncillary,
|
||||
isBreakfast: state.isBreakfast,
|
||||
currentStep: state.currentStep,
|
||||
})
|
||||
)
|
||||
|
||||
if (!selectedAncillary || currentStep === AncillaryStepEnum.confirmation) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.contentContainer}>
|
||||
<div className={styles.price}>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
{isBreakfast ? (
|
||||
<BreakfastPriceList />
|
||||
) : (
|
||||
<p>
|
||||
{formatPrice(
|
||||
intl,
|
||||
selectedAncillary.price.total,
|
||||
selectedAncillary.price.currency
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</Typography>
|
||||
{selectedAncillary.points && (
|
||||
<div className={styles.pointsDivider}>
|
||||
<Divider variant="vertical" />
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
id: "common.numberOfPoints",
|
||||
defaultMessage:
|
||||
"{points, plural, one {# point} other {# points}}",
|
||||
},
|
||||
{
|
||||
points: selectedAncillary.points,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
{selectedAncillary.description && (
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: selectedAncillary.description,
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function BreakfastPriceList() {
|
||||
const intl = useIntl()
|
||||
const breakfastData = useAddAncillaryStore((state) => state.breakfastData)
|
||||
|
||||
if (!breakfastData) {
|
||||
return intl.formatMessage({
|
||||
id: "ancillaries.unableToDisplayBreakfastPrices",
|
||||
defaultMessage: "Unable to display breakfast prices.",
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.breakfastPriceList}>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
id: "addAncillaryFlowModal.pricePerNightPerAdult",
|
||||
defaultMessage: "{price}/night per adult",
|
||||
},
|
||||
{
|
||||
price: formatPrice(
|
||||
intl,
|
||||
breakfastData.priceAdult,
|
||||
breakfastData.currency
|
||||
),
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
|
||||
{breakfastData.nrOfPayingChildren > 0 && (
|
||||
<>
|
||||
<div className={styles.divider}>
|
||||
<Divider variant="vertical" color="Border/Divider/Subtle" />
|
||||
</div>
|
||||
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
id: "addAncillaryFlowModal.pricePerNightPerKids",
|
||||
defaultMessage: "{price}/night for kids (ages 4–12)",
|
||||
},
|
||||
{
|
||||
price: formatPrice(
|
||||
intl,
|
||||
breakfastData.priceChild,
|
||||
breakfastData.currency
|
||||
),
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
|
||||
{breakfastData.nrOfFreeChildren > 0 && (
|
||||
<>
|
||||
<div className={styles.divider}>
|
||||
<Divider variant="vertical" color="Border/Divider/Subtle" />
|
||||
</div>
|
||||
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<span>
|
||||
{intl.formatMessage({
|
||||
id: "addAncillaryFlowModal.freeBreakfastForKids",
|
||||
defaultMessage: "Free for kids (under 4)",
|
||||
})}
|
||||
</span>
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user