web: add footer and ingredients

This commit is contained in:
Dmitriy Pleshevskiy 2022-05-27 23:07:07 +03:00
parent b6a69cbeac
commit 72bb7e04cd
6 changed files with 54 additions and 37 deletions

View File

@ -6,34 +6,41 @@ export function PageLayout(ctx: Context, children: AnyNode[]): Elem {
return E("div", { id: "main" }, [
Header(ctx),
E("div", classNames("content"), children),
// Footer(),
Footer(),
]);
}
export function Header(ctx: Context): Elem {
export function Header(ctx: Context): AnyNode {
return E("header", classNames("header"), [
E("div", classNames("content-width"), [HeaderNav(ctx)]),
]);
}
export function HeaderNav(ctx: Context): Elem {
export function HeaderNav(ctx: Context): AnyNode {
return E("nav", classNames("main-menu"), [
Link(navLink("/", ctx), "Главная"),
Link(navLink("/recipes", ctx), "Рецепты"),
Link(navLink("/ingredients", ctx), "Ингредиенты"),
Link("Главная", navLink("/", ctx)),
Link("Рецепты", navLink("/recipes", ctx)),
Link("Ингредиенты", navLink("/ingredients", ctx)),
]);
}
export function Link(attrs: Attrs | Attrs[], text: string): Elem {
return E("a", attrs, text);
}
function navLink(href: string, ctx?: Context): Attrs {
const attrs: Attrs = { href };
if (ctx?.locPath === href) attrs["aria-current"] = "true";
return attrs;
}
export function Footer(): Elem {
return E("footer", classNames("footer"), "footer");
export function Footer(): AnyNode {
return E("footer", classNames("footer"), [
E("div", classNames("content-width"), [
Link("Исходный код", {
href: "https://notabug.org/pleshevskiy/recipes",
rel: "external nofollow noopener noreferrer",
}),
]),
]);
}
export function Link(text: string, attrs: Attrs | Attrs[]): AnyNode {
return E("a", attrs, text);
}

View File

@ -1,10 +1,12 @@
PAR := $(MAKE) -j 128
DOCKER_NAME := pleshevski
DOCKER_TAG := pleshevski
DOCKER_NAME := recipes
DOCKER_TAG := recipes
watch:
$(PAR) hr ts-w
deno run -A --watch server.ts
start:
deno run -A server.ts
docker-restart: docker-stop docker-run
@ -16,20 +18,3 @@ docker-run:
docker-build:
docker build -t ${DOCKER_TAG} .
build: ts
start:
npm run start
hr:
deno run -A ~/sandbox/hr/server.ts target static
ts:
npm run build
ts-w:
NODE_ENV=develop npx tsc-watch --onSuccess "make start"
clean:
rm -rf target

View File

@ -11,7 +11,9 @@ export class RestIngredientRepo implements IngredientRepo {
const restIngrs: RestIngredient[] = await res.json();
return restIngrs.map(intoAppIngredient);
return restIngrs.map(intoAppIngredient).sort((a, b) =>
a.name.localeCompare(b.name)
);
}
}

View File

@ -55,8 +55,10 @@ async function handleRequest(req: Request): Promise<Response> {
} else if (ctx.locPath === "/ingredients") {
const repo = new RestIngredientRepo();
const ingredients = await repo.fetchIngredients();
console.log({ ingredients });
return createHtmlResponse(ren.render(IngredientsPage(ctx)));
return createHtmlResponse(
ren.render(IngredientsPage(ctx, { ingredients })),
);
} else {
return createHtmlResponse(ren.render(E404Page(ctx)), 404);
}

View File

@ -61,6 +61,11 @@ ul, ol {
padding-bottom: 1.5rem;
}
.footer {
padding-top: 1.5rem;
padding-bottom: 1.5rem;
}
.main-menu {
display: flex;
flex-direction: row;

View File

@ -3,11 +3,27 @@ import { AnyNode, E } from "ren/node.ts";
import { classNames } from "ren/attrs.ts";
import { Context } from "../context.ts";
import { H3 } from "../uikit/typo.ts";
import { Ingredient } from "../domain/ingredient/types.ts";
export function IngredientsPage(ctx: Context): AnyNode {
interface IngredientsPageData {
ingredients: Ingredient[];
}
export function IngredientsPage(
ctx: Context,
data: IngredientsPageData,
): AnyNode {
return PageLayout(ctx, [
E("div", classNames("content-width"), [
H3("Ингредиенты"),
E("div", [], data.ingredients.map(IngredientItem)),
]),
]);
}
export function IngredientItem(ingr: Ingredient): AnyNode {
return E("div", [], [
ingr.name,
// E("a", { href: `/ingredients/${ingr.key}` }, ingr.name),
]);
}