fix(sw-2501): remove the continue buttons on enter details This removes the continue buttons on the enter details page. This is only that, not the refactoring of the whole enter details page with changing to one form etc. Since I just didn’t complete that refactor today I decided to do this light variant for now. A quick explanation is that the continue buttons are removed and instead the form is submitted (meaning saving the form data to the store) on blur on the input elements IF the form is valid. If it’s invalid we change the isComplete flag in the store to false. This will hopefully also fix a bug where you were able to submit old data if the new data is invalid. When clicking the submit button and a room is incomplete/invalid the browser scrolls to the first invalid room. Approved-by: Erik Tiekstra
157 lines
4.9 KiB
TypeScript
157 lines
4.9 KiB
TypeScript
"use client"
|
|
import { zodResolver } from "@hookform/resolvers/zod"
|
|
import { useCallback, useEffect } from "react"
|
|
import { FormProvider, useForm } from "react-hook-form"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import SpecialRequests from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests"
|
|
import CountrySelect from "@/components/TempDesignSystem/Form/Country"
|
|
import Input from "@/components/TempDesignSystem/Form/Input"
|
|
import Phone from "@/components/TempDesignSystem/Form/Phone"
|
|
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
|
import { useRoomContext } from "@/contexts/Details/Room"
|
|
|
|
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
|
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
|
import Signup from "./Signup"
|
|
|
|
import styles from "./details.module.css"
|
|
|
|
import type {
|
|
DetailsProps,
|
|
DetailsSchema,
|
|
} from "@/types/components/hotelReservation/enterDetails/details"
|
|
|
|
const formID = "enter-details"
|
|
export default function Details({ user }: DetailsProps) {
|
|
const intl = useIntl()
|
|
|
|
const {
|
|
actions: { updateDetails, setIncomplete },
|
|
room,
|
|
roomNr,
|
|
} = useRoomContext()
|
|
const initialData = room.guest
|
|
|
|
const memberRate = "member" in room.roomRate ? room.roomRate.member : null
|
|
|
|
const methods = useForm<DetailsSchema>({
|
|
criteriaMode: "all",
|
|
mode: "all",
|
|
resolver: zodResolver(user ? signedInDetailsSchema : guestDetailsSchema),
|
|
reValidateMode: "onChange",
|
|
values: {
|
|
countryCode: user?.address?.countryCode ?? initialData.countryCode,
|
|
dateOfBirth:
|
|
"dateOfBirth" in initialData ? initialData.dateOfBirth : undefined,
|
|
email: user?.email ?? initialData.email,
|
|
firstName: user?.firstName ?? initialData.firstName,
|
|
join: initialData.join,
|
|
lastName: user?.lastName ?? initialData.lastName,
|
|
membershipNo: initialData.membershipNo,
|
|
phoneNumber: user?.phoneNumber ?? initialData.phoneNumber,
|
|
zipCode: "zipCode" in initialData ? initialData.zipCode : undefined,
|
|
specialRequest: {
|
|
comment: room.specialRequest.comment,
|
|
},
|
|
},
|
|
})
|
|
|
|
const onSubmit = useCallback(
|
|
(values: DetailsSchema) => {
|
|
updateDetails(values)
|
|
},
|
|
[updateDetails]
|
|
)
|
|
|
|
const updateDetailsStore = useCallback(() => {
|
|
if (methods.formState.isValid) {
|
|
methods.handleSubmit(onSubmit)()
|
|
} else {
|
|
setIncomplete()
|
|
}
|
|
}, [methods, onSubmit, setIncomplete])
|
|
|
|
useEffect(updateDetailsStore, [methods.formState.isValid, updateDetailsStore])
|
|
|
|
return (
|
|
<FormProvider {...methods}>
|
|
<form
|
|
className={styles.form}
|
|
id={`${formID}-room-${roomNr}`}
|
|
onSubmit={methods.handleSubmit(onSubmit)}
|
|
>
|
|
{user || !memberRate ? null : <JoinScandicFriendsCard />}
|
|
<div className={styles.container}>
|
|
<Footnote
|
|
color="uiTextHighContrast"
|
|
textTransform="uppercase"
|
|
type="label"
|
|
className={styles.fullWidth}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Guest information",
|
|
})}
|
|
</Footnote>
|
|
<Input
|
|
label={intl.formatMessage({
|
|
defaultMessage: "First name",
|
|
})}
|
|
maxLength={30}
|
|
name="firstName"
|
|
readOnly={!!user}
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
<Input
|
|
label={intl.formatMessage({
|
|
defaultMessage: "Last name",
|
|
})}
|
|
maxLength={30}
|
|
name="lastName"
|
|
readOnly={!!user}
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
<CountrySelect
|
|
className={styles.fullWidth}
|
|
label={intl.formatMessage({
|
|
defaultMessage: "Country",
|
|
})}
|
|
name="countryCode"
|
|
readOnly={!!user}
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
<Input
|
|
className={styles.fullWidth}
|
|
label={intl.formatMessage({
|
|
defaultMessage: "Email address",
|
|
})}
|
|
name="email"
|
|
readOnly={!!user}
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
<Phone
|
|
className={styles.fullWidth}
|
|
label={intl.formatMessage({
|
|
defaultMessage: "Phone number",
|
|
})}
|
|
name="phoneNumber"
|
|
readOnly={!!user}
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
{user ? null : (
|
|
<div className={styles.fullWidth}>
|
|
<Signup
|
|
name="join"
|
|
registerOptions={{ onBlur: updateDetailsStore }}
|
|
/>
|
|
</div>
|
|
)}
|
|
<SpecialRequests
|
|
registerOptions={{ required: true, onBlur: updateDetailsStore }}
|
|
/>
|
|
</div>
|
|
</form>
|
|
</FormProvider>
|
|
)
|
|
}
|