Commit Graph

415 Commits

Author SHA1 Message Date
jamey
8c053f7495 reference SEO enhancements plan in progress and roadmap
All checks were successful
deploy / deploy (push) Successful in 59s
2026-03-10 08:54:15 +00:00
jamey
e04a5edbbb add SEO enhancements plan 2026-03-10 08:53:47 +00:00
jamey
9f804459fb add editor reorganisation plan to progress
All checks were successful
deploy / deploy (push) Successful in 56s
2026-03-10 08:21:55 +00:00
jamey
f49d52a1e0 add editor reorganisation plan
All checks were successful
deploy / deploy (push) Successful in 50s
2026-03-10 08:14:00 +00:00
jamey
6f78b210ff update progress: mark onboarding UX v2 and notification overhaul complete
All checks were successful
deploy / deploy (push) Successful in 1m5s
2026-03-10 07:57:40 +00:00
jamey
2282af91db complete onboarding UX v2
Some checks failed
deploy / deploy (push) Has been cancelled
Tasks C, H, I from the plan:

- Forgiving API key validation: add Printify UUID format and Printful
  length validation, validate on blur for fast feedback, helpful error
  messages with specific guidance

- External links UX: verified all external links use <.external_link>
  component with target="_blank", rel="noopener noreferrer", icon, and
  screen reader text

- Input styling WCAG compliance: increase input border contrast from
  ~3.3:1 to ~4.5-5:1 across all theme moods (neutral, warm, cool, dark)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-10 07:56:54 +00:00
jamey
951147a675 update progress: mark unified on-site editing complete
All checks were successful
deploy / deploy (push) Successful in 1m14s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 22:00:18 +00:00
jamey
94c6137ab1 sync editor state with URL for browser back support
Some checks failed
deploy / deploy (push) Has been cancelled
- add ?edit=page/theme/settings param when opening editor or switching tabs
- remove ?edit param when closing editor
- restore .themed class on shop_root for editor panel background tokens
- collapse editor when navigating back to URL without ?edit param

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 21:59:48 +00:00
jamey
2c3c5050f4 mark unified on-site editing feature complete
All checks were successful
deploy / deploy (push) Successful in 52s
All 7 phases done. Admins can now edit theme and page content directly
on the live shop via /?edit=theme, /?edit=page, or /?edit=settings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 21:18:29 +00:00
jamey
caded6c9f8 fix theme data attributes not updating live during editing
All checks were successful
deploy / deploy (push) Successful in 1m26s
The shop_root.html.heex had duplicate .themed element with data-mood etc
attributes that were static (rendered once at page load). This prevented
live theme changes from visually updating since CSS matched the outer
stale element.

Fix: Remove data attributes from shop_root.html.heex, keeping only the
live-updated .shop-container.themed element inside the LiveView.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 20:51:59 +00:00
jamey
6f0b7f4f63 redirect /admin/theme to on-site editor at /?edit=theme
All checks were successful
deploy / deploy (push) Successful in 1m41s
- Phase 5 was already implemented (URL mode activation via ?edit param)
- Phase 6: Add RedirectController to redirect /admin/theme → /?edit=theme
- Update admin sidebar and dashboard links to point directly to /?edit=theme
- Delete old Admin.Theme.Index LiveView and template (no longer needed)
- Update tests for new redirect behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 20:30:33 +00:00
jamey
378b3fdb6b add image uploads to on-site theme editor and fix scroll on navigation
All checks were successful
deploy / deploy (push) Successful in 1m27s
Phase 4 of unified editing: image upload handling in hook context.
- Configure uploads in Shop.Page mount for logo, header, icon
- Add upload UI components to theme_editor compact_editor
- Pass uploads through page_renderer to theme editor
- Add cancel_upload handler to PageEditorHook

