commit a97c5127d89b126c70b35c326a2b33269e311f65 Author: George Lambert Date: Fri Sep 11 19:55:13 2026 -0400 Initial import of verae-staff-ui from zapier monorepo diff --git a/NATS.md b/NATS.md new file mode 100644 index 0000000..1794266 --- /dev/null +++ b/NATS.md @@ -0,0 +1,3 @@ +# NATS + +None. Static HTML template. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a8af5f --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# verae-staff-ui + +One review HTML template for **customer-service** and **access-staff** (they were twins). Tokens: `{{TITLE}}`, `{{KICKER}}`, `{{LEDE}}`. + +In the monorepo both servers load `packages/verae-staff-ui/public/review.html`. A cloned package can set `STAFF_UI_HTML` or keep a local `public/index.html` fallback. + +**Forgejo:** https://git.georgelambert.org/marchon/verae-staff-ui diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 0000000..a07381b --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,3 @@ +# verae-staff-ui + +Shared staff account-review page (dollars, names typeahead, credit form) used by CS and the staff access plane. diff --git a/package.json b/package.json new file mode 100644 index 0000000..677ffd6 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "verae-staff-ui", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Shared staff review HTML for CS and access-staff", + "scripts": { "test": "node --test test/*.test.js" } +} diff --git a/public/review.html b/public/review.html new file mode 100644 index 0000000..c993109 --- /dev/null +++ b/public/review.html @@ -0,0 +1,157 @@ + + + + + + {{TITLE}} + + + + + +
+
{{KICKER}}
+

{{TITLE}}

+

{{LEDE}}

+
+
+
+
+
+ + + +
+ +
+
+
+

Apply credit

+
+
+ + +
+
+ + +
+
+ + +
+ +
+

Credits write to account-balance. The customer sees dollars, not cents.

+
+
+
+ + + diff --git a/src/load.js b/src/load.js new file mode 100644 index 0000000..2998152 --- /dev/null +++ b/src/load.js @@ -0,0 +1,27 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const HERE = path.dirname(fileURLToPath(import.meta.url)); + +export function reviewHtmlPath(fallback) { + const env = process.env.STAFF_UI_HTML; + const shared = path.join(HERE, '..', 'public', 'review.html'); + const sibling = path.join(HERE, '..', '..', 'verae-staff-ui', 'public', 'review.html'); + for (const p of [env, shared, sibling, fallback]) { + if (p && fs.existsSync(p)) return p; + } + return fallback; +} + +export function loadReviewHtml(opts, fallback) { + const file = reviewHtmlPath(fallback); + let html = fs.readFileSync(file, 'utf8'); + const map = { + '{{TITLE}}': opts.title || 'Staff review', + '{{KICKER}}': opts.kicker || 'staff', + '{{LEDE}}': opts.lede || 'Review prepaid balance, credits, usage, and payments in dollars.', + }; + for (const [k, v] of Object.entries(map)) html = html.split(k).join(v); + return html; +} diff --git a/test/load.test.js b/test/load.test.js new file mode 100644 index 0000000..a3796df --- /dev/null +++ b/test/load.test.js @@ -0,0 +1,11 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { loadReviewHtml } from '../src/load.js'; + +test('fills title kicker lede', () => { + const html = loadReviewHtml({ title: 'Staff access', kicker: 'staff plane', lede: 'After authz.' }); + assert.match(html, /Staff access/); + assert.match(html, /staff plane/); + assert.match(html, /After authz/); + assert.doesNotMatch(html, /\{\{TITLE\}\}/); +});