From 72bb7e04cd2853486f91dbdfb1f2d00398e2190e Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Fri, 27 May 2022 23:07:07 +0300 Subject: [PATCH] web: add footer and ingredients --- web/comp/page_layout.ts | 31 +++++++++++++++++++------------ web/makefile | 27 ++++++--------------------- web/repo/ingredient/rest.ts | 4 +++- web/server.ts | 6 ++++-- web/static/styles.css | 5 +++++ web/views/ingredients.ts | 18 +++++++++++++++++- 6 files changed, 54 insertions(+), 37 deletions(-) diff --git a/web/comp/page_layout.ts b/web/comp/page_layout.ts index 3830548..dc43ae7 100644 --- a/web/comp/page_layout.ts +++ b/web/comp/page_layout.ts @@ -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); } diff --git a/web/makefile b/web/makefile index 909e4b1..1500a9e 100644 --- a/web/makefile +++ b/web/makefile @@ -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 diff --git a/web/repo/ingredient/rest.ts b/web/repo/ingredient/rest.ts index 45c6db6..1c8fa15 100644 --- a/web/repo/ingredient/rest.ts +++ b/web/repo/ingredient/rest.ts @@ -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) + ); } } diff --git a/web/server.ts b/web/server.ts index e059a60..dcd4eea 100644 --- a/web/server.ts +++ b/web/server.ts @@ -55,8 +55,10 @@ async function handleRequest(req: Request): Promise { } 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); } diff --git a/web/static/styles.css b/web/static/styles.css index 7f916ea..1c84641 100644 --- a/web/static/styles.css +++ b/web/static/styles.css @@ -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; diff --git a/web/views/ingredients.ts b/web/views/ingredients.ts index fa06b92..9a0a055 100644 --- a/web/views/ingredients.ts +++ b/web/views/ingredients.ts @@ -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), + ]); +}