Files
web/apps/scandic-web/components/Header/MainMenu/MobileMenu/index.tsx
Joakim Jäderberg aafad9781f Merged in feat/lokalise-rebuild (pull request #2993)
Feat/lokalise rebuild

* chore(lokalise): update translation ids

* chore(lokalise): easier to switch between projects

* chore(lokalise): update translation ids

* .

* .

* .

* .

* .

* .

* chore(lokalise): update translation ids

* chore(lokalise): update translation ids

* .

* .

* .

* chore(lokalise): update translation ids

* chore(lokalise): update translation ids

* .

* .

* chore(lokalise): update translation ids

* chore(lokalise): update translation ids

* chore(lokalise): new translations

* merge

* switch to errors for missing id's

* merge

* sync translations


Approved-by: Linus Flood
2025-10-22 11:00:03 +00:00

143 lines
4.1 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 { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { findMyBookingRoutes } from "@scandic-hotels/common/constants/routes/findMyBookingRoutes"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import useDropdownStore from "@/stores/main-menu"
import LanguageSwitcher from "@/components/LanguageSwitcher"
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
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 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({
id: "header.closeMenu",
defaultMessage: "Close menu",
})
const openMsg = intl.formatMessage({
id: "header.openMenu",
defaultMessage: "Open menu",
})
const findMyBookingUrl = findMyBookingRoutes[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({
id: "header.menu",
defaultMessage: "Menu",
})}
>
{children}
<footer className={styles.footer}>
<HeaderLink
href={findMyBookingUrl}
iconName={IconName.Search}
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
>
{intl.formatMessage({
id: "booking.findBooking",
defaultMessage: "Find booking",
})}
</HeaderLink>
<TopLink isLoggedIn={isLoggedIn} topLink={topLink} iconSize={20} />
<HeaderLink
href={customerService[lang]}
iconName={IconName.Service}
>
{intl.formatMessage({
id: "common.customerService",
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({
id: "header.openMenu",
defaultMessage: "Open menu",
})}
>
<span className={styles.bar} />
</button>
)
}