feat(SW-572): Added support for logged in and logged out variants of the top link inside the header
This commit is contained in:
@@ -106,7 +106,7 @@
|
|||||||
--max-width-navigation: 89.5rem;
|
--max-width-navigation: 89.5rem;
|
||||||
|
|
||||||
--main-menu-mobile-height: 75px;
|
--main-menu-mobile-height: 75px;
|
||||||
--main-menu-desktop-height: 129px;
|
--main-menu-desktop-height: 125px;
|
||||||
--booking-widget-mobile-height: 75px;
|
--booking-widget-mobile-height: 75px;
|
||||||
--booking-widget-desktop-height: 77px;
|
--booking-widget-desktop-height: 77px;
|
||||||
--hotel-page-map-desktop-width: 23.75rem;
|
--hotel-page-map-desktop-width: 23.75rem;
|
||||||
|
|||||||
@@ -2,5 +2,16 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Spacing-x1);
|
gap: var(--Spacing-x1);
|
||||||
font-size: var(--typography-Caption-Regular-fontSize);
|
}
|
||||||
|
|
||||||
|
.headerLink:hover {
|
||||||
|
color: var(--Base-Text-High-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerLink .icon * {
|
||||||
|
fill: var(--Base-Text-Medium-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerLink:hover .icon * {
|
||||||
|
fill: var(--Base-Text-High-contrast);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "next/link"
|
||||||
|
|
||||||
|
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
||||||
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
import styles from "./headerLink.module.css"
|
import styles from "./headerLink.module.css"
|
||||||
|
|
||||||
@@ -6,16 +9,19 @@ import type { HeaderLinkProps } from "@/types/components/header/headerLink"
|
|||||||
|
|
||||||
export default function HeaderLink({
|
export default function HeaderLink({
|
||||||
children,
|
children,
|
||||||
className,
|
href,
|
||||||
...props
|
iconName,
|
||||||
|
iconSize = 20,
|
||||||
}: HeaderLinkProps) {
|
}: HeaderLinkProps) {
|
||||||
|
const Icon = getIconByIconName(iconName)
|
||||||
return (
|
return (
|
||||||
<Link
|
<Caption type="regular" color="textMediumContrast" asChild>
|
||||||
color="burgundy"
|
<Link href={href} className={styles.headerLink}>
|
||||||
className={`${styles.headerLink} ${className}`}
|
{Icon ? (
|
||||||
{...props}
|
<Icon className={styles.icon} width={iconSize} height={iconSize} />
|
||||||
>
|
) : null}
|
||||||
{children}
|
{children}
|
||||||
</Link>
|
</Link>
|
||||||
|
</Caption>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,21 +7,23 @@ import { useMediaQuery } from "usehooks-ts"
|
|||||||
|
|
||||||
import useDropdownStore from "@/stores/main-menu"
|
import useDropdownStore from "@/stores/main-menu"
|
||||||
|
|
||||||
import { GiftIcon, SearchIcon, ServiceIcon } from "@/components/Icons"
|
|
||||||
import LanguageSwitcher from "@/components/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/LanguageSwitcher"
|
||||||
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
|
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
|
||||||
|
|
||||||
import HeaderLink from "../../HeaderLink"
|
import HeaderLink from "../../HeaderLink"
|
||||||
|
import TopLink from "../../TopLink"
|
||||||
|
|
||||||
import styles from "./mobileMenu.module.css"
|
import styles from "./mobileMenu.module.css"
|
||||||
|
|
||||||
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
|
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
|
||||||
import type { MobileMenuProps } from "@/types/components/header/mobileMenu"
|
import type { MobileMenuProps } from "@/types/components/header/mobileMenu"
|
||||||
|
import { IconName } from "@/types/components/icon"
|
||||||
|
|
||||||
export default function MobileMenu({
|
export default function MobileMenu({
|
||||||
children,
|
children,
|
||||||
languageUrls,
|
languageUrls,
|
||||||
topLink,
|
topLink,
|
||||||
|
isLoggedIn,
|
||||||
}: React.PropsWithChildren<MobileMenuProps>) {
|
}: React.PropsWithChildren<MobileMenuProps>) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const {
|
const {
|
||||||
@@ -77,18 +79,11 @@ export default function MobileMenu({
|
|||||||
>
|
>
|
||||||
<Suspense fallback={"Loading nav"}>{children}</Suspense>
|
<Suspense fallback={"Loading nav"}>{children}</Suspense>
|
||||||
<footer className={styles.footer}>
|
<footer className={styles.footer}>
|
||||||
<HeaderLink href="#">
|
<HeaderLink href="#" iconName={IconName.Search}>
|
||||||
<SearchIcon width={20} height={20} color="burgundy" />
|
|
||||||
{intl.formatMessage({ id: "Find booking" })}
|
{intl.formatMessage({ id: "Find booking" })}
|
||||||
</HeaderLink>
|
</HeaderLink>
|
||||||
{topLink.link ? (
|
<TopLink isLoggedIn={isLoggedIn} topLink={topLink} iconSize={20} />
|
||||||
<HeaderLink href={topLink.link.url}>
|
<HeaderLink href="#" iconName={IconName.Service}>
|
||||||
<GiftIcon width={20} height={20} color="burgundy" />
|
|
||||||
{topLink.title}
|
|
||||||
</HeaderLink>
|
|
||||||
) : null}
|
|
||||||
<HeaderLink href="#">
|
|
||||||
<ServiceIcon width={20} height={20} color="burgundy" />
|
|
||||||
{intl.formatMessage({ id: "Customer service" })}
|
{intl.formatMessage({ id: "Customer service" })}
|
||||||
</HeaderLink>
|
</HeaderLink>
|
||||||
<LanguageSwitcher type="mobileHeader" urls={languageUrls} />
|
<LanguageSwitcher type="mobileHeader" urls={languageUrls} />
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { getHeader, getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
|
getHeader,
|
||||||
|
getLanguageSwitcher,
|
||||||
|
getName,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import MobileMenu from "../MobileMenu"
|
import MobileMenu from "../MobileMenu"
|
||||||
|
|
||||||
@@ -8,13 +12,18 @@ export default async function MobileMenuWrapper({
|
|||||||
// preloaded
|
// preloaded
|
||||||
const languages = await getLanguageSwitcher()
|
const languages = await getLanguageSwitcher()
|
||||||
const header = await getHeader()
|
const header = await getHeader()
|
||||||
|
const user = await getName()
|
||||||
|
|
||||||
if (!languages || !header) {
|
if (!languages || !header) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MobileMenu languageUrls={languages.urls} topLink={header.data.topLink}>
|
<MobileMenu
|
||||||
|
languageUrls={languages.urls}
|
||||||
|
topLink={header.data.topLink}
|
||||||
|
isLoggedIn={!!user}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</MobileMenu>
|
</MobileMenu>
|
||||||
)
|
)
|
||||||
|
|||||||
26
components/Header/TopLink/index.tsx
Normal file
26
components/Header/TopLink/index.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import HeaderLink from "../HeaderLink"
|
||||||
|
|
||||||
|
import type { TopLinkProps } from "@/types/components/header/topLink"
|
||||||
|
import { IconName } from "@/types/components/icon"
|
||||||
|
|
||||||
|
export default function TopLink({
|
||||||
|
isLoggedIn,
|
||||||
|
topLink,
|
||||||
|
iconSize = 16,
|
||||||
|
}: TopLinkProps) {
|
||||||
|
const linkData = isLoggedIn ? topLink.logged_in : topLink.logged_out
|
||||||
|
|
||||||
|
if (!linkData?.link?.url || !linkData?.title) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HeaderLink
|
||||||
|
href={linkData.link.url}
|
||||||
|
iconName={linkData.icon || IconName.Gift}
|
||||||
|
iconSize={iconSize}
|
||||||
|
>
|
||||||
|
{linkData.title}
|
||||||
|
</HeaderLink>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,21 +1,27 @@
|
|||||||
import { getHeader, getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
|
getHeader,
|
||||||
|
getLanguageSwitcher,
|
||||||
|
getName,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { GiftIcon, SearchIcon } from "@/components/Icons"
|
|
||||||
import LanguageSwitcher from "@/components/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/LanguageSwitcher"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
import HeaderLink from "../HeaderLink"
|
import HeaderLink from "../HeaderLink"
|
||||||
|
import TopLink from "../TopLink"
|
||||||
|
|
||||||
import styles from "./topMenu.module.css"
|
import styles from "./topMenu.module.css"
|
||||||
|
|
||||||
|
import { IconName } from "@/types/components/icon"
|
||||||
|
|
||||||
export default async function TopMenu() {
|
export default async function TopMenu() {
|
||||||
// cached
|
// cached
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
// both preloaded
|
// both preloaded
|
||||||
const languages = await getLanguageSwitcher()
|
const languages = await getLanguageSwitcher()
|
||||||
const header = await getHeader()
|
const header = await getHeader()
|
||||||
|
const user = await getName()
|
||||||
|
|
||||||
if (!languages || !header) {
|
if (!languages || !header) {
|
||||||
return null
|
return null
|
||||||
@@ -24,28 +30,15 @@ export default async function TopMenu() {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.topMenu}>
|
<div className={styles.topMenu}>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
{header.data.topLink.link ? (
|
<TopLink isLoggedIn={!!user} topLink={header.data.topLink} />
|
||||||
<Caption type="regular" color="textMediumContrast" asChild>
|
|
||||||
<Link
|
|
||||||
href={header.data.topLink.link.url}
|
|
||||||
color="peach80"
|
|
||||||
variant="icon"
|
|
||||||
>
|
|
||||||
<GiftIcon width={20} height={20} />
|
|
||||||
{header.data.topLink.title}
|
|
||||||
</Link>
|
|
||||||
</Caption>
|
|
||||||
) : null}
|
|
||||||
<div className={styles.options}>
|
<div className={styles.options}>
|
||||||
<LanguageSwitcher type="desktopHeader" urls={languages.urls} />
|
<LanguageSwitcher type="desktopHeader" urls={languages.urls} />
|
||||||
|
|
||||||
<Caption type="regular" color="textMediumContrast" asChild>
|
<Caption type="regular" color="textMediumContrast" asChild>
|
||||||
<Link href="#" color="peach80" variant="icon">
|
<HeaderLink href="#" iconName={IconName.Search}>
|
||||||
<SearchIcon width={20} height={20} />
|
|
||||||
{intl.formatMessage({ id: "Find booking" })}
|
{intl.formatMessage({ id: "Find booking" })}
|
||||||
</Link>
|
</HeaderLink>
|
||||||
</Caption>
|
</Caption>
|
||||||
<HeaderLink href="#"></HeaderLink>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { Suspense } from "react"
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import { getHeader, getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
|
getHeader,
|
||||||
|
getLanguageSwitcher,
|
||||||
|
getName,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import MainMenu from "./MainMenu"
|
import MainMenu from "./MainMenu"
|
||||||
import TopMenu from "./TopMenu"
|
import TopMenu from "./TopMenu"
|
||||||
@@ -10,6 +14,8 @@ import styles from "./header.module.css"
|
|||||||
export default function Header() {
|
export default function Header() {
|
||||||
void getHeader()
|
void getHeader()
|
||||||
void getLanguageSwitcher()
|
void getLanguageSwitcher()
|
||||||
|
void getName()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<Suspense fallback="Loading top menu">
|
<Suspense fallback="Loading top menu">
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import {
|
|||||||
PhoneIcon,
|
PhoneIcon,
|
||||||
PlusCircleIcon,
|
PlusCircleIcon,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
|
PriceTagIcon,
|
||||||
RestaurantIcon,
|
RestaurantIcon,
|
||||||
RoomServiceIcon,
|
RoomServiceIcon,
|
||||||
SaunaIcon,
|
SaunaIcon,
|
||||||
@@ -101,7 +102,9 @@ import {
|
|||||||
|
|
||||||
import { IconName, IconProps } from "@/types/components/icon"
|
import { IconName, IconProps } from "@/types/components/icon"
|
||||||
|
|
||||||
export function getIconByIconName(icon?: IconName): FC<IconProps> | null {
|
export function getIconByIconName(
|
||||||
|
icon: IconName | null = null
|
||||||
|
): FC<IconProps> | null {
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
case IconName.Accesories:
|
case IconName.Accesories:
|
||||||
return AccesoriesIcon
|
return AccesoriesIcon
|
||||||
@@ -253,6 +256,8 @@ export function getIconByIconName(icon?: IconName): FC<IconProps> | null {
|
|||||||
return PlusIcon
|
return PlusIcon
|
||||||
case IconName.PlusCircle:
|
case IconName.PlusCircle:
|
||||||
return PlusCircleIcon
|
return PlusCircleIcon
|
||||||
|
case IconName.PriceTag:
|
||||||
|
return PriceTagIcon
|
||||||
case IconName.Restaurant:
|
case IconName.Restaurant:
|
||||||
return RestaurantIcon
|
return RestaurantIcon
|
||||||
case IconName.RoomService:
|
case IconName.RoomService:
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export default function LanguageSwitcher({
|
|||||||
const languageSwitcherRef = useRef<HTMLDivElement>(null)
|
const languageSwitcherRef = useRef<HTMLDivElement>(null)
|
||||||
const isFooter = type === LanguageSwitcherTypesEnum.Footer
|
const isFooter = type === LanguageSwitcherTypesEnum.Footer
|
||||||
const isHeader = !isFooter
|
const isHeader = !isFooter
|
||||||
|
const globeIconSize = type === "desktopHeader" ? 16 : 20
|
||||||
|
|
||||||
const position = isFooter ? "footer" : "header"
|
const position = isFooter ? "footer" : "header"
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ export default function LanguageSwitcher({
|
|||||||
})}
|
})}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<GlobeIcon width={20} height={20} />
|
<GlobeIcon width={globeIconSize} height={globeIconSize} />
|
||||||
<Caption className={styles.buttonText} type="regular" asChild>
|
<Caption className={styles.buttonText} type="regular" asChild>
|
||||||
<span>{languages[currentLanguage]}</span>
|
<span>{languages[currentLanguage]}</span>
|
||||||
</Caption>
|
</Caption>
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#import "../Fragments/System.graphql"
|
#import "../Fragments/System.graphql"
|
||||||
|
|
||||||
|
#import "../Fragments/PageLink/AccountPageLink.graphql"
|
||||||
|
#import "../Fragments/PageLink/CollectionPageLink.graphql"
|
||||||
#import "../Fragments/PageLink/ContentPageLink.graphql"
|
#import "../Fragments/PageLink/ContentPageLink.graphql"
|
||||||
#import "../Fragments/PageLink/HotelPageLink.graphql"
|
#import "../Fragments/PageLink/HotelPageLink.graphql"
|
||||||
#import "../Fragments/PageLink/LoyaltyPageLink.graphql"
|
#import "../Fragments/PageLink/LoyaltyPageLink.graphql"
|
||||||
#import "../Fragments/Blocks/Card.graphql"
|
#import "../Fragments/Blocks/Card.graphql"
|
||||||
|
|
||||||
#import "../Fragments/Blocks/Refs/Card.graphql"
|
#import "../Fragments/Blocks/Refs/Card.graphql"
|
||||||
|
#import "../Fragments/AccountPage/Ref.graphql"
|
||||||
|
#import "../Fragments/CollectionPage/Ref.graphql"
|
||||||
#import "../Fragments/ContentPage/Ref.graphql"
|
#import "../Fragments/ContentPage/Ref.graphql"
|
||||||
#import "../Fragments/HotelPage/Ref.graphql"
|
#import "../Fragments/HotelPage/Ref.graphql"
|
||||||
#import "../Fragments/LoyaltyPage/Ref.graphql"
|
#import "../Fragments/LoyaltyPage/Ref.graphql"
|
||||||
@@ -14,11 +18,15 @@ query GetHeader($locale: String!) {
|
|||||||
all_header(limit: 1, locale: $locale) {
|
all_header(limit: 1, locale: $locale) {
|
||||||
items {
|
items {
|
||||||
top_link {
|
top_link {
|
||||||
|
logged_in {
|
||||||
|
icon
|
||||||
title
|
title
|
||||||
linkConnection {
|
linkConnection {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
__typename
|
__typename
|
||||||
|
...AccountPageLink
|
||||||
|
...CollectionPageLink
|
||||||
...ContentPageLink
|
...ContentPageLink
|
||||||
...HotelPageLink
|
...HotelPageLink
|
||||||
...LoyaltyPageLink
|
...LoyaltyPageLink
|
||||||
@@ -26,6 +34,23 @@ query GetHeader($locale: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logged_out {
|
||||||
|
icon
|
||||||
|
title
|
||||||
|
linkConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageLink
|
||||||
|
...CollectionPageLink
|
||||||
|
...ContentPageLink
|
||||||
|
...HotelPageLink
|
||||||
|
...LoyaltyPageLink
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
menu_items {
|
menu_items {
|
||||||
title
|
title
|
||||||
linkConnection {
|
linkConnection {
|
||||||
@@ -84,10 +109,13 @@ query GetHeaderRef($locale: String!) {
|
|||||||
all_header(limit: 1, locale: $locale) {
|
all_header(limit: 1, locale: $locale) {
|
||||||
items {
|
items {
|
||||||
top_link {
|
top_link {
|
||||||
|
logged_in {
|
||||||
linkConnection {
|
linkConnection {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
__typename
|
__typename
|
||||||
|
...AccountPageRef
|
||||||
|
...CollectionPageRef
|
||||||
...ContentPageRef
|
...ContentPageRef
|
||||||
...HotelPageRef
|
...HotelPageRef
|
||||||
...LoyaltyPageRef
|
...LoyaltyPageRef
|
||||||
@@ -95,6 +123,21 @@ query GetHeaderRef($locale: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logged_out {
|
||||||
|
linkConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
...AccountPageRef
|
||||||
|
...CollectionPageRef
|
||||||
|
...ContentPageRef
|
||||||
|
...HotelPageRef
|
||||||
|
...LoyaltyPageRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
menu_items {
|
menu_items {
|
||||||
linkConnection {
|
linkConnection {
|
||||||
edges {
|
edges {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { removeMultipleSlashes } from "@/utils/url"
|
|||||||
|
|
||||||
import { systemSchema } from "../schemas/system"
|
import { systemSchema } from "../schemas/system"
|
||||||
|
|
||||||
|
import { IconName } from "@/types/components/icon"
|
||||||
import { AlertTypeEnum } from "@/types/enums/alert"
|
import { AlertTypeEnum } from "@/types/enums/alert"
|
||||||
import type { Image } from "@/types/image"
|
import type { Image } from "@/types/image"
|
||||||
|
|
||||||
@@ -514,6 +515,11 @@ const menuItemsRefsSchema = z.intersection(
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const topLinkRefsSchema = z.object({
|
||||||
|
logged_in: linkRefsSchema.nullable(),
|
||||||
|
logged_out: linkRefsSchema.nullable(),
|
||||||
|
})
|
||||||
|
|
||||||
export const headerRefsSchema = z
|
export const headerRefsSchema = z
|
||||||
.object({
|
.object({
|
||||||
all_header: z.object({
|
all_header: z.object({
|
||||||
@@ -522,7 +528,7 @@ export const headerRefsSchema = z
|
|||||||
z.object({
|
z.object({
|
||||||
menu_items: z.array(menuItemsRefsSchema),
|
menu_items: z.array(menuItemsRefsSchema),
|
||||||
system: systemSchema,
|
system: systemSchema,
|
||||||
top_link: linkRefsSchema,
|
top_link: topLinkRefsSchema,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.max(1),
|
.max(1),
|
||||||
@@ -636,6 +642,32 @@ export const menuItemSchema = z
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const topLinkItemSchema = z.intersection(
|
||||||
|
linkAndTitleSchema,
|
||||||
|
z.object({
|
||||||
|
icon: z
|
||||||
|
.enum(["loyalty", "info", "offer"])
|
||||||
|
.nullable()
|
||||||
|
.transform((icon) => {
|
||||||
|
switch (icon) {
|
||||||
|
case "loyalty":
|
||||||
|
return IconName.Gift
|
||||||
|
case "info":
|
||||||
|
return IconName.InfoCircle
|
||||||
|
case "offer":
|
||||||
|
return IconName.PriceTag
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
export const topLinkSchema = z.object({
|
||||||
|
logged_in: topLinkItemSchema.nullable(),
|
||||||
|
logged_out: topLinkItemSchema.nullable(),
|
||||||
|
})
|
||||||
|
|
||||||
export const headerSchema = z
|
export const headerSchema = z
|
||||||
.object({
|
.object({
|
||||||
all_header: z.object({
|
all_header: z.object({
|
||||||
@@ -643,7 +675,7 @@ export const headerSchema = z
|
|||||||
.array(
|
.array(
|
||||||
z.object({
|
z.object({
|
||||||
menu_items: z.array(menuItemSchema),
|
menu_items: z.array(menuItemSchema),
|
||||||
top_link: linkAndTitleSchema,
|
top_link: topLinkSchema,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.max(1),
|
.max(1),
|
||||||
|
|||||||
@@ -14,8 +14,13 @@ import type { ContactConfig } from "./output"
|
|||||||
export function getConnections({ header }: HeaderRefs) {
|
export function getConnections({ header }: HeaderRefs) {
|
||||||
const connections: System["system"][] = [header.system]
|
const connections: System["system"][] = [header.system]
|
||||||
|
|
||||||
if (header.top_link?.link) {
|
if (header.top_link) {
|
||||||
connections.push(header.top_link.link)
|
if (header.top_link.logged_in?.link) {
|
||||||
|
connections.push(header.top_link.logged_in.link)
|
||||||
|
}
|
||||||
|
if (header.top_link.logged_out?.link) {
|
||||||
|
connections.push(header.top_link.logged_out.link)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.menu_items.length) {
|
if (header.menu_items.length) {
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
import type { LinkProps } from "@/components/TempDesignSystem/Link/link"
|
import type { LinkProps } from "next/link"
|
||||||
|
|
||||||
export interface HeaderLinkProps extends React.PropsWithChildren<LinkProps> {}
|
import type { IconName } from "../icon"
|
||||||
|
|
||||||
|
export interface HeaderLinkProps extends React.PropsWithChildren {
|
||||||
|
href: LinkProps["href"]
|
||||||
|
iconName: IconName | null
|
||||||
|
iconSize?: number
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ import type { Header } from "@/types/trpc/routers/contentstack/header"
|
|||||||
export interface MobileMenuProps {
|
export interface MobileMenuProps {
|
||||||
languageUrls: LanguageSwitcherData
|
languageUrls: LanguageSwitcherData
|
||||||
topLink: Header["header"]["topLink"]
|
topLink: Header["header"]["topLink"]
|
||||||
|
isLoggedIn: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
7
types/components/header/topLink.ts
Normal file
7
types/components/header/topLink.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { Header } from "@/types/trpc/routers/contentstack/header"
|
||||||
|
|
||||||
|
export interface TopLinkProps {
|
||||||
|
isLoggedIn: boolean
|
||||||
|
topLink: Header["header"]["topLink"]
|
||||||
|
iconSize?: number
|
||||||
|
}
|
||||||
@@ -82,6 +82,7 @@ export enum IconName {
|
|||||||
Phone = "Phone",
|
Phone = "Phone",
|
||||||
Plus = "Plus",
|
Plus = "Plus",
|
||||||
PlusCircle = "PlusCircle",
|
PlusCircle = "PlusCircle",
|
||||||
|
PriceTag = "PriceTag",
|
||||||
Restaurant = "Restaurant",
|
Restaurant = "Restaurant",
|
||||||
RoomService = "RoomService",
|
RoomService = "RoomService",
|
||||||
Sauna = "Sauna",
|
Sauna = "Sauna",
|
||||||
|
|||||||
Reference in New Issue
Block a user