From 781512399b9e38f5fc911e84e2788179a0daa656 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 2 Jul 2026 14:10:17 -0400 Subject: [PATCH] Update homepage routes to include language and mode --- .../app/[locale]/{ => [mode]}/[slug]/page.tsx | 20 ++- .../component-lab/ComponentLabInteractive.tsx | 96 ++++++++++++ .../[mode]/component-lab/page.module.css | 32 ++++ .../[locale]/[mode]/component-lab/page.tsx | 82 ++++++++++ .../[locale]/[mode]/forgot-password/page.tsx | 21 +++ .../homepage/src/app/[locale]/[mode]/page.tsx | 82 ++++++++++ .../src/app/[locale]/[mode]/sign-in/page.tsx | 21 +++ .../src/app/[locale]/component-lab/page.tsx | 88 ++--------- .../src/app/[locale]/forgot-password/page.tsx | 26 ++-- apps/homepage/src/app/[locale]/layout.tsx | 6 +- apps/homepage/src/app/[locale]/page.tsx | 82 ++-------- .../src/app/[locale]/sign-in/page.tsx | 26 ++-- .../src/components/app-shell/AuthHeader.tsx | 4 +- .../src/components/app-shell/BrandLink.tsx | 15 +- .../components/app-shell/HeaderNavigation.tsx | 7 +- .../src/components/app-shell/LocalePill.tsx | 7 +- .../app-shell/LocalizedNotFound.tsx | 11 +- .../components/app-shell/MobileNavigation.tsx | 9 +- .../src/components/app-shell/SiteFooter.tsx | 41 +++-- .../src/components/app-shell/SiteHeader.tsx | 11 +- .../src/components/app-shell/ThemePill.tsx | 17 ++- .../components/app-shell/ThemeSelector.tsx | 7 + .../src/components/auth/AuthShell.tsx | 6 +- .../components/auth/ForgotPasswordForm.tsx | 6 +- .../src/components/auth/ResetPasswordForm.tsx | 9 +- .../src/components/auth/SignInForm.tsx | 7 +- apps/homepage/src/lib/localization/config.ts | 72 ++++++++- .../src/lib/metadata/build-metadata.ts | 10 +- apps/homepage/src/proxy.ts | 143 ++++++++++++------ .../tests/a11y/component-system.a11y.spec.ts | 2 +- .../homepage/tests/a11y/homepage.a11y.spec.ts | 4 +- .../integrations/demo-workflow.a11y.spec.ts | 2 +- apps/homepage/tests/a11y/shell.a11y.spec.ts | 2 +- .../tests/browser/component-system.spec.ts | 6 +- apps/homepage/tests/browser/homepage.spec.ts | 14 +- .../integrations/demo-workflow.spec.ts | 8 +- .../homepage/tests/browser/navigation.spec.ts | 8 +- .../tests/browser/no-javascript.spec.ts | 2 +- .../homepage/tests/browser/responsive.spec.ts | 4 +- apps/homepage/tests/browser/shell.spec.ts | 14 +- .../tests/browser/text-expansion.spec.ts | 2 +- apps/homepage/tests/browser/theme-csp.spec.ts | 7 +- .../component-system/component-matrix.json | 2 +- .../unit/integrations/destinations.test.ts | 4 +- apps/homepage/tests/unit/localization.test.ts | 22 +-- .../tests/unit/pricing-section.test.tsx | 6 +- apps/homepage/tests/unit/proxy.test.ts | 51 ++++++- .../visual/component-system.visual.spec.ts | 2 +- .../tests/visual/homepage.visual.spec.ts | 2 +- .../tests/visual/integrations.visual.spec.ts | 2 +- .../tests/visual/shell.visual.spec.ts | 6 +- 51 files changed, 792 insertions(+), 344 deletions(-) rename apps/homepage/src/app/[locale]/{ => [mode]}/[slug]/page.tsx (79%) create mode 100644 apps/homepage/src/app/[locale]/[mode]/component-lab/ComponentLabInteractive.tsx create mode 100644 apps/homepage/src/app/[locale]/[mode]/component-lab/page.module.css create mode 100644 apps/homepage/src/app/[locale]/[mode]/component-lab/page.tsx create mode 100644 apps/homepage/src/app/[locale]/[mode]/forgot-password/page.tsx create mode 100644 apps/homepage/src/app/[locale]/[mode]/page.tsx create mode 100644 apps/homepage/src/app/[locale]/[mode]/sign-in/page.tsx diff --git a/apps/homepage/src/app/[locale]/[slug]/page.tsx b/apps/homepage/src/app/[locale]/[mode]/[slug]/page.tsx similarity index 79% rename from apps/homepage/src/app/[locale]/[slug]/page.tsx rename to apps/homepage/src/app/[locale]/[mode]/[slug]/page.tsx index ad928cd..56f8fa6 100644 --- a/apps/homepage/src/app/[locale]/[slug]/page.tsx +++ b/apps/homepage/src/app/[locale]/[mode]/[slug]/page.tsx @@ -4,18 +4,20 @@ import { ForgotPasswordForm } from '@/components/auth/ForgotPasswordForm'; import { ResetPasswordForm } from '@/components/auth/ResetPasswordForm'; import { isLocale, - localizedPath, + isMode, + localizedModePath, routeIdFromSlug, type Locale, type RouteId, } from '@/lib/localization/config'; import { getMessages, type ShellMessages } from '@/lib/localization/messages'; import { buildLocalizedMetadata } from '@/lib/metadata/build-metadata'; +import type { ThemePreference } from '@/lib/theme/config'; import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; interface PendingRouteProps { - params: Promise<{ locale: string; slug: string }>; + params: Promise<{ locale: string; mode: string; slug: string }>; } function routeLabel(messages: ShellMessages, routeId: RouteId): string { @@ -39,19 +41,21 @@ function routeLabel(messages: ShellMessages, routeId: RouteId): string { } async function resolveParams(params: PendingRouteProps['params']) { - const { locale: localeValue, slug } = await params; + const { locale: localeValue, mode: modeValue, slug } = await params; if (!isLocale(localeValue)) notFound(); + if (!isMode(modeValue)) notFound(); const routeId = routeIdFromSlug(localeValue, slug); if (!routeId || routeId === 'home') notFound(); - return { locale: localeValue as Locale, routeId }; + return { locale: localeValue as Locale, mode: modeValue as ThemePreference, routeId }; } export async function generateMetadata({ params }: PendingRouteProps): Promise { - const { locale, routeId } = await resolveParams(params); + const { locale, mode, routeId } = await resolveParams(params); const messages = getMessages(locale).shell; const label = routeLabel(messages, routeId); return buildLocalizedMetadata({ locale, + mode, routeId, title: `${label} | ${messages.metadata.pendingTitle}`, description: messages.metadata.pendingDescription, @@ -60,7 +64,7 @@ export async function generateMetadata({ params }: PendingRouteProps): Promise - {messages.states.backHome} + + {messages.states.backHome} + ); diff --git a/apps/homepage/src/app/[locale]/[mode]/component-lab/ComponentLabInteractive.tsx b/apps/homepage/src/app/[locale]/[mode]/component-lab/ComponentLabInteractive.tsx new file mode 100644 index 0000000..1cba5e1 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/component-lab/ComponentLabInteractive.tsx @@ -0,0 +1,96 @@ +'use client'; + +import { Button } from '@/components/actions/Button'; +import { Accordion } from '@/components/controls/Accordion'; +import { SegmentedControl } from '@/components/controls/SegmentedControl'; +import { Tabs } from '@/components/controls/Tabs'; +import { Alert } from '@/components/feedback/Alert'; +import { Checkbox, Switch } from '@/components/forms/ChoiceControls'; +import { FormField } from '@/components/forms/FormField'; +import { TextInput } from '@/components/forms/TextInput'; +import { DropdownMenu } from '@/components/overlays/DropdownMenu'; +import { Dialog } from '@/components/overlays/Dialog'; +import type { ComponentLabCopy } from '@/content/development/component-lab'; +import { useRef, useState } from 'react'; +import styles from './page.module.css'; + +export function ComponentLabInteractive({ copy }: { copy: ComponentLabCopy }) { + const [dialogOpen, setDialogOpen] = useState(false); + const [segment, setSegment] = useState('comfortable'); + const triggerRef = useRef(null); + return ( +
+
+

Actions

+
+ + + + + + undefined }, + { + id: 'archive', + label: copy.menu.second, + onSelect: () => undefined, + destructive: true, + }, + ]} + /> +
+
+
+

Form controls

+ + + + + + +
+
+

Selection and disclosure

+ + +
+ + {copy.alert.body} + + +

{copy.dialog.content}

+
+
+ ); +} diff --git a/apps/homepage/src/app/[locale]/[mode]/component-lab/page.module.css b/apps/homepage/src/app/[locale]/[mode]/component-lab/page.module.css new file mode 100644 index 0000000..52517f5 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/component-lab/page.module.css @@ -0,0 +1,32 @@ +.main { + min-block-size: 100dvh; +} +.interactiveGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--space-6); +} +.group { + display: grid; + align-content: start; + gap: var(--space-4); + min-inline-size: 0; + padding: var(--space-6); + border: 1px solid var(--border-standard); + border-radius: var(--radius-md); + background: var(--surface-elevated); +} +.group h2 { + margin: 0; + font-size: var(--type-heading-3-size); +} +.cluster { + display: flex; + flex-wrap: wrap; + gap: var(--space-3); +} +@media (max-width: 767px) { + .interactiveGrid { + grid-template-columns: 1fr; + } +} diff --git a/apps/homepage/src/app/[locale]/[mode]/component-lab/page.tsx b/apps/homepage/src/app/[locale]/[mode]/component-lab/page.tsx new file mode 100644 index 0000000..2e7fe27 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/component-lab/page.tsx @@ -0,0 +1,82 @@ +import { Container, Section, Stack } from '@/components/layout/LayoutPrimitives'; +import { Comparison } from '@/components/marketing/Comparison'; +import { CTA } from '@/components/marketing/CTA'; +import { Metric } from '@/components/marketing/Evidence'; +import { ProductPreview } from '@/components/marketing/ProductPreview'; +import { SectionHeader } from '@/components/marketing/SectionHeader'; +import { Workflow } from '@/components/marketing/Workflow'; +import { getComponentLabCopy } from '@/content/development/component-lab'; +import { isLocale, isMode, type Locale } from '@/lib/localization/config'; +import { notFound } from 'next/navigation'; +import { ComponentLabInteractive } from './ComponentLabInteractive'; +import styles from './page.module.css'; + +export const metadata = { robots: { index: false, follow: false } }; + +export default async function ComponentLabPage({ + params, +}: { + params: Promise<{ locale: string; mode: string }>; +}) { + if (process.env.COMPONENT_FIXTURES_ENABLED !== 'true') notFound(); + const { locale, mode } = await params; + if (!isLocale(locale)) notFound(); + if (!isMode(mode)) notFound(); + const resolvedLocale: Locale = locale; + const copy = getComponentLabCopy(resolvedLocale); + return ( +
+
+ + + + + + + ({ + ...row, + statusTone: index === 0 ? 'success' : 'warning', + }))} + /> + + + + +
+
+ ); +} diff --git a/apps/homepage/src/app/[locale]/[mode]/forgot-password/page.tsx b/apps/homepage/src/app/[locale]/[mode]/forgot-password/page.tsx new file mode 100644 index 0000000..1799ce9 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/forgot-password/page.tsx @@ -0,0 +1,21 @@ +import { ForgotPasswordForm } from '@/components/auth/ForgotPasswordForm' +import { isLocale, isMode, type Locale } from '@/lib/localization/config' +import { notFound } from 'next/navigation' +import { Suspense } from 'react' + +export default async function ForgotPasswordPage({ + params, +}: { + params: Promise<{ locale: string; mode: string }> +}) { + const { locale: localeValue, mode } = await params + if (!isLocale(localeValue)) notFound() + if (!isMode(mode)) notFound() + const locale = localeValue as Locale + + return ( + + + + ) +} diff --git a/apps/homepage/src/app/[locale]/[mode]/page.tsx b/apps/homepage/src/app/[locale]/[mode]/page.tsx new file mode 100644 index 0000000..ba8c725 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/page.tsx @@ -0,0 +1,82 @@ +import styles from '@/components/homepage/Homepage.module.css'; +import { + ComparisonSection, + FaqSection, + FinalCtaSection, + HeroSection, + IntegrationsSection, + ModulesSection, + PricingSection, + ResultsSection, + RolesSection, + SecuritySection, + TrustSection, + WorkflowSection, +} from '@/components/homepage/sections'; +import { buildHomepageContent } from '@/content/homepage-model'; +import { getPublicIntegrationConfig } from '@/lib/integrations/environment'; +import { isLocale, isMode, localizedModePath, type Locale } from '@/lib/localization/config'; +import { getMessages } from '@/lib/localization/messages'; +import { buildLocalizedMetadata } from '@/lib/metadata/build-metadata'; +import type { ThemePreference } from '@/lib/theme/config'; +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; + +interface LocalePageProps { + params: Promise<{ locale: string; mode: string }>; +} + +export async function generateMetadata({ params }: LocalePageProps): Promise { + const { locale: localeValue, mode: modeValue } = await params; + if (!isLocale(localeValue)) notFound(); + if (!isMode(modeValue)) notFound(); + const messages = getMessages(localeValue); + return buildLocalizedMetadata({ + locale: localeValue, + mode: modeValue, + routeId: 'home', + title: messages.homepage.meta.title, + description: messages.homepage.meta.description, + indexable: true, + }); +} + +export default async function LocaleHomePage({ params }: LocalePageProps) { + const { locale: localeValue, mode: modeValue } = await params; + if (!isLocale(localeValue)) notFound(); + if (!isMode(modeValue)) notFound(); + + const locale: Locale = localeValue; + const mode: ThemePreference = modeValue; + const messages = getMessages(locale); + const content = buildHomepageContent(messages.homepage, messages.shell, locale); + const integrationConfig = getPublicIntegrationConfig(); + const homePath = localizedModePath('home', locale, mode); + + return ( +
+ + + + + + + + + + + + +
+ ); +} diff --git a/apps/homepage/src/app/[locale]/[mode]/sign-in/page.tsx b/apps/homepage/src/app/[locale]/[mode]/sign-in/page.tsx new file mode 100644 index 0000000..7473c80 --- /dev/null +++ b/apps/homepage/src/app/[locale]/[mode]/sign-in/page.tsx @@ -0,0 +1,21 @@ +import { SignInForm } from '@/components/auth/SignInForm' +import { isLocale, isMode, type Locale } from '@/lib/localization/config' +import { notFound } from 'next/navigation' +import { Suspense } from 'react' + +export default async function SignInPage({ + params, +}: { + params: Promise<{ locale: string; mode: string }> +}) { + const { locale: localeValue, mode } = await params + if (!isLocale(localeValue)) notFound() + if (!isMode(mode)) notFound() + const locale = localeValue as Locale + + return ( + + + + ) +} diff --git a/apps/homepage/src/app/[locale]/component-lab/page.tsx b/apps/homepage/src/app/[locale]/component-lab/page.tsx index 120134c..638135f 100644 --- a/apps/homepage/src/app/[locale]/component-lab/page.tsx +++ b/apps/homepage/src/app/[locale]/component-lab/page.tsx @@ -1,81 +1,19 @@ -import { Container, Section, Stack } from '@/components/layout/LayoutPrimitives'; -import { Comparison } from '@/components/marketing/Comparison'; -import { CTA } from '@/components/marketing/CTA'; -import { Metric } from '@/components/marketing/Evidence'; -import { ProductPreview } from '@/components/marketing/ProductPreview'; -import { SectionHeader } from '@/components/marketing/SectionHeader'; -import { Workflow } from '@/components/marketing/Workflow'; -import { getComponentLabCopy } from '@/content/development/component-lab'; -import { isLocale, type Locale } from '@/lib/localization/config'; -import { notFound } from 'next/navigation'; -import { ComponentLabInteractive } from './ComponentLabInteractive'; -import styles from './page.module.css'; +import { defaultMode, isLocale } from '@/lib/localization/config' +import { isThemePreference, themeCookie } from '@/lib/theme/config' +import { cookies } from 'next/headers' +import { notFound, redirect } from 'next/navigation' -export const metadata = { robots: { index: false, follow: false } }; +export const metadata = { robots: { index: false, follow: false } } -export default async function ComponentLabPage({ +export default async function LegacyComponentLabPage({ params, }: { - params: Promise<{ locale: string }>; + params: Promise<{ locale: string }> }) { - if (process.env.COMPONENT_FIXTURES_ENABLED !== 'true') notFound(); - const { locale } = await params; - if (!isLocale(locale)) notFound(); - const resolvedLocale: Locale = locale; - const copy = getComponentLabCopy(resolvedLocale); - return ( -
-
- - - - - - - ({ - ...row, - statusTone: index === 0 ? 'success' : 'warning', - }))} - /> - - - - -
-
- ); + const { locale } = await params + if (!isLocale(locale)) notFound() + const cookieStore = await cookies() + const cookieMode = cookieStore.get(themeCookie)?.value + const mode = isThemePreference(cookieMode) ? cookieMode : defaultMode + redirect(`/${locale}/${mode}/component-lab`) } diff --git a/apps/homepage/src/app/[locale]/forgot-password/page.tsx b/apps/homepage/src/app/[locale]/forgot-password/page.tsx index dd66b86..267ed4b 100644 --- a/apps/homepage/src/app/[locale]/forgot-password/page.tsx +++ b/apps/homepage/src/app/[locale]/forgot-password/page.tsx @@ -1,20 +1,22 @@ -import { ForgotPasswordForm } from '@/components/auth/ForgotPasswordForm' -import { isLocale, type Locale } from '@/lib/localization/config' -import { notFound } from 'next/navigation' -import { Suspense } from 'react' +import { + defaultMode, + isLocale, + localizedModePath, + type Locale, +} from '@/lib/localization/config' +import { isThemePreference, themeCookie } from '@/lib/theme/config' +import { cookies } from 'next/headers' +import { notFound, redirect } from 'next/navigation' -export default async function ForgotPasswordPage({ +export default async function LegacyForgotPasswordPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale: localeValue } = await params if (!isLocale(localeValue)) notFound() - const locale = localeValue as Locale - - return ( - - - - ) + const cookieStore = await cookies() + const cookieMode = cookieStore.get(themeCookie)?.value + const mode = isThemePreference(cookieMode) ? cookieMode : defaultMode + redirect(localizedModePath('forgot-password', localeValue as Locale, mode)) } diff --git a/apps/homepage/src/app/[locale]/layout.tsx b/apps/homepage/src/app/[locale]/layout.tsx index 710a2a0..23f28c5 100644 --- a/apps/homepage/src/app/[locale]/layout.tsx +++ b/apps/homepage/src/app/[locale]/layout.tsx @@ -48,8 +48,11 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro const requestHeaders = await headers(); const nonce = requestHeaders.get('x-nonce') ?? undefined; const cookieStore = await cookies(); + const headerPreference = requestHeaders.get('x-theme-preference'); const cookiePreference = cookieStore.get(themeCookie)?.value; - const preference: ThemePreference = isThemePreference(cookiePreference) + const preference: ThemePreference = isThemePreference(headerPreference) + ? headerPreference + : isThemePreference(cookiePreference) ? cookiePreference : 'system'; const resolvedTheme = serverResolvedTheme(preference); @@ -89,6 +92,7 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro /> diff --git a/apps/homepage/src/app/[locale]/page.tsx b/apps/homepage/src/app/[locale]/page.tsx index 64eba9b..b6a3df8 100644 --- a/apps/homepage/src/app/[locale]/page.tsx +++ b/apps/homepage/src/app/[locale]/page.tsx @@ -1,77 +1,25 @@ -import styles from '@/components/homepage/Homepage.module.css'; import { - ComparisonSection, - FaqSection, - FinalCtaSection, - HeroSection, - IntegrationsSection, - ModulesSection, - PricingSection, - ResultsSection, - RolesSection, - SecuritySection, - TrustSection, - WorkflowSection, -} from '@/components/homepage/sections'; -import { buildHomepageContent } from '@/content/homepage-model'; -import { getPublicIntegrationConfig } from '@/lib/integrations/environment'; -import { isLocale, localizedPath, type Locale } from '@/lib/localization/config'; -import { getMessages } from '@/lib/localization/messages'; -import { buildLocalizedMetadata } from '@/lib/metadata/build-metadata'; -import type { Metadata } from 'next'; -import { notFound } from 'next/navigation'; + defaultMode, + isLocale, + localizedModePath, + type Locale, +} from '@/lib/localization/config'; +import { isThemePreference, themeCookie } from '@/lib/theme/config'; +import { cookies } from 'next/headers'; +import { notFound, redirect } from 'next/navigation'; -interface LocalePageProps { +interface LocaleRedirectPageProps { params: Promise<{ locale: string }>; } -export async function generateMetadata({ params }: LocalePageProps): Promise { - const { locale: localeValue } = await params; - if (!isLocale(localeValue)) notFound(); - const messages = getMessages(localeValue); - return buildLocalizedMetadata({ - locale: localeValue, - routeId: 'home', - title: messages.homepage.meta.title, - description: messages.homepage.meta.description, - indexable: true, - }); +async function preferredMode() { + const cookieStore = await cookies(); + const cookieMode = cookieStore.get(themeCookie)?.value; + return isThemePreference(cookieMode) ? cookieMode : defaultMode; } -export default async function LocaleHomePage({ params }: LocalePageProps) { +export default async function LocaleRedirectPage({ params }: LocaleRedirectPageProps) { const { locale: localeValue } = await params; if (!isLocale(localeValue)) notFound(); - - const locale: Locale = localeValue; - const messages = getMessages(locale); - const content = buildHomepageContent(messages.homepage, messages.shell, locale); - const integrationConfig = getPublicIntegrationConfig(); - const homePath = localizedPath('home', locale); - - return ( -
- - - - - - - - - - - - -
- ); + redirect(localizedModePath('home', localeValue as Locale, await preferredMode())); } diff --git a/apps/homepage/src/app/[locale]/sign-in/page.tsx b/apps/homepage/src/app/[locale]/sign-in/page.tsx index 763d68d..718db10 100644 --- a/apps/homepage/src/app/[locale]/sign-in/page.tsx +++ b/apps/homepage/src/app/[locale]/sign-in/page.tsx @@ -1,20 +1,22 @@ -import { SignInForm } from '@/components/auth/SignInForm' -import { isLocale, type Locale } from '@/lib/localization/config' -import { notFound } from 'next/navigation' -import { Suspense } from 'react' +import { + defaultMode, + isLocale, + localizedModePath, + type Locale, +} from '@/lib/localization/config' +import { isThemePreference, themeCookie } from '@/lib/theme/config' +import { cookies } from 'next/headers' +import { notFound, redirect } from 'next/navigation' -export default async function SignInPage({ +export default async function LegacySignInPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale: localeValue } = await params if (!isLocale(localeValue)) notFound() - const locale = localeValue as Locale - - return ( - - - - ) + const cookieStore = await cookies() + const cookieMode = cookieStore.get(themeCookie)?.value + const mode = isThemePreference(cookieMode) ? cookieMode : defaultMode + redirect(localizedModePath('sign-in', localeValue as Locale, mode)) } diff --git a/apps/homepage/src/components/app-shell/AuthHeader.tsx b/apps/homepage/src/components/app-shell/AuthHeader.tsx index 57535ee..d98617b 100644 --- a/apps/homepage/src/components/app-shell/AuthHeader.tsx +++ b/apps/homepage/src/components/app-shell/AuthHeader.tsx @@ -1,6 +1,6 @@ 'use client'; -import { localizedPath, type Locale } from '@/lib/localization/config'; +import { localizedModePath, type Locale } from '@/lib/localization/config'; import { type ThemePreference } from '@/lib/theme/config'; import Image from 'next/image'; import { LocalePill } from './LocalePill'; @@ -13,7 +13,7 @@ interface Props { } export function AuthHeader({ locale, themePreference }: Props) { - const homePath = localizedPath('home', locale); + const homePath = localizedModePath('home', locale, themePreference); return (
diff --git a/apps/homepage/src/components/app-shell/BrandLink.tsx b/apps/homepage/src/components/app-shell/BrandLink.tsx index 9dae94f..7d9403d 100644 --- a/apps/homepage/src/components/app-shell/BrandLink.tsx +++ b/apps/homepage/src/components/app-shell/BrandLink.tsx @@ -1,16 +1,25 @@ 'use client'; -import { localizedPath, routeIdFromPathname, type Locale } from '@/lib/localization/config'; +import { localizedModePath, routeIdFromPathname, type Locale } from '@/lib/localization/config'; +import type { ThemePreference } from '@/lib/theme/config'; import Image from 'next/image'; import { usePathname } from 'next/navigation'; import styles from './SiteHeader.module.css'; -export function BrandLink({ locale, label }: { locale: Locale; label: string }) { +export function BrandLink({ + locale, + mode, + label, +}: { + locale: Locale; + mode: ThemePreference; + label: string; +}) { const pathname = usePathname(); return ( diff --git a/apps/homepage/src/components/app-shell/HeaderNavigation.tsx b/apps/homepage/src/components/app-shell/HeaderNavigation.tsx index 347851d..5e6d0ce 100644 --- a/apps/homepage/src/components/app-shell/HeaderNavigation.tsx +++ b/apps/homepage/src/components/app-shell/HeaderNavigation.tsx @@ -1,6 +1,7 @@ 'use client'; -import { localizedPath, routeIdFromPathname, type Locale } from '@/lib/localization/config'; +import { localizedModePath, routeIdFromPathname, type Locale } from '@/lib/localization/config'; +import type { ThemePreference } from '@/lib/theme/config'; import { usePathname } from 'next/navigation'; import { useEffect, useState } from 'react'; import styles from './SiteHeader.module.css'; @@ -9,6 +10,7 @@ export type HeaderNavId = 'product' | 'workflow' | 'modules' | 'pricing' | 'faq' interface HeaderNavigationProps { locale: Locale; + mode: ThemePreference; label: string; labels: Record; onNavigate?: () => void; @@ -19,6 +21,7 @@ const navigationIds: HeaderNavId[] = ['product', 'workflow', 'modules', 'pricing export function HeaderNavigation({ locale, + mode, label, labels, onNavigate, @@ -35,7 +38,7 @@ export function HeaderNavigation({ return () => window.removeEventListener('hashchange', updateHash); }, []); - const home = localizedPath('home', locale); + const home = localizedModePath('home', locale, mode); return (