56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { AnyNode, Attrs, E, Elem } from "ren/node.ts";
|
|
import { classNames } from "ren/attrs.ts";
|
|
import { Context, Lang } from "../context.ts";
|
|
|
|
export function PageLayout(ctx: Context, children: AnyNode[]): Elem {
|
|
return E("div", { id: "main" }, [
|
|
Header(ctx),
|
|
E("div", classNames("content"), children),
|
|
Footer(ctx),
|
|
]);
|
|
}
|
|
|
|
export function Header(ctx: Context): AnyNode {
|
|
return E("header", classNames("header gap-v-1x5"), [
|
|
E("div", classNames("content-width"), [HeaderNav(ctx)]),
|
|
]);
|
|
}
|
|
|
|
export function HeaderNav(ctx: Context): AnyNode {
|
|
return E("nav", classNames("main-menu"), [
|
|
Link(ctx.tr.Home, navLink("/", ctx)),
|
|
Link(ctx.tr.Recipes, navLink("/recipes", ctx)),
|
|
Link(ctx.tr.Ingredients, navLink("/ingredients", ctx)),
|
|
]);
|
|
}
|
|
|
|
function navLink(lhref: string, ctx?: Context): Attrs {
|
|
const attrs: Attrs = { lhref };
|
|
if (ctx?.locPath === lhref) attrs["aria-current"] = "true";
|
|
return attrs;
|
|
}
|
|
|
|
export function Footer(ctx: Context): AnyNode {
|
|
return E("footer", classNames("footer gap-v-1x5"), [
|
|
E("div", classNames("content-width"), [
|
|
Link(ctx.tr.Source_code, {
|
|
href: "https://notabug.org/pleshevskiy/recipes",
|
|
rel: "external nofollow noopener noreferrer",
|
|
}),
|
|
E("div", [], [
|
|
ChangeLangBtn(ctx, Lang.Rus),
|
|
ChangeLangBtn(ctx, Lang.Eng),
|
|
]),
|
|
]),
|
|
]);
|
|
}
|
|
|
|
export function Link(text: string, attrs: Attrs | Attrs[]): AnyNode {
|
|
return E("a", attrs, text);
|
|
}
|
|
|
|
export function ChangeLangBtn(ctx: Context, lang: Lang): AnyNode {
|
|
const prefix = lang === Lang.Rus ? "" : `/${lang}`;
|
|
return E("a", { "href": prefix + ctx.locPath }, lang);
|
|
}
|