Also fixes scroll position not resetting on patch navigation:
- Push scroll-top event when path changes in handle_params
- JS listener scrolls window to top instantly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 19:45:43 +00:00
jamey
89c411e0fc clear page-specific assigns on navigation to prevent stale data
All checks were successful
deploy / deploy (push) Successful in 1m27s
When navigating between page types in the unified shop LiveView,
assigns from the previous page could persist and cause stale data
to appear or template errors. Now explicitly nils them out.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 18:34:45 +00:00
jamey
6aaddeaf44 fix settings editor crash on product pages
All checks were successful
deploy / deploy (push) Successful in 1m33s
The provider_label function was accessing product.provider_type but
that field is on the provider_connection association, not the product
itself. Handle the case where the association may not be preloaded.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 16:25:00 +00:00
jamey
f7891188e0 add settings editor component for unified on-site editing
All checks were successful
deploy / deploy (push) Successful in 4m13s
Phase 3b of unified editing mode. The Settings tab now shows
context-specific forms: custom pages get editable title, slug,
meta, visibility and nav options; system pages get read-only info
with links to admin; product/collection pages show provider info.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 15:38:06 +00:00
jamey
bb5d220079 consolidate shop pages into unified LiveView for editor state persistence
All checks were successful
deploy / deploy (push) Successful in 1m27s
Replace individual shop LiveViews with a single Shop.Page that dispatches
to page modules based on live_action. This enables patch navigation between
pages, preserving socket state (including editor state) across transitions.

Changes:
- Add Shop.Page unified LiveView with handle_params dispatch
- Extract page logic into Shop.Pages.* modules (Home, Product, Collection, etc.)
- Update router to use Shop.Page with live_action for all shop routes
- Change navigate= to patch= in shop component links
- Add maybe_sync_editing_blocks to reload editor state when page changes
- Track editor_page_slug to detect cross-page navigation while editing
- Fix picture element height when hover image disabled
- Extract ThemeEditor components for shared use

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 14:47:50 +00:00
jamey
ae0a149ecd add draft-then-publish workflow plan
All checks were successful
deploy / deploy (push) Successful in 53s
Plan for auto-saving drafts with explicit publish. Visitors always see
published version, admins see their drafts while editing. Removes need
for beforeunload warnings since work is never lost.

Planned to follow unified-editing-mode completion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 11:07:46 +00:00
jamey
0741095a84 exclude /health from force_ssl redirect
All checks were successful
deploy / deploy (push) Successful in 3m38s
Fly.io internal health checks are made over HTTP, so they get redirected
to HTTPS with a 301 which fails the health check. Exclude /health path
from SSL enforcement.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 10:06:26 +00:00
jamey
b82d486877 fix header nav spacing for standard layout
All checks were successful
deploy / deploy (push) Successful in 48s
Remove global margin-left: auto from .shop-actions since it conflicts
with justify-content: space-between in the standard header layout.
Keep margin-left: auto only for the left layout variant where it's
needed. Also fix .shop-cart → .shop-actions selector in layer2.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 09:53:54 +00:00
jamey
a011169459 fix force_ssl compile-time config mismatch
All checks were successful
deploy / deploy (push) Successful in 3m28s
force_ssl must be set at compile time (in prod.exs), not runtime.
Phoenix validates compile-time config at boot and was crashing
because the value differed between compile and runtime.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 09:48:06 +00:00
jamey
168b6ce76f implement unified on-site editor phases 1-2
All checks were successful
deploy / deploy (push) Successful in 1m10s
Add theme editing to the existing PageEditorHook, enabling on-site
theme customisation alongside page editing. The editor panel now has
three tabs (Page, Theme, Settings) and can be collapsed while
keeping editing state intact.

