using Elternbeirat.Contracts; namespace Elternbeirat.Web.Features.Layout; /// /// Builds the header and footer navigation from the public pages. Every page /// carries a required ("header" or "footer") and an /// ; this splits them into the two menus, each ordered. /// public static class NavBuilder { /// Header links, ordered, built from pages with location "header". public static IReadOnlyList Header(IReadOnlyList pages) => ToLinks(PagesAt(pages, "header")); /// Footer links, ordered, built from pages with location "footer". public static IReadOnlyList Footer(IReadOnlyList pages) => ToLinks(PagesAt(pages, "footer")); /// /// Returns the pages of the header menu themselves, in menu order. /// /// All public pages. /// The pages with location header, ordered by . /// /// For callers that need more than a link, such as the tiles on the home page, /// which also show part of each page's body. Using the same selection as /// keeps tiles and menu in step. /// public static IReadOnlyList HeaderPages(IReadOnlyList pages) => PagesAt(pages, "header"); /// /// Returns the URL a page is reached at. /// /// The page's slug. /// / for the home page, otherwise /{slug}. /// /// The home page owns "/" (served by the Home component); every other slug is /// reached at "/{slug}", where either a literal route or the catch-all content /// page renders it. /// public static string HrefFor(string slug) => Page.IsHomeSlug(slug) ? "/" : $"/{slug}"; private static List PagesAt( IReadOnlyList pages, string location) => [.. pages .Where(page => string.Equals(page.Location, location, StringComparison.Ordinal)) .OrderBy(page => page.Order)]; private static List ToLinks(IEnumerable pages) => [.. pages.Select(page => new NavLinkItem(HrefFor(page.Slug), page.Title))]; }