import m from "https://esm.sh/mithril@2.3.8"; const API = "/api/v1/flashcards"; const Card = { view: function (v) { const c = v.attrs.card; const maxNote = (c.note || "").length > 120 ? c.note.slice(0, 120) + "…" : c.note; return m( ".cyber-card.cyber-card--interactive.cyber-neon-border.cyber-mb-md", { onclick: () => m.route.set("/flashcard/" + c.id), style: "cursor:pointer", }, [ c.tags?.length ? m( ".cyber-card__header", c.tags.map((t) => m("span.cyber-badge.cyber-badge--pulse.cyber-mr-xs", t)), ) : null, m(".cyber-card__body", [ m(".cyber-text-muted.cyber-font-mono", `#${c.id} v${c.version}`), m("p.cyber-text-primary.cyber-mt-sm", maxNote || m("em.cyber-text-muted", "no content")), ]), ], ); }, }; const PAGE_SIZE = 20; const Pager = { view: function (v) { const { page, total } = v.attrs; if (total <= 1) return null; return m(".cyber-flex.cyber-justify-center.cyber-items-center.cyber-gap-sm.cyber-my-md", [ m( "button.cyber-btn.cyber-btn--sm" + (page <= 1 ? ".cyber-btn--ghost" : ""), { disabled: page <= 1, onclick: () => v.attrs.onpage(page - 1) }, "\u2190", ), m("span.cyber-font-mono.cyber-text-muted", `${page} / ${total}`), m( "button.cyber-btn.cyber-btn--sm" + (page >= total ? ".cyber-btn--ghost" : ""), { disabled: page >= total, onclick: () => v.attrs.onpage(page + 1) }, "\u2192", ), ]); }, }; const List = { oninit: async function (v) { v.state.cards = []; v.state.loading = true; const res = await fetch(API); const data = await res.json(); v.state.cards = data.flashcards || []; v.state.loading = false; v.state.page = 1; m.redraw(); }, view: function (v) { if (v.state.loading) { return m(".cyber-center-xy", [ m(".cyber-spinner.cyber-spinner--lg"), m("p.cyber-text-muted.cyber-mt-md", "loading…"), ]); } const totalPages = Math.max(1, Math.ceil(v.state.cards.length / PAGE_SIZE)); const page = Math.min(v.state.page, totalPages); const slice = v.state.cards.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE); return m(".cyber-p-lg", { style: "max-width:720px;margin:0 auto" }, [ m(Pager, { page, total: totalPages, onpage: (n) => { v.state.page = n; }, }), m(".cyber-scanlines", slice.map((c) => m(Card, { card: c }))), m(Pager, { page, total: totalPages, onpage: (n) => { v.state.page = n; }, }), ]); }, }; const Detail = { oninit: async function (v) { v.state.entry = null; v.state.loading = true; try { const res = await fetch(`${API}/${v.attrs.id}`); if (res.ok) v.state.entry = await res.json(); } catch {} v.state.loading = false; m.redraw(); }, view: function (v) { if (v.state.loading) { return m(".cyber-center-xy", m(".cyber-spinner.cyber-spinner--lg")); } const e = v.state.entry; if (!e) { return m(".cyber-p-lg", { style: "max-width:720px;margin:0 auto" }, [ m("button.cyber-btn.cyber-btn--ghost", { onclick: () => m.route.set("/") }, "\u2B05 Back"), m("p.cyber-text-magenta", "Flashcard not found."), ]); } return m(".cyber-p-lg", { style: "max-width:720px;margin:0 auto" }, [ m("button.cyber-btn.cyber-btn--ghost.cyber-mb-md", { onclick: () => m.route.set("/") }, "\u2B05 Back"), m(".cyber-card.cyber-card--holo", [ m(".cyber-card__header", [ m("span.cyber-font-mono.cyber-text-cyan", `#${e.id} v${e.version}`), ]), m(".cyber-card__body", [ m(".cyber-field", [m(".cyber-field__label", "Note"), m("p", e.note)]), e.host ? m(".cyber-field.cyber-mt-sm", [m(".cyber-field__label", "Host"), m("p", e.host)]) : null, e.user ? m(".cyber-field.cyber-mt-sm", [m(".cyber-field__label", "User"), m("p", e.user)]) : null, e.context ? m(".cyber-field.cyber-mt-sm", [m(".cyber-field__label", "Context"), m("p", e.context)]) : null, e.repos?.length ? m(".cyber-field.cyber-mt-sm", [ m(".cyber-field__label", "Repos"), m("div", e.repos.map((r) => m("span.cyber-badge.cyber-mr-xs", r))), ]) : null, e.tags?.length ? m(".cyber-field.cyber-mt-sm", [ m(".cyber-field__label", "Tags"), m("div", e.tags.map((t) => m("span.cyber-badge.cyber-mr-xs", t))), ]) : null, m(".cyber-field.cyber-mt-sm", [m(".cyber-field__label", "Created"), m("p", e.created)]), e.delete_timestamp ? m(".cyber-field.cyber-mt-sm", [m(".cyber-field__label", "Deleted"), m("p", e.delete_timestamp)]) : null, ]), ]), ]); }, }; m.route(document.getElementById("app"), "/", { "/": List, "/flashcard/:id": Detail, });