- Add theme editing state and event handlers to PageEditorHook
- Add 3-tab UI with tab switching logic
- Add transparent overlay for click-outside dismiss
- Add mobile drag-to-resize with height persistence
- Fix animation replay on drag release (has-dragged class)
- Preserve panel height across LiveView re-renders
- Default to Page tab on editable pages, Theme otherwise
- Show unsaved changes indicator on FAB when panel collapsed
- Fix handle_event grouping warning in admin theme

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 09:01:21 +00:00
jamey
74ab6411f7 add unified on-site editing mode plan
All checks were successful
deploy / deploy (push) Successful in 46s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 23:09:51 +00:00
jamey
476da8121a add header background contrast warning and improve branding UX
All checks were successful
deploy / deploy (push) Successful in 1m12s
- extract dominant colors from header images during optimization
- calculate WCAG contrast ratios against theme text color
- show warning in theme editor when text may be hard to read
- prevent hiding shop name when no logo is uploaded
- auto-enable shop name when logo is deleted
- fix image cache invalidation on delete
- add missing .hidden utility class

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 22:40:08 +00:00
jamey
32cc425458 separate account settings from shop settings
All checks were successful
deploy / deploy (push) Successful in 3m28s
- Create dedicated /admin/account page for user account management
- Move email, password, and 2FA settings from /admin/settings
- Add Account link to top of admin sidebar navigation
- Add TOTP-based two-factor authentication with NimbleTOTP
- Add TOTP verification LiveView for login flow
- Add AccountController for TOTP session management
- Remove Advanced section from settings (duplicated in dev tools)
- Remove user email from sidebar footer (replaced by Account link)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 18:42:29 +00:00
jamey
0c2d4ac406 add rate limiting and HSTS for security hardening
Some checks failed
deploy / deploy (push) Failing after 8m33s
- Add Hammer library for rate limiting with ETS backend
- Rate limit login (5/min), magic link (3/min), newsletter (10/min), API (60/min)
- Add themed 429 error page using bare shop styling
- Enable HSTS in production with rewrite_on for Fly proxy
- Add security hardening plan to docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 08:58:43 +00:00
jamey
48eb7a9d9c update notification system docs as implementation reference
All checks were successful
deploy / deploy (push) Successful in 1m22s
Rewrote planning doc as a reference guide with:
- decision tree for choosing feedback type
- implementation patterns with code examples
- accessibility requirements
- common mistakes to avoid

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 07:55:55 +00:00
jamey
5e03dccb69 improve notification accessibility
- use role="status" for info messages, role="alert" for errors
- add aria-live attribute (polite for info, assertive for errors)
- move phx-click to close button for better keyboard navigation
- add close buttons to shop flash messages
- add aria-hidden to decorative icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 07:53:17 +00:00
jamey
8af5cbf41e mark notification system overhaul complete
All 7 tasks done:
- Inline feedback component for form saves
- Banner component (document-flow flash) for page-level outcomes
- Admin forms migrated: theme, pages, settings, email, providers
- Remaining admin pages migrated: media, products, newsletter
- Shop pages: already use correct patterns (cart drawer, banners)
- Setup wizard: already uses inline form errors + banners
- Old toast CSS removed (no .admin-toast exists)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 07:42:53 +00:00
jamey
db28cb8d9f migrate remaining admin pages to inline feedback
Replace put_flash with inline feedback for form saves:
- Media library: metadata save shows "Saved" checkmark
- Product show: storefront controls save shows "Saved" checkmark
- Newsletter campaign form: draft save shows "Saved" checkmark

Page-level outcomes (uploads, deletes, async operations) remain as
flash/banner messages — these are the correct pattern for non-form
actions.

Completes Task 4 of notification overhaul.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 07:34:17 +00:00
jamey
0834437340 add no-JS fallback for provider forms
Progressive enhancement: provider form now works without JavaScript.
Forms POST to ProvidersController (create/update), which handles
validation and redirects with flash messages.

With JS: LiveView phx-submit handles save, navigates with flash.
Without JS: Form POSTs to controller, redirects with flash.

Completes Task 3 of notification overhaul (admin forms migration).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 07:30:16 +00:00
jamey
3e29a89fff add link picker and validation to navigation editor
All checks were successful
deploy / deploy (push) Successful in 1m26s
- replace freeform inputs with grouped dropdown (pages, custom pages,
  collections, external URL)
- add inline URL validation for external links
- add inline feedback component instead of flash messages
- add dismiss-on-interaction pattern (feedback clears on changes)
- add no-JS fallback via NavigationController
- add DirtyGuard hook to warn before navigating away with unsaved changes
- add no-JS fallbacks for settings forms (from address, signing secret)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 02:10:06 +00:00
jamey
42542ac177 migrate admin forms to inline feedback
All checks were successful
deploy / deploy (push) Successful in 1m26s
Replace put_flash calls with inline feedback for form saves:
- Email settings: "Now send a test email" after saving
- Settings: from address and signing secret saves
- Page editor: save button shows "Saved" checkmark

