145 lines
4.3 KiB
TypeScript
145 lines
4.3 KiB
TypeScript
"use client"
|
|
import { useWatch } from "react-hook-form"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { dt } from "@/lib/dt"
|
|
|
|
import { EditIcon, SearchIcon } from "@/components/Icons"
|
|
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
|
import Divider from "@/components/TempDesignSystem/Divider"
|
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
import useLang from "@/hooks/useLang"
|
|
import isValidJson from "@/utils/isValidJson"
|
|
|
|
import styles from "./button.module.css"
|
|
|
|
import type {
|
|
BookingWidgetSchema,
|
|
BookingWidgetToggleButtonProps,
|
|
} from "@/types/components/bookingWidget"
|
|
import type { Location } from "@/types/trpc/routers/hotel/locations"
|
|
|
|
export default function MobileToggleButton({
|
|
openMobileSearch,
|
|
}: BookingWidgetToggleButtonProps) {
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
const d = useWatch({ name: "date" })
|
|
const location = useWatch({ name: "location" })
|
|
const rooms: BookingWidgetSchema["rooms"] = useWatch({ name: "rooms" })
|
|
|
|
const parsedLocation: Location | null =
|
|
location && isValidJson(location)
|
|
? JSON.parse(decodeURIComponent(location))
|
|
: null
|
|
|
|
const nights = dt(d.toDate).diff(dt(d.fromDate), "days")
|
|
|
|
const selectedFromDate = dt(d.fromDate).locale(lang).format("D MMM")
|
|
const selectedToDate = dt(d.toDate).locale(lang).format("D MMM")
|
|
|
|
const locationAndDateIsSet = parsedLocation && d
|
|
|
|
const totalRooms = rooms.length
|
|
const totalAdults = rooms.reduce((acc, room) => {
|
|
if (room.adults) {
|
|
acc = acc + room.adults
|
|
}
|
|
return acc
|
|
}, 0)
|
|
const totalChildren = rooms.reduce((acc, room) => {
|
|
if (room.child) {
|
|
acc = acc + room.child.length
|
|
}
|
|
return acc
|
|
}, 0)
|
|
|
|
return (
|
|
<div
|
|
className={locationAndDateIsSet ? styles.complete : styles.partial}
|
|
onClick={openMobileSearch}
|
|
role="button"
|
|
>
|
|
{!locationAndDateIsSet && (
|
|
<>
|
|
<div>
|
|
<Caption type="bold" color="red">
|
|
{intl.formatMessage({ id: "Where to" })}
|
|
</Caption>
|
|
<Body color="uiTextPlaceholder">
|
|
{parsedLocation
|
|
? parsedLocation.name
|
|
: intl.formatMessage({ id: "Destination" })}
|
|
</Body>
|
|
</div>
|
|
<Divider color="baseSurfaceSubtleNormal" variant="vertical" />
|
|
<div>
|
|
<Caption type="bold" color="red">
|
|
{intl.formatMessage(
|
|
{ id: "booking.nights" },
|
|
{ totalNights: nights }
|
|
)}
|
|
</Caption>
|
|
<Body>
|
|
{selectedFromDate} - {selectedToDate}
|
|
</Body>
|
|
</div>
|
|
<div className={styles.icon}>
|
|
<SearchIcon color="white" />
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{locationAndDateIsSet && (
|
|
<>
|
|
<div>
|
|
<Caption color="red">{parsedLocation?.name}</Caption>
|
|
<Caption>
|
|
{`${selectedFromDate} - ${selectedToDate} (${intl.formatMessage(
|
|
{ id: "booking.nights" },
|
|
{ totalNights: nights }
|
|
)}) ${intl.formatMessage({ id: "booking.adults" }, { totalAdults })}, ${
|
|
totalChildren > 0
|
|
? intl.formatMessage(
|
|
{ id: "booking.children" },
|
|
{ totalChildren }
|
|
) + ", "
|
|
: ""
|
|
}${intl.formatMessage({ id: "booking.rooms" }, { totalRooms })}`}
|
|
</Caption>
|
|
</div>
|
|
<div className={styles.icon}>
|
|
<EditIcon color="white" />
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function MobileToggleButtonSkeleton() {
|
|
const intl = useIntl()
|
|
|
|
return (
|
|
<div className={styles.partial}>
|
|
<div>
|
|
<Caption type="bold" color="red">
|
|
{intl.formatMessage({ id: "Where to" })}
|
|
</Caption>
|
|
<SkeletonShimmer height="24px" />
|
|
</div>
|
|
<Divider color="baseSurfaceSubtleNormal" variant="vertical" />
|
|
<div>
|
|
<Caption type="bold" color="red">
|
|
{intl.formatMessage({ id: "booking.nights" }, { totalNights: 0 })}
|
|
</Caption>
|
|
<SkeletonShimmer height="24px" />
|
|
</div>
|
|
<div className={styles.icon}>
|
|
<SearchIcon color="white" />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|