Merged in fix/sw-1897-member-price-modal (pull request #1856)
fix(sw-1897): show member price modal immediately * fix(sw-1897): show member price modal immediately * Make checkbox fully controlled * Remove action in the store that wasn't used Approved-by: Hrishikesh Vaipurkar
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { useState } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
@@ -9,6 +10,8 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|||||||
import { useRoomContext } from "@/contexts/Details/Room"
|
import { useRoomContext } from "@/contexts/Details/Room"
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
|
import MemberPriceModal from "../../MemberPriceModal"
|
||||||
|
|
||||||
import styles from "./joinScandicFriendsCard.module.css"
|
import styles from "./joinScandicFriendsCard.module.css"
|
||||||
|
|
||||||
import type { JoinScandicFriendsCardProps } from "@/types/components/hotelReservation/enterDetails/details"
|
import type { JoinScandicFriendsCardProps } from "@/types/components/hotelReservation/enterDetails/details"
|
||||||
@@ -18,7 +21,19 @@ export default function JoinScandicFriendsCard({
|
|||||||
name = "join",
|
name = "join",
|
||||||
}: JoinScandicFriendsCardProps) {
|
}: JoinScandicFriendsCardProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const { room, roomNr } = useRoomContext()
|
const {
|
||||||
|
room,
|
||||||
|
roomNr,
|
||||||
|
actions: { updateJoin },
|
||||||
|
} = useRoomContext()
|
||||||
|
const [isMemberPriceModalOpen, setIsMemberPriceModalOpen] = useState(false)
|
||||||
|
|
||||||
|
function onChange(event: { target: { value: boolean } }) {
|
||||||
|
updateJoin(event.target.value)
|
||||||
|
if (event.target.value) {
|
||||||
|
setIsMemberPriceModalOpen(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!("member" in room.roomRate) || !room.roomRate.member) {
|
if (!("member" in room.roomRate) || !room.roomRate.member) {
|
||||||
return null
|
return null
|
||||||
@@ -58,7 +73,11 @@ export default function JoinScandicFriendsCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.cardContainer}>
|
<div className={styles.cardContainer}>
|
||||||
<Checkbox name={name} className={styles.checkBox}>
|
<Checkbox
|
||||||
|
name={name}
|
||||||
|
className={styles.checkBox}
|
||||||
|
registerOptions={{ onChange, value: room.guest.join }}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<Caption type="label" textTransform="uppercase" color="red">
|
<Caption type="label" textTransform="uppercase" color="red">
|
||||||
{saveOnJoiningLabel}
|
{saveOnJoiningLabel}
|
||||||
@@ -88,6 +107,10 @@ export default function JoinScandicFriendsCard({
|
|||||||
</Caption>
|
</Caption>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<MemberPriceModal
|
||||||
|
isOpen={isMemberPriceModalOpen}
|
||||||
|
setIsOpen={setIsMemberPriceModalOpen}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { useState } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
@@ -15,6 +16,8 @@ import { useRoomContext } from "@/contexts/Details/Room"
|
|||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
|
import MemberPriceModal from "../../MemberPriceModal"
|
||||||
|
|
||||||
import styles from "./joinScandicFriendsCard.module.css"
|
import styles from "./joinScandicFriendsCard.module.css"
|
||||||
|
|
||||||
import type { JoinScandicFriendsCardProps } from "@/types/components/hotelReservation/enterDetails/details"
|
import type { JoinScandicFriendsCardProps } from "@/types/components/hotelReservation/enterDetails/details"
|
||||||
@@ -25,7 +28,18 @@ export default function JoinScandicFriendsCard({
|
|||||||
}: JoinScandicFriendsCardProps) {
|
}: JoinScandicFriendsCardProps) {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const { room } = useRoomContext()
|
const {
|
||||||
|
room,
|
||||||
|
actions: { updateJoin },
|
||||||
|
} = useRoomContext()
|
||||||
|
const [isMemberPriceModalOpen, setIsMemberPriceModalOpen] = useState(false)
|
||||||
|
|
||||||
|
function onChange(event: { target: { value: boolean } }) {
|
||||||
|
updateJoin(event.target.value)
|
||||||
|
if (event.target.value) {
|
||||||
|
setIsMemberPriceModalOpen(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!("member" in room.roomRate) || !room.roomRate.member) {
|
if (!("member" in room.roomRate) || !room.roomRate.member) {
|
||||||
return null
|
return null
|
||||||
@@ -64,7 +78,11 @@ export default function JoinScandicFriendsCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.cardContainer}>
|
<div className={styles.cardContainer}>
|
||||||
<Checkbox name={name} className={styles.checkBox}>
|
<Checkbox
|
||||||
|
name={name}
|
||||||
|
className={styles.checkBox}
|
||||||
|
registerOptions={{ onChange }}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<Caption type="label" textTransform="uppercase" color="red">
|
<Caption type="label" textTransform="uppercase" color="red">
|
||||||
{saveOnJoiningLabel}
|
{saveOnJoiningLabel}
|
||||||
@@ -138,6 +156,10 @@ export default function JoinScandicFriendsCard({
|
|||||||
)}
|
)}
|
||||||
</Footnote>
|
</Footnote>
|
||||||
</div>
|
</div>
|
||||||
|
<MemberPriceModal
|
||||||
|
isOpen={isMemberPriceModalOpen}
|
||||||
|
setIsOpen={setIsMemberPriceModalOpen}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
import { useCallback, useState } from "react"
|
import { useCallback } from "react"
|
||||||
import { FormProvider, useForm } from "react-hook-form"
|
import { FormProvider, useForm } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
@@ -17,7 +17,6 @@ import { useRoomContext } from "@/contexts/Details/Room"
|
|||||||
import { trackPaymentSectionOpen } from "@/utils/tracking/booking"
|
import { trackPaymentSectionOpen } from "@/utils/tracking/booking"
|
||||||
|
|
||||||
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
||||||
import MemberPriceModal from "./MemberPriceModal"
|
|
||||||
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
||||||
import Signup from "./Signup"
|
import Signup from "./Signup"
|
||||||
|
|
||||||
@@ -31,7 +30,6 @@ import type {
|
|||||||
const formID = "enter-details"
|
const formID = "enter-details"
|
||||||
export default function Details({ user }: DetailsProps) {
|
export default function Details({ user }: DetailsProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const [isMemberPriceModalOpen, setIsMemberPriceModalOpen] = useState(false)
|
|
||||||
|
|
||||||
const { canProceedToPayment, lastRoom, isMultiRoom } = useEnterDetailsStore(
|
const { canProceedToPayment, lastRoom, isMultiRoom } = useEnterDetailsStore(
|
||||||
(state) => ({
|
(state) => ({
|
||||||
@@ -76,12 +74,9 @@ export default function Details({ user }: DetailsProps) {
|
|||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
(values: DetailsSchema) => {
|
(values: DetailsSchema) => {
|
||||||
if ((values.join || values.membershipNo) && memberRate && !user) {
|
|
||||||
setIsMemberPriceModalOpen(true)
|
|
||||||
}
|
|
||||||
updateDetails(values)
|
updateDetails(values)
|
||||||
},
|
},
|
||||||
[updateDetails, setIsMemberPriceModalOpen, memberRate, user]
|
[updateDetails]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -187,10 +182,6 @@ export default function Details({ user }: DetailsProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
) : null}
|
) : null}
|
||||||
<MemberPriceModal
|
|
||||||
isOpen={isMemberPriceModalOpen}
|
|
||||||
setIsOpen={setIsMemberPriceModalOpen}
|
|
||||||
/>
|
|
||||||
</form>
|
</form>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -223,6 +223,40 @@ export function createDetailsStore(
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
updateJoin(join) {
|
||||||
|
return set(
|
||||||
|
produce((state: DetailsState) => {
|
||||||
|
const currentRoom = state.rooms[idx].room
|
||||||
|
|
||||||
|
currentRoom.guest.join = join
|
||||||
|
|
||||||
|
if (join) {
|
||||||
|
currentRoom.guest.membershipNo = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
currentRoom.roomPrice = getRoomPrice(
|
||||||
|
currentRoom.roomRate,
|
||||||
|
Boolean(
|
||||||
|
join ||
|
||||||
|
currentRoom.guest.membershipNo ||
|
||||||
|
(idx === 0 && isMember)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const nights = dt(state.booking.toDate).diff(
|
||||||
|
state.booking.fromDate,
|
||||||
|
"days"
|
||||||
|
)
|
||||||
|
|
||||||
|
state.totalPrice = calcTotalPrice(
|
||||||
|
state.rooms,
|
||||||
|
state.totalPrice.local.currency,
|
||||||
|
isMember,
|
||||||
|
nights
|
||||||
|
)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
updateDetails(data) {
|
updateDetails(data) {
|
||||||
return set(
|
return set(
|
||||||
produce((state: DetailsState) => {
|
produce((state: DetailsState) => {
|
||||||
@@ -281,56 +315,6 @@ export function createDetailsStore(
|
|||||||
state.rooms[idx].isComplete = true
|
state.rooms[idx].isComplete = true
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToSessionStorage({
|
|
||||||
booking: state.booking,
|
|
||||||
rooms: state.rooms,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
},
|
|
||||||
updateMultiroomDetails(data) {
|
|
||||||
return set(
|
|
||||||
produce((state: DetailsState) => {
|
|
||||||
state.rooms[idx].steps[StepEnum.details].isValid = true
|
|
||||||
|
|
||||||
state.rooms[idx].room.guest.countryCode = data.countryCode
|
|
||||||
state.rooms[idx].room.guest.email = data.email
|
|
||||||
state.rooms[idx].room.guest.firstName = data.firstName
|
|
||||||
state.rooms[idx].room.guest.join = data.join
|
|
||||||
state.rooms[idx].room.guest.lastName = data.lastName
|
|
||||||
|
|
||||||
if (data.join) {
|
|
||||||
state.rooms[idx].room.guest.membershipNo = undefined
|
|
||||||
} else {
|
|
||||||
state.rooms[idx].room.guest.membershipNo = data.membershipNo
|
|
||||||
}
|
|
||||||
state.rooms[idx].room.guest.phoneNumber = data.phoneNumber
|
|
||||||
|
|
||||||
const getMemberPrice = Boolean(data.join || data.membershipNo)
|
|
||||||
state.rooms[idx].room.roomPrice = getRoomPrice(
|
|
||||||
state.rooms[idx].room.roomRate,
|
|
||||||
getMemberPrice
|
|
||||||
)
|
|
||||||
|
|
||||||
const nights = dt(state.booking.toDate).diff(
|
|
||||||
state.booking.fromDate,
|
|
||||||
"days"
|
|
||||||
)
|
|
||||||
|
|
||||||
state.totalPrice = calcTotalPrice(
|
|
||||||
state.rooms,
|
|
||||||
state.totalPrice.local.currency,
|
|
||||||
getMemberPrice,
|
|
||||||
nights
|
|
||||||
)
|
|
||||||
|
|
||||||
const isAllStepsCompleted = checkRoomProgress(
|
|
||||||
state.rooms[idx].steps
|
|
||||||
)
|
|
||||||
if (isAllStepsCompleted) {
|
|
||||||
state.rooms[idx].isComplete = true
|
|
||||||
}
|
|
||||||
|
|
||||||
writeToSessionStorage({
|
writeToSessionStorage({
|
||||||
booking: state.booking,
|
booking: state.booking,
|
||||||
rooms: state.rooms,
|
rooms: state.rooms,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface RoomContextValue {
|
|||||||
actions: {
|
actions: {
|
||||||
updateBedType: (data: BedTypeSchema) => void
|
updateBedType: (data: BedTypeSchema) => void
|
||||||
updateBreakfast: (data: BreakfastPackage | false) => void
|
updateBreakfast: (data: BreakfastPackage | false) => void
|
||||||
|
updateJoin: (join: boolean) => void
|
||||||
updateDetails: (data: DetailsSchema) => void
|
updateDetails: (data: DetailsSchema) => void
|
||||||
}
|
}
|
||||||
isComplete: RoomState["isComplete"]
|
isComplete: RoomState["isComplete"]
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ export interface RoomState {
|
|||||||
actions: {
|
actions: {
|
||||||
updateBedType: (data: BedTypeSchema) => void
|
updateBedType: (data: BedTypeSchema) => void
|
||||||
updateBreakfast: (data: BreakfastPackage | false) => void
|
updateBreakfast: (data: BreakfastPackage | false) => void
|
||||||
|
updateJoin: (join: boolean) => void
|
||||||
updateDetails: (data: DetailsSchema) => void
|
updateDetails: (data: DetailsSchema) => void
|
||||||
updateMultiroomDetails: (data: MultiroomDetailsSchema) => void
|
|
||||||
}
|
}
|
||||||
isComplete: boolean
|
isComplete: boolean
|
||||||
room: Room
|
room: Room
|
||||||
|
|||||||
Reference in New Issue
Block a user