/** * Frontend route helpers for internal navigation. * * Why this file exists: * - Keep route building consistent across the UI (no stringly-typed URLs scattered everywhere). * - Central place to adjust URL structure if we ever need it. * - Easy to test in pure Node (no DOM / no Next runtime required). * * Notes: * - We encode dynamic segments defensively via encodeURIComponent. * - We validate inputs early to catch mistakes during development. */ /** * Ensure a dynamic route segment is a non-empty string. * * @param {string} name - Human readable segment name for error messages. * @param {unknown} value - The segment value. * @returns {string} Trimmed segment. */ function requireSegment(name, value) { if (typeof value !== "string") { throw new Error(`Route segment "${name}" must be a string`); } const trimmed = value.trim(); if (!trimmed) { throw new Error(`Route segment "${name}" must not be empty`); } return trimmed; } /** * Encode a segment for safe usage in URLs. * * @param {string} name * @param {unknown} value * @returns {string} */ function encodeSegment(name, value) { return encodeURIComponent(requireSegment(name, value)); } /** * Build an absolute path from named segments. * * @param {Array<{ name: string, value: unknown }>} parts * @returns {string} */ function buildPath(parts) { const encoded = parts.map((p) => encodeSegment(p.name, p.value)); return `/${encoded.join("/")}`; } /** * / */ export function homePath() { return "/"; } /** * /login */ export function loginPath() { return "/login"; } /** * /:branch * * @param {string} branch */ export function branchPath(branch) { return buildPath([{ name: "branch", value: branch }]); } /** * /:branch/:year * * @param {string} branch * @param {string} year */ export function yearPath(branch, year) { return buildPath([ { name: "branch", value: branch }, { name: "year", value: year }, ]); } /** * /:branch/:year/:month * * @param {string} branch * @param {string} year * @param {string} month */ export function monthPath(branch, year, month) { return buildPath([ { name: "branch", value: branch }, { name: "year", value: year }, { name: "month", value: month }, ]); } /** * /:branch/:year/:month/:day * * @param {string} branch * @param {string} year * @param {string} month * @param {string} day */ export function dayPath(branch, year, month, day) { return buildPath([ { name: "branch", value: branch }, { name: "year", value: year }, { name: "month", value: month }, { name: "day", value: day }, ]); } /** * /:branch/search * * @param {string} branch */ export function searchPath(branch) { return buildPath([ { name: "branch", value: branch }, { name: "search", value: "search" }, ]); }