mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
feat(site): dogfood the Scarf dashboard format as the catalog website
Adds site/ with vanilla HTML + CSS + ~300 lines of JavaScript that
renders ProjectDashboard JSON directly in the browser. Each template's
detail page shows a live preview of the exact dashboard the user will
get post-install — the catalog IS the dogfood.
site/widgets.js mirrors the Swift widget dispatcher:
- stat (big number + colored icon + optional subtitle)
- progress (0..1 bar)
- text with inline markdown subset (headings, bold/italic, inline code,
code fences, bullet + numbered lists, links)
- table (plain HTML)
- list (with up/down/unknown status badges)
- chart (SVG line + bar — no Chart.js dependency)
- webview (sandboxed iframe)
- unknown (placeholder so the page doesn't silently omit widgets)
Plus the renderMarkdown helper used by the template detail page to
display the bundle's README.
site/index.html.tmpl + site/template.html.tmpl are substitution-only —
the Python regenerator swaps {{CARDS}}, {{COUNT}}, {{COUNT_PLURAL}},
{{NAME}}, {{DESC}}, {{VERSION}}, {{AUTHOR_HTML}}, {{TAGS_HTML}},
{{INSTALL_URL_ENCODED}}, {{SCARF_INSTALL_URL}}. The detail page fetches
dashboard.json + README.md at page load and hands them to widgets.js.
No client-side framework, no bundler, no npm.
site/styles.css: minimal CSS with scarf green accent, prefers-color-
scheme dark support, responsive at 680px. One file, ~280 lines.
build-catalog.py extended to copy dashboard.json + README.md out of each
bundle into its detail dir so widgets.js can fetch them without
reaching across directories (and so gh-pages doesn't need to serve zip
contents at request time).
Two new Python tests: end-to-end site rendering (both cards, install
URL wiring, static asset copy, per-template dashboard + README copy)
and the {{COUNT_PLURAL}} singular-vs-plural flip. 16/16 Python tests
green.
Smoke-tested locally with python3 -m http.server: every endpoint
(index, catalog.json, detail HTML, per-template dashboard.json + README,
widgets.js) returns 200. The .gh-pages-worktree/appcast.xml +
.gh-pages-worktree/index.html are untouched — the catalog is purely
additive under /templates/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{NAME}} — Scarf Templates</title>
|
||||
<meta name="description" content="{{DESC}}">
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<link rel="icon" type="image/png" href="../assets/icon.png">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<a class="brand" href="..">
|
||||
<img src="../assets/icon.png" alt="" width="40" height="40">
|
||||
<span class="brand-name">Scarf Templates</span>
|
||||
</a>
|
||||
<nav class="site-nav">
|
||||
<a href="..">Catalog</a>
|
||||
<a href="https://github.com/awizemann/scarf">GitHub</a>
|
||||
<a href="https://github.com/awizemann/scarf/blob/main/templates/CONTRIBUTING.md">Contribute</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="detail">
|
||||
<section class="detail-header">
|
||||
<div>
|
||||
<h1>{{NAME}} <span class="version">v{{VERSION}}</span></h1>
|
||||
<p class="desc">{{DESC}}</p>
|
||||
<p class="meta">
|
||||
<span class="author">by {{AUTHOR_HTML}}</span>
|
||||
<span class="id">{{ID}}</span>
|
||||
<span class="category">{{CATEGORY}}</span>
|
||||
</p>
|
||||
<p class="tags">{{TAGS_HTML}}</p>
|
||||
</div>
|
||||
<div class="install-actions">
|
||||
<a class="btn btn-primary" href="{{SCARF_INSTALL_URL}}">Install with Scarf</a>
|
||||
<a class="btn btn-secondary" href="{{INSTALL_URL_ENCODED}}">Download .scarftemplate</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="detail-dashboard">
|
||||
<h2>Live dashboard preview</h2>
|
||||
<p class="detail-dashboard-note">
|
||||
Exactly what you'll see inside Scarf after install. Values shown here are
|
||||
placeholders; the agent updates them each time the cron job runs.
|
||||
</p>
|
||||
<div id="dashboard-preview"></div>
|
||||
</section>
|
||||
|
||||
<section class="detail-readme">
|
||||
<h2>README</h2>
|
||||
<div id="readme-body"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<p>
|
||||
Scarf is open source:
|
||||
<a href="https://github.com/awizemann/scarf">github.com/awizemann/scarf</a>.
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script src="../widgets.js"></script>
|
||||
<script>
|
||||
// Fetch + render dashboard + README at page load. Both files live
|
||||
// alongside index.html in this template's detail dir.
|
||||
(async function () {
|
||||
const dashboardEl = document.getElementById("dashboard-preview");
|
||||
const readmeEl = document.getElementById("readme-body");
|
||||
try {
|
||||
const d = await fetch("dashboard.json").then(r => r.json());
|
||||
ScarfWidgets.renderDashboard(dashboardEl, d);
|
||||
} catch (e) {
|
||||
dashboardEl.textContent = "Could not load dashboard preview.";
|
||||
}
|
||||
try {
|
||||
const md = await fetch("README.md").then(r => r.text());
|
||||
readmeEl.innerHTML = ScarfWidgets.renderMarkdown(md);
|
||||
} catch (e) {
|
||||
readmeEl.textContent = "Could not load README.";
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user