76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
/* ============================================================================
|
|||
|
|
ROUTE SLUGS - the single source of truth for the site's ten sections
|
||
|
|
----------------------------------------------------------------------------
|
||
|
|
This module has ZERO imports on purpose: it is loaded by `app/routes.ts`,
|
||
|
|
which the React Router dev plugin evaluates in Node while building the route
|
||
|
|
config, long before the React tree exists.
|
||
|
|
|
||
|
|
This table is the source of truth for the site's URLs, and the consumers
|
||
|
|
are checked against it rather than repeating it: the footer sitemap imports
|
||
|
|
`ROUTE_SLUGS` directly, and `NAV_PATHS` in
|
||
|
|
~/components/ui/Navigation/nav-items.ts is constrained by `RouteSlugs`, so
|
||
|
|
a slug changed here and forgotten there is a type error, not a dead link.
|
||
|
|
|
||
|
|
Both locales share the Latin slug; the locale lives in the URL prefix
|
||
|
|
(/en/contact, /ar/contact) and never in the slug itself.
|
||
|
|
========================================================================= */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Slug for every top-level section, WITHOUT a leading slash so it can be
|
||
|
|
* handed straight to `route()` in the route config. `home` is the index of the
|
||
|
|
* `:lang` layout and therefore has no slug of its own.
|
||
|
|
*/
|
||
|
|
export const ROUTE_SLUGS = {
|
||
|
|
home: "",
|
||
|
|
about: "about",
|
||
|
|
whatWeDo: "what-we-do",
|
||
|
|
activities: "activities-and-initiatives",
|
||
|
|
events: "events-calendar",
|
||
|
|
applications: "applications-and-opportunities",
|
||
|
|
news: "news-and-updates",
|
||
|
|
contact: "contact",
|
||
|
|
resources: "resources-and-publications",
|
||
|
|
knowledgeHub: "knowledge-hub",
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
export type RouteSlugKey = keyof typeof ROUTE_SLUGS;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The table's own shape, so a consumer can be typed against the exact slugs
|
||
|
|
* without importing the value and taking on this module's Node-time role.
|
||
|
|
*/
|
||
|
|
export type RouteSlugs = typeof ROUTE_SLUGS;
|
||
|
|
|
||
|
|
/** The ten section keys in navigation order. */
|
||
|
|
export const ROUTE_SLUG_KEYS = Object.keys(ROUTE_SLUGS) as readonly RouteSlugKey[];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The unprefixed pathname of a section, e.g. "/" or "/what-we-do".
|
||
|
|
* Use `sectionPath()` from ~/i18n when you want the locale-prefixed URL.
|
||
|
|
*/
|
||
|
|
export function sectionSlugPath(key: RouteSlugKey): string {
|
||
|
|
const slug = ROUTE_SLUGS[key];
|
||
|
|
return slug === "" ? "/" : `/${slug}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** The IA groups the navigation and the footer sitemap both render. */
|
||
|
|
export const ROUTE_SECTION_GROUPS = [
|
||
|
|
{
|
||
|
|
id: "about-and-strategy",
|
||
|
|
children: ["about", "whatWeDo", "activities"],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "engagement-and-opportunities",
|
||
|
|
children: ["events", "applications", "news", "contact"],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "knowledge-and-impact",
|
||
|
|
children: ["resources", "knowledgeHub"],
|
||
|
|
},
|
||
|
|
] as const satisfies readonly {
|
||
|
|
id: string;
|
||
|
|
children: readonly RouteSlugKey[];
|
||
|
|
}[];
|
||
|
|
|
||
|
|
export type RouteSectionGroupId = (typeof ROUTE_SECTION_GROUPS)[number]["id"];
|