Go to file
jamey 89c411e0fc
All checks were successful
deploy / deploy (push) Successful in 1m27s
clear page-specific assigns on navigation to prevent stale data
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
.gitea/workflows switch deploy workflow to local docker build 2026-02-20 18:58:14 +00:00
assets add settings editor component for unified on-site editing 2026-03-09 15:38:06 +00:00
config exclude /health from force_ssl redirect 2026-03-09 10:06:26 +00:00
docs add draft-then-publish workflow plan 2026-03-09 11:07:46 +00:00
lib clear page-specific assigns on navigation to prevent stale data 2026-03-09 18:34:45 +00:00
priv add header background contrast warning and improve branding UX 2026-03-08 22:40:08 +00:00
rel rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
test consolidate shop pages into unified LiveView for editor state persistence 2026-03-09 14:47:50 +00:00
.credo.exs add CI pipeline with credo and dialyzer 2026-02-08 15:19:42 +00:00
.dialyzer_ignore.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
.dockerignore fix production deployment: CSS, images and theme seeding 2026-02-08 23:42:56 +00:00
.formatter.exs mix phx.new simpleshop_theme --database sqlite3 --adapter bandit --binary-id 2025-12-30 12:26:26 +00:00
.gitignore remove accidentally tracked node_modules, update gitignore 2026-02-18 21:23:42 +00:00
.mcp.json chore: add MCP config for Claude Code + Tidewave integration 2026-01-31 13:49:07 +00:00
AGENTS.md docs: consolidate project tracking into PROGRESS.md 2026-01-31 14:06:07 +00:00
CLAUDE.md add progressive enhancement guidelines to CLAUDE.md 2026-03-04 23:28:21 +00:00
Dockerfile use Oban for startup variant processing, add vips-heif 2026-02-22 09:24:34 +00:00
fly.toml disable auto-stop to prevent cold start latency 2026-03-02 09:35:03 +00:00
LICENSE add AGPL-3.0 license file 2026-03-02 01:02:27 +00:00
mise.toml feat: add cart page, cart drawer, and shared cart infrastructure 2026-02-06 19:39:37 +00:00
mix.exs separate account settings from shop settings 2026-03-08 18:42:29 +00:00
mix.lock separate account settings from shop settings 2026-03-08 18:42:29 +00:00
PROGRESS.md add settings editor component for unified on-site editing 2026-03-09 15:38:06 +00:00
README.md tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00
ROADMAP.md add plans from usability testing: onboarding v2, notifications, live editor 2026-03-03 22:45:41 +00:00

Berrypod

A customisable e-commerce storefront for print-on-demand sellers, built with Phoenix LiveView. Professional shops without design expertise, privacy-respecting by default, fully self-hostable.

Features

Shop

Complete storefront with all the pages you need:

  • Home — hero banner, category navigation, featured products, newsletter
  • Products — grid layout with hover effects, sorting, filtering by collection
  • Product detail — image gallery with per-colour filtering, variant selector, related products
  • Cart — drawer + full page, quantity controls, shipping estimate, cross-tab sync
  • Checkout — Stripe-hosted checkout with shipping costs, order confirmation
  • Custom pages — CMS pages at any URL with 26 block types
  • Legal pages — auto-generated privacy, delivery, and terms from actual shop settings
  • Search — FTS5 full-text search with live modal, keyboard nav, ARIA
  • Contact — contact form with order status lookup

Admin

  • Theme editor — 8 presets, real-time preview, comprehensive customisation
  • Page builder — drag-free block editor with undo/redo, live editing on shop pages
  • Analytics — privacy-first, cookie-free, comparison mode, CSV export
  • Orders — status tracking, fulfilment timeline, provider submission
  • Media library — image management with alt text, usage tracking, orphan detection
  • Activity log — global event feed, "needs attention" tab, contextual retry
  • URL redirects — auto-redirect on slug change, 404 monitoring, dead link scanning
  • Email settings — 10 adapter options, test email, env var precedence
  • Print providers — Printify + Printful with sync, orders, shipping, webhooks

Technical highlights

  • Hand-written CSS with three-layer architecture (9.8 KB gzipped shop, 17.8 KB admin)
  • SQLite with BLOB storage, IMMEDIATE transactions, WAL, mmap
  • Image optimisation pipeline (AVIF/WebP/JPEG responsive variants via Oban)
  • ETS caching for CSS, pages, redirects, favicons
  • 99-100 PageSpeed mobile, no-JS support across all key flows
  • 1679+ tests, CI with credo + dialyzer

Getting started

Prerequisites

  • Elixir 1.19+
  • Erlang/OTP 28+
  • Node.js 20+ (for esbuild asset bundling)

Setup

git clone <repo-url>
cd berrypod
mix setup       # install deps, create DB, run migrations, build assets
mix phx.server  # start dev server at localhost:4000

Visit http://localhost:4000/setup to create your admin account and connect a print provider.

Running tests

mix test              # all tests
mix test path/to.exs  # specific file
mix precommit         # compile warnings + format + test (run before committing)

Project structure

lib/berrypod/                    # core business logic
├── accounts.ex                  # user accounts + auth
├── analytics.ex                 # privacy-first pageview tracking
├── activity_log.ex              # system event logging
├── cart.ex                      # session-based cart
├── media.ex                     # image uploads, optimisation, media library
├── newsletter.ex                # email list + campaigns
├── orders.ex                    # order lifecycle + fulfilment
├── pages.ex                     # page builder (blocks, cache, defaults)
├── products.ex                  # products, variants, categories
├── providers.ex                 # POD provider abstraction (Printify, Printful)
├── redirects.ex                 # URL redirects + dead link monitoring
├── search.ex                    # FTS5 full-text search
├── settings.ex                  # theme + shop settings
├── shipping.ex                  # shipping rates + country detection
├── theme/                       # CSS generation, presets, ETS cache
└── workers/                     # Oban background jobs

lib/berrypod_web/                # web layer
├── components/
│   ├── layouts/                 # app, admin, and shop layouts
│   ├── shop_components/         # shop UI (product cards, cart, gallery, etc.)
│   └── block_editor_components.ex
├── live/
│   ├── admin/                   # admin LiveViews (orders, pages, media, etc.)
│   ├── shop/                    # shop LiveViews (home, collection, product, etc.)
│   └── auth/                    # authentication
├── page_renderer.ex             # generic block-to-component dispatch
└── controllers/                 # Stripe webhooks, favicons, images, cart API

assets/css/
├── shop/                        # shop component styles
├── admin/                       # admin component styles
├── theme-layer1-primitives.css  # design tokens
├── theme-layer2-attributes.css  # theme-specific values
└── theme-layer3-semantic.css    # component styles

Stripe setup

  1. Create a Stripe account
  2. Navigate to Admin > Settings in your shop
  3. Paste your secret key and click "Connect Stripe"

For local webhook testing:

stripe listen --forward-to localhost:4000/webhooks/stripe

Test cards: 4242 4242 4242 4242 (success), 4000 0000 0000 0002 (declined).

Documentation

License

AGPL-3.0