Merged in fix/handle-single-ancillaries (pull request #3231)
Fix(STAY-128): Handle single ancillaries * fix: refactor ancillaries flow * fix: add logic to determine if an ancillary requires quantity * fix: breakout ancillary description to its own component * fix: cleanup * fix: cleanup Approved-by: Bianca Widstam Approved-by: Erik Tiekstra
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { useAddAncillaryStore } from "@/stores/my-stay/add-ancillary-flow"
|
||||
|
||||
import WrappedAncillaryCard from "../../Card"
|
||||
|
||||
import styles from "./selectAncillaryStep.module.css"
|
||||
|
||||
export default function SelectAncillaryStep({
|
||||
onClose,
|
||||
}: {
|
||||
onClose: () => void
|
||||
}) {
|
||||
const {
|
||||
ancillariesBySelectedCategory,
|
||||
selectedCategory,
|
||||
categories,
|
||||
selectCategory,
|
||||
} = useAddAncillaryStore((state) => ({
|
||||
categories: state.categories,
|
||||
selectedCategory: state.selectedCategory,
|
||||
ancillariesBySelectedCategory: state.ancillariesBySelectedCategory,
|
||||
selectCategory: state.selectCategory,
|
||||
}))
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.tabs}>
|
||||
{categories.map((categoryName) => (
|
||||
<button
|
||||
key={categoryName}
|
||||
className={`${styles.chip} ${categoryName === selectedCategory ? styles.selected : ""}`}
|
||||
onClick={() => selectCategory(categoryName)}
|
||||
>
|
||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||
<p>
|
||||
{categoryName
|
||||
? categoryName
|
||||
: intl.formatMessage({
|
||||
id: "common.other",
|
||||
defaultMessage: "Other",
|
||||
})}
|
||||
</p>
|
||||
</Typography>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
{ancillariesBySelectedCategory.map((ancillary) => (
|
||||
<WrappedAncillaryCard
|
||||
key={ancillary.id}
|
||||
ancillary={ancillary}
|
||||
onClose={onClose}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: var(--Space-x1);
|
||||
padding: var(--Space-x3) 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(251px, 1fr));
|
||||
gap: var(--Space-x2);
|
||||
height: 470px;
|
||||
overflow-y: auto;
|
||||
padding-right: var(--Space-x15);
|
||||
margin-top: var(--Space-x2);
|
||||
}
|
||||
|
||||
.chip {
|
||||
border-radius: var(--Corner-radius-rounded);
|
||||
padding: calc(var(--Space-x1) + var(--Space-x025)) var(--Space-x2);
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--Border-Interactive-Default);
|
||||
color: var(--Text-Default);
|
||||
background-color: var(--Background-Secondary);
|
||||
}
|
||||
|
||||
.chip.selected {
|
||||
background: var(--Surface-Brand-Primary-3-Default);
|
||||
color: var(--Text-Inverted);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
.modalWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70dvh;
|
||||
width: 100%;
|
||||
margin-top: var(--Space-x3);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.modalWrapper {
|
||||
width: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1052px) {
|
||||
.modalWrapper {
|
||||
width: 833px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import Modal from "@scandic-hotels/design-system/Modal"
|
||||
|
||||
import SelectAncillaryStep from "./SelectAncillaryStep"
|
||||
|
||||
import styles from "./allAncillariesModal.module.css"
|
||||
|
||||
export default function AllAncillariesModal() {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
const intl = useIntl()
|
||||
|
||||
const modalTitle = intl.formatMessage({
|
||||
id: "ancillaries.upgradeYourStay",
|
||||
defaultMessage: "Upgrade your stay",
|
||||
})
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
variant="Text"
|
||||
size="Small"
|
||||
color="Primary"
|
||||
onPress={() => setIsOpen(true)}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id: "common.seeAll",
|
||||
defaultMessage: "See all",
|
||||
})}
|
||||
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
|
||||
</Button>
|
||||
<Modal isOpen={isOpen} onToggle={setIsOpen} title={modalTitle}>
|
||||
<div className={styles.modalWrapper}>
|
||||
<SelectAncillaryStep onClose={() => setIsOpen(false)} />
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user