Merge remote-tracking branch 'origin' into feat/tracking-payment
This commit is contained in:
@@ -65,9 +65,6 @@ export default function RoomFilter({
|
||||
const tooltipText = intl.formatMessage({
|
||||
id: "Pet-friendly rooms have an additional fee of 20 EUR per stay",
|
||||
})
|
||||
|
||||
const showTooltip = isAboveMobile && petFriendly
|
||||
|
||||
const submitFilter = useCallback(() => {
|
||||
const data = getValues()
|
||||
onFilter(data)
|
||||
@@ -94,19 +91,14 @@ export default function RoomFilter({
|
||||
</div>
|
||||
<div className={styles.infoMobile}>
|
||||
<div className={styles.filterInfo}>
|
||||
{!isAboveMobile ? (
|
||||
<Tooltip
|
||||
text={tooltipText}
|
||||
position="bottom"
|
||||
arrow="left"
|
||||
isTouchable
|
||||
>
|
||||
<InfoCircleIcon
|
||||
color="uiTextHighContrast"
|
||||
height={20}
|
||||
width={20}
|
||||
/>
|
||||
|
||||
<Tooltip
|
||||
text={tooltipText}
|
||||
position="bottom"
|
||||
arrow="left"
|
||||
isTouchable
|
||||
>
|
||||
<InfoCircleIcon color="uiTextHighContrast" height={20} width={20} />
|
||||
<div className={styles.filter}>
|
||||
<Caption
|
||||
type="label"
|
||||
color="baseTextMediumContrast"
|
||||
@@ -114,30 +106,14 @@ export default function RoomFilter({
|
||||
>
|
||||
{intl.formatMessage({ id: "Filter" })}
|
||||
</Caption>
|
||||
<Caption type="label" color="baseTextMediumContrast">
|
||||
<Caption type="regular" color="baseTextMediumContrast">
|
||||
{Object.entries(selectedFilters)
|
||||
.filter(([_, value]) => value)
|
||||
.map(([key]) => intl.formatMessage({ id: key }))
|
||||
.join(", ")}
|
||||
</Caption>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<>
|
||||
<Caption
|
||||
type="label"
|
||||
color="baseTextMediumContrast"
|
||||
textTransform="uppercase"
|
||||
>
|
||||
{intl.formatMessage({ id: "Filter" })}
|
||||
</Caption>
|
||||
<Caption type="label" color="baseTextMediumContrast">
|
||||
{Object.entries(selectedFilters)
|
||||
.filter(([_, value]) => value)
|
||||
.map(([key]) => intl.formatMessage({ id: key }))
|
||||
.join(", ")}
|
||||
</Caption>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Caption color="uiTextHighContrast">
|
||||
{intl.formatMessage(
|
||||
@@ -170,12 +146,13 @@ export default function RoomFilter({
|
||||
/>
|
||||
)
|
||||
|
||||
return showTooltip ? (
|
||||
return isPetRoom && isAboveMobile ? (
|
||||
<Tooltip
|
||||
key={option.code}
|
||||
text={tooltipText}
|
||||
position="bottom"
|
||||
arrow="right"
|
||||
isTouchable
|
||||
>
|
||||
{checkboxChip}
|
||||
</Tooltip>
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
margin-left: var(--Spacing-x-half);
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.filterInfo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -77,24 +77,15 @@ input[type="radio"]:checked + .card .checkIcon {
|
||||
margin: 0 auto var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.popover {
|
||||
background-color: var(--Main-Grey-White);
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
left: 0px;
|
||||
max-height: 400px;
|
||||
padding: var(--Spacing-x2);
|
||||
top: calc(55px + var(--Spacing-x1));
|
||||
width: 100%;
|
||||
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
|
||||
.terms {
|
||||
margin-top: var(--Spacing-x3);
|
||||
margin-bottom: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.popover section:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
.popover .popoverText {
|
||||
margin-bottom: var(--Spacing-x-half);
|
||||
}
|
||||
.popover .popoverHeading {
|
||||
.termsText:nth-child(n) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: var(--Spacing-x1);
|
||||
font-weight: 600; /* TODO: Remove when this is updated in Design system */
|
||||
}
|
||||
.termsIcon {
|
||||
margin-right: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import { useSearchParams } from "next/navigation"
|
||||
import { useEffect, useRef } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { CheckIcon, InfoCircleIcon } from "@/components/Icons"
|
||||
import { CheckCircleIcon, CheckIcon, InfoCircleIcon } from "@/components/Icons"
|
||||
import Modal from "@/components/Modal"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Label from "@/components/TempDesignSystem/Form/Label"
|
||||
import Popover from "@/components/TempDesignSystem/Popover"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
|
||||
import { RATE_CARD_EQUAL_HEIGHT_CLASS } from "../utils"
|
||||
@@ -116,33 +118,37 @@ export default function FlexibilityOption({
|
||||
/>
|
||||
<div className={`${styles.card} ${RATE_CARD_EQUAL_HEIGHT_CLASS}`}>
|
||||
<div className={styles.header}>
|
||||
<Popover
|
||||
placement="bottom left"
|
||||
triggerContent={
|
||||
<InfoCircleIcon
|
||||
width={16}
|
||||
height={16}
|
||||
color="uiTextMediumContrast"
|
||||
/>
|
||||
<Modal
|
||||
trigger={
|
||||
<Button intent="text">
|
||||
<InfoCircleIcon
|
||||
width={16}
|
||||
height={16}
|
||||
color="uiTextMediumContrast"
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
title={name}
|
||||
subtitle={paymentTerm}
|
||||
>
|
||||
<Caption
|
||||
color="uiTextHighContrast"
|
||||
type="bold"
|
||||
className={styles.popoverHeading}
|
||||
>
|
||||
{name}
|
||||
</Caption>
|
||||
{priceInformation?.map((info) => (
|
||||
<Caption
|
||||
key={info}
|
||||
color="uiTextHighContrast"
|
||||
className={styles.popoverText}
|
||||
>
|
||||
{info}
|
||||
</Caption>
|
||||
))}
|
||||
</Popover>
|
||||
<div className={styles.terms}>
|
||||
{priceInformation?.map((info) => (
|
||||
<Body
|
||||
key={info}
|
||||
color="uiTextHighContrast"
|
||||
className={styles.termsText}
|
||||
>
|
||||
<CheckIcon
|
||||
color="uiSemanticSuccess"
|
||||
width={20}
|
||||
height={20}
|
||||
className={styles.termsIcon}
|
||||
></CheckIcon>
|
||||
{info}
|
||||
</Body>
|
||||
))}
|
||||
</div>
|
||||
</Modal>
|
||||
<div className={styles.priceType}>
|
||||
<Caption color="uiTextHighContrast">{name}</Caption>
|
||||
<Caption color="uiTextPlaceholder">({paymentTerm})</Caption>
|
||||
|
||||
@@ -85,7 +85,7 @@ export default function RoomCard({
|
||||
)
|
||||
)
|
||||
|
||||
const { name, roomSize, occupancy, images } = selectedRoom || {}
|
||||
const { name, roomSize, totalOccupancy, images } = selectedRoom || {}
|
||||
|
||||
const freeCancelation = intl.formatMessage({ id: "Free cancellation" })
|
||||
const nonRefundable = intl.formatMessage({ id: "Non-refundable" })
|
||||
@@ -150,13 +150,13 @@ export default function RoomCard({
|
||||
</div>
|
||||
|
||||
<div className={styles.specification}>
|
||||
{occupancy?.total && (
|
||||
{totalOccupancy && (
|
||||
<Caption color="uiTextMediumContrast" className={styles.guests}>
|
||||
{intl.formatMessage(
|
||||
{
|
||||
id: "booking.guests",
|
||||
},
|
||||
{ nrOfGuests: occupancy.total }
|
||||
{ max: totalOccupancy.max, range: totalOccupancy.range }
|
||||
)}
|
||||
</Caption>
|
||||
)}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
"use client"
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||
import { useSession } from "next-auth/react"
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react"
|
||||
|
||||
import { debounce } from "@/utils/debounce"
|
||||
import { isValidSession } from "@/utils/session"
|
||||
|
||||
import RateSummary from "./RateSummary"
|
||||
import RoomCard from "./RoomCard"
|
||||
@@ -20,16 +22,16 @@ import type { RoomSelectionProps } from "@/types/components/hotelReservation/sel
|
||||
export default function RoomSelection({
|
||||
roomsAvailability,
|
||||
roomCategories,
|
||||
user,
|
||||
availablePackages,
|
||||
selectedPackages,
|
||||
isUserLoggedIn,
|
||||
setRateCode,
|
||||
rateSummary,
|
||||
hotelType,
|
||||
}: RoomSelectionProps) {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const searchParams = useSearchParams()
|
||||
const isUserLoggedIn = !!user
|
||||
const roomRefs = useRef<HTMLLIElement[]>([])
|
||||
const { roomConfigurations, rateDefinitions } = roomsAvailability
|
||||
|
||||
@@ -109,9 +111,9 @@ export default function RoomSelection({
|
||||
rateSummary.member.rateCode
|
||||
)
|
||||
}
|
||||
if (selectedPackages.length > 0) {
|
||||
params.set(`room[${index}].packages`, selectedPackages.join(","))
|
||||
}
|
||||
selectedPackages.length > 0
|
||||
? params.set(`room[${index}].packages`, selectedPackages.join(","))
|
||||
: params.delete(`room[${index}].packages`)
|
||||
})
|
||||
|
||||
return params
|
||||
@@ -119,6 +121,12 @@ export default function RoomSelection({
|
||||
|
||||
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault()
|
||||
|
||||
window.history.replaceState(
|
||||
null,
|
||||
"",
|
||||
`${pathname}?${queryParams.toString()}`
|
||||
)
|
||||
router.push(`select-bed?${queryParams}`)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ import { dt } from "@/lib/dt"
|
||||
import {
|
||||
getHotelData,
|
||||
getPackages,
|
||||
getProfileSafely,
|
||||
getRoomsAvailability,
|
||||
} from "@/lib/trpc/memoizedRequests"
|
||||
|
||||
import { auth } from "@/auth"
|
||||
import { safeTry } from "@/utils/safeTry"
|
||||
import { isValidSession } from "@/utils/session"
|
||||
|
||||
import { generateChildrenString } from "../RoomSelection/utils"
|
||||
import Rooms from "."
|
||||
@@ -32,8 +33,8 @@ export async function RoomsContainer({
|
||||
childArray,
|
||||
lang,
|
||||
}: Props) {
|
||||
const user = await getProfileSafely()
|
||||
|
||||
const session = await auth()
|
||||
const isUserLoggedIn = isValidSession(session)
|
||||
const fromDateString = dt(fromDate).format("YYYY-MM-DD")
|
||||
const toDateString = dt(toDate).format("YYYY-MM-DD")
|
||||
|
||||
@@ -92,11 +93,11 @@ export async function RoomsContainer({
|
||||
|
||||
return (
|
||||
<Rooms
|
||||
user={user}
|
||||
availablePackages={packages ?? []}
|
||||
roomsAvailability={roomsAvailability}
|
||||
roomCategories={hotelData?.included?.rooms ?? []}
|
||||
hotelType={hotelData?.data.attributes?.hotelType}
|
||||
isUserLoggedIn={isUserLoggedIn}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ import type { RoomConfiguration } from "@/server/routers/hotels/output"
|
||||
export default function Rooms({
|
||||
roomsAvailability,
|
||||
roomCategories = [],
|
||||
user,
|
||||
availablePackages,
|
||||
hotelType,
|
||||
isUserLoggedIn,
|
||||
}: SelectRateProps) {
|
||||
const visibleRooms: RoomConfiguration[] = useMemo(() => {
|
||||
const deduped = filterDuplicateRoomTypesByLowestPrice(
|
||||
@@ -184,12 +184,12 @@ export default function Rooms({
|
||||
<RoomSelection
|
||||
roomsAvailability={rooms}
|
||||
roomCategories={roomCategories}
|
||||
user={user}
|
||||
availablePackages={availablePackages}
|
||||
selectedPackages={selectedPackages}
|
||||
setRateCode={setSelectedRate}
|
||||
rateSummary={rateSummary}
|
||||
hotelType={hotelType}
|
||||
isUserLoggedIn={isUserLoggedIn}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user