fix: handle submit from summary bottom sheet
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 }),
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user