fix: handle submit from summary bottom sheet

This commit is contained in:
Christel Westerberg
2024-11-11 11:00:43 +01:00
parent ee6aa8d188
commit daed74481e
7 changed files with 87 additions and 29 deletions

View File

@@ -11,7 +11,7 @@
.enter-details-layout__content {
display: grid;
gap: var(--Spacing-x3) var(--Spacing-x9);
margin: var(--Spacing-x5) auto 0;
margin: var(--Spacing-x3) var(--Spacing-x2) 0;
/* simulates padding on viewport smaller than --max-width-navigation */
width: min(
calc(100dvw - (var(--Spacing-x2) * 2)),
@@ -31,6 +31,7 @@
.enter-details-layout__content {
grid-template-columns: 1fr 340px;
grid-template-rows: auto 1fr;
margin: var(--Spacing-x5) auto 0;
}
.enter-details-layout__summaryContainer {

View File

@@ -45,6 +45,8 @@ import { BreakfastPackageEnum } from "@/types/enums/breakfast"
const maxRetries = 40
const retryInterval = 2000
export const formId = "submit-booking"
function isPaymentMethodEnum(value: string): value is PaymentMethodEnum {
return Object.values(PaymentMethodEnum).includes(value as PaymentMethodEnum)
}
@@ -59,10 +61,13 @@ export default function Payment({
const lang = useLang()
const intl = useIntl()
const queryParams = useSearchParams()
const { userData, roomData } = useEnterDetailsStore((state) => ({
userData: state.userData,
roomData: state.roomData,
}))
const { userData, roomData, setIsSubmittingDisabled } = useEnterDetailsStore(
(state) => ({
userData: state.userData,
roomData: state.roomData,
setIsSubmittingDisabled: state.setIsSubmittingDisabled,
})
)
const {
firstName,
@@ -119,6 +124,16 @@ export default function Payment({
}
}, [bookingStatus, router])
useEffect(() => {
setIsSubmittingDisabled(
!methods.formState.isValid || methods.formState.isSubmitting
)
}, [
methods.formState.isValid,
methods.formState.isSubmitting,
setIsSubmittingDisabled,
])
function handleSubmit(data: PaymentFormData) {
const allQueryParams =
queryParams.size > 0 ? `?${queryParams.toString()}` : ""
@@ -209,6 +224,7 @@ export default function Payment({
<form
className={styles.paymentContainer}
onSubmit={methods.handleSubmit(handleSubmit)}
id={formId}
>
{mustBeGuaranteed ? (
<section className={styles.section}>
@@ -309,15 +325,16 @@ export default function Payment({
</Caption>
</AriaLabel>
</section>
<Button
type="submit"
className={styles.submitButton}
disabled={
!methods.formState.isValid || methods.formState.isSubmitting
}
>
{intl.formatMessage({ id: "Complete booking & go to payment" })}
</Button>
<div className={styles.submitButton}>
<Button
type="submit"
disabled={
!methods.formState.isValid || methods.formState.isSubmitting
}
>
{intl.formatMessage({ id: "Complete booking" })}
</Button>
</div>
</form>
</FormProvider>
)

View File

@@ -18,7 +18,7 @@
}
.submitButton {
align-self: flex-start;
display: none;
}
.paymentContainer .link {
@@ -31,3 +31,10 @@
flex-direction: row;
gap: var(--Spacing-x-one-and-half);
}
@media screen and (min-width: 1367px) {
.submitButton {
display: flex;
align-self: flex-start;
}
}

View File

@@ -3,7 +3,6 @@
display: flex;
flex-direction: row;
gap: var(--Spacing-x-one-and-half);
padding-top: var(--Spacing-x3);
}
.main {
@@ -67,6 +66,7 @@
@media screen and (min-width: 1367px) {
.wrapper {
gap: var(--Spacing-x3);
padding-top: var(--Spacing-x3);
}
.iconWrapper {

View File

@@ -13,8 +13,6 @@
grid-template-columns: 1fr auto;
padding: var(--Spacing-x2) var(--Spacing-x3) var(--Spacing-x5)
var(--Spacing-x3);
justify-content: space-between;
width: auto;
align-items: flex-start;
transition: 0.5s ease-in-out;
}
@@ -24,11 +22,9 @@
border: none;
background: none;
text-align: start;
opacity: 1;
transition:
opacity 0.5s ease-in-out,
padding 0.5s ease-in-out;
transition: padding 0.5s ease-in-out;
cursor: pointer;
white-space: nowrap;
}
.wrapper[data-open="true"] {
@@ -36,15 +32,39 @@
}
.wrapper[data-open="true"] .bottomSheet {
grid-template-columns: 0fr 1fr;
grid-template-columns: 0fr auto;
}
.wrapper[data-open="true"] .priceDetailsButton {
animation: fadeOut 0.3s ease-out;
opacity: 0;
padding: 0;
}
.wrapper[data-open="false"] .priceDetailsButton {
animation: fadeIn 0.8s ease-in;
opacity: 1;
}
.content,
.priceDetailsButton {
overflow: hidden;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

View File

@@ -1,6 +1,6 @@
"use client"
import { PropsWithChildren, useState } from "react"
import { PropsWithChildren } from "react"
import { useIntl } from "react-intl"
import { useEnterDetailsStore } from "@/stores/enter-details"
@@ -9,18 +9,20 @@ import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formId } from "../../Payment"
import styles from "./bottomSheet.module.css"
export function SummaryBottomSheet({ children }: PropsWithChildren) {
const intl = useIntl()
const { isSummaryOpen, toggleSummaryOpen, totalPrice } = useEnterDetailsStore(
(state) => ({
const { isSummaryOpen, toggleSummaryOpen, totalPrice, isSubmittingDisabled } =
useEnterDetailsStore((state) => ({
isSummaryOpen: state.isSummaryOpen,
toggleSummaryOpen: state.toggleSummaryOpen,
totalPrice: state.totalPrice,
})
)
isSubmittingDisabled: state.isSubmittingDisabled,
}))
return (
<div className={styles.wrapper} data-open={isSummaryOpen}>
@@ -45,7 +47,13 @@ export function SummaryBottomSheet({ children }: PropsWithChildren) {
{intl.formatMessage({ id: "See details" })}
</Caption>
</button>
<Button intent="primary" size="large" type="submit">
<Button
intent="primary"
size="large"
type="submit"
disabled={isSubmittingDisabled}
form={formId}
>
{intl.formatMessage({ id: "Complete booking" })}
</Button>
</div>

View File

@@ -38,6 +38,7 @@ interface EnterDetailsState {
selectRateUrl: string
currentStep: StepEnum
totalPrice: TotalPrice
isSubmittingDisabled: boolean
isSummaryOpen: boolean
isValid: Record<StepEnum, boolean>
completeStep: (updatedData: Partial<EnterDetailsState["userData"]>) => void
@@ -51,6 +52,7 @@ interface EnterDetailsState {
setCurrentStep: (step: StepEnum) => void
toggleSummaryOpen: () => void
setTotalPrice: (totalPrice: TotalPrice) => void
setIsSubmittingDisabled: (isSubmittingDisabled: boolean) => void
}
export function initEditDetailsState(
@@ -143,6 +145,7 @@ export function initEditDetailsState(
euro: { price: 0, currency: "" },
},
isSummaryOpen: false,
isSubmittingDisabled: false,
setCurrentStep: (step) => set({ currentStep: step }),
navigate: (step, updatedData) =>
set(
@@ -182,6 +185,8 @@ export function initEditDetailsState(
),
toggleSummaryOpen: () => set({ isSummaryOpen: !get().isSummaryOpen }),
setTotalPrice: (totalPrice) => set({ totalPrice: totalPrice }),
setIsSubmittingDisabled: (isSubmittingDisabled) =>
set({ isSubmittingDisabled }),
}))
}