Commit Graph

51 Commits

Author SHA1 Message Date
jamey
3336b3aa26 add page builder polish: utility blocks, templates, duplicate
All checks were successful
deploy / deploy (push) Successful in 1m24s
New block types: spacer, divider, button/CTA, video embed (YouTube,
Vimeo with privacy-enhanced embeds, fallback for unknown URLs).

Page templates (blank, content, landing) shown when creating custom
pages. Duplicate page action on admin index with slug deduplication.

Fix block picker on shop edit sidebar being cut off on mobile by
accounting for bottom nav and making the grid scrollable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:33:25 +00:00
jamey
79b5161e02 add undo/redo to page editors with keyboard shortcuts
All checks were successful
deploy / deploy (push) Successful in 1m29s
History stacks (@history/@future) on both admin editor and live sidebar,
capped at 50 entries. All mutations routed through apply_mutation for
consistent history tracking. EditorKeyboard JS hook combines DirtyGuard
with Ctrl+Z/Ctrl+Shift+Z. Settings panel fade-in animation. 10 new tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:16:15 +00:00
jamey
3a243151af add data-driven navigation with admin editor
All checks were successful
deploy / deploy (push) Successful in 1m34s
Replace hardcoded header, footer and mobile nav with settings-driven
loops. Nav items stored as JSON via Settings, loaded in ThemeHook with
sensible defaults. New admin navigation editor at /admin/navigation
for add/remove/reorder/save/reset. Mobile bottom nav also driven from
header nav items with icon mapping by slug.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:18:37 +00:00
jamey
045be2ed7e add admin CRUD for custom CMS pages
All checks were successful
deploy / deploy (push) Successful in 1m21s
New settings form for creating and editing custom page metadata
(title, slug, meta description, published, nav settings). Pages
index shows custom pages section with draft badges and delete.
Editor shows settings button for custom pages, hides reset to
defaults. 20 new tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:43:03 +00:00
jamey
f479be5728 show proper 404 page for missing custom pages instead of redirecting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 08:35:01 +00:00
jamey
ad2f2517e5 add custom page LiveView with catch-all routing
Shop.CustomPage handles /:slug catch-all for CMS pages. Restructured
router so the catch-all is last — all admin, auth, setup, and SEO
routes defined before the shop scope to prevent interception.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 02:21:11 +00:00
jamey
2c634177c4 add image picker to page editor and fix thumbnail layout
Wire up image field in block settings with a modal picker that
browses the media library. Fix picker thumbnails collapsing to
14px by replacing overflow:hidden with overflow:clip on grid
items (hidden sets min-height:0 in grid context). Polish media
library mobile sheet with scrim overlay and tighter spacing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:00:48 +00:00
jamey
847b5f3e5e add admin media library with image management and block picker integration
- Schema: alt, caption, tags fields on images table with metadata changeset
- Context: list_images with filters, find_usages, used_image_ids, delete_with_cleanup
- Admin UI: /admin/media with grid view, upload, filters, detail panel, metadata editing
- Block editor: :image field type for image_text and content_body blocks
- Page renderer: image_id resolution with legacy URL fallback
- Mobile: bottom sheet detail panel with slide-up animation
- CSS: uses correct --t-* admin theme tokens, admin-badge colour variants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:20:51 +00:00
jamey
a039c8d53c add live page editor sidebar with collapsible UI
All checks were successful
deploy / deploy (push) Successful in 6m49s
Admins can now edit pages directly on the live shop by clicking the
pencil icon in the header. A sidebar slides in with block management
controls (add, remove, reorder, edit settings, save, reset, done).

Key features:
- PageEditorHook on_mount with handle_params/event/info hooks
- BlockEditor pure functions extracted from admin editor
- Shared BlockEditorComponents with event_prefix namespacing
- Collapsible sidebar: X closes it, header pencil reopens it
- Backdrop overlay dismisses sidebar on tap
- Conditional admin.css loading for logged-in users
- content_body block now portable (textarea setting + rich text fallback)

13 integration tests, 26 unit tests, 1370 total passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:22:35 +00:00
jamey
b340c24aa1 add live preview pane to page editor
All checks were successful
deploy / deploy (push) Successful in 4m55s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 08:06:17 +00:00
jamey
6fbd654d57 add SettingsField struct and repeater field type for block settings
All checks were successful
deploy / deploy (push) Successful in 1m23s
Introduces typed settings schema with SettingsField struct, replaces
the read-only JSON textarea with a full repeater UI for info_card items.
Supports add, remove, reorder and inline editing of repeater items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 00:54:13 +00:00
jamey
3f97742c0b add inline block settings editing to page editor
All checks were successful
deploy / deploy (push) Successful in 3m40s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:47:24 +00:00
jamey
660fda928f add admin page editor with block reordering and management
Stage 6 of the page builder: admin UI at /admin/pages for managing
page layouts. Page list shows all 14 pages grouped by category.
Editor supports reorder (up/down), add, remove, duplicate, save,
and reset to defaults. DirtyGuard JS hook warns on unsaved changes.
ARIA live regions announce block operations for screen readers.

