80 lines
2.8 KiB
TypeScript
80 lines
2.8 KiB
TypeScript
/* ============================================================================
|
|||
|
|
SITE NAVIGATION DATA
|
||
|
|
----------------------------------------------------------------------------
|
||
|
|
Builds the <Navigation /> tree and the <Footer /> sitemap from ONE source:
|
||
|
|
`ROUTE_SLUGS` (which `app/routes.ts` also builds the route table from) plus
|
||
|
|
the `nav.sections.*` labels in the message catalogues. Slugs, routes, header
|
||
|
|
links and footer links therefore cannot drift apart.
|
||
|
|
|
||
|
|
<Footer />'s own defaults use a shorter slug set (/en/events, /en/news, ...);
|
||
|
|
the shell passes these groups explicitly so both bars point at the routes
|
||
|
|
that actually exist.
|
||
|
|
|
||
|
|
When the CMS is wired, replace these two functions with a Strapi
|
||
|
|
site-settings query - the shapes they return are exactly what both
|
||
|
|
components accept as props.
|
||
|
|
========================================================================= */
|
||
|
|
|
||
|
|
import type { FooterLinkGroup } from "~/components/ui/Footer";
|
||
|
|
import type { NavItem } from "~/components/ui/Navigation";
|
||
|
|
import type { Locale } from "~/i18n/config";
|
||
|
|
import { ROUTE_SECTION_GROUPS, sectionPath, type RouteSlugKey } from "~/i18n/paths";
|
||
|
|
import { getMessages } from "~/i18n/t";
|
||
|
|
|
||
|
|
/** Section labels for a locale, keyed the same way as `ROUTE_SLUGS`. */
|
||
|
|
function sectionLabels(locale: Locale) {
|
||
|
|
return getMessages(locale).nav.sections;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Heading for one of the three IA groups. */
|
||
|
|
function groupHeading(locale: Locale, groupId: string): string {
|
||
|
|
const labels = sectionLabels(locale);
|
||
|
|
|
||
|
|
switch (groupId) {
|
||
|
|
case "about-and-strategy":
|
||
|
|
return labels.aboutAndStrategy;
|
||
|
|
case "engagement-and-opportunities":
|
||
|
|
return labels.engagementAndOpportunities;
|
||
|
|
default:
|
||
|
|
return labels.knowledgeAndImpact;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The header navigation: Home as a link, then the three groups as
|
||
|
|
* disclosures. Every href is already locale-prefixed.
|
||
|
|
*/
|
||
|
|
export function buildNavItems(locale: Locale): NavItem[] {
|
||
|
|
const labels = sectionLabels(locale);
|
||
|
|
|
||
|
|
return [
|
||
|
|
{ id: "home", label: labels.home, href: sectionPath("home", locale) },
|
||
|
|
...ROUTE_SECTION_GROUPS.map((group) => ({
|
||
|
|
id: group.id,
|
||
|
|
label: groupHeading(locale, group.id),
|
||
|
|
children: group.children.map((key: RouteSlugKey) => ({
|
||
|
|
id: key,
|
||
|
|
label: labels[key],
|
||
|
|
href: sectionPath(key, locale),
|
||
|
|
})),
|
||
|
|
})),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The footer sitemap: the same three groups, without Home - the wordmark
|
||
|
|
* above the columns already links there.
|
||
|
|
*/
|
||
|
|
export function buildFooterLinkGroups(locale: Locale): FooterLinkGroup[] {
|
||
|
|
const labels = sectionLabels(locale);
|
||
|
|
|
||
|
|
return ROUTE_SECTION_GROUPS.map((group) => ({
|
||
|
|
id: group.id,
|
||
|
|
heading: groupHeading(locale, group.id),
|
||
|
|
links: group.children.map((key: RouteSlugKey) => ({
|
||
|
|
label: labels[key],
|
||
|
|
href: sectionPath(key, locale),
|
||
|
|
})),
|
||
|
|
}));
|
||
|
|
}
|