initial commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/* ============================================================================
|
||||
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"];
|
||||
Reference in New Issue
Block a user