Merged in feat/SW-2612-mystay-breakfast-buffet-u (pull request #2059)
Feat: SW-2612 Updated breakfast ancillary UI and Optimised code * Feat: SW-2612 Updated breakfast ancillary UI and Optimised code * feat: SW-2612 Updated UI as per figma * feat: SW-2612 Optimised code * feat: SW-2612 Optimised code Approved-by: Tobias Johansson
This commit is contained in:
@@ -2,12 +2,12 @@
|
||||
display: flex;
|
||||
gap: var(--Spacing-x4);
|
||||
justify-content: flex-end;
|
||||
padding: var(--Space-x2) var(--Space-x15) 0;
|
||||
padding: var(--Space-x2) var(--Space-x15) 0 0;
|
||||
}
|
||||
|
||||
.confirmButtons {
|
||||
display: flex;
|
||||
padding: 0 var(--Space-x15);
|
||||
padding-left: var(--Space-x15);
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ export default function ActionButtons({
|
||||
}: ActionButtonsProps) {
|
||||
const {
|
||||
currentStep,
|
||||
isBreakfast,
|
||||
prevStep,
|
||||
prevStepMobile,
|
||||
selectQuantity,
|
||||
@@ -33,6 +34,7 @@ export default function ActionButtons({
|
||||
selectedAncillary,
|
||||
} = useAddAncillaryStore((state) => ({
|
||||
currentStep: state.currentStep,
|
||||
isBreakfast: state.isBreakfast,
|
||||
prevStep: state.prevStep,
|
||||
prevStepMobile: state.prevStepMobile,
|
||||
selectQuantity: state.selectQuantity,
|
||||
@@ -96,19 +98,13 @@ export default function ActionButtons({
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Price details",
|
||||
})}
|
||||
{isPriceDetailsOpen ? (
|
||||
<MaterialIcon
|
||||
icon="keyboard_arrow_up"
|
||||
size={20}
|
||||
color="Icon/Interactive/Accent"
|
||||
/>
|
||||
) : (
|
||||
<MaterialIcon
|
||||
icon="keyboard_arrow_down"
|
||||
size={20}
|
||||
color="Icon/Interactive/Accent"
|
||||
/>
|
||||
)}
|
||||
<MaterialIcon
|
||||
icon={
|
||||
isPriceDetailsOpen ? "keyboard_arrow_up" : "keyboard_arrow_down"
|
||||
}
|
||||
size={20}
|
||||
color="Icon/Interactive/Accent"
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
<div className={styles.buttons}>
|
||||
@@ -140,7 +136,7 @@ export default function ActionButtons({
|
||||
<Button
|
||||
type="button"
|
||||
typography="Body/Supporting text (caption)/smBold"
|
||||
variant="Secondary"
|
||||
variant={isBreakfast ? "Primary" : "Secondary"}
|
||||
size="Small"
|
||||
isDisabled={isSubmitting}
|
||||
onPress={handleNextStep}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Fragment } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
@@ -44,7 +45,7 @@ export default function PriceSummary({
|
||||
<Divider color="subtle" />
|
||||
|
||||
{items.map((item) => (
|
||||
<>
|
||||
<Fragment key={item.title}>
|
||||
{!!item.quantityWithCard && (
|
||||
<PriceRow
|
||||
title={item.title}
|
||||
@@ -68,7 +69,7 @@ export default function PriceSummary({
|
||||
/>
|
||||
)}
|
||||
<Divider color="subtle" />
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
<div className={styles.column}>
|
||||
|
||||
@@ -37,7 +37,10 @@ export default function PriceDetails({
|
||||
const quantityWithPoints = useWatch({ name: "quantityWithPoints" })
|
||||
const quantityWithCard = useWatch({ name: "quantityWithCard" })
|
||||
|
||||
if (!selectedAncillary || currentStep !== AncillaryStepEnum.confirmation) {
|
||||
if (
|
||||
!selectedAncillary ||
|
||||
(currentStep !== AncillaryStepEnum.confirmation && !isBreakfast)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -147,8 +150,69 @@ export default function PriceDetails({
|
||||
</p>
|
||||
</Typography>
|
||||
)}
|
||||
{isBreakfast && breakfastData ? (
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p className={styles.hideOnDesktop}>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
"{totalNights, plural, one {# night} other {# nights}}",
|
||||
},
|
||||
{
|
||||
totalNights: breakfastData.nrOfNights,
|
||||
}
|
||||
) +
|
||||
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
|
||||
" / " +
|
||||
intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
"{value, plural, one {# guest} other {# guests}}",
|
||||
},
|
||||
{
|
||||
value:
|
||||
breakfastData.nrOfAdults +
|
||||
breakfastData.nrOfPayingChildren +
|
||||
breakfastData.nrOfFreeChildren,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</Typography>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.totalPriceValue}>
|
||||
{isBreakfast && breakfastData ? (
|
||||
<>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p className={styles.showOnDesktop}>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
"{totalNights, plural, one {# night} other {# nights}}",
|
||||
},
|
||||
{
|
||||
totalNights: breakfastData.nrOfNights,
|
||||
}
|
||||
) +
|
||||
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
|
||||
" / " +
|
||||
intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
"{value, plural, one {# guest} other {# guests}}",
|
||||
},
|
||||
{
|
||||
value:
|
||||
breakfastData.nrOfAdults +
|
||||
breakfastData.nrOfPayingChildren +
|
||||
breakfastData.nrOfFreeChildren,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</Typography>
|
||||
<Divider variant="vertical" color="subtle" />
|
||||
</>
|
||||
) : null}
|
||||
{hasTotalPrice && (
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p>
|
||||
@@ -185,7 +249,7 @@ export default function PriceDetails({
|
||||
</div>
|
||||
</div>
|
||||
<Divider color="subtle" />
|
||||
{isPriceDetailsOpen && (
|
||||
{isPriceDetailsOpen && currentStep === AncillaryStepEnum.confirmation && (
|
||||
<PriceSummary
|
||||
totalPrice={totalPrice}
|
||||
totalPoints={totalPoints}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
.totalPrice {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--Spacing-x1);
|
||||
padding: var(--Spacing-x-one-and-half);
|
||||
background-color: var(--Base-Surface-Secondary-light-Normal);
|
||||
border-radius: var(--Corner-radius-md);
|
||||
}
|
||||
.showOnDesktop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.totalPriceInclVAT {
|
||||
display: flex;
|
||||
gap: var(--Space-x15);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.totalPriceValue {
|
||||
@@ -22,3 +26,15 @@
|
||||
.vatText {
|
||||
color: var(--Text-Tertiary);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.showOnDesktop {
|
||||
display: block;
|
||||
}
|
||||
.hideOnDesktop {
|
||||
display: none;
|
||||
}
|
||||
.totalPrice {
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,10 +126,6 @@ function BreakfastInfo() {
|
||||
const intl = useIntl()
|
||||
const breakfastData = useAddAncillaryStore((state) => state.breakfastData)
|
||||
|
||||
const { setValue } = useFormContext()
|
||||
|
||||
setValue("quantityWithCard", 1)
|
||||
|
||||
if (!breakfastData) {
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Can not show breakfast prices.",
|
||||
|
||||
@@ -91,7 +91,8 @@ export default function AddAncillaryFlowModal({
|
||||
const formMethods = useForm<AncillaryFormData>({
|
||||
defaultValues: {
|
||||
quantityWithPoints: null,
|
||||
quantityWithCard: !user || hasInsufficientPoints ? 1 : null,
|
||||
quantityWithCard:
|
||||
!user || hasInsufficientPoints || isBreakfast ? 1 : null,
|
||||
deliveryTime: defaultDeliveryTime,
|
||||
optionalText: "",
|
||||
termsAndConditions: false,
|
||||
@@ -357,17 +358,17 @@ export default function AddAncillaryFlowModal({
|
||||
<div className={styles.contentContainer}>
|
||||
<div className={styles.price}>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p>
|
||||
{isBreakfast ? (
|
||||
<BreakfastPriceList />
|
||||
) : (
|
||||
formatPrice(
|
||||
{isBreakfast ? (
|
||||
<BreakfastPriceList />
|
||||
) : (
|
||||
<p>
|
||||
{formatPrice(
|
||||
intl,
|
||||
selectedAncillary.price.total,
|
||||
selectedAncillary.price.currency
|
||||
)
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</Typography>
|
||||
{selectedAncillary.points && (
|
||||
<div className={styles.pointsDivider}>
|
||||
@@ -406,7 +407,8 @@ export default function AddAncillaryFlowModal({
|
||||
{currentStep === AncillaryStepEnum.selectAncillary ? null : (
|
||||
<div
|
||||
className={
|
||||
currentStep === AncillaryStepEnum.confirmation
|
||||
currentStep === AncillaryStepEnum.confirmation ||
|
||||
isBreakfast
|
||||
? styles.confirmStep
|
||||
: ""
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x-half);
|
||||
padding: 0 var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.header {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Fragment } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
@@ -71,7 +72,7 @@ export function AddedAncillaries({
|
||||
} X${ancillary.totalUnit}`
|
||||
|
||||
return (
|
||||
<>
|
||||
<Fragment key={ancillary.code}>
|
||||
<Accordion className={styles.ancillaryMobile}>
|
||||
<AccordionItem
|
||||
title={ancillaryTitle}
|
||||
@@ -209,7 +210,7 @@ export function AddedAncillaries({
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</Fragment>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user