Also: regenerate admin icons (81 rules via mix task with @layer
wrapping), add gen_smtp dep for SMTP email adapter, add :key to
page renderer block loop for correct LiveView diffing.

1309 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:15:01 +00:00
jamey
24ad3b8b60 wire order pages and theme preview to page renderer, remove old templates
Some checks failed
deploy / deploy (push) Has been cancelled
All 14 pages now render through PageRenderer. Theme editor preview
unified from 10 preview_page clauses to one function + page-context
helpers. PageTemplates module and 10 .heex template files deleted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:32:50 +00:00
jamey
16ebc29fa9 wire collection, PDP, cart, and search pages to page renderer
Stage 4 of the page builder: all shop pages now render via
PageRenderer instead of inline templates or PageTemplates.

- Collection: full filter bar moved to renderer (category pills,
  sort dropdown, CollectionFilters hook, empty state)
- PDP: related_products and reviews loaded via block data loaders
  instead of manual queries
- Cart: page definition loaded in mount, subtotal computed in render
- Search: page definition loaded in mount, handle_params unchanged
- Added Phoenix.VerifiedRoutes to PageRenderer for ~p sigil
- Net -55 lines (128 added, 183 removed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:13:00 +00:00
jamey
c69e51051f wire simple pages to PageRenderer (stage 3)
Home, Content (about/delivery/privacy/terms), Contact, and ErrorHTML
now render through the generic PageRenderer instead of hardcoded
templates. Block wrapper divs enable CSS grid targeting. Featured
products block supports layout/card_variant/columns settings for
different page contexts. Contact page uses CSS grid on data-block-type
attributes for two-column layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:29:20 +00:00
jamey
6e57af82fc add URL redirects with ETS-cached plug, broken URL tracking, and admin UI
All checks were successful
deploy / deploy (push) Successful in 3m30s
Redirects context with redirect/broken_url schemas, chain flattening,
ETS cache for fast lookups in the request pipeline. BrokenUrlTracker
plug logs 404s. Auto-redirect on product slug change via upsert_product
hook. Admin redirects page with active/broken tabs, manual create form.
RedirectPrunerWorker cleans up old broken URLs. 1227 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 14:14:14 +00:00
jamey
23e95a3de6 make PDP variant selection work without JS
All checks were successful
deploy / deploy (push) Successful in 1m3s
Variant options (colour, size) are now URL params handled via
handle_params instead of phx-click events. Swatches and size buttons
render as patch links in shop mode, so changing variants works as
plain navigation without JS. Quantity is now a number input that
submits with the form. Unavailable variants render as disabled spans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:08:36 +00:00
jamey
0b0adba0fe add no-JS progressive enhancement for all shop flows
All checks were successful
deploy / deploy (push) Successful in 1m23s
Every key shop flow now works via plain HTML forms when JS is
unavailable. LiveView progressively enhances when JS connects.

- PDP: form wraps variant/qty/add-to-cart with action="/cart/add"
- Cart page: qty +/- and remove use form POST fallbacks
- Cart/search header icons are now links with phx-click enhancement
- Collection sort form has GET action + noscript submit button
- New /search page with form-based search for no-JS users
- CartController gains add/remove/update_item POST actions
- CartHook gains update_quantity_form and remove_item_form handlers
- Fix flaky analytics tests caused by event table pollution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:56:19 +00:00
jamey
f788108665 add favicon and site icon generation from uploaded images
All checks were successful
deploy / deploy (push) Successful in 1m26s
Upload a source image (PNG, JPEG, or SVG) and get a complete favicon
setup: PNG variants at 32, 180, 192, 512px served from DB via
FaviconController with ETag caching, SVG favicon for vector sources,
dynamic site.webmanifest, and theme-color meta tag. Theme editor gains
a site icon section with "use logo as icon" toggle, dedicated icon
upload, short name, and background colour picker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:22:15 +00:00
jamey
933f685b63 add legal page generator for privacy, delivery, and terms
All checks were successful
deploy / deploy (push) Successful in 1m23s
Replaces hardcoded PreviewData placeholders with generated content
derived from real shop state: connected providers (production lead
times), shipping countries (grouped by region), shop country
(jurisdiction language and governing law), and feature flags
(abandoned cart recovery section, newsletter, VAT clause).

Returns policy correctly cites Consumer Contracts Regulations Reg
28(1)(b) for POD exemption and Consumer Rights Act for defective goods.
Cart recovery section uses jurisdiction-specific wording: PECR Reg 22
for UK, GDPR Art 6(1)(f) for EU, generic otherwise.

About page unchanged — shop owner's story to tell.

26 new tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:48:49 +00:00
jamey
2f4cd81f98 add abandoned cart recovery
When a Stripe checkout session expires without payment, if the customer
entered their email, we record an AbandonedCart and schedule a single
plain-text recovery email (1h delay via Oban).

Privacy design:
- feature is off by default; shop owner opts in via admin settings
- only contacts customers who entered their email at Stripe checkout
- single email, never more (emailed_at timestamp gate)
- suppression list blocks repeat contact; one-click unsubscribe via
  signed token (/unsubscribe/:token)
- records pruned after 30 days (nightly Oban cron)
- no tracking pixels, no redirected links, no HTML

Legal notes:
- custom_text added to Stripe session footer when recovery is on
- UK PECR soft opt-in; EU legitimate interests both satisfied by this design

Files:
- migration: abandoned_carts + email_suppressions tables
- schemas: AbandonedCart, EmailSuppression
- context: Orders.create_abandoned_cart, check_suppression, add_suppression,
  has_recent_paid_order?, get_abandoned_cart_by_session, mark_abandoned_cart_emailed
- workers: AbandonedCartEmailWorker (checkout queue), AbandonedCartPruneWorker (cron)
- notifier: OrderNotifier.deliver_cart_recovery/3
- webhook: extended checkout.session.expired handler
- controller: UnsubscribeController, admin settings toggle
- tests: 28 new tests across context, workers, and controller

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:02:37 +00:00
jamey
758e66db5c add analytics CSV export
All checks were successful
deploy / deploy (push) Successful in 1m25s
Downloads a ZIP with one CSV per report (overview, trend, pages, entry/exit
pages, sources, referrers, countries, devices, funnel). Export button lives
next to the period selector and picks up the current period and any active
filters using a JS hook + JS.set_attribute, so the downloaded data always
matches what's on screen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 09:37:45 +00:00
jamey
01ff8decd5 add order status lookup for customers
All checks were successful
deploy / deploy (push) Successful in 1m17s
Magic link flow on contact page: customer enters email, gets a
time-limited signed link, clicks through to /orders showing all their
paid orders and full detail pages with thumbnails and product links.

- OrderLookupController generates/verifies Phoenix.Token signed links
- Contact LiveView handles lookup_orders + reset_tracking events
- Orders and OrderDetail LiveViews gated by session email
- Order detail shows thumbnails, links to products still available
- .themed-button gets base padding/font-weight so all usages are consistent
- order-summary-card sticky scoped to .cart-grid (was leaking to orders list)
- 27 new tests (1095 total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 08:40:08 +00:00
jamey
4e36b654d3 add JSON-LD structured data
Product pages: Product schema (name, description, image, price/currency,
availability) + BreadcrumbList (Home > Category > Product). Home page:
Organization schema (name, url). Uses Jason with html_safe escaping so
the JSON is safe to embed in <script> tags.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 22:37:34 +00:00
jamey
0f1135256d add canonical URLs, robots.txt, and sitemap.xml
Canonical: all shop pages now assign og_url (reusing the existing og:url
assign), which the layout renders as <link rel="canonical">. Collection
pages strip the sort param so ?sort=price_asc doesn't create a duplicate
canonical.

robots.txt: dynamic controller disallows /admin/, /api/, /users/,
/webhooks/, /checkout/. Removed robots.txt from static_paths so it
goes through the router instead of Plug.Static.

sitemap.xml: auto-generated from all visible products + categories +
static pages, served as application/xml. 8 tests.

Also updates PROGRESS.md: marks tasks 55, 58, 59, 61, 62 as done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:47:35 +00:00
jamey
b11f7d47d0 add open graph and twitter card meta tags
Product pages get og:type=product, og:url, og:image (hero image), and
twitter:card=summary_large_image. All other shop pages get og:type=website
and twitter:card=summary. og:title and og:description mirror the existing
page title and meta description.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:37:50 +00:00
jamey
c6da3b3d2b add meta descriptions to all shop pages
All checks were successful
deploy / deploy (push) Successful in 1m38s
Product pages: first 155 chars of description, stripped of HTML, truncated on word boundary.
Collections: contextual description based on collection type.
Content pages (about, delivery, privacy, terms): from hero_description text.
Contact: static description.
Home falls through to site_description from settings (already in layout).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:31:35 +00:00
jamey
9b78793701 add entry/exit pages panel to analytics dashboard
All checks were successful
deploy / deploy (push) Successful in 1m28s
ROW_NUMBER() window function picks first/last pageview per session.
Both tables live in the pages tab and support the pathname filter.
6 new tests, 1061 total.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:14:24 +00:00
jamey
7ceee9c814 add dashboard filtering to analytics
All checks were successful
deploy / deploy (push) Successful in 1m19s
Click any row in pages, sources, countries, or devices tables to
filter the entire dashboard by that dimension. Active filters show
as dismissible chips. Filters thread through all queries including
previous-period deltas. 1050 tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:46:34 +00:00
jamey
6eda1de1bc add period comparison deltas to analytics stat cards
All checks were successful
deploy / deploy (push) Successful in 1m21s
Each stat card now shows the percentage change vs the equivalent
previous period (e.g. 30d compares last 30 days vs 30 days before).
Handles zero-baseline with "new" label and caps extreme deltas at
>999%. Seed data extended to 2 years for meaningful 12m comparisons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:01:25 +00:00
jamey
08fcd60eb6 improve analytics chart with hourly today view and readable labels
- add visitors_by_hour query for hourly breakdown on "today" period
- replace SVG-only chart with HTML/CSS grid layout (bars + labels)
- Y-axis scale with nice rounded max, midpoint, and zero
- X-axis date labels (formatted as "Feb 18") spaced evenly
- adaptive bar gaps (1px for sparse data, 0 for 365-day dense view)
- labels use real HTML text so they're readable on mobile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:28:35 +00:00
jamey
65e646a7eb add analytics v2 plan, demo seed data, and improved funnel display
- analytics-v2 plan with prioritised improvements (comparison mode, filtering, CSV export, entry/exit pages)
- seed script generating ~35k realistic events over 12 months (weighted traffic, referrers, devices, e-commerce funnel)
- funnel chart now shows overall conversion rate from product views instead of step-to-step percentages
- summary line with overall conversion rate and revenue

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:30:24 +00:00
jamey
f91b47f0c3 include browser/os/screen_size in e-commerce analytics events
All checks were successful
deploy / deploy (push) Successful in 1m37s
Event call sites (product_view, add_to_cart, checkout_start, purchase)
were only passing visitor_hash and pathname, leaving browser, OS, screen
size and country nil. Add AnalyticsHook.attrs/1 helper to extract common
analytics fields from socket assigns, and use it in all LiveView event
call sites. Checkout controller reads the same fields from the session.

Also fix plug analytics test to clear stale events before assertions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:13:47 +00:00
jamey
e26a02a0fb fix setup flow stale state and Stripe URL issues
All checks were successful
deploy / deploy (push) Successful in 1m9s
Onboarding: re-fetch setup_status() after provider/Stripe connect instead
of manually patching the local assigns, which could miss admin_created and
leave users stuck on the setup page with no way forward.

Dev config: respect PHX_HOST for endpoint URL so Stripe checkout redirects
to the correct host instead of always using localhost.

Stripe setup: detect private/LAN IPs (10.x, 172.16-31.x, 192.168.x) as
unreachable, not just localhost — prevents creating webhook endpoints that
Stripe can never reach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:51:44 +00:00
jamey
2bd2e613c7 add privacy-first analytics with progressive event collection
All checks were successful
deploy / deploy (push) Successful in 3m20s
Three-layer pipeline: Plug for all HTTP requests (no JS needed), LiveView
hook for SPA navigations, JS hook for screen width. ETS-backed buffer
batches writes to SQLite every 10s. Daily-rotating salt for visitor hashing.
Includes admin dashboard with date ranges, visitor trends, top pages,
sources, devices, and e-commerce conversion funnel. Oban cron for 12-month
data retention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 12:50:55 +00:00
jamey
762a2ee100 add Stripe connection step to launch checklist
All checks were successful
deploy / deploy (push) Successful in 1m10s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:26:13 +00:00
jamey
3dca9ad9d0 gate magic link login on verified email delivery
All checks were successful
deploy / deploy (push) Successful in 1m2s
The login page now only shows the magic link form when a test email has
been sent successfully, not just when an adapter is configured. Saving
email settings or disconnecting clears the flag so the admin must
re-verify after config changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:25:27 +00:00
jamey
b0607621f3 add admin account recovery via setup secret
All checks were successful
deploy / deploy (push) Successful in 1m33s
When email isn't configured, the login page now hides the magic link
form and shows a recovery link. The /recover page logs the setup secret
to server logs and lets the admin reset their password with it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 21:40:53 +00:00
jamey
194fec8240 namespace email settings keys per adapter
All checks were successful
deploy / deploy (push) Successful in 57s
Settings keys like api_key were shared across providers, so switching
from e.g. Postmark to SendGrid showed the old API key. Now each
adapter gets its own namespaced key (email_postmark_api_key, etc.)
so credentials persist independently and switching back pre-fills
previously saved values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:57:23 +00:00
jamey
366a1e6a48 add admin email settings page with provider selection
All checks were successful
deploy / deploy (push) Successful in 56s
Card radio component for picking email providers (SMTP, SendGrid, Mailjet, etc.)
with instant client-side switching via JS hook. Adapter configs are pre-rendered
and toggled without a server round-trip. Secrets are preserved when re-saving
with blank password fields. Includes from address field, test email sending,
and disconnect flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:29:34 +00:00
jamey
9d9bd09059 auto-confirm admin during setup, skip email verification
Some checks failed
deploy / deploy (push) Has been cancelled
Setup wizard no longer requires email delivery. Admin account is
auto-confirmed and auto-logged-in via token redirect. Adds setup
secret gate for prod (logged on boot), SMTP env var config in
runtime.exs, email_configured? helper, and admin warning banner
when email isn't set up. Includes plan files for this task and
the follow-up email settings UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 10:24:26 +00:00
jamey
65ea11c3a2 replace --color-* with --t-* tokens, delete bridge and .preview-frame
Phase 4: admin components and utilities now reference --t-* theme
tokens directly. Status colour tokens added to theme-semantic.css.
Bridge file (admin/themes.css) deleted.

Phase 5: removed duplicated .preview-frame CSS block (~160 lines).
Admin components and icons wrapped in @layer admin. Layer order
updated in admin_root to include admin layer.

Phase 6: added prefers-reduced-motion support (zeroes all durations
and disables animations). Migrated physical properties to logical
equivalents (text-align start/end, margin-inline, padding-inline,
inset-inline-end) across shop and admin CSS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 00:13:33 +00:00
jamey
2563338a6a add logo to coming soon page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:19:15 +00:00
jamey
b05b696681 rework setup wizard into phased flow
All checks were successful
deploy / deploy (push) Successful in 3m30s
phase 1 (no admin): show only the email form
phase 2 (admin created, not logged in): "check your inbox" gate with
  "wrong email? start over" link that deletes the unconfirmed user
phase 3 (logged in via magic link): show provider + stripe steps

removes the confusing redirect to /users/log-in after account creation.
users now stay on /setup throughout the entire setup process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:07:07 +00:00
jamey
a78a1db847 fix admin font loading and theme CSS cache miss bug
add system font stack to admin reset CSS so setup/admin pages render
sans-serif on all devices instead of falling through to browser default.
pass path_resolver to CSSGenerator.generate on cache miss paths so
font URLs resolve to digested paths in production.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:39:41 +00:00
jamey
f6a38bb48f fix muted text invisible in dark mode on setup and dashboard pages
Replace non-existent --color-base-content-60 variable (with hard-coded
black fallback) with color-mix(in oklch, var(--color-base-content) 60%,
transparent) which adapts to the current theme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:07:25 +00:00
jamey
c2caeed64d add setup onboarding page, dashboard launch checklist, provider registry
- new /setup page with three-section onboarding (account, provider, payments)
- dashboard launch checklist with progress bar, go-live, dismiss
- provider registry on Provider module (single source of truth for metadata)
- payments registry for Stripe
- setup context made provider-agnostic (provider_connected, theme_customised, etc.)
- admin provider pages now fully registry-driven (no hardcoded provider names)
- auth flow: fresh installs redirect to /setup, signed_in_path respects setup state
- removed old /admin/setup wizard
- 840 tests, 0 failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 00:34:06 +00:00
jamey
2007279fc6 replace dead Tailwind classes in shop pages with custom CSS
Coming soon page was unstyled after Tailwind removal — replaced
utility classes with proper component CSS. Also removed dead h-full
classes from shop_root layout, adding height: 100% to the shop reset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:27:52 +00:00
jamey
559798206f extract setup wizard to dedicated /admin/setup page
Move the setup stepper out of the dashboard into its own LiveView.
Dashboard now redirects to setup when site isn't live, and shows
stats-only view once live. Also cleans up button component variant
handling, fixes alert CSS, and removes stale demo.html.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:55:42 +00:00