Inline feedback appears next to save buttons and auto-clears after
3 seconds. Banners (put_flash) remain for page-level outcomes like
deletions, state changes, and async operations.

Task 3 of notification overhaul. Theme editor skipped as it auto-saves.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-07 21:01:54 +00:00
jamey
bd07c9c7d9 separate editor FAB and panel for cleaner animation
All checks were successful
deploy / deploy (push) Successful in 1m32s
Split the editor sheet into two distinct elements:
- .editor-fab: floating action button, always a pill in the corner
- .editor-panel: sliding panel that animates in/out independently

This enables proper CSS keyframe animations (slide-up/down on mobile,
slide-in/out on desktop) with a closing class for exit transitions.
Simplified the JS hook to only handle close behaviour.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-07 19:01:32 +00:00
jamey
3f96769840 refine editor sheet to floating pill button
All checks were successful
deploy / deploy (push) Successful in 1m32s
- collapsed state: floating pill button in bottom-right corner
- removed panel background when collapsed (transparent)
- violet accent colour to distinguish from shop theme
- white glow outline for visibility on any background
- consistent behaviour on mobile and desktop
- opens to bottom sheet (mobile) or side panel (desktop)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-07 11:36:18 +00:00
jamey
f4f036b84b replace admin rail with unified bottom sheet editor
All checks were successful
deploy / deploy (push) Successful in 1m30s
- add editor sheet component anchored bottom (mobile) / right (desktop)
- admin cog moves to header, always visible for admins
- remove Done button from editor header, keep only Save
- add editor_at_defaults tracking to disable Reset when at defaults
- sheet collapses on click outside or Escape, stays in edit mode
- dirty indicator + beforeunload warning for unsaved changes
- keyboard shortcuts: Ctrl+Z undo, Ctrl+Shift+Z redo
- WCAG compliant: aria-expanded, live region, focus management

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-07 09:30:07 +00:00
jamey
dbcecc7878 update notification overhaul plan
All checks were successful
deploy / deploy (push) Successful in 37s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:30:29 +00:00
jamey
c6636cab65 improve email settings progressive enhancement and admin layout
Some checks failed
deploy / deploy (push) Has been cancelled
- semantic HTML: step numbers inside h2, strong provider names, details
  for adapter configs, strong error messages, fieldset drawer toggle hidden
