Merged in feat/sw-1245-bw-button-update (pull request #2262)
Feat/sw 1245 - Booking widget - change button text when new values * feat(sw-1245) - use isDirty to update button text * Change text only in booking flow * Revert test code Approved-by: Michael Zetterberg
This commit is contained in:
@@ -28,10 +28,14 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
||||
|
||||
const close = useCallback(() => {
|
||||
if (!selectedDate.toDate) {
|
||||
setValue(name, {
|
||||
fromDate: selectedDate.fromDate,
|
||||
toDate: dt(selectedDate.fromDate).add(1, "day").format("YYYY-MM-DD"),
|
||||
})
|
||||
setValue(
|
||||
name,
|
||||
{
|
||||
fromDate: selectedDate.fromDate,
|
||||
toDate: dt(selectedDate.fromDate).add(1, "day").format("YYYY-MM-DD"),
|
||||
},
|
||||
{ shouldDirty: true }
|
||||
)
|
||||
}
|
||||
|
||||
setIsOpen(false)
|
||||
@@ -54,10 +58,14 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
||||
// Handle form value updates based on the requirements
|
||||
if (selectedDate.fromDate && selectedDate.toDate) {
|
||||
// Both dates were previously selected, starting fresh with new date
|
||||
setValue(name, {
|
||||
fromDate: dateClickedFormatted,
|
||||
toDate: undefined,
|
||||
})
|
||||
setValue(
|
||||
name,
|
||||
{
|
||||
fromDate: dateClickedFormatted,
|
||||
toDate: undefined,
|
||||
},
|
||||
{ shouldDirty: true }
|
||||
)
|
||||
} else if (selectedDate.fromDate && !selectedDate.toDate) {
|
||||
// If the selected day is the same as the first date, we don't need to update the form value
|
||||
if (dateClicked.isSame(selectedDate.fromDate)) {
|
||||
@@ -66,16 +74,24 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
|
||||
// We're selecting the second date
|
||||
if (dateClicked.isBefore(selectedDate.fromDate)) {
|
||||
// If second selected date is before first date, swap them
|
||||
setValue(name, {
|
||||
fromDate: dateClickedFormatted,
|
||||
toDate: selectedDate.fromDate,
|
||||
})
|
||||
setValue(
|
||||
name,
|
||||
{
|
||||
fromDate: dateClickedFormatted,
|
||||
toDate: selectedDate.fromDate,
|
||||
},
|
||||
{ shouldDirty: true }
|
||||
)
|
||||
} else {
|
||||
// If second selected date is after first date, keep order
|
||||
setValue(name, {
|
||||
fromDate: selectedDate.fromDate,
|
||||
toDate: dateClickedFormatted,
|
||||
})
|
||||
setValue(
|
||||
name,
|
||||
{
|
||||
fromDate: selectedDate.fromDate,
|
||||
toDate: dateClickedFormatted,
|
||||
},
|
||||
{ shouldDirty: true }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,13 +60,18 @@ export default function BookingCode() {
|
||||
|
||||
function updateBookingCodeFormValue(value: string) {
|
||||
// Set value and show error if validation fails
|
||||
setValue("bookingCode.value", value.toUpperCase(), { shouldValidate: true })
|
||||
setValue("bookingCode.value", value.toUpperCase(), {
|
||||
shouldValidate: true,
|
||||
shouldDirty: true,
|
||||
})
|
||||
|
||||
if (getValues(REDEMPTION)) {
|
||||
// Remove the redemption as user types booking code and show notification for the same
|
||||
// Add delay to handle table mode rendering
|
||||
setTimeout(function () {
|
||||
setValue(REDEMPTION, false)
|
||||
setValue(REDEMPTION, false, {
|
||||
shouldDirty: true,
|
||||
})
|
||||
})
|
||||
// Hide the above notification popup after 5 seconds by re-triggering validation
|
||||
// This is kept consistent with location search field error notification timeout
|
||||
@@ -87,7 +92,10 @@ export default function BookingCode() {
|
||||
) {
|
||||
setShowRemember(false)
|
||||
if (codeError) {
|
||||
setValue("bookingCode.value", "", { shouldValidate: true })
|
||||
setValue("bookingCode.value", "", {
|
||||
shouldValidate: true,
|
||||
shouldDirty: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -306,7 +314,7 @@ export function RemoveExtraRooms({ ...props }: ButtonProps) {
|
||||
// Timeout to delay the event scheduling issue with touch events on mobile
|
||||
window.setTimeout(() => {
|
||||
const rooms = getValues("rooms")[0]
|
||||
setValue("rooms", [rooms], { shouldValidate: true })
|
||||
setValue("rooms", [rooms], { shouldValidate: true, shouldDirty: true })
|
||||
trigger("bookingCode.value")
|
||||
trigger(REDEMPTION)
|
||||
}, 300)
|
||||
@@ -357,12 +365,12 @@ function TabletBookingCode({
|
||||
}
|
||||
}
|
||||
if (!isOpen && !bookingCode?.value) {
|
||||
setValue("bookingCode.flag", false)
|
||||
setValue("bookingCode.flag", false, { shouldDirty: true })
|
||||
setIsOpen(isOpen)
|
||||
} else if (!codeError || isOpen) {
|
||||
setIsOpen(isOpen)
|
||||
if (isOpen || bookingCode?.value) {
|
||||
setValue("bookingCode.flag", true)
|
||||
setValue("bookingCode.flag", true, { shouldDirty: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +386,7 @@ function TabletBookingCode({
|
||||
{...register("bookingCode.flag", {
|
||||
onChange: function () {
|
||||
if (bookingCode?.value || isOpen) {
|
||||
setValue("bookingCode.flag", true)
|
||||
setValue("bookingCode.flag", true, { shouldDirty: true })
|
||||
}
|
||||
},
|
||||
})}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
"use client"
|
||||
|
||||
import { usePathname } from "next/navigation"
|
||||
import { useFormContext, useWatch } from "react-hook-form"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { hotelreservation } from "@/constants/routes/hotelReservation"
|
||||
import { dt } from "@/lib/dt"
|
||||
|
||||
import DatePicker from "@/components/DatePicker"
|
||||
import GuestsRoomsPickerForm from "@/components/GuestsRoomsPicker"
|
||||
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import { RemoveExtraRooms } from "./BookingCode"
|
||||
import { Search, SearchSkeleton } from "./Search"
|
||||
@@ -30,9 +33,13 @@ export default function FormContent({
|
||||
}: BookingWidgetFormContentProps) {
|
||||
const intl = useIntl()
|
||||
const {
|
||||
formState: { errors },
|
||||
formState: { errors, isDirty },
|
||||
} = useFormContext<BookingWidgetSchema>()
|
||||
|
||||
const lang = useLang()
|
||||
const pathName = usePathname()
|
||||
const isBookingFlow = pathName.includes(hotelreservation(lang))
|
||||
|
||||
const selectedDate = useWatch<BookingWidgetSchema, "date">({ name: "date" })
|
||||
|
||||
const nights = dt(selectedDate.toDate).diff(dt(selectedDate.fromDate), "days")
|
||||
@@ -121,9 +128,9 @@ export default function FormContent({
|
||||
className={styles.buttonText}
|
||||
>
|
||||
<span>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Search",
|
||||
})}
|
||||
{isDirty && isBookingFlow
|
||||
? intl.formatMessage({ defaultMessage: "Update" })
|
||||
: intl.formatMessage({ defaultMessage: "Search" })}
|
||||
</span>
|
||||
</Typography>
|
||||
<span className={styles.icon}>
|
||||
|
||||
@@ -33,7 +33,8 @@ export default function Form({ type, onClose }: BookingWidgetFormProps) {
|
||||
type,
|
||||
})
|
||||
|
||||
const { handleSubmit, setValue } = useFormContext<BookingWidgetSchema>()
|
||||
const { handleSubmit, setValue, reset } =
|
||||
useFormContext<BookingWidgetSchema>()
|
||||
|
||||
function onSubmit(data: BookingWidgetSchema) {
|
||||
const bookingFlowPage = data.hotel ? selectRate(lang) : selectHotel(lang)
|
||||
@@ -54,11 +55,14 @@ export default function Form({ type, onClose }: BookingWidgetFormProps) {
|
||||
router.push(`${bookingFlowPage}?${bookingWidgetParams.toString()}`)
|
||||
})
|
||||
if (!data.bookingCode?.value) {
|
||||
setValue("bookingCode.remember", false)
|
||||
setValue("bookingCode.remember", false, {
|
||||
shouldDirty: true,
|
||||
})
|
||||
localStorage.removeItem("bookingCode")
|
||||
} else if (data.bookingCode?.remember) {
|
||||
localStorage.setItem("bookingCode", JSON.stringify(data.bookingCode))
|
||||
}
|
||||
reset(data)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -24,13 +24,13 @@ export default function AdultSelector({
|
||||
|
||||
function increaseAdultsCount() {
|
||||
if (currentAdults < 6) {
|
||||
setValue(name, currentAdults + 1)
|
||||
setValue(name, currentAdults + 1, { shouldDirty: true })
|
||||
}
|
||||
}
|
||||
|
||||
function decreaseAdultsCount() {
|
||||
if (currentAdults > 1) {
|
||||
setValue(name, currentAdults - 1)
|
||||
setValue(name, currentAdults - 1, { shouldDirty: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,16 +26,22 @@ export default function ChildSelector({
|
||||
|
||||
function increaseChildrenCount(roomIndex: number) {
|
||||
if (currentChildren.length < 5) {
|
||||
setValue(`rooms.${roomIndex}.childrenInRoom.${currentChildren.length}`, {
|
||||
age: undefined,
|
||||
bed: undefined,
|
||||
})
|
||||
setValue(
|
||||
`rooms.${roomIndex}.childrenInRoom.${currentChildren.length}`,
|
||||
{
|
||||
age: undefined,
|
||||
bed: undefined,
|
||||
},
|
||||
{ shouldDirty: true }
|
||||
)
|
||||
}
|
||||
}
|
||||
function decreaseChildrenCount(roomIndex: number) {
|
||||
if (currentChildren.length > 0) {
|
||||
currentChildren.pop()
|
||||
setValue(`rooms.${roomIndex}.childrenInRoom`, currentChildren)
|
||||
setValue(`rooms.${roomIndex}.childrenInRoom`, currentChildren, {
|
||||
shouldDirty: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ export default function GuestsRoomsPickerDialog({
|
||||
const handleAddRoom = useCallback(() => {
|
||||
setValue("rooms", [...roomsValue, { adults: 1, childrenInRoom: [] }], {
|
||||
shouldValidate: true,
|
||||
shouldDirty: true,
|
||||
})
|
||||
}, [roomsValue, setValue])
|
||||
|
||||
@@ -66,7 +67,7 @@ export default function GuestsRoomsPickerDialog({
|
||||
setValue(
|
||||
"rooms",
|
||||
roomsValue.filter((_, i) => i !== index),
|
||||
{ shouldValidate: true }
|
||||
{ shouldValidate: true, shouldDirty: true }
|
||||
)
|
||||
},
|
||||
[roomsValue, setValue]
|
||||
|
||||
Reference in New Issue
Block a user