diff --git a/ismism.ts/ui/index/bind.ts b/ismism.ts/ui/index/bind.ts index 6b79aef..d0160be 100644 --- a/ismism.ts/ui/index/bind.ts +++ b/ismism.ts/ui/index/bind.ts @@ -1,7 +1,7 @@ // deno-lint-ignore-file no-window-prefix import { Agenda, Rec } from "../../../cli/json.ts" import { utc_medium } from "../../src/date.ts" -import { Tag } from "../../src/typ.ts" +import { Goal, Tag } from "../../src/typ.ts" let hash = "" let agenda: Agenda[] @@ -49,20 +49,40 @@ function etag( }) } +function egoal( + el: HTMLElement, + goal: Goal[], +) { + el.innerHTML = "" + for (const { pct, name } of goal) { + const [t, [p, n]] = template("goal", ["pct", "name"]) + if (pct === 100) { + p.classList.add("done") + p.innerText = "完成" + } else if (pct > 0) { + p.classList.add("ongoing") + p.style.setProperty("--pct", `${pct}`) + p.innerText = `${pct}%` + } + n.innerText = name + el.appendChild(t) + } +} + function eagenda( el: HTMLElement, agenda: Agenda[] ) { el.innerHTML = "" - for (const { _id, name, tag, utc, dat, fund, budget, expense, detail } of agenda) { + for (const { _id, name, tag, utc, dat, fund, budget, expense, detail, goal } of agenda) { const [t, [ cidname, cid, cname, ctag, cdate, cphoto, cphoto_title, cphoto_prev, cphoto_next, cphoto_nbr, cphoto_total, cphoto_img, - cbar, cfund, cexpense, cdetail, + cbar, cfund, cexpense, cdetail, cgoal, ]] = template("agenda", [ "idname", "id", "name", "tag", "date", "photo", "photo-title", "photo-prev", "photo-next", "photo-nbr", "photo-total", "photo-img", - "bar", "fund", "expense", "detail", + "bar", "fund", "expense", "detail", "goal" ]); (cidname as HTMLLinkElement).href = `#a${_id}` @@ -103,6 +123,7 @@ function eagenda( spct.innerText = `${budget == 0 ? 0 : (expense / budget * 100).toFixed(0)}%` } (cdetail as HTMLLinkElement).href = detail + egoal(cgoal, goal) el.appendChild(t) } diff --git a/ismism.ts/ui/index/index.html b/ismism.ts/ui/index/index.html index eeb1fba..25e811f 100644 --- a/ismism.ts/ui/index/index.html +++ b/ismism.ts/ui/index/index.html @@ -303,6 +303,51 @@ left: -16px; } + div.goal { + display: flex; + flex-flow: row wrap; + justify-content: center; + text-align: center; + } + + div.goal>div { + flex-basis: 1px; + flex-grow: 1; + display: flex; + flex-flow: column nowrap; + align-items: center; + margin: 10px; + font-size: var(--large); + } + + div.goal>div>div.pct { + --size: 4em; + width: var(--size); + height: var(--size); + margin-bottom: 10px; + border-radius: 50%; + display: grid; + place-items: center; + background: radial-gradient(closest-side, var(--white) 66%, var(--lightgray) 66%); + font-family: monospace; + font-size: calc(var(--size) / 2); + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + color: var(--gray); + text-shadow: 0 2px 2px var(--lightgray); + } + + div.goal>div>div.pct.ongoing { + --pct: 65; + color: var(--amber); + background: + radial-gradient(closest-side, var(--white) 66%, transparent 66%), + conic-gradient(var(--gray) calc(var(--pct) * 1%), var(--lightgray) 0); + } + + div.goal>div>div.pct.done { + background: radial-gradient(closest-side, var(--white) 66%, var(--gray) 66%); + } + article { margin: 16px; padding: 8px 16px; @@ -342,6 +387,12 @@ +