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" }, [ return E("div", { id: "main" }, [
Header(ctx), Header(ctx),
E("div", classNames("content"), children), E("div", classNames("content"), children),
// Footer(), Footer(),
]); ]);
} }
export function Header(ctx: Context): Elem { export function Header(ctx: Context): AnyNode {
return E("header", classNames("header"), [ return E("header", classNames("header"), [
E("div", classNames("content-width"), [HeaderNav(ctx)]), 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"), [ return E("nav", classNames("main-menu"), [
Link(navLink("/", ctx), "Главная"), Link("Главная", navLink("/", ctx)),
Link(navLink("/recipes", ctx), "Рецепты"), Link("Рецепты", navLink("/recipes", ctx)),
Link(navLink("/ingredients", 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 { function navLink(href: string, ctx?: Context): Attrs {
const attrs: Attrs = { href }; const attrs: Attrs = { href };
if (ctx?.locPath === href) attrs["aria-current"] = "true"; if (ctx?.locPath === href) attrs["aria-current"] = "true";
return attrs; return attrs;
} }
export function Footer(): Elem { export function Footer(): AnyNode {
return E("footer", classNames("footer"), "footer"); 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 PAR := $(MAKE) -j 128
DOCKER_NAME := pleshevski DOCKER_NAME := recipes
DOCKER_TAG := pleshevski DOCKER_TAG := recipes
watch: watch:
$(PAR) hr ts-w deno run -A --watch server.ts
start:
deno run -A server.ts
docker-restart: docker-stop docker-run docker-restart: docker-stop docker-run
@ -16,20 +18,3 @@ docker-run:
docker-build: docker-build:
docker build -t ${DOCKER_TAG} . 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(); 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") { } else if (ctx.locPath === "/ingredients") {
const repo = new RestIngredientRepo(); const repo = new RestIngredientRepo();
const ingredients = await repo.fetchIngredients(); const ingredients = await repo.fetchIngredients();
console.log({ ingredients });
return createHtmlResponse(ren.render(IngredientsPage(ctx))); return createHtmlResponse(
ren.render(IngredientsPage(ctx, { ingredients })),
);
} else { } else {
return createHtmlResponse(ren.render(E404Page(ctx)), 404); return createHtmlResponse(ren.render(E404Page(ctx)), 404);
} }

View File

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

View File

@ -3,11 +3,27 @@ import { AnyNode, E } from "ren/node.ts";
import { classNames } from "ren/attrs.ts"; import { classNames } from "ren/attrs.ts";
import { Context } from "../context.ts"; import { Context } from "../context.ts";
import { H3 } from "../uikit/typo.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, [ return PageLayout(ctx, [
E("div", classNames("content-width"), [ E("div", classNames("content-width"), [
H3("Ингредиенты"), 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),
]);
}