Commit Graph

18 Commits

Author SHA1 Message Date
jamey
162a5bfe9a replace analytics double-count prevention with buffer supersede
All checks were successful
deploy / deploy (push) Successful in 1m13s
The Plug records a pageview with a known ID (plug_ref) into the ETS
buffer. When JS connects, the LiveView hook supersedes that event by
ID and records its own with full data (screen_size from connect params).
If JS never connects, the Plug's event flushes normally after 10s.

Also fixes: admin browsing no longer leaks product_view events — the
Plug now sets no analytics session data for admins, so all downstream
visitor_hash guards naturally filter them out.

Replaces the previous time-based skip logic which was brittle and
race-prone. The supersede approach is deterministic and handles both
the ETS buffer and already-flushed DB cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 14:48:50 +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
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
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
9528700862 rename project from SimpleshopTheme to Berrypod
All modules, configs, paths, and references updated.
836 tests pass, zero warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:23:15 +00:00
jamey
3158a94f0b progressive enhancement for collection filter pills
Flex-wrap base (no JS needed, active pill always visible). JS hook
switches to horizontal scroll with scroll-into-view when pills exceed
2.5 rows on mobile. Desktop always wraps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:47:51 +00:00
jamey
ccc14aa5e1 fix category images, gallery reset, scroll hint and orphan image cleanup
- category_nav pulls first product image per category from DB
- ProductImageScroll JS hook resets to index 0 on updated()
- collection filter bar gets CSS fade gradient scroll hint on mobile
- sync_product_images and delete_product_images now clean up orphaned
  Media.Image records to prevent DB bloat from repeated syncs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 08:20:55 +00:00
jamey
5c2f70ce44 add shipping costs with live exchange rates and country detection
Shipping rates fetched from Printify during product sync, converted to
GBP at sync time using frankfurter.app ECB exchange rates with 5%
buffer. Cached in shipping_rates table per blueprint/provider/country.

Cart page shows shipping estimate with country selector (detected from
Accept-Language header, persisted in cookie). Stripe Checkout includes
shipping_options for UK domestic and international delivery. Order
shipping_cost extracted from Stripe on payment.

ScheduledSyncWorker runs every 6 hours via Oban cron to keep rates
and exchange rates fresh. REST_OF_THE_WORLD fallback covers unlisted
countries. 780 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:48:00 +00:00
jamey
44933acebb fix search modal race condition and add 304 support for images
Route all search modal open/close through the JS hook via custom DOM
events so the _closing flag is always correctly managed. Prevents the
modal flashing back after Escape when a search response is in flight.

Add If-None-Match / 304 Not Modified handling to the image controller
so browsers don't re-download images on revalidation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:21:51 +00:00
jamey
994f6fe0d6 fix search modal closing on keypress and add admin header icon
Track search_open as server state so morphdom doesn't reset display
to none on re-render. Move admin bar from layout banner to a gear
icon in the header actions. Extract layout_assigns/1 helper so page
templates use a spread instead of listing every attr explicitly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:02:25 +00:00
jamey
57c3ba0e28 wire shop LiveViews to DB queries and improve search UX
Replace PreviewData indirection in all shop LiveViews with direct
Products context queries. Home, collection, product detail and error
pages now query the database. Categories loaded once in ThemeHook.
Cart hydration no longer falls back to mock data. PreviewData kept
only for the theme editor.

Search modal gains keyboard navigation (arrow keys, Enter, Escape),
Cmd+K/Ctrl+K shortcut, full ARIA combobox pattern, LiveView navigate
links, and 150ms debounce. SearchModal JS hook manages selection
state and highlight. search.ex gets transaction safety on reindex
and a public remove_product/1. 10 new integration tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:27:26 +00:00
jamey
8445e9e8b1 replace PDP image gallery with scroll-snap carousel
Mobile: swipeable carousel with dot indicators, no lightbox trigger.
Desktop: carousel with thumbnail grid, prev/next arrows, click to
open existing lightbox. Keeps all lightbox appearance and behaviour.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 15:33:41 +00:00
jamey
1a69736734 add mobile swipe for product card images and fix dev asset caching
Product cards now use CSS scroll-snap on touch devices (mobile) for
swiping between images, with dot indicators and a JS hook for active
state. Desktop keeps the existing hover crossfade via @media (hover:
hover). Dots use size differentiation (WCAG 2.2 AA compliant) with
outline rings for contrast on any background.

Also fixes: no-image placeholder (SVG icon instead of broken img),
unnecessary wrapper div for single-image cards, and dev static asset
caching (was immutable for all envs, now only prod).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:24:52 +00:00
jamey
c5e353eba1 improve lighthouse scores: image priority and long-poll removal
- Add priority attr to product_card, thread through to responsive_image
- First 2 featured products get fetchpriority="high" and eager loading
- Remove longPollFallbackMs to avoid unnecessary fallback attempt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 23:43:01 +00:00
jamey
1bc08bfb23 feat: add cart page, cart drawer, and shared cart infrastructure
- Cart context with pure functions for add/remove/update/hydrate
- Price formatting via ex_money (replaces all float division)
- CartHook on_mount with attach_hook for shared event handlers
  (open/close drawer, remove item, PubSub sync)
- Accessible cart drawer with focus trap, scroll lock, aria-live
- Cart page with increment/decrement quantity controls
- Preview mode cart drawer support in theme editor
- Cart persistence to session via JS hook + API endpoint
- 19 tests covering all Cart pure functions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:39:37 +00:00
37653e5e7a feat: redesign contact page for POD sellers & add theme enhancements
Contact page redesign:
- Replace retail-style contact info (phone, address, hours) with POD-appropriate layout
- Add order tracking card with email input
- Add "Handy to know" section with printing/delivery/returns info
- Add email contact with response time promise
- Add social links (Instagram, Pinterest)
- Update intro text to be warmer and more personal

Collection page improvements:
- Replace sidebar filters with horizontal category pills
- Add filter pill CSS with theme token integration

PDP enhancements:
- Add image lightbox with keyboard navigation
- Add thumbnail gallery with active state
- Add reviews section (toggleable)
- Add related products section (toggleable)
- Add trust badges section (toggleable)

Theme system additions:
- Add button_style setting (filled/outline/soft)
- Add product_text_align setting (left/center)
- Add image_aspect_ratio setting (square/portrait/landscape)
- Add responsive form layouts with flex-wrap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 13:48:03 +00:00
0dada968aa feat: add ColorSync hook to sync color picker and text input
The color picker and text input for accent color weren't syncing properly when the user changed the color picker value. This was because LiveView doesn't update input values that might have user focus, to avoid interfering with user input.

Added a JavaScript LiveView hook (ColorSync) that:
- Listens to 'input' events on both the color picker and text input
- Syncs their values in real-time as the user interacts with either one
- Provides immediate visual feedback when changing colors via the picker

The hook is attached to the accent color form with phx-hook="ColorSync" and syncs the two inputs bidirectionally, ensuring they always display the same value.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 01:00:22 +00:00
4f2ed90044 mix phx.new simpleshop_theme --database sqlite3 --adapter bandit --binary-id 2025-12-30 12:26:26 +00:00