@tideworthy/tidysites-platform 0.10.8 → 0.10.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.10
4
+
5
+ - Editor: the bar reads Edit, Request a change, Revisions, Publish live; Publish live is green.
6
+
7
+ ## 0.10.9
8
+
9
+ - Editor: the request panel greets the person by name and speaks plainly; the floating button is a pen, not a chat bubble. `GET /_tidy/change` says who is signed in.
10
+
3
11
  ## 0.10.8
4
12
 
5
13
  - Editor: Request a change, from the bar and a floating button at the corner. A panel takes what to change and which page (the current one by default) and hands it to the platform through the control plane (`POST /_tidy/change`); it shows up under Changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tideworthy/tidysites-platform",
3
- "version": "0.10.8",
3
+ "version": "0.10.10",
4
4
  "description": "The Tidysites platform integration for EmDash sites: bootstrap, sessions, maintenance, health, and publish hooks under /_tidy/*.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -110,6 +110,8 @@ const htmlClass = !signedIn ? (signInUrl ? "tidy-has-bar tidy-idle" : "") : !act
110
110
  .tidy-btn-primary { background: #2b7fd1; border-color: #2b7fd1; color: #fff; }
111
111
  .tidy-btn-primary:hover { background: #2470bd; }
112
112
  .tidy-btn-danger:hover { background: #b3261e; border-color: #b3261e; }
113
+ .tidy-btn-go { background: #1f9d55; border-color: #1f9d55; color: #fff; }
114
+ .tidy-btn-go:hover { background: #1a8a4a; }
113
115
  .tidy-btn-sm { padding: 3px 8px; font-size: 12px; }
114
116
  .tidy-add-end { display: block; width: calc(100% - 32px); margin: 16px; padding: 14px; border: 2px dashed #2b7fd1; border-radius: 10px; background: rgba(43,127,209,.06); color: #2b7fd1; font: 600 14px system-ui, sans-serif; cursor: pointer; }
115
117
  .tidy-panel { position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 100vw); z-index: 2147483001; overflow: auto; background: #fff; color: #17211c; border-left: 1px solid #d3dcd6; box-shadow: -12px 0 40px rgba(0,0,0,.18); padding: 20px; font: 14px/1.45 system-ui, sans-serif; }
@@ -29,8 +29,16 @@ export function mountRequestChange(): void {
29
29
  panel.replaceChildren();
30
30
  }
31
31
 
32
- function render() {
33
- const head = el("div", { class: "tidy-panel-head" }, [el("h2", { text: "Request a change" }), el("p", { text: "Say what you would like changed. It shows up under Changes and someone picks it up." })]);
32
+ let who: { name: string | null } | null = null;
33
+ const firstName = () => (who?.name ?? "").trim().split(/\s+/)[0] || "";
34
+
35
+ async function render() {
36
+ if (!who) who = (await fetch(ROUTE, { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : null)).catch(() => null)) as { name: string | null } | null;
37
+ const name = firstName();
38
+ const head = el("div", { class: "tidy-panel-head" }, [
39
+ el("h2", { text: name ? `Hi ${name},` : "Hi there," }),
40
+ el("p", { text: "We would love to help you make some adjustments to your website. Describe what you would like to see different or new, and we will get a version back to you as soon as possible." })
41
+ ]);
34
42
  const body = el("textarea", { id: "tidy-change-body", rows: "7", maxlength: "10000", required: "" });
35
43
  const page = el("input", { id: "tidy-change-page", type: "text", value: here });
36
44
  const err = el("p", { class: "tidy-field-note", hidden: "" });
@@ -53,7 +61,7 @@ export function mountRequestChange(): void {
53
61
  sending = false;
54
62
  if (r?.ok && j.ok) {
55
63
  panel.replaceChildren(
56
- el("div", { class: "tidy-panel-head" }, [el("h2", { text: "Request sent" }), el("p", { text: "It is under Changes now. You will hear back there." })]),
64
+ el("div", { class: "tidy-panel-head" }, [el("h2", { text: name ? `Thanks, ${name}.` : "Thanks." }), el("p", { text: "We have your request and will get a version back to you as soon as possible." })]),
57
65
  el("div", { class: "tidy-panel-actions" }, [el("button", { type: "button", class: "tidy-btn", text: "Close" })])
58
66
  );
59
67
  panel.querySelector("button")?.addEventListener("click", close);
@@ -67,7 +75,7 @@ export function mountRequestChange(): void {
67
75
  panel.replaceChildren(
68
76
  head,
69
77
  el("div", { class: "tidy-form" }, [
70
- el("div", { class: "tidy-field" }, [el("label", { class: "tidy-field-label", for: "tidy-change-body", text: "What would you like changed?" }), body]),
78
+ el("div", { class: "tidy-field" }, [el("label", { class: "tidy-field-label", for: "tidy-change-body", text: "What would you like to see different or new?" }), body]),
71
79
  el("div", { class: "tidy-field" }, [el("label", { class: "tidy-field-label", for: "tidy-change-page", text: "Which page" }), page]),
72
80
  err
73
81
  ]),
@@ -79,10 +87,11 @@ export function mountRequestChange(): void {
79
87
 
80
88
  const barBtn = el("button", { type: "button", class: "tidy-btn", text: "Request a change" });
81
89
  barBtn.addEventListener("click", render);
82
- actions.prepend(barBtn);
90
+ // Right after Edit (or Done), before Revisions and Publish live.
91
+ actions.insertBefore(barBtn, actions.children[1] ?? null);
83
92
 
84
93
  const fab = el("button", { type: "button", class: "tidy-fab", title: "Request a change", "aria-label": "Request a change" });
85
- fab.innerHTML = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>';
94
+ fab.innerHTML = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z"/></svg>';
86
95
  fab.addEventListener("click", render);
87
96
  document.body.append(fab);
88
97
  document.addEventListener("keydown", (e) => {
@@ -41,8 +41,9 @@ export function startRevisions(): void {
41
41
  if (!actions) return;
42
42
  const here = location.pathname;
43
43
  const revBtn = el("button", { type: "button", class: "tidy-btn", text: "Revisions" });
44
- const liveBtn = el("button", { type: "button", class: "tidy-btn", text: "Publish live" });
45
- actions.prepend(revBtn, liveBtn);
44
+ const liveBtn = el("button", { type: "button", class: "tidy-btn tidy-btn-go", text: "Publish live" });
45
+ // Edit, Request a change, Revisions, Publish live: the bar reads left to right in that order.
46
+ actions.append(revBtn, liveBtn);
46
47
 
47
48
  // --- the panel --------------------------------------------------------
48
49
  const panel = el("div", { class: "tidy-panel", hidden: "" });
@@ -4,6 +4,7 @@
4
4
  * own secret. The Astro session is the gate; the person's name and email
5
5
  * come from the site's user record.
6
6
  *
7
+ * GET → { name, email } of the signed-in person
7
8
  * POST { body, pageUrl? } → { ok, changeId }
8
9
  */
9
10
  import type { APIRoute } from "astro";
@@ -45,4 +46,15 @@ export const POST: APIRoute = platformRoute(
45
46
  { requireBearer: false }
46
47
  );
47
48
 
48
- export const ALL = methodNotAllowed("POST");
49
+ /** Who is signed in, for the panel's greeting: { name, email } or 401. */
50
+ export const GET: APIRoute = platformRoute(
51
+ async (context, deps) => {
52
+ const session = context.session ? ((await context.session.get("user")) as { id?: string } | null) : null;
53
+ if (!session?.id) return new Response("Unauthorized", { status: 401 });
54
+ const user = await deps.store.findUserById(session.id);
55
+ return json({ name: user?.name ?? null, email: user?.email ?? null }, 200, { "cache-control": "no-store" });
56
+ },
57
+ { requireBearer: false }
58
+ );
59
+
60
+ export const ALL = methodNotAllowed("GET, POST");
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Kept in step with package.json by the release checklist in MAINTAINING.md. */
2
- export const VERSION = "0.10.8";
2
+ export const VERSION = "0.10.10";
3
3
  export const PLUGIN_ID = "tidy-platform";