- inline field errors via flash for no-JS controller fallback
- single form POST button for test email (works with and without JS)
- admin sidebar: remove brand/view-shop, move user email to footer nav
- replace inline style with .admin-setup-step-spaced class
- clean up unused CSS (.admin-brand, .admin-sidebar-header, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:29:05 +00:00
jamey
5dee2ae0be fix email settings: hidden attr for no-CSS, block-level card labels
All checks were successful
deploy / deploy (push) Successful in 1m29s
Non-selected adapter configs now get HTML hidden attribute so only the
active config shows without CSS. Provider card labels use div instead
of span for natural block stacking in text-only rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 09:40:35 +00:00
jamey
e24f9aa4f3 add progressive enhancement guidelines to CLAUDE.md
All checks were successful
deploy / deploy (push) Successful in 59s
Document the CSS :has(:checked) pattern for forms with dynamic
sections, noscript fallbacks for JS-only elements, and the HEEx
<style> raw text gotcha.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:28:21 +00:00
jamey
db130a7155 rework email settings for true progressive enhancement
All checks were successful
deploy / deploy (push) Successful in 1m19s
Render all adapter field sections in the form with CSS :has(:checked)
controlling visibility. Selecting a provider instantly shows its config
fields — no JS, no page reload, no server round-trip needed.

- Render all 6 adapter configs with data-adapter attribute
- CSS :has(:checked) show/hide rules per adapter in admin stylesheet
- Namespace field names per adapter (email[brevo][api_key] etc)
- Drop 4 transactional-only providers (Resend, Postmark, Mailgun, MailPace)
- Remove noscript "Switch provider" button and controller redirect workaround
- Remove configured_adapter hidden input tracking
- Hide JS-only test email button for no-JS users via noscript style
- LiveView progressively enhances with async save and test email

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:10:37 +00:00
jamey
dd20ea824f fix email settings: missing providers, a11y, no-JS support
show all 10 providers in three groups (popular, transactional,
advanced) with category headings. fix phx-change clobbering text
fields, async test email sending state, integer parse crash on
bad port. add keyboard focus on card radios, fieldset legend,
WCAG-compliant badge contrast, responsive grid. extract shared
save_config into Mailer, add no-JS controller fallback with
configured_adapter hidden field for adapter change detection.
remove CardRadioScroll JS hook (no longer needed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:26:59 +00:00
jamey
dd659e4c61 replace orphaned tailwind classes with project CSS
All checks were successful
deploy / deploy (push) Successful in 1m27s
auth pages (login, registration, confirmation, recover) now use
setup-page/setup-header/admin-btn-block. theme toggle indicator
gets proper CSS. cleaned up dead h-full, size-3.5, ml-2 classes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:12:21 +00:00
jamey
7547d0d4b8 rework email settings UX with guided flow and friendly errors
grouped providers by category, added per-provider key validation
with cross-provider detection, friendly delivery error messages,
retryable vs config error distinction, from-address in general
settings, and "Save settings" button to match admin conventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:12:10 +00:00
jamey
67a26eb6b4 add contextual prompts for skipped setup steps
All checks were successful
deploy / deploy (push) Successful in 1m26s
Disable checkout when Stripe isn't connected (cart drawer, cart page,
and early guard in checkout controller to prevent orphaned orders).
Show amber warning on order detail when email isn't configured.
Fix pre-existing missing vertical spacing between page blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 14:02:49 +00:00
jamey
005ebca432 fix external link icon specificity in shop CSS
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:22:05 +00:00
jamey
76cff0494e add forgiving API key validation with inline errors
Add KeyValidation module for format-checking API keys before
attempting connections. Auto-strips whitespace, detects common
mistakes (e.g. pasting a Stripe publishable key), and returns
helpful error messages.

Inline field errors across all three entry points:
- Setup wizard: provider + Stripe keys
- Admin provider form: simplified to single Connect button
- Email settings: per-field errors instead of flash toasts

Also: plain text inputs for all API keys (not password fields),
accessible error states (aria-invalid, role=alert, thick border,
bold text), inner_block slot declaration on error component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:17:56 +00:00
jamey
e139a75b69 consolidate all external links through external_link component
All checks were successful
deploy / deploy (push) Successful in 1m32s
Add icon={false} option to external_link for links with their own
visual indicator. Migrate remaining manual target="_blank" links:
email settings adapter links, product show provider edit, card radio
links, social link cards/icons, page renderer tracking and video
fallback. Every external link in the codebase now goes through the
single component — one place to change rel, target, or sr-only text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:12:25 +00:00
jamey
156a23da16 add external link UX: icons, rel attributes, screen reader labels
New external_link component in core_components handles target="_blank",
rel="noopener noreferrer", external-link icon, and sr-only "(opens in
new tab)" text. Migrated admin providers form, settings (Stripe),
order tracking, onboarding setup links to use it. Fixed rel="noopener"
to "noopener noreferrer" on remaining links (email settings, product
show, core_components card radio). Added sr-only text to shop social
link cards and aria-label to page renderer tracking link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:55:09 +00:00
jamey
696843bacd add WCAG-compliant input border contrast across all moods
New --t-border-input token per mood, all 3:1+ contrast against their
surface backgrounds (neutral #8c8c8c, warm #8a827a, cool #7a8591,
dark #707070). Used on admin inputs/selects/textareas and shop
themed-input/themed-select, with graceful fallback to --t-border-default.
Decorative borders on cards, dividers, panels are unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:48:08 +00:00
jamey
92a008926e fix coming soon page: crash, logo centering, admin login link
Add AnalyticsHook to the coming_soon live session — the shop layout
fires an analytics:screen JS event but the session had no handler,
crashing the page on connect.

Centre the logo image (display:block from CSS reset needs
margin-inline:auto). Add a subtle "Admin" link at the bottom using
flex flow rather than fixed/absolute positioning so it works in
iframes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:41:15 +00:00