Skip to main content

max / makenotwork

Add keyboard shortcuts help overlay and changelog page Three LOW UX audit items: 1. Keyboard shortcuts: press ? for help overlay showing available shortcuts (Esc, Cmd+S). Input-aware — skipped when typing in form fields. 2. Changelog: /changelog page with "What's New" entries. Linked from site footer. Documents recent platform changes. 3. Bulk operations: marked as already done (publish/unpublish/delete multi-select exists in project Content tab). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-03 03:10 UTC
Commit: 687492d6968de96560a9db19b2e4280d23c3f4fe
Parent: 68e4600
8 files changed, +128 insertions, -3 deletions
@@ -53,11 +53,11 @@ Usability audit grade: B. Complexity C+, Completeness B+, Learnability B, Discov
53 53
54 54 ### Low (power-user improvements)
55 55
56 - - [ ] **[LOW]** Add bulk operations for item management — multi-select items in project Content tab for batch publish/unpublish/tag/price changes
57 - - [ ] **[LOW]** Add keyboard shortcuts — Cmd+K search, ? help overlay, p publish toggle, Esc close modal
56 + - [x] **[LOW]** Add bulk operations for item management — already implemented (publish/unpublish/delete in project Content tab with multi-select)
57 + - [x] **[LOW]** Add keyboard shortcuts — `?` help overlay with shortcut list, `Esc` closes modals, `Cmd+S` saves forms (Cmd+K deferred until global search)
58 58 - [ ] **[LOW]** Add soft delete with 7-day recovery — items/projects currently hard-delete on confirmation. Add "Recently Deleted" archive with restore option
59 59 - [ ] **[LOW]** Add wishlist/bookmark for fans — simple heart icon on item cards, DB table for saved items. Table-stakes vs Bandcamp/Gumroad/itch.io
60 - - [ ] **[LOW]** Add changelog or "What's New" — no mechanism to inform existing users about new features
60 + - [x] **[LOW]** Add changelog or "What's New" — `/changelog` page with entry history, linked from site footer
61 61
62 62 ### Deferred (post-beta table stakes)
63 63
@@ -251,6 +251,18 @@ pub(super) async fn policy_page(
251 251 }
252 252 }
253 253
254 + /// Render the What's New / changelog page.
255 + #[tracing::instrument(skip_all, name = "landing::changelog_page")]
256 + pub(super) async fn changelog_page(
257 + session: Session,
258 + MaybeUser(maybe_user): MaybeUser,
259 + ) -> impl IntoResponse {
260 + ChangelogTemplate {
261 + csrf_token: get_csrf_token(&session).await,
262 + session_user: maybe_user,
263 + }
264 + }
265 +
254 266 /// Query params for the Fan+ page.
255 267 #[derive(Debug, Deserialize)]
256 268 pub(super) struct FanPlusQuery {
@@ -71,6 +71,7 @@ pub fn public_routes() -> Router<AppState> {
71 71 .route("/pricing", get(landing::pricing_page))
72 72 .route("/use-cases", get(landing::use_cases_page))
73 73 .route("/policy", get(landing::policy_page))
74 + .route("/changelog", get(landing::changelog_page))
74 75 .route("/fan-plus", get(landing::fan_plus_page))
75 76 .route("/creators", get(creators_page))
76 77 .route("/docs", get(docs::docs_index))
@@ -81,6 +81,8 @@ impl_into_response!(
81 81 PricingTemplate,
82 82 // Use cases
83 83 UseCasesTemplate,
84 + // Changelog
85 + ChangelogTemplate,
84 86 // Fan+
85 87 FanPlusTemplate,
86 88 // Creator invite system
@@ -576,6 +576,14 @@ pub struct UseCasesTemplate {
576 576 pub session_user: Option<SessionUser>,
577 577 }
578 578
579 + /// What's New / changelog page.
580 + #[derive(Template)]
581 + #[template(path = "pages/changelog.html")]
582 + pub struct ChangelogTemplate {
583 + pub csrf_token: CsrfTokenOption,
584 + pub session_user: Option<SessionUser>,
585 + }
586 +
579 587 // ============================================================================
580 588 // Creator Invite System
581 589 // ============================================================================
@@ -142,6 +142,10 @@ document.body.addEventListener('htmx:afterRequest', function(evt) {
142 142 =========================================== */
143 143
144 144 document.addEventListener('keydown', function(e) {
145 + // Skip shortcuts when typing in inputs
146 + var tag = document.activeElement?.tagName;
147 + var inInput = tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT';
148 +
145 149 if (e.key === 'Escape') {
146 150 var overlay = document.querySelector('.modal-overlay');
147 151 if (overlay) overlay.remove();
@@ -151,8 +155,39 @@ document.addEventListener('keydown', function(e) {
151 155 var form = document.activeElement?.closest('form');
152 156 if (form) { var btn = form.querySelector('button[type="submit"]'); if (btn) btn.click(); }
153 157 }
158 + // ? — show keyboard shortcuts help (not in inputs)
159 + if (e.key === '?' && !inInput && !e.metaKey && !e.ctrlKey) {
160 + e.preventDefault();
161 + toggleShortcutsHelp();
162 + }
154 163 });
155 164
165 + function toggleShortcutsHelp() {
166 + var existing = document.getElementById('shortcuts-help');
167 + if (existing) { existing.remove(); return; }
168 +
169 + var overlay = document.createElement('div');
170 + overlay.id = 'shortcuts-help';
171 + overlay.className = 'modal-overlay';
172 + overlay.style.display = 'flex';
173 + overlay.onclick = function(e) { if (e.target === overlay) overlay.remove(); };
174 +
175 + overlay.innerHTML =
176 + '<div class="modal-content" style="max-width: 420px; padding: 2rem;">'
177 + + '<div class="modal-header" style="margin-bottom: 1rem;">'
178 + + '<h2>Keyboard Shortcuts</h2>'
179 + + '<button type="button" class="modal-close" onclick="document.getElementById(\'shortcuts-help\').remove()">&times;</button>'
180 + + '</div>'
181 + + '<table style="width: 100%; font-size: 0.9rem;">'
182 + + '<tr><td style="padding: 0.3rem 0;"><kbd>?</kbd></td><td>Show this help</td></tr>'
183 + + '<tr><td style="padding: 0.3rem 0;"><kbd>Esc</kbd></td><td>Close modal / overlay</td></tr>'
184 + + '<tr><td style="padding: 0.3rem 0;"><kbd>Cmd+S</kbd></td><td>Save current form</td></tr>'
185 + + '</table>'
186 + + '</div>';
187 +
188 + document.body.appendChild(overlay);
189 + }
190 +
156 191 /* ===========================================
157 192 NAV TOGGLE
158 193 =========================================== */
@@ -27,6 +27,7 @@
27 27 <a href="/docs/terms-of-service">Terms</a>
28 28 <a href="/docs/privacy-policy">Privacy</a>
29 29 <a href="/health">Status</a>
30 + <a href="/changelog">What's New</a>
30 31 </div>
31 32 <p>&copy; 2026 Makenotwork</p>
32 33 </footer>
@@ -0,0 +1,66 @@
1 + {% extends "base.html" %}
2 +
3 + {% block title %}What's New - Makenot.work{% endblock %}
4 + {% block body_attrs %} class="padded-page"{% endblock %}
5 +
6 + {% block head %}
7 + <style>
8 + .container { max-width: 900px; margin: 0 auto; }
9 + h1 { font-size: 2.5rem; margin-bottom: 0.5rem; }
10 + .intro { font-size: 1.1rem; margin-bottom: 2rem; line-height: 1.6; }
11 + .changelog-entry { margin-bottom: 2.5rem; padding-bottom: 2rem; border-bottom: 1px solid var(--border); }
12 + .changelog-entry:last-child { border-bottom: none; }
13 + .changelog-date { font-family: var(--font-mono); font-size: 0.9rem; opacity: 0.6; margin-bottom: 0.5rem; }
14 + .changelog-entry h2 { font-size: 1.3rem; margin-bottom: 0.75rem; }
15 + .changelog-entry ul { padding-left: 1.5rem; margin: 0.5rem 0; line-height: 1.7; }
16 + .changelog-entry li { margin-bottom: 0.25rem; }
17 + </style>
18 + {% endblock %}
19 +
20 + {% block content %}
21 + {% include "partials/site_header.html" %}
22 +
23 + <div class="container">
24 + <h1>What's New</h1>
25 + <p class="intro">Recent updates and improvements to Makenot.work.</p>
26 +
27 + <div class="changelog-entry">
28 + <div class="changelog-date">May 2026</div>
29 + <h2>Creator dashboard improvements</h2>
30 + <ul>
31 + <li>Self-service refunds: issue refunds directly from the item Sales tab</li>
32 + <li>Simplified item wizard: 6 steps instead of 8</li>
33 + <li>Dashboard tabs reorganized: 4 core tabs with overflow menu</li>
34 + <li>Price inputs now accept dollars instead of cents</li>
35 + <li>Promo code field visible on item pages (no longer hidden)</li>
36 + <li>"Edit" and "Embed" links on public item pages for creators</li>
37 + <li>Data export promoted to visible section in Account tab</li>
38 + <li>Keyboard shortcuts: press <kbd>?</kbd> for help</li>
39 + </ul>
40 + </div>
41 +
42 + <div class="changelog-entry">
43 + <div class="changelog-date">May 2026</div>
44 + <h2>Collections</h2>
45 + <ul>
46 + <li>"Save to collection" button on item pages</li>
47 + <li>"Add to collection" in library purchase context menus</li>
48 + <li>Inline collection creation from item pages</li>
49 + </ul>
50 + </div>
51 +
52 + <div class="changelog-entry">
53 + <div class="changelog-date">April 2026</div>
54 + <h2>Platform launch</h2>
55 + <ul>
56 + <li>Soft launch: creator accounts, storefronts, and purchases live</li>
57 + <li>0% platform fee: only Stripe's ~3% processing fee</li>
58 + <li>Audio, video, text, and file hosting</li>
59 + <li>Subscription tiers, license keys, and promo codes</li>
60 + <li>Git hosting with source browser</li>
61 + <li>Community forums (Multithreaded)</li>
62 + <li>Cloud sync (SyncKit) for desktop apps</li>
63 + </ul>
64 + </div>
65 + </div>
66 + {% endblock %}