Files
immich-folio/lib/siteNav.ts
Ralksta ad8b09700b release: v0.19.0
Release v0.19.0. See the `## [0.19.0] — 2026-09-29` section of
[CHANGELOG.md](https://github.com/ralksta/immich-folio/blob/dev/CHANGELOG.md)
for the full list.

Highlights: client proofing links (#683), custom content pages (#738),
asset picker search (#740), concurrent-edit detection (#742), env-locked
settings (#739), an accessibility baseline (#741), three security fixes
with advisories (#737, #755, #759), and a pre-release quality pass
(#780–#797).

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-09-29 22:50:30 +02:00

53 lines
1.8 KiB
TypeScript

/**
* The site's navigation entries, in the one order the header and the home
* page hero share (#696): subpages and content pages (gallery.yaml order),
* standalone albums, Journal, About, Map.
*
* Client-safe: callers do the fetching and pass the results in.
*/
import type { Dictionary } from './i18n';
import type { MenuItem } from './pages';
export interface SiteNavLink {
key: string;
href: string;
label: string;
/** "3 albums" / "12 photos" — only the hero shows it, and only presets that want it. */
count?: string;
}
export interface SiteNavInput {
/** Subpages and content pages, from `resolveMenu()`. */
menu: readonly MenuItem[];
/** Album count per subpage slug, for the hero's count line. */
subpageAlbumCounts?: ReadonlyMap<string, number>;
albums: ReadonlyArray<{ id: string; slug: string; albumName: string; assetCount?: number }>;
/** At least one published (non-draft) journal entry. */
hasJournal: boolean;
aboutEnabled: boolean;
map: boolean;
}
export function siteNavLinks(input: SiteNavInput, t: Dictionary): SiteNavLink[] {
const links: SiteNavLink[] = input.menu.map((item) => {
const n = input.subpageAlbumCounts?.get(item.href.slice(1));
return {
...item,
...(item.key.startsWith('sp-') && n !== undefined ? { count: t.common.albums(n) } : {}),
};
});
for (const a of input.albums) {
links.push({
key: `al-${a.id}`,
href: `/${a.slug}`,
label: a.albumName,
...(a.assetCount !== undefined ? { count: t.common.photos(a.assetCount) } : {}),
});
}
if (input.hasJournal) links.push({ key: 'journal', href: '/journal', label: t.nav.journal });
if (input.aboutEnabled) links.push({ key: 'about', href: '/about', label: t.nav.about });
if (input.map) links.push({ key: 'map', href: '/map', label: t.nav.map });
return links;
}