Move user router to trpc package * Move more schemas in hotel router * Fix deps * fix getNonContentstackUrls * Fix import error * Fix entry error handling * Fix generateMetadata metrics * Fix alertType enum * Fix duplicated types * lint:fix * Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package * Fix broken imports * Move booking router to trpc package * Move partners router to trpc package * Move autocomplete router to trpc package * Move booking router to trpc package * Remove translations from My Pages navigation trpc procedure * Move navigation router to trpc package * Move user router to trpc package * Merge branch 'master' into feat/sw-2862-move-booking-router-to-trpc-package * Merge branch 'feat/sw-2862-move-booking-router-to-trpc-package' into feat/sw-2865-move-navigation-router-to-trpc-package * Merge branch 'master' into feat/sw-2865-move-navigation-router-to-trpc-package * Merge branch 'master' into feat/sw-2865-move-navigation-router-to-trpc-package * Merge branch 'master' into feat/sw-2865-move-navigation-router-to-trpc-package * Merge branch 'feat/sw-2865-move-navigation-router-to-trpc-package' into feat/sw-2867-move-user-router-to-trpc-package * Merge branch 'master' into feat/sw-2867-move-user-router-to-trpc-package Approved-by: Linus Flood
151 lines
4.3 KiB
TypeScript
151 lines
4.3 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect } from "react"
|
|
import { Dialog, Modal } from "react-aria-components"
|
|
import { useIntl } from "react-intl"
|
|
import { useMediaQuery } from "usehooks-ts"
|
|
|
|
import {
|
|
findMyBooking,
|
|
findMyBookingCurrentWebPath,
|
|
} from "@scandic-hotels/common/constants/routes/findMyBooking"
|
|
import { getCurrentWebUrl } from "@scandic-hotels/common/utils/url"
|
|
|
|
import { customerService } from "@/constants/webHrefs"
|
|
import { env } from "@/env/client"
|
|
import useDropdownStore from "@/stores/main-menu"
|
|
|
|
import { IconName } from "@/components/Icons/iconName"
|
|
import LanguageSwitcher from "@/components/LanguageSwitcher"
|
|
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
|
|
import { useIsLangLive } from "@/hooks/useIsLangLive"
|
|
import useLang from "@/hooks/useLang"
|
|
|
|
import HeaderLink from "../../HeaderLink"
|
|
import TopLink from "../../TopLink"
|
|
|
|
import styles from "./mobileMenu.module.css"
|
|
|
|
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
|
|
import type { MobileMenuProps } from "@/types/components/header/mobileMenu"
|
|
|
|
export default function MobileMenu({
|
|
children,
|
|
topLink,
|
|
isLoggedIn,
|
|
}: React.PropsWithChildren<MobileMenuProps>) {
|
|
const isLangLive = useIsLangLive()
|
|
const lang = useLang()
|
|
const intl = useIntl()
|
|
const {
|
|
toggleDropdown,
|
|
isHamburgerMenuOpen,
|
|
isMyPagesMobileMenuOpen,
|
|
isHeaderLanguageSwitcherMobileOpen,
|
|
isFooterLanguageSwitcherOpen,
|
|
} = useDropdownStore()
|
|
|
|
const isHamburgerExtended =
|
|
isHamburgerMenuOpen ||
|
|
isMyPagesMobileMenuOpen ||
|
|
isHeaderLanguageSwitcherMobileOpen ||
|
|
isFooterLanguageSwitcherOpen
|
|
|
|
const isAboveMobile = useMediaQuery("(min-width: 768px)")
|
|
useEffect(() => {
|
|
if (isAboveMobile && isHamburgerMenuOpen) {
|
|
toggleDropdown(DropdownTypeEnum.HamburgerMenu)
|
|
}
|
|
}, [isAboveMobile, isHamburgerMenuOpen, toggleDropdown])
|
|
|
|
useHandleKeyUp((event: KeyboardEvent) => {
|
|
if (event.key === "Escape" && isHamburgerMenuOpen) {
|
|
toggleDropdown(DropdownTypeEnum.HamburgerMenu)
|
|
}
|
|
})
|
|
|
|
// Making sure the menu is always opened at the top of the page, just below the header.
|
|
useEffect(() => {
|
|
if (isHamburgerMenuOpen) {
|
|
window.scrollTo({ top: 0, behavior: "instant" })
|
|
}
|
|
}, [isHamburgerMenuOpen])
|
|
|
|
const closeMsg = intl.formatMessage({
|
|
defaultMessage: "Close menu",
|
|
})
|
|
const openMsg = intl.formatMessage({
|
|
defaultMessage: "Open menu",
|
|
})
|
|
|
|
const baseUrl = env.NEXT_PUBLIC_PUBLIC_URL || "https://www.scandichotels.com"
|
|
const findMyBookingUrl = !isLangLive
|
|
? getCurrentWebUrl({
|
|
path: findMyBookingCurrentWebPath[lang],
|
|
lang,
|
|
baseUrl,
|
|
})
|
|
: findMyBooking[lang]
|
|
|
|
return (
|
|
<>
|
|
<button
|
|
type="button"
|
|
className={`${styles.hamburger} ${isHamburgerExtended ? styles.isExpanded : ""}`}
|
|
aria-label={isHamburgerExtended ? closeMsg : openMsg}
|
|
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
|
|
>
|
|
<span className={styles.bar} />
|
|
</button>
|
|
<Modal className={styles.modal} isOpen={isHamburgerMenuOpen}>
|
|
<Dialog
|
|
className={styles.dialog}
|
|
aria-label={intl.formatMessage({
|
|
defaultMessage: "Menu",
|
|
})}
|
|
>
|
|
{children}
|
|
<footer className={styles.footer}>
|
|
<HeaderLink
|
|
href={findMyBookingUrl}
|
|
iconName={IconName.Search}
|
|
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Find booking",
|
|
})}
|
|
</HeaderLink>
|
|
<TopLink isLoggedIn={isLoggedIn} topLink={topLink} iconSize={20} />
|
|
<HeaderLink
|
|
href={customerService[lang]}
|
|
iconName={IconName.Service}
|
|
>
|
|
{intl.formatMessage({
|
|
defaultMessage: "Customer service",
|
|
})}
|
|
</HeaderLink>
|
|
<LanguageSwitcher type="mobileHeader" />
|
|
</footer>
|
|
</Dialog>
|
|
</Modal>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export function MobileMenuSkeleton() {
|
|
const intl = useIntl()
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
disabled
|
|
className={styles.hamburger}
|
|
aria-label={intl.formatMessage({
|
|
defaultMessage: "Open menu",
|
|
})}
|
|
>
|
|
<span className={styles.bar} />
|
|
</button>
|
|
)
|
|
}
|