Puts Workshops in the header, pairs the hero with a static rule card and breakpoint CTAs, and shows the three pilot marks with no wall label. Co-authored-by: Cursor <cursoragent@cursor.com>
174 lines
7.0 KiB
TypeScript
174 lines
7.0 KiB
TypeScript
"use client";
|
|
|
|
import { memo } from "react";
|
|
import Script from "next/script";
|
|
import { useTranslation } from "../../../contexts/MessagesContext";
|
|
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
|
import Menu from "../Menu";
|
|
import type { TopViewProps } from "./Top.types";
|
|
|
|
import Logo from "../../asset/Logo";
|
|
|
|
function TopView({
|
|
folderTop,
|
|
loggedIn: _loggedIn,
|
|
profile: _profile,
|
|
logIn,
|
|
schemaData,
|
|
logoSize,
|
|
renderNavigationItems,
|
|
renderLoginButton,
|
|
renderCreateRuleButton,
|
|
}: TopViewProps) {
|
|
const t = useTranslation(folderTop ? "homeHeader" : "header");
|
|
|
|
const phoneAuthItem = logIn ? renderLoginButton("md:hidden") : null;
|
|
const desktopAuthItem = logIn ? (
|
|
<Menu size="X Small" className="hidden md:flex lg:gap-[var(--space-300)]">
|
|
{renderLoginButton()}
|
|
</Menu>
|
|
) : null;
|
|
|
|
if (folderTop) {
|
|
return (
|
|
<>
|
|
<Script
|
|
id="top-navigation-schema"
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }}
|
|
/>
|
|
<header
|
|
className="w-full overflow-visible bg-transparent"
|
|
role="banner"
|
|
aria-label={t("ariaLabels.homePageNavigationHeader")}
|
|
data-figma-node="5944-17779"
|
|
>
|
|
<nav
|
|
className="relative mx-auto flex h-[50px] items-end justify-between pl-[var(--space-200)] pr-[var(--space-400)] pt-[var(--space-250)] sm:h-[62px] sm:px-[var(--space-250)] sm:pr-[var(--space-500)] sm:pt-[var(--space-250)] md:h-[68px] md:px-[var(--space-400)] md:pr-[var(--space-800)] md:pt-[var(--space-400)] lg:h-[68px] lg:pl-[var(--space-600)] lg:pr-[var(--space-1400)] lg:pt-[var(--space-400)] xl:h-[88px] xl:pl-[var(--space-1200)] xl:pr-[var(--space-1400)] xl:pt-[var(--space-600)]"
|
|
role="navigation"
|
|
aria-label={t("ariaLabels.mainNavigation")}
|
|
>
|
|
<div className="HeaderTab header-breakpoint-transition relative flex h-[var(--space-1000)] min-w-0 flex-1 items-center justify-between self-end overflow-visible rounded-tl-[var(--radius-400)] rounded-tr-[var(--radius-400)] bg-[var(--color-surface-invert-brand-primary)] pl-[var(--space-300)] pr-[var(--space-300)] sm:mr-[var(--space-200)] sm:h-[52px] sm:rounded-t-[var(--radius-500)] sm:pr-[var(--space-150)] md:h-[52px] md:rounded-t-[var(--radius-500)] md:pl-[var(--space-600)] md:pr-[var(--space-300)] lg:mr-[var(--space-600)] lg:h-[52px] lg:rounded-t-[var(--radius-500)] lg:pl-[var(--space-600)] lg:pr-[var(--space-1200)] xl:mr-[var(--space-800)] xl:h-[64px] xl:rounded-t-[var(--radius-500)] xl:pl-[var(--space-800)] xl:pr-[var(--space-3000)]">
|
|
<div className="relative z-[1] shrink-0">
|
|
<Logo
|
|
size={logoSize}
|
|
wordmark
|
|
palette={folderTop ? "inverse" : "default"}
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
className="relative z-[1] min-w-0 md:absolute md:top-1/2 md:left-[calc(50vw-var(--space-400))] md:-translate-x-1/2 md:-translate-y-1/2 lg:left-[calc(50vw-var(--space-600))] xl:left-[calc(50vw-var(--space-1200))]"
|
|
data-top="nav"
|
|
>
|
|
<Menu
|
|
size="X Small"
|
|
className="md:gap-[var(--space-100)] lg:gap-[var(--space-300)]"
|
|
>
|
|
{renderNavigationItems()}
|
|
{phoneAuthItem}
|
|
</Menu>
|
|
</div>
|
|
|
|
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG, not content */}
|
|
<img
|
|
src={getAssetPath(ASSETS.UNION_XSM)}
|
|
alt=""
|
|
role="presentation"
|
|
className="pointer-events-none absolute -bottom-[3px] -right-[52px] z-0 h-[24px] w-[61px] sm:hidden sm:h-[31.5px] sm:w-[61px]"
|
|
/>
|
|
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG */}
|
|
<img
|
|
src={getAssetPath(ASSETS.UNION_SM_MD_LG)}
|
|
alt=""
|
|
role="presentation"
|
|
className="pointer-events-none absolute -bottom-[3.7px] -right-[53px] z-0 hidden h-[24px] w-[61px] sm:block sm:h-[31.5px] sm:w-[61px] xl:hidden"
|
|
/>
|
|
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG */}
|
|
<img
|
|
src={getAssetPath(ASSETS.UNION_XLG)}
|
|
alt=""
|
|
role="presentation"
|
|
className="pointer-events-none absolute -bottom-[6px] -right-[94px] z-0 hidden h-[53px] w-[105px] xl:block"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
className="flex shrink-0 items-center gap-[var(--space-100)] self-center md:gap-[var(--space-250)]"
|
|
data-top="auth"
|
|
>
|
|
{desktopAuthItem}
|
|
{renderCreateRuleButton()}
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
</>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Standard marketing / app top nav.
|
|
* Figma: "Navigation / Top" (Community-Rule-System, node 5944:17779).
|
|
* Below md: logo | links (with Log in / Profile) | Create rule, so the mark
|
|
* cannot paint over the cluster. From md: 1fr | auto | 1fr so the cluster
|
|
* sits on the page midline.
|
|
*/
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }}
|
|
/>
|
|
<header
|
|
className="relative z-50 w-full border-b border-[var(--border-color-default-tertiary)] bg-[var(--color-surface-default-primary)]"
|
|
role="banner"
|
|
aria-label={t("ariaLabels.mainNavigationHeader")}
|
|
data-figma-node="5944-17779"
|
|
>
|
|
<nav
|
|
className="flex w-full items-center gap-[var(--space-200)] px-[var(--space-400)] py-[var(--space-200)] sm:px-[var(--space-400)] md:grid md:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] md:gap-0 lg:px-[var(--space-1800)] lg:py-[var(--space-400)]"
|
|
role="navigation"
|
|
aria-label={t("ariaLabels.mainNavigation")}
|
|
>
|
|
<div
|
|
className="min-w-0 shrink-0 justify-self-start lg:w-[200px] lg:max-w-[200px]"
|
|
data-top="logo"
|
|
>
|
|
<Logo
|
|
size={logoSize}
|
|
wordmark
|
|
palette={folderTop ? "inverse" : "default"}
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
className="flex min-w-0 flex-1 items-center justify-end md:flex-none md:justify-center"
|
|
data-top="nav"
|
|
>
|
|
<Menu
|
|
size="X Small"
|
|
className="min-w-0 lg:gap-[var(--space-300)]"
|
|
>
|
|
{renderNavigationItems()}
|
|
{phoneAuthItem}
|
|
</Menu>
|
|
</div>
|
|
|
|
<div
|
|
className="flex shrink-0 items-center justify-self-end gap-[var(--space-100)] md:gap-[var(--space-250)] lg:gap-[var(--space-100)]"
|
|
data-top="auth"
|
|
>
|
|
{desktopAuthItem}
|
|
{renderCreateRuleButton()}
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
</>
|
|
);
|
|
}
|
|
|
|
TopView.displayName = "TopView";
|
|
|
|
export default memo(TopView);
|
|
export { TopView };
|