From 95287008621d64a2896a5adca9e7b98ecdb1a75e Mon Sep 17 00:00:00 2001 From: jamey Date: Wed, 18 Feb 2026 21:23:15 +0000 Subject: [PATCH] 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 --- .dialyzer_ignore.exs | 22 +- .gitignore | 2 +- CLAUDE.md | 10 +- Dockerfile | 14 +- PROGRESS.md | 8 +- README.md | 12 +- ROADMAP.md | 4 +- assets/js/app.js | 2 +- config/config.exs | 38 +- config/dev.exs | 18 +- config/prod.exs | 3 +- config/runtime.exs | 24 +- config/test.exs | 12 +- docs/plans/admin-redesign.md | 26 +- docs/plans/css-migration.md | 16 +- docs/plans/dry-refactor.md | 2 +- docs/plans/image-optimization.md | 156 +- docs/plans/page-builder.md | 36 +- docs/plans/printful-integration.md | 38 +- docs/plans/printify-integration-research.md | 14 +- docs/plans/products-context.md | 158 +- docs/plans/provider-strategy.md | 8 +- docs/plans/search.md | 12 +- docs/plans/setup-wizard.md | 42 +- docs/plans/shipping-sync.md | 56 +- docs/research/design-philosophy.md | 2 +- fly.toml | 8 +- lib/{simpleshop_theme.ex => berrypod.ex} | 4 +- .../accounts.ex | 12 +- .../accounts/scope.ex | 6 +- .../accounts/user.ex | 6 +- .../accounts/user_notifier.ex | 8 +- .../accounts/user_token.ex | 6 +- .../application.ex | 28 +- lib/{simpleshop_theme => berrypod}/cart.ex | 6 +- lib/{simpleshop_theme => berrypod}/cldr.ex | 2 +- .../clients/printful.ex | 2 +- .../clients/printify.ex | 2 +- .../exchange_rate.ex | 4 +- .../images/optimize_worker.ex | 4 +- .../images/optimizer.ex | 10 +- .../images/variant_cache.ex | 14 +- lib/berrypod/mailer.ex | 3 + lib/{simpleshop_theme => berrypod}/media.ex | 10 +- .../media/image.ex | 2 +- .../media/svg_recolorer.ex | 2 +- .../mockups/generator.ex | 6 +- .../mockups/printful_generator.ex | 8 +- lib/{simpleshop_theme => berrypod}/orders.ex | 10 +- .../orders/fulfilment_status_worker.ex | 4 +- .../orders/order.ex | 4 +- .../orders/order_item.ex | 4 +- .../orders/order_notifier.ex | 8 +- .../orders/order_submission_worker.ex | 4 +- .../products.ex | 10 +- .../products/product.ex | 8 +- .../products/product_image.ex | 6 +- .../products/product_variant.ex | 4 +- .../products/provider_connection.ex | 6 +- .../providers.ex | 6 +- .../providers/printful.ex | 8 +- .../providers/printify.ex | 8 +- .../providers/provider.ex | 10 +- lib/{simpleshop_theme => berrypod}/release.ex | 8 +- lib/berrypod/repo.ex | 5 + lib/{simpleshop_theme => berrypod}/search.ex | 6 +- lib/{simpleshop_theme => berrypod}/secrets.ex | 4 +- .../settings.ex | 12 +- .../settings/setting.ex | 2 +- .../settings/theme_settings.ex | 2 +- lib/{simpleshop_theme => berrypod}/setup.ex | 4 +- .../shipping.ex | 12 +- .../shipping/shipping_rate.ex | 4 +- .../stripe/setup.ex | 10 +- .../sync/image_download_worker.ex | 6 +- .../sync/mockup_enricher.ex | 10 +- .../sync/product_sync_worker.ex | 20 +- .../sync/scheduled_sync_worker.ex | 4 +- .../theme/css_cache.ex | 8 +- .../theme/css_generator.ex | 8 +- .../theme/fonts.ex | 6 +- .../theme/presets.ex | 4 +- .../theme/preview_data.ex | 6 +- lib/{simpleshop_theme => berrypod}/vault.ex | 6 +- .../webhooks.ex | 12 +- .../webhooks/product_delete_worker.ex | 4 +- ...impleshop_theme_web.ex => berrypod_web.ex} | 22 +- .../admin_layout_hook.ex | 2 +- .../cart_hook.ex | 10 +- .../components/core_components.ex | 8 +- .../components/layouts.ex | 4 +- .../components/layouts/admin.html.heex | 4 +- .../components/layouts/admin_root.html.heex | 2 +- .../components/layouts/root.html.heex | 2 +- .../components/layouts/shop.html.heex | 0 .../components/layouts/shop_root.html.heex | 4 +- .../components/page_templates.ex | 4 +- .../components/page_templates/cart.html.heex | 0 .../page_templates/checkout_success.html.heex | 4 +- .../page_templates/collection.html.heex | 0 .../page_templates/contact.html.heex | 0 .../page_templates/content.html.heex | 0 .../components/page_templates/error.html.heex | 0 .../components/page_templates/home.html.heex | 2 +- .../components/page_templates/pdp.html.heex | 2 +- .../components/shop_components.ex | 14 +- .../components/shop_components/base.ex | 2 +- .../components/shop_components/cart.ex | 18 +- .../components/shop_components/content.ex | 6 +- .../components/shop_components/layout.ex | 10 +- .../components/shop_components/product.ex | 28 +- .../controllers/admin_controller.ex | 7 + .../controllers/cart_controller.ex | 6 +- .../controllers/checkout_controller.ex | 12 +- .../controllers/error_html.ex | 16 +- .../controllers/error_json.ex | 2 +- .../controllers/error_preview_controller.ex | 8 +- .../controllers/health_controller.ex | 7 + .../controllers/image_controller.ex | 8 +- .../controllers/page_controller.ex | 7 + .../controllers/page_html.ex | 4 +- .../controllers/page_html/home.html.heex | 0 .../controllers/stripe_webhook_controller.ex | 10 +- .../controllers/user_session_controller.ex | 8 +- .../controllers/webhook_controller.ex | 6 +- .../endpoint.ex | 18 +- .../gettext.ex | 6 +- .../live/admin/dashboard.ex | 18 +- .../live/admin/order_show.ex | 8 +- .../live/admin/orders.ex | 8 +- .../live/admin/product_show.ex | 10 +- .../live/admin/products.ex | 10 +- .../live/admin/providers/form.ex | 12 +- .../live/admin/providers/form.html.heex | 0 .../live/admin/providers/index.ex | 8 +- .../live/admin/providers/index.html.heex | 0 .../live/admin/settings.ex | 12 +- .../live/admin/theme/index.ex | 32 +- .../live/admin/theme/index.html.heex | 4 +- .../live/auth/confirmation.ex | 6 +- .../live/auth/login.ex | 8 +- .../live/auth/registration.ex | 10 +- .../live/auth/settings.ex | 6 +- .../live/shop/cart.ex | 8 +- .../live/shop/checkout_success.ex | 12 +- .../live/shop/collection.ex | 6 +- .../live/shop/coming_soon.ex | 4 +- .../live/shop/contact.ex | 6 +- .../live/shop/content.ex | 8 +- .../live/shop/home.ex | 8 +- .../live/shop/product_show.ex | 16 +- .../plugs/cache_raw_body.ex | 2 +- .../plugs/country_detect.ex | 2 +- .../plugs/load_theme.ex | 6 +- .../plugs/verify_printful_webhook.ex | 4 +- .../plugs/verify_printify_webhook.ex | 4 +- .../router.ex | 76 +- .../search_hook.ex | 4 +- .../telemetry.ex | 14 +- .../theme_hook.ex | 8 +- .../user_auth.ex | 22 +- .../download_images.ex | 8 +- lib/mix/tasks/generate_mockups.ex | 8 +- lib/mix/tasks/lighthouse.ex | 14 +- lib/mix/tasks/register_webhooks.ex | 4 +- lib/mix/tasks/screenshots.ex | 16 +- lib/simpleshop_theme/mailer.ex | 3 - lib/simpleshop_theme/repo.ex | 5 - .../controllers/admin_controller.ex | 7 - .../controllers/health_controller.ex | 7 - .../controllers/page_controller.ex | 7 - mix.exs | 20 +- node_modules/.bin/pixelmatch | 1 + node_modules/.package-lock.json | 30 + node_modules/pixelmatch/LICENSE | 15 + node_modules/pixelmatch/README.md | 111 + node_modules/pixelmatch/bin/pixelmatch | 39 + node_modules/pixelmatch/index.d.ts | 29 + node_modules/pixelmatch/index.js | 271 + node_modules/pixelmatch/package.json | 42 + node_modules/pngjs/CHANGELOG.md | 128 + node_modules/pngjs/LICENSE | 20 + node_modules/pngjs/README.md | 287 + node_modules/pngjs/browser.js | 18985 ++++++++++++++++ node_modules/pngjs/lib/bitmapper.js | 267 + node_modules/pngjs/lib/bitpacker.js | 158 + node_modules/pngjs/lib/chunkstream.js | 189 + node_modules/pngjs/lib/constants.js | 32 + node_modules/pngjs/lib/crc.js | 40 + node_modules/pngjs/lib/filter-pack.js | 171 + node_modules/pngjs/lib/filter-parse-async.js | 24 + node_modules/pngjs/lib/filter-parse-sync.js | 21 + node_modules/pngjs/lib/filter-parse.js | 177 + node_modules/pngjs/lib/format-normaliser.js | 93 + node_modules/pngjs/lib/interlace.js | 95 + node_modules/pngjs/lib/packer-async.js | 50 + node_modules/pngjs/lib/packer-sync.js | 56 + node_modules/pngjs/lib/packer.js | 129 + node_modules/pngjs/lib/paeth-predictor.js | 16 + node_modules/pngjs/lib/parser-async.js | 169 + node_modules/pngjs/lib/parser-sync.js | 112 + node_modules/pngjs/lib/parser.js | 290 + node_modules/pngjs/lib/png-sync.js | 12 + node_modules/pngjs/lib/png.js | 194 + node_modules/pngjs/lib/sync-inflate.js | 168 + node_modules/pngjs/lib/sync-reader.js | 45 + node_modules/pngjs/package.json | 76 + package-lock.json | 36 + package.json | 6 + ...0251230122634_create_users_auth_tables.exs | 2 +- .../20251230213057_create_settings.exs | 2 +- .../20251230213058_create_images.exs | 2 +- ...0121220351_add_image_metadata_and_oban.exs | 2 +- ...0128235845_create_provider_connections.exs | 2 +- .../20260128235846_create_products.exs | 2 +- .../20260128235847_create_product_images.exs | 2 +- ...20260128235848_create_product_variants.exs | 2 +- ...1232618_add_image_id_to_product_images.exs | 2 +- .../20260207005141_create_orders.exs | 2 +- ...084327_add_encrypted_value_to_settings.exs | 2 +- ...234225_add_fulfilment_fields_to_orders.exs | 2 +- .../20260208165931_add_error_tracker.exs | 2 +- ...260213005639_add_cached_product_fields.exs | 2 +- .../20260213020000_create_products_search.exs | 2 +- .../20260214004900_create_shipping_rates.exs | 2 +- ...0214004901_add_shipping_cost_to_orders.exs | 2 +- ...0215205353_add_color_to_product_images.exs | 2 +- priv/repo/seeds.exs | 4 +- priv/static/demo.html | 4 +- rel/overlays/bin/migrate | 2 +- rel/overlays/bin/server | 2 +- .../accounts_test.exs | 10 +- .../cart_test.exs | 4 +- .../clients/printful_test.exs | 4 +- .../images/optimize_worker_test.exs | 10 +- .../images/optimizer_test.exs | 12 +- .../media/svg_recolorer_test.exs | 4 +- .../media_test.exs | 6 +- .../orders/fulfilment_status_worker_test.exs | 16 +- .../orders/order_notifier_test.exs | 10 +- .../orders/order_submission_worker_test.exs | 16 +- .../orders_test.exs | 18 +- .../products/product_image_test.exs | 8 +- .../products/product_test.exs | 12 +- .../products/product_variant_test.exs | 10 +- .../products/provider_connection_test.exs | 12 +- .../products_test.exs | 10 +- .../products_upsert_test.exs | 8 +- .../providers/printful_test.exs | 22 +- .../providers/printify_test.exs | 14 +- .../search_test.exs | 24 +- .../settings_test.exs | 12 +- .../setup_test.exs | 8 +- .../shipping_test.exs | 10 +- .../stripe/setup_test.exs | 8 +- .../sync/product_sync_worker_test.exs | 12 +- .../sync/scheduled_sync_worker_test.exs | 12 +- .../theme/css_cache_test.exs | 10 +- .../theme/css_generator_test.exs | 6 +- .../theme/presets_test.exs | 4 +- .../theme/preview_data_test.exs | 4 +- .../vault_test.exs | 6 +- .../webhooks/product_delete_worker_test.exs | 12 +- .../webhooks_test.exs | 18 +- .../controllers/error_html_test.exs | 8 +- .../controllers/error_json_test.exs | 14 + .../controllers/image_controller_test.exs | 6 +- .../controllers/page_controller_test.exs | 8 +- .../user_session_controller_test.exs | 10 +- .../controllers/webhook_controller_test.exs | 10 +- .../live/admin/dashboard_test.exs | 16 +- .../live/admin/layout_test.exs | 8 +- .../live/admin/orders_test.exs | 18 +- .../live/admin/products_test.exs | 16 +- .../live/admin/providers_test.exs | 18 +- .../live/admin/settings_test.exs | 12 +- .../live/admin/theme_test.exs | 8 +- .../live/auth/confirmation_test.exs | 8 +- .../live/auth/login_test.exs | 8 +- .../live/auth/registration_test.exs | 6 +- .../live/auth/settings_test.exs | 8 +- .../live/shop/cart_test.exs | 12 +- .../live/shop/collection_test.exs | 12 +- .../live/shop/coming_soon_test.exs | 10 +- .../live/shop/content_test.exs | 8 +- .../live/shop/home_test.exs | 12 +- .../live/shop/product_show_test.exs | 12 +- .../live/shop/search_integration_test.exs | 16 +- .../live/theme_css_consistency_test.exs | 20 +- .../plugs/country_detect_test.exs | 6 +- .../user_auth_test.exs | 30 +- .../controllers/error_json_test.exs | 14 - test/support/conn_case.ex | 20 +- test/support/data_case.ex | 12 +- test/support/fixtures/accounts_fixtures.ex | 14 +- test/support/fixtures/image_fixtures.ex | 12 +- test/support/fixtures/orders_fixtures.ex | 6 +- test/support/fixtures/products_fixtures.ex | 8 +- test/support/mocks.ex | 4 +- test/test_helper.exs | 2 +- 300 files changed, 23932 insertions(+), 1349 deletions(-) rename lib/{simpleshop_theme.ex => berrypod.ex} (66%) rename lib/{simpleshop_theme => berrypod}/accounts.ex (95%) rename lib/{simpleshop_theme => berrypod}/accounts/scope.ex (84%) rename lib/{simpleshop_theme => berrypod}/accounts/user.ex (95%) rename lib/{simpleshop_theme => berrypod}/accounts/user_notifier.ex (90%) rename lib/{simpleshop_theme => berrypod}/accounts/user_token.ex (97%) rename lib/{simpleshop_theme => berrypod}/application.ex (55%) rename lib/{simpleshop_theme => berrypod}/cart.ex (98%) rename lib/{simpleshop_theme => berrypod}/cldr.ex (87%) rename lib/{simpleshop_theme => berrypod}/clients/printful.ex (99%) rename lib/{simpleshop_theme => berrypod}/clients/printify.ex (99%) rename lib/{simpleshop_theme => berrypod}/exchange_rate.ex (97%) rename lib/{simpleshop_theme => berrypod}/images/optimize_worker.ex (93%) rename lib/{simpleshop_theme => berrypod}/images/optimizer.ex (96%) rename lib/{simpleshop_theme => berrypod}/images/variant_cache.ex (92%) create mode 100644 lib/berrypod/mailer.ex rename lib/{simpleshop_theme => berrypod}/media.ex (94%) rename lib/{simpleshop_theme => berrypod}/media/image.ex (97%) rename lib/{simpleshop_theme => berrypod}/media/svg_recolorer.ex (98%) rename lib/{simpleshop_theme => berrypod}/mockups/generator.ex (99%) rename lib/{simpleshop_theme => berrypod}/mockups/printful_generator.ex (98%) rename lib/{simpleshop_theme => berrypod}/orders.ex (98%) rename lib/{simpleshop_theme => berrypod}/orders/fulfilment_status_worker.ex (92%) rename lib/{simpleshop_theme => berrypod}/orders/order.ex (95%) rename lib/{simpleshop_theme => berrypod}/orders/order_item.ex (87%) rename lib/{simpleshop_theme => berrypod}/orders/order_notifier.ex (95%) rename lib/{simpleshop_theme => berrypod}/orders/order_submission_worker.ex (94%) rename lib/{simpleshop_theme => berrypod}/products.ex (98%) rename lib/{simpleshop_theme => berrypod}/products/product.ex (95%) rename lib/{simpleshop_theme => berrypod}/products/product_image.ex (91%) rename lib/{simpleshop_theme => berrypod}/products/product_variant.ex (95%) rename lib/{simpleshop_theme => berrypod}/products/provider_connection.ex (94%) rename lib/{simpleshop_theme => berrypod}/providers.ex (82%) rename lib/{simpleshop_theme => berrypod}/providers/printful.ex (99%) rename lib/{simpleshop_theme => berrypod}/providers/printify.ex (98%) rename lib/{simpleshop_theme => berrypod}/providers/provider.ex (90%) rename lib/{simpleshop_theme => berrypod}/release.ex (85%) create mode 100644 lib/berrypod/repo.ex rename lib/{simpleshop_theme => berrypod}/search.ex (98%) rename lib/{simpleshop_theme => berrypod}/secrets.ex (94%) rename lib/{simpleshop_theme => berrypod}/settings.ex (95%) rename lib/{simpleshop_theme => berrypod}/settings/setting.ex (95%) rename lib/{simpleshop_theme => berrypod}/settings/theme_settings.ex (98%) rename lib/{simpleshop_theme => berrypod}/setup.ex (91%) rename lib/{simpleshop_theme => berrypod}/shipping.ex (97%) rename lib/{simpleshop_theme => berrypod}/shipping/shipping_rate.ex (90%) rename lib/{simpleshop_theme => berrypod}/stripe/setup.ex (94%) rename lib/{simpleshop_theme => berrypod}/sync/image_download_worker.ex (97%) rename lib/{simpleshop_theme => berrypod}/sync/mockup_enricher.ex (97%) rename lib/{simpleshop_theme => berrypod}/sync/product_sync_worker.ex (93%) rename lib/{simpleshop_theme => berrypod}/sync/scheduled_sync_worker.ex (90%) rename lib/{simpleshop_theme => berrypod}/theme/css_cache.ex (91%) rename lib/{simpleshop_theme => berrypod}/theme/css_generator.ex (98%) rename lib/{simpleshop_theme => berrypod}/theme/fonts.ex (97%) rename lib/{simpleshop_theme => berrypod}/theme/presets.ex (98%) rename lib/{simpleshop_theme => berrypod}/theme/preview_data.ex (99%) rename lib/{simpleshop_theme => berrypod}/vault.ex (93%) rename lib/{simpleshop_theme => berrypod}/webhooks.ex (96%) rename lib/{simpleshop_theme => berrypod}/webhooks/product_delete_worker.ex (92%) rename lib/{simpleshop_theme_web.ex => berrypod_web.ex} (81%) rename lib/{simpleshop_theme_web => berrypod_web}/admin_layout_hook.ex (92%) rename lib/{simpleshop_theme_web => berrypod_web}/cart_hook.ex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/components/core_components.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts/admin.html.heex (97%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts/admin_root.html.heex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts/root.html.heex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts/shop.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/layouts/shop_root.html.heex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates.ex (88%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/cart.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/checkout_success.html.heex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/collection.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/contact.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/content.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/error.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/home.html.heex (85%) rename lib/{simpleshop_theme_web => berrypod_web}/components/page_templates/pdp.html.heex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components.ex (54%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components/base.ex (99%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components/cart.ex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components/content.ex (99%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components/layout.ex (99%) rename lib/{simpleshop_theme_web => berrypod_web}/components/shop_components/product.ex (98%) create mode 100644 lib/berrypod_web/controllers/admin_controller.ex rename lib/{simpleshop_theme_web => berrypod_web}/controllers/cart_controller.ex (85%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/checkout_controller.ex (93%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/error_html.ex (92%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/error_json.ex (93%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/error_preview_controller.ex (62%) create mode 100644 lib/berrypod_web/controllers/health_controller.ex rename lib/{simpleshop_theme_web => berrypod_web}/controllers/image_controller.ex (88%) create mode 100644 lib/berrypod_web/controllers/page_controller.ex rename lib/{simpleshop_theme_web => berrypod_web}/controllers/page_html.ex (71%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/page_html/home.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/stripe_webhook_controller.ex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/user_session_controller.ex (92%) rename lib/{simpleshop_theme_web => berrypod_web}/controllers/webhook_controller.ex (93%) rename lib/{simpleshop_theme_web => berrypod_web}/endpoint.ex (79%) rename lib/{simpleshop_theme_web => berrypod_web}/gettext.ex (82%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/dashboard.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/order_show.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/orders.ex (97%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/product_show.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/products.ex (97%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/providers/form.ex (95%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/providers/form.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/providers/index.ex (93%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/providers/index.html.heex (100%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/settings.ex (98%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/theme/index.ex (93%) rename lib/{simpleshop_theme_web => berrypod_web}/live/admin/theme/index.html.heex (99%) rename lib/{simpleshop_theme_web => berrypod_web}/live/auth/confirmation.ex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/live/auth/login.ex (95%) rename lib/{simpleshop_theme_web => berrypod_web}/live/auth/registration.ex (91%) rename lib/{simpleshop_theme_web => berrypod_web}/live/auth/settings.ex (86%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/cart.ex (62%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/checkout_success.ex (70%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/collection.ex (97%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/coming_soon.ex (86%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/contact.ex (55%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/content.ex (89%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/home.ex (64%) rename lib/{simpleshop_theme_web => berrypod_web}/live/shop/product_show.ex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/plugs/cache_raw_body.ex (92%) rename lib/{simpleshop_theme_web => berrypod_web}/plugs/country_detect.ex (96%) rename lib/{simpleshop_theme_web => berrypod_web}/plugs/load_theme.ex (88%) rename lib/{simpleshop_theme_web => berrypod_web}/plugs/verify_printful_webhook.ex (95%) rename lib/{simpleshop_theme_web => berrypod_web}/plugs/verify_printify_webhook.ex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/router.ex (66%) rename lib/{simpleshop_theme_web => berrypod_web}/search_hook.ex (94%) rename lib/{simpleshop_theme_web => berrypod_web}/telemetry.ex (89%) rename lib/{simpleshop_theme_web => berrypod_web}/theme_hook.ex (89%) rename lib/{simpleshop_theme_web => berrypod_web}/user_auth.ex (92%) rename lib/mix/tasks/{simpleshop => berrypod}/download_images.ex (84%) delete mode 100644 lib/simpleshop_theme/mailer.ex delete mode 100644 lib/simpleshop_theme/repo.ex delete mode 100644 lib/simpleshop_theme_web/controllers/admin_controller.ex delete mode 100644 lib/simpleshop_theme_web/controllers/health_controller.ex delete mode 100644 lib/simpleshop_theme_web/controllers/page_controller.ex create mode 120000 node_modules/.bin/pixelmatch create mode 100644 node_modules/.package-lock.json create mode 100644 node_modules/pixelmatch/LICENSE create mode 100644 node_modules/pixelmatch/README.md create mode 100755 node_modules/pixelmatch/bin/pixelmatch create mode 100644 node_modules/pixelmatch/index.d.ts create mode 100644 node_modules/pixelmatch/index.js create mode 100644 node_modules/pixelmatch/package.json create mode 100644 node_modules/pngjs/CHANGELOG.md create mode 100644 node_modules/pngjs/LICENSE create mode 100644 node_modules/pngjs/README.md create mode 100644 node_modules/pngjs/browser.js create mode 100644 node_modules/pngjs/lib/bitmapper.js create mode 100644 node_modules/pngjs/lib/bitpacker.js create mode 100644 node_modules/pngjs/lib/chunkstream.js create mode 100644 node_modules/pngjs/lib/constants.js create mode 100644 node_modules/pngjs/lib/crc.js create mode 100644 node_modules/pngjs/lib/filter-pack.js create mode 100644 node_modules/pngjs/lib/filter-parse-async.js create mode 100644 node_modules/pngjs/lib/filter-parse-sync.js create mode 100644 node_modules/pngjs/lib/filter-parse.js create mode 100644 node_modules/pngjs/lib/format-normaliser.js create mode 100644 node_modules/pngjs/lib/interlace.js create mode 100644 node_modules/pngjs/lib/packer-async.js create mode 100644 node_modules/pngjs/lib/packer-sync.js create mode 100644 node_modules/pngjs/lib/packer.js create mode 100644 node_modules/pngjs/lib/paeth-predictor.js create mode 100644 node_modules/pngjs/lib/parser-async.js create mode 100644 node_modules/pngjs/lib/parser-sync.js create mode 100644 node_modules/pngjs/lib/parser.js create mode 100644 node_modules/pngjs/lib/png-sync.js create mode 100644 node_modules/pngjs/lib/png.js create mode 100644 node_modules/pngjs/lib/sync-inflate.js create mode 100644 node_modules/pngjs/lib/sync-reader.js create mode 100644 node_modules/pngjs/package.json create mode 100644 package-lock.json create mode 100644 package.json rename test/{simpleshop_theme => berrypod}/accounts_test.exs (98%) rename test/{simpleshop_theme => berrypod}/cart_test.exs (98%) rename test/{simpleshop_theme => berrypod}/clients/printful_test.exs (92%) rename test/{simpleshop_theme => berrypod}/images/optimize_worker_test.exs (83%) rename test/{simpleshop_theme => berrypod}/images/optimizer_test.exs (94%) rename test/{simpleshop_theme => berrypod}/media/svg_recolorer_test.exs (98%) rename test/{simpleshop_theme => berrypod}/media_test.exs (96%) rename test/{simpleshop_theme => berrypod}/orders/fulfilment_status_worker_test.exs (83%) rename test/{simpleshop_theme => berrypod}/orders/order_notifier_test.exs (95%) rename test/{simpleshop_theme => berrypod}/orders/order_submission_worker_test.exs (88%) rename test/{simpleshop_theme => berrypod}/orders_test.exs (92%) rename test/{simpleshop_theme => berrypod}/products/product_image_test.exs (95%) rename test/{simpleshop_theme => berrypod}/products/product_test.exs (97%) rename test/{simpleshop_theme => berrypod}/products/product_variant_test.exs (96%) rename test/{simpleshop_theme => berrypod}/products/provider_connection_test.exs (94%) rename test/{simpleshop_theme => berrypod}/products_test.exs (98%) rename test/{simpleshop_theme => berrypod}/products_upsert_test.exs (96%) rename test/{simpleshop_theme => berrypod}/providers/printful_test.exs (95%) rename test/{simpleshop_theme => berrypod}/providers/printify_test.exs (91%) rename test/{simpleshop_theme => berrypod}/search_test.exs (90%) rename test/{simpleshop_theme => berrypod}/settings_test.exs (96%) rename test/{simpleshop_theme => berrypod}/setup_test.exs (92%) rename test/{simpleshop_theme => berrypod}/shipping_test.exs (97%) rename test/{simpleshop_theme => berrypod}/stripe/setup_test.exs (91%) rename test/{simpleshop_theme => berrypod}/sync/product_sync_worker_test.exs (90%) rename test/{simpleshop_theme => berrypod}/sync/scheduled_sync_worker_test.exs (76%) rename test/{simpleshop_theme => berrypod}/theme/css_cache_test.exs (92%) rename test/{simpleshop_theme => berrypod}/theme/css_generator_test.exs (97%) rename test/{simpleshop_theme => berrypod}/theme/presets_test.exs (97%) rename test/{simpleshop_theme => berrypod}/theme/preview_data_test.exs (98%) rename test/{simpleshop_theme => berrypod}/vault_test.exs (96%) rename test/{simpleshop_theme => berrypod}/webhooks/product_delete_worker_test.exs (81%) rename test/{simpleshop_theme => berrypod}/webhooks_test.exs (95%) rename test/{simpleshop_theme_web => berrypod_web}/controllers/error_html_test.exs (61%) create mode 100644 test/berrypod_web/controllers/error_json_test.exs rename test/{simpleshop_theme_web => berrypod_web}/controllers/image_controller_test.exs (95%) rename test/{simpleshop_theme_web => berrypod_web}/controllers/page_controller_test.exs (52%) rename test/{simpleshop_theme_web => berrypod_web}/controllers/user_session_controller_test.exs (94%) rename test/{simpleshop_theme_web => berrypod_web}/controllers/webhook_controller_test.exs (94%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/dashboard_test.exs (88%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/layout_test.exs (93%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/orders_test.exs (90%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/products_test.exs (91%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/providers_test.exs (93%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/settings_test.exs (96%) rename test/{simpleshop_theme_web => berrypod_web}/live/admin/theme_test.exs (97%) rename test/{simpleshop_theme_web => berrypod_web}/live/auth/confirmation_test.exs (95%) rename test/{simpleshop_theme_web => berrypod_web}/live/auth/login_test.exs (93%) rename test/{simpleshop_theme_web => berrypod_web}/live/auth/registration_test.exs (94%) rename test/{simpleshop_theme_web => berrypod_web}/live/auth/settings_test.exs (93%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/cart_test.exs (91%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/collection_test.exs (94%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/coming_soon_test.exs (91%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/content_test.exs (92%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/home_test.exs (88%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/product_show_test.exs (97%) rename test/{simpleshop_theme_web => berrypod_web}/live/shop/search_integration_test.exs (89%) rename test/{simpleshop_theme_web => berrypod_web}/live/theme_css_consistency_test.exs (92%) rename test/{simpleshop_theme_web => berrypod_web}/plugs/country_detect_test.exs (94%) rename test/{simpleshop_theme_web => berrypod_web}/user_auth_test.exs (94%) delete mode 100644 test/simpleshop_theme_web/controllers/error_json_test.exs diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs index ea89234..2815918 100644 --- a/.dialyzer_ignore.exs +++ b/.dialyzer_ignore.exs @@ -6,23 +6,23 @@ {"lib/mix/tasks/optimize_images.ex", :unknown_function}, {"lib/mix/tasks/register_webhooks.ex", :callback_info_missing}, {"lib/mix/tasks/register_webhooks.ex", :unknown_function}, - {"lib/mix/tasks/simpleshop/download_images.ex", :callback_info_missing}, - {"lib/mix/tasks/simpleshop/download_images.ex", :unknown_function}, + {"lib/mix/tasks/berrypod/download_images.ex", :callback_info_missing}, + {"lib/mix/tasks/berrypod/download_images.ex", :unknown_function}, # Stripe library type specs cause false positives - {"lib/simpleshop_theme/stripe/setup.ex", :pattern_match_cov}, - {"lib/simpleshop_theme/stripe/setup.ex", :pattern_match}, - {"lib/simpleshop_theme/stripe/setup.ex", :no_return}, - {"lib/simpleshop_theme/stripe/setup.ex", :call}, - {"lib/simpleshop_theme_web/controllers/checkout_controller.ex", :call}, - {"lib/simpleshop_theme_web/controllers/checkout_controller.ex", :pattern_match_cov}, - {"lib/simpleshop_theme_web/controllers/checkout_controller.ex", :no_return}, + {"lib/berrypod/stripe/setup.ex", :pattern_match_cov}, + {"lib/berrypod/stripe/setup.ex", :pattern_match}, + {"lib/berrypod/stripe/setup.ex", :no_return}, + {"lib/berrypod/stripe/setup.ex", :call}, + {"lib/berrypod_web/controllers/checkout_controller.ex", :call}, + {"lib/berrypod_web/controllers/checkout_controller.ex", :pattern_match_cov}, + {"lib/berrypod_web/controllers/checkout_controller.ex", :no_return}, # Environment-dependent: localhost?() is always true in dev - {"lib/simpleshop_theme_web/live/admin/settings.ex", :pattern_match}, + {"lib/berrypod_web/live/admin/settings.ex", :pattern_match}, # Provider behaviour type not derived by dialyzer - {"lib/simpleshop_theme/providers/provider.ex", :unknown_type}, + {"lib/berrypod/providers/provider.ex", :unknown_type}, # ExUnit internals not in PLT (test support files) {"test/support/conn_case.ex", :unknown_function}, diff --git a/.gitignore b/.gitignore index 62de3dd..5464111 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ erl_crash.dump /tmp/ # Ignore package tarball (built via "mix hex.build"). -simpleshop_theme-*.tar +berrypod-*.tar # Ignore assets that are produced by build tools. /priv/static/assets/ diff --git a/CLAUDE.md b/CLAUDE.md index 96536f8..dd7307b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -SimpleShop is a customisable e-commerce storefront for print-on-demand sellers, built with Phoenix 1.8 + LiveView 1.1 on Elixir/Erlang. Uses SQLite with BLOB storage for images. Licensed under AGPL-3.0. +Berrypod is a customisable e-commerce storefront for print-on-demand sellers, built with Phoenix 1.8 + LiveView 1.1 on Elixir/Erlang. Uses SQLite with BLOB storage for images. Licensed under AGPL-3.0. ## Common Commands @@ -19,7 +19,7 @@ mix precommit # REQUIRED before committing: compile --warning-as-errors ## Architecture -### Core Contexts (lib/simpleshop_theme/) +### Core Contexts (lib/berrypod/) - **Settings** - Theme configuration persistence as JSON - **Theme** - CSS generation, ETS caching, 8 presets (Gallery, Studio, Boutique, etc.) @@ -27,7 +27,7 @@ mix precommit # REQUIRED before committing: compile --warning-as-errors - **Media/Images** - Image uploads and optimization pipeline (Oban jobs) - **Providers** - Abstraction layer for POD providers (Printify integration) -### Web Layer (lib/simpleshop_theme_web/) +### Web Layer (lib/berrypod_web/) - **live/** - LiveViews for shop pages and theme editor - **components/page_templates/** - Shared templates between preview and live shop @@ -78,7 +78,7 @@ Theme switching is instant via CSS custom property injection (no reload). Routes requiring auth go in `:require_authenticated_user` live_session: ```elixir live_session :require_authenticated_user, - on_mount: [{SimpleshopThemeWeb.UserAuth, :require_authenticated}] do + on_mount: [{BerrypodWeb.UserAuth, :require_authenticated}] do live "/admin/theme", ThemeLive.Index end ``` @@ -86,7 +86,7 @@ end Public routes with optional user go in `:current_user` live_session: ```elixir live_session :current_user, - on_mount: [{SimpleshopThemeWeb.UserAuth, :mount_current_scope}] do + on_mount: [{BerrypodWeb.UserAuth, :mount_current_scope}] do live "/", ShopLive.Home end ``` diff --git a/Dockerfile b/Dockerfile index c2d8579..ed0150e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,15 @@ -# Lean Alpine-based image for SimpleshopTheme. +# Lean Alpine-based image for Berrypod. # # Builder and runner both use Alpine (musl). The vix NIF is compiled against # Alpine's system libvips instead of the glibc-linked precompiled binary. # -# Build: docker build -t simpleshop_theme . +# Build: docker build -t berrypod . # Run: docker run --rm -p 4000:4000 \ # -e SECRET_KEY_BASE=$(mix phx.gen.secret) \ -# -e DATABASE_PATH=/data/simpleshop_theme.db \ +# -e DATABASE_PATH=/data/berrypod.db \ # -e PHX_HOST=localhost \ -# -v simpleshop_data:/data \ -# simpleshop_theme +# -v berrypod_data:/data \ +# berrypod # # Images: # https://hub.docker.com/r/hexpm/elixir/tags?name=alpine @@ -101,12 +101,12 @@ RUN mkdir -p /data && chown appuser:appuser /data ENV MIX_ENV="prod" # Copy the release from the builder -COPY --from=builder --chown=appuser:appuser /app/_build/${MIX_ENV}/rel/simpleshop_theme ./ +COPY --from=builder --chown=appuser:appuser /app/_build/${MIX_ENV}/rel/berrypod ./ USER appuser # Ensure /data is the default database location -ENV DATABASE_PATH="/data/simpleshop_theme.db" +ENV DATABASE_PATH="/data/berrypod.db" EXPOSE 4000 diff --git a/PROGRESS.md b/PROGRESS.md index 5d64589..492fc75 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,4 +1,4 @@ -# SimpleShop Progress +# Berrypod Progress > Single source of truth for project status and task tracking. @@ -110,7 +110,7 @@ Issues from hands-on testing of the deployed prod site (Feb 2025). 16 of 18 comp ### Tier 5 — Platform vision -16. **Hosted platform** — Marketing/brochure site for SimpleShop as a service. Subscribe/sign-up flow. Multi-tenancy with per-tenant databases. Stripe Connect for customer shops (each merchant connects their own Stripe account via OAuth). +16. **Hosted platform** — Marketing/brochure site for Berrypod as a service. Subscribe/sign-up flow. Multi-tenancy with per-tenant databases. Stripe Connect for customer shops (each merchant connects their own Stripe account via OAuth). 17. **Migration & export** — Let shop owners export their data (products, orders, customers, theme settings). Import from other platforms (Shopify, WooCommerce). Portable data as a selling point for the self-hosted story. 18. **Internationalisation (i18n)** — Multi-language support via Gettext (already in Phoenix). Currency formatting. RTL layout support. Per-shop locale configuration. **Note:** `ex_money`/`ex_cldr` are currently used *only* for `Cart.format_price/1` (a single GBP formatting call) but add ~13 MB to the release (ex_cldr 9.5 MB, digital_token 3.7 MB, ex_cldr_numbers, ex_cldr_currencies). Consider replacing with a simple `format_price/2` function that handles GBP/EUR/USD directly — all three use 2 decimal places and are trivial to format. Re-add `ex_money` later if proper locale-aware number formatting is needed (e.g., German `12.345,67 €`). @@ -141,7 +141,7 @@ Issues from hands-on testing of the deployed prod site (Feb 2025). 16 of 18 comp - ImageDownloadWorker downloads and links images to ProductImage - PreviewData uses local images for responsive `` elements - Startup recovery re-enqueues pending downloads - - `mix simpleshop.download_images` backfill task + - `mix berrypod.download_images` backfill task See: [docs/plans/image-optimization.md](docs/plans/image-optimization.md) for implementation details @@ -160,7 +160,7 @@ See: [docs/plans/image-optimization.md](docs/plans/image-optimization.md) for im - [x] Product image download pipeline (1b49b47) - Downloads Printify CDN images via ImageDownloadWorker - Processes through Media pipeline (WebP conversion, AVIF/WebP variants) - - Startup recovery and `mix simpleshop.download_images` backfill + - Startup recovery and `mix berrypod.download_images` backfill - [x] Variant selector component (880e7a2) - Color swatches with hex colors, size buttons - Fixed Printify options parsing (Color/Size swap bug) diff --git a/README.md b/README.md index bc54a8a..e7c68ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# SimpleShop +# Berrypod A beautiful, customisable e-commerce storefront built with Phoenix LiveView. Designed for print-on-demand sellers who want professional shops without design expertise. @@ -49,7 +49,7 @@ Customise your shop's look without touching code: ```bash # Clone the repository git clone -cd simpleshop_theme +cd berrypod # Install dependencies mix setup @@ -72,7 +72,7 @@ mix test ``` lib/ -├── simpleshop_theme/ # Core business logic +├── berrypod/ # Core business logic │ ├── settings.ex # Theme settings context │ ├── settings/ │ │ └── theme_settings.ex # Theme settings schema @@ -83,7 +83,7 @@ lib/ │ ├── presets.ex # 8 theme presets │ └── preview_data.ex # Mock data for previews │ -├── simpleshop_theme_web/ # Web layer +├── berrypod_web/ # Web layer │ ├── components/ │ │ ├── layouts/ # App and shop layouts │ │ ├── page_templates/ # Shared page templates (*.heex) @@ -122,7 +122,7 @@ assets/css/ ## Stripe Checkout -SimpleShop uses [Stripe Checkout](https://stripe.com/docs/payments/checkout) (hosted payment page) for secure payment processing. +Berrypod uses [Stripe Checkout](https://stripe.com/docs/payments/checkout) (hosted payment page) for secure payment processing. ### Setup @@ -181,7 +181,7 @@ mix generate_mockups --search "poster" mix generate_mockups --list-blueprints ``` -Product definitions are in `lib/simpleshop_theme/printify/mockup_generator.ex`. +Product definitions are in `lib/berrypod/printify/mockup_generator.ex`. ## Documentation diff --git a/ROADMAP.md b/ROADMAP.md index 9a4eed0..d958e12 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -# SimpleShop Roadmap +# Berrypod Roadmap > Vision and future features. For current status, see [PROGRESS.md](PROGRESS.md). @@ -75,4 +75,4 @@ Areas needing better coverage: - Network error handling in LiveView ### Rename Project -The project is named `simpleshop_theme` but it's now a full storefront. Consider renaming to `simple_shop`. +The project is named `berrypod` but it's now a full storefront. Consider renaming to `simple_shop`. diff --git a/assets/js/app.js b/assets/js/app.js index 0c21b48..e70cd79 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -22,7 +22,7 @@ import "phoenix_html" // Establish Phoenix Socket and LiveView configuration. import {Socket} from "phoenix" import {LiveSocket} from "phoenix_live_view" -import {hooks as colocatedHooks} from "phoenix-colocated/simpleshop_theme" +import {hooks as colocatedHooks} from "phoenix-colocated/berrypod" import topbar from "../vendor/topbar" // Hook to sync color picker and text input diff --git a/config/config.exs b/config/config.exs index d306d3c..37c82e3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -7,33 +7,33 @@ # General application configuration import Config -config :simpleshop_theme, :scopes, +config :berrypod, :scopes, user: [ default: true, - module: SimpleshopTheme.Accounts.Scope, + module: Berrypod.Accounts.Scope, assign_key: :current_scope, access_path: [:user, :id], schema_key: :user_id, schema_type: :binary_id, schema_table: :users, - test_data_fixture: SimpleshopTheme.AccountsFixtures, + test_data_fixture: Berrypod.AccountsFixtures, test_setup_helper: :register_and_log_in_user ] -config :simpleshop_theme, +config :berrypod, env: config_env(), - ecto_repos: [SimpleshopTheme.Repo], + ecto_repos: [Berrypod.Repo], generators: [timestamp_type: :utc_datetime, binary_id: true] # Configures the endpoint -config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, +config :berrypod, BerrypodWeb.Endpoint, url: [host: "localhost"], adapter: Bandit.PhoenixAdapter, render_errors: [ - formats: [html: SimpleshopThemeWeb.ErrorHTML, json: SimpleshopThemeWeb.ErrorJSON], + formats: [html: BerrypodWeb.ErrorHTML, json: BerrypodWeb.ErrorJSON], layout: false ], - pubsub_server: SimpleshopTheme.PubSub, + pubsub_server: Berrypod.PubSub, live_view: [signing_salt: "HWdz7Vt8"] # Configures the mailer @@ -43,22 +43,22 @@ config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, # # For production it's recommended to configure a different adapter # at the `config/runtime.exs`. -config :simpleshop_theme, SimpleshopTheme.Mailer, adapter: Swoosh.Adapters.Local +config :berrypod, Berrypod.Mailer, adapter: Swoosh.Adapters.Local # Configure esbuild (the version is required) config :esbuild, version: "0.25.4", - simpleshop_theme: [ + berrypod: [ args: ~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]} ], - simpleshop_theme_shop_css: [ + berrypod_shop_css: [ args: ~w(css/shop.css --bundle --outdir=../priv/static/assets/css), cd: Path.expand("../assets", __DIR__) ], - simpleshop_theme_admin_css: [ + berrypod_admin_css: [ args: ~w(css/admin.css --bundle --outdir=../priv/static/assets/css), cd: Path.expand("../assets", __DIR__) ] @@ -72,28 +72,28 @@ config :logger, :default_formatter, config :phoenix, :json_library, Jason # ex_money configuration for currency handling -config :ex_money, default_cldr_backend: SimpleshopTheme.Cldr +config :ex_money, default_cldr_backend: Berrypod.Cldr # Error tracking (stored in DB, auto-captures Phoenix/LiveView/Oban errors) config :error_tracker, - repo: SimpleshopTheme.Repo, - otp_app: :simpleshop_theme, + repo: Berrypod.Repo, + otp_app: :berrypod, plugins: [ErrorTracker.Plugins.Pruner] # Stripe configuration config :stripity_stripe, api_version: "2024-12-18.acacia" # Oban configuration for background jobs -config :simpleshop_theme, Oban, +config :berrypod, Oban, engine: Oban.Engines.Lite, - repo: SimpleshopTheme.Repo, + repo: Berrypod.Repo, plugins: [ {Oban.Plugins.Pruner, max_age: 60}, {Oban.Plugins.Lifeline, rescue_after: :timer.minutes(5)}, {Oban.Plugins.Cron, crontab: [ - {"*/30 * * * *", SimpleshopTheme.Orders.FulfilmentStatusWorker}, - {"0 */6 * * *", SimpleshopTheme.Sync.ScheduledSyncWorker} + {"*/30 * * * *", Berrypod.Orders.FulfilmentStatusWorker}, + {"0 */6 * * *", Berrypod.Sync.ScheduledSyncWorker} ]} ], queues: [images: 2, sync: 1, checkout: 1] diff --git a/config/dev.exs b/config/dev.exs index 8444c3a..a9e9d81 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,8 +1,8 @@ import Config # Configure your database -config :simpleshop_theme, SimpleshopTheme.Repo, - database: Path.expand("../simpleshop_theme_dev.db", __DIR__), +config :berrypod, Berrypod.Repo, + database: Path.expand("../berrypod_dev.db", __DIR__), pool_size: 5, journal_mode: :wal, busy_timeout: 5000, @@ -15,7 +15,7 @@ config :simpleshop_theme, SimpleshopTheme.Repo, # The watchers configuration can be used to run external # watchers to your application. For example, we can use it # to bundle .js and .css sources. -config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, +config :berrypod, BerrypodWeb.Endpoint, # Binding to loopback ipv4 address prevents access from other machines. # Change to `ip: {0, 0, 0, 0}` to allow access from other machines. http: [ip: {0, 0, 0, 0}, port: String.to_integer(System.get_env("PORT") || "4000")], @@ -24,11 +24,11 @@ config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, debug_errors: true, secret_key_base: "Jk04sYT/pzfZ0cywS+i0vCURPoQYgqAGa72uS8bv2gydLyusWFc08kJyEnQP4zgT", watchers: [ - esbuild: {Esbuild, :install_and_run, [:simpleshop_theme, ~w(--sourcemap=inline --watch)]}, + esbuild: {Esbuild, :install_and_run, [:berrypod, ~w(--sourcemap=inline --watch)]}, esbuild_shop_css: - {Esbuild, :install_and_run, [:simpleshop_theme_shop_css, ~w(--sourcemap=inline --watch)]}, + {Esbuild, :install_and_run, [:berrypod_shop_css, ~w(--sourcemap=inline --watch)]}, esbuild_admin_css: - {Esbuild, :install_and_run, [:simpleshop_theme_admin_css, ~w(--sourcemap=inline --watch)]} + {Esbuild, :install_and_run, [:berrypod_admin_css, ~w(--sourcemap=inline --watch)]} ] # ## SSL Support @@ -55,18 +55,18 @@ config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, # different ports. # Watch static and templates for browser reloading. -config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, +config :berrypod, BerrypodWeb.Endpoint, live_reload: [ web_console_logger: true, patterns: [ ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$", ~r"priv/gettext/.*(po)$", - ~r"lib/simpleshop_theme_web/(?:controllers|live|components|router)/?.*\.(ex|heex)$" + ~r"lib/berrypod_web/(?:controllers|live|components|router)/?.*\.(ex|heex)$" ] ] # Enable dev routes for dashboard and mailbox -config :simpleshop_theme, dev_routes: true +config :berrypod, dev_routes: true # Do not include metadata nor timestamps in development logs config :logger, :default_formatter, format: "[$level] $message\n" diff --git a/config/prod.exs b/config/prod.exs index de4360e..050640b 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -5,8 +5,7 @@ import Config # manifest is generated by the `mix assets.deploy` task, # which you should run after static files are built and # before starting your production server. -config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, - cache_static_manifest: "priv/static/cache_manifest.json" +config :berrypod, BerrypodWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json" # Configures Swoosh API Client config :swoosh, api_client: Swoosh.ApiClient.Req diff --git a/config/runtime.exs b/config/runtime.exs index 800c41d..6803ed9 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -12,12 +12,12 @@ import Config # If you use `mix release`, you need to explicitly enable the server # by passing the PHX_SERVER=true when you start it: # -# PHX_SERVER=true bin/simpleshop_theme start +# PHX_SERVER=true bin/berrypod start # # Alternatively, you can use `mix phx.gen.release` to generate a `bin/server` # script that automatically sets the env var above. if System.get_env("PHX_SERVER") do - config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, server: true + config :berrypod, BerrypodWeb.Endpoint, server: true end if config_env() == :prod do @@ -25,10 +25,10 @@ if config_env() == :prod do System.get_env("DATABASE_PATH") || raise """ environment variable DATABASE_PATH is missing. - For example: /data/simpleshop_theme.db + For example: /data/berrypod.db """ - config :simpleshop_theme, SimpleshopTheme.Repo, + config :berrypod, Berrypod.Repo, database: database_path, pool_size: String.to_integer(System.get_env("POOL_SIZE") || "5"), journal_mode: :wal, @@ -49,9 +49,9 @@ if config_env() == :prod do host = System.get_env("PHX_HOST") || "example.com" port = String.to_integer(System.get_env("PORT") || "4000") - config :simpleshop_theme, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") + config :berrypod, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") - config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, + config :berrypod, BerrypodWeb.Endpoint, url: [host: host, port: 443, scheme: "https"], http: [ # Enable IPv6 and bind on all interfaces. @@ -68,7 +68,7 @@ if config_env() == :prod do # To get SSL working, you will need to add the `https` key # to your endpoint configuration: # - # config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, + # config :berrypod, BerrypodWeb.Endpoint, # https: [ # ..., # port: 443, @@ -90,7 +90,7 @@ if config_env() == :prod do # We also recommend setting `force_ssl` in your config/prod.exs, # ensuring no data is ever sent via http, always redirecting to https: # - # config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, + # config :berrypod, BerrypodWeb.Endpoint, # force_ssl: [hsts: true] # # Check `Plug.SSL` for all available options in `force_ssl`. @@ -102,20 +102,20 @@ if config_env() == :prod do # # Postmark (recommended): # - # config :simpleshop_theme, SimpleshopTheme.Mailer, + # config :berrypod, Berrypod.Mailer, # adapter: Swoosh.Adapters.Postmark, # api_key: System.get_env("POSTMARK_API_KEY") # # Mailgun: # - # config :simpleshop_theme, SimpleshopTheme.Mailer, + # config :berrypod, Berrypod.Mailer, # adapter: Swoosh.Adapters.Mailgun, # api_key: System.get_env("MAILGUN_API_KEY"), # domain: System.get_env("MAILGUN_DOMAIN") # # SMTP (any provider): # - # config :simpleshop_theme, SimpleshopTheme.Mailer, + # config :berrypod, Berrypod.Mailer, # adapter: Swoosh.Adapters.SMTP, # relay: System.get_env("SMTP_HOST"), # port: String.to_integer(System.get_env("SMTP_PORT") || "587"), @@ -124,5 +124,5 @@ if config_env() == :prod do # tls: :if_available # Stripe and Printify keys are stored encrypted in the database and loaded - # at runtime by SimpleshopTheme.Secrets. No env vars needed for those. + # at runtime by Berrypod.Secrets. No env vars needed for those. end diff --git a/config/test.exs b/config/test.exs index 362cd0e..dd76644 100644 --- a/config/test.exs +++ b/config/test.exs @@ -8,8 +8,8 @@ config :bcrypt_elixir, :log_rounds, 1 # The MIX_TEST_PARTITION environment variable can be used # to provide built-in test partitioning in CI environment. # Run `mix help test` for more information. -config :simpleshop_theme, SimpleshopTheme.Repo, - database: Path.expand("../simpleshop_theme_test.db", __DIR__), +config :berrypod, Berrypod.Repo, + database: Path.expand("../berrypod_test.db", __DIR__), pool_size: 1, pool: Ecto.Adapters.SQL.Sandbox, journal_mode: :wal, @@ -17,13 +17,13 @@ config :simpleshop_theme, SimpleshopTheme.Repo, # We don't run a server during test. If one is required, # you can enable the server option below. -config :simpleshop_theme, SimpleshopThemeWeb.Endpoint, +config :berrypod, BerrypodWeb.Endpoint, http: [ip: {127, 0, 0, 1}, port: 4002], secret_key_base: "FgIOvs+0ZwA+GU1gInqNuyDz3zSnfeRu0kD7DYyGpC05/wE+G2xVJ5zlc/ufGedN", server: false # In test we don't send emails -config :simpleshop_theme, SimpleshopTheme.Mailer, adapter: Swoosh.Adapters.Test +config :berrypod, Berrypod.Mailer, adapter: Swoosh.Adapters.Test # Disable swoosh api client as it is only required for production adapters config :swoosh, :api_client, false @@ -39,7 +39,7 @@ config :phoenix_live_view, enable_expensive_runtime_checks: true # Use inline testing mode for Oban -config :simpleshop_theme, Oban, testing: :inline +config :berrypod, Oban, testing: :inline # Isolate image cache so test cleanup doesn't wipe the dev cache -config :simpleshop_theme, :image_cache_dir, Path.expand("../tmp/test_image_cache", __DIR__) +config :berrypod, :image_cache_dir, Path.expand("../tmp/test_image_cache", __DIR__) diff --git a/docs/plans/admin-redesign.md b/docs/plans/admin-redesign.md index 1a82ebf..1661cfe 100644 --- a/docs/plans/admin-redesign.md +++ b/docs/plans/admin-redesign.md @@ -113,7 +113,7 @@ Build the structural pieces first, using existing DaisyUI components. No CSS cha ### 1.1 Admin shell layout -**New file:** `lib/simpleshop_theme_web/components/admin_components.ex` +**New file:** `lib/berrypod_web/components/admin_components.ex` A shared admin layout component that wraps all admin pages: @@ -156,7 +156,7 @@ The shell provides: ### 1.2 Admin root layout -**File:** `lib/simpleshop_theme_web/components/layouts/admin_root.html.heex` (new) +**File:** `lib/berrypod_web/components/layouts/admin_root.html.heex` (new) A dedicated root layout for admin pages that: - Loads `app.css` (or later `app-admin.css`) @@ -164,7 +164,7 @@ A dedicated root layout for admin pages that: - Doesn't include the shop nav/footer chrome - Replaces the current generic `root.html.heex` for admin routes -**File:** `lib/simpleshop_theme_web/components/layouts/admin.html.heex` (new) +**File:** `lib/berrypod_web/components/layouts/admin.html.heex` (new) The admin child layout (equivalent of `shop.html.heex`): - Renders flash messages @@ -176,7 +176,7 @@ The admin child layout (equivalent of `shop.html.heex`): ### 1.3 Dashboard page -**File:** `lib/simpleshop_theme_web/live/admin_live/dashboard.ex` (new) +**File:** `lib/berrypod_web/live/admin_live/dashboard.ex` (new) Replace the current `/admin` → redirect-to-theme with a proper dashboard: @@ -195,7 +195,7 @@ When the shop isn't live yet, the dashboard IS the setup wizard (from [setup-wiz Currently settings are split across three pages. Consolidate into one settings page with sections: -**File:** `lib/simpleshop_theme_web/live/admin_live/settings.ex` (refactor) +**File:** `lib/berrypod_web/live/admin_live/settings.ex` (refactor) Sections: - **Payments** — Stripe API key, webhook config (current `/admin/settings` content) @@ -209,7 +209,7 @@ Each section is a collapsible card or tab. The existing `/admin/providers` and ` ### 1.5 Admin bar on shop pages -**File:** `lib/simpleshop_theme_web/components/shop_components/layout.ex` +**File:** `lib/berrypod_web/components/shop_components/layout.ex` When the admin is browsing the shop (authenticated), show a thin bar at the top: @@ -313,12 +313,12 @@ Replaces DaisyUI for admin pages. Structure: @import "tailwindcss" source(none); @source "../css"; @source "../js"; -@source "../../lib/simpleshop_theme_web/live/admin"; -@source "../../lib/simpleshop_theme_web/live/user"; -@source "../../lib/simpleshop_theme_web/components/admin_components.ex"; -@source "../../lib/simpleshop_theme_web/components/core_components.ex"; -@source "../../lib/simpleshop_theme_web/components/layouts/admin_root.html.heex"; -@source "../../lib/simpleshop_theme_web/components/layouts/admin.html.heex"; +@source "../../lib/berrypod_web/live/admin"; +@source "../../lib/berrypod_web/live/user"; +@source "../../lib/berrypod_web/components/admin_components.ex"; +@source "../../lib/berrypod_web/components/core_components.ex"; +@source "../../lib/berrypod_web/components/layouts/admin_root.html.heex"; +@source "../../lib/berrypod_web/components/layouts/admin.html.heex"; @plugin "../vendor/heroicons"; @@ -353,7 +353,7 @@ Each is ~5-15 lines of CSS. No need for DaisyUI's full component library. ### 2.3 Migrate core_components.ex -**File:** `lib/simpleshop_theme_web/components/core_components.ex` +**File:** `lib/berrypod_web/components/core_components.ex` Replace DaisyUI class references with the new admin classes. This is a find-and-replace job: - `btn btn-primary` → `admin-btn admin-btn-primary` diff --git a/docs/plans/css-migration.md b/docs/plans/css-migration.md index bd4bd71..b5fad5f 100644 --- a/docs/plans/css-migration.md +++ b/docs/plans/css-migration.md @@ -202,7 +202,7 @@ Acceptance: layout primitives available, no visual changes, all tests pass. - Visual regression: PDP page Files modified: -- `lib/simpleshop_theme_web/components/shop_components/product.ex` (83 style= -> 0) +- `lib/berrypod_web/components/shop_components/product.ex` (83 style= -> 0) - `assets/css/shop/components.css` Acceptance: `product.ex` has zero inline styles, visual regression clean. @@ -224,8 +224,8 @@ Acceptance: `product.ex` has zero inline styles, visual regression clean. - Visual regression: cart page, cart drawer Files modified: -- `lib/simpleshop_theme_web/components/shop_components/layout.ex` (59 -> 0) -- `lib/simpleshop_theme_web/components/shop_components/cart.ex` (51 -> 0) +- `lib/berrypod_web/components/shop_components/layout.ex` (59 -> 0) +- `lib/berrypod_web/components/shop_components/cart.ex` (51 -> 0) - `assets/css/shop/components.css` Acceptance: both files zero inline styles, visual regression clean. @@ -246,9 +246,9 @@ Acceptance: both files zero inline styles, visual regression clean. - Also `base.ex` (2) Files modified: -- `lib/simpleshop_theme_web/components/shop_components/content.ex` (57 -> 0) -- `lib/simpleshop_theme_web/components/shop_components/base.ex` (2 -> 0) -- `lib/simpleshop_theme_web/components/page_templates/*.html.heex` (29 -> 0) +- `lib/berrypod_web/components/shop_components/content.ex` (57 -> 0) +- `lib/berrypod_web/components/shop_components/base.ex` (2 -> 0) +- `lib/berrypod_web/components/page_templates/*.html.heex` (29 -> 0) - `assets/css/shop/components.css` Acceptance: **zero inline styles remain** (0/281), full visual regression clean. @@ -268,7 +268,7 @@ Acceptance: **zero inline styles remain** (0/281), full visual regression clean. **5b** — Remove Tailwind shop build (~1.5h): - Replace remaining Tailwind classes in `.heex` page templates - Remove `@import "tailwindcss"` from `app-shop.css` -- Remove `simpleshop_theme_shop` Tailwind profile from `config/config.exs` +- Remove `berrypod_shop` Tailwind profile from `config/config.exs` - Remove `tailwind_shop` watcher from `config/dev.exs` - Update `assets.build` and `assets.deploy` Mix aliases - Full visual regression @@ -301,7 +301,7 @@ Acceptance: no Tailwind classes in shop code, Tailwind shop build removed, admin Files modified: - `assets/css/admin-components.css` (new) - `assets/css/app.css` (remove DaisyUI) -- `lib/simpleshop_theme_web/components/core_components.ex` +- `lib/berrypod_web/components/core_components.ex` - All admin LiveView files - Auth LiveView files diff --git a/docs/plans/dry-refactor.md b/docs/plans/dry-refactor.md index 4749fb9..de70ceb 100644 --- a/docs/plans/dry-refactor.md +++ b/docs/plans/dry-refactor.md @@ -133,7 +133,7 @@ end **Net saving:** ~65 lines removed (80 duplicated minus ~15 for the helper function). -**Files:** `lib/simpleshop_theme_web/live/theme_live/index.ex` +**Files:** `lib/berrypod_web/live/theme_live/index.ex` **Complexity:** Low. Pure refactor within one file. diff --git a/docs/plans/image-optimization.md b/docs/plans/image-optimization.md index 24872e6..945b1cb 100644 --- a/docs/plans/image-optimization.md +++ b/docs/plans/image-optimization.md @@ -126,9 +126,9 @@ For a production-quality system, Oban's durability is worth the small complexity ```elixir # config/config.exs -config :simpleshop_theme, Oban, +config :berrypod, Oban, engine: Oban.Engines.Lite, # SQLite support - repo: SimpleshopTheme.Repo, + repo: Berrypod.Repo, plugins: [ # Prune completed jobs after 60 seconds - keeps DB lean {Oban.Plugins.Pruner, max_age: 60} @@ -144,7 +144,7 @@ With `max_age: 60`, the Oban tables typically contain: ### Job Worker ```elixir -defmodule SimpleshopTheme.Workers.ImageVariants do +defmodule Berrypod.Workers.ImageVariants do use Oban.Worker, queue: :images, max_attempts: 3 @impl Oban.Worker @@ -168,7 +168,7 @@ def upload_image(attrs) do {:ok, image} -> # Enqueue async variant generation %{image_id: image.id} - |> SimpleshopTheme.Workers.ImageVariants.new() + |> Berrypod.Workers.ImageVariants.new() |> Oban.insert() {:ok, image} @@ -195,7 +195,7 @@ defp ensure_all_variants do |> Enum.each(fn image -> # Re-enqueue for processing %{image_id: image.id} - |> SimpleshopTheme.Workers.ImageVariants.new() + |> Berrypod.Workers.ImageVariants.new() |> Oban.insert() end) end @@ -223,7 +223,7 @@ end **File:** `priv/repo/migrations/YYYYMMDDHHMMSS_add_image_metadata.exs` ```elixir -defmodule SimpleshopTheme.Repo.Migrations.AddImageMetadata do +defmodule Berrypod.Repo.Migrations.AddImageMetadata do use Ecto.Migration def change do @@ -244,10 +244,10 @@ end ### Step 3: Image Optimizer Module -**File:** `lib/simpleshop_theme/images/optimizer.ex` +**File:** `lib/berrypod/images/optimizer.ex` ```elixir -defmodule SimpleshopTheme.Images.Optimizer do +defmodule Berrypod.Images.Optimizer do @moduledoc """ Generates optimized image variants. Only creates sizes ≤ source dimensions. """ @@ -290,7 +290,7 @@ defmodule SimpleshopTheme.Images.Optimizer do Called by Oban worker. """ def process_for_image(image_id) do - alias SimpleshopTheme.{Repo, Media.Image} + alias Berrypod.{Repo, Media.Image} case Repo.get(Image, image_id) do nil -> @@ -387,16 +387,16 @@ end ### Step 4: Oban Worker -**File:** `lib/simpleshop_theme/workers/image_variants.ex` +**File:** `lib/berrypod/workers/image_variants.ex` ```elixir -defmodule SimpleshopTheme.Workers.ImageVariants do +defmodule Berrypod.Workers.ImageVariants do use Oban.Worker, queue: :images, max_attempts: 3, unique: [period: 60] # Prevent duplicate jobs - alias SimpleshopTheme.Images.Optimizer + alias Berrypod.Images.Optimizer @impl Oban.Worker def perform(%Oban.Job{args: %{"image_id" => image_id}}) do @@ -410,11 +410,11 @@ end ### Step 5: Update Media Module -**File:** `lib/simpleshop_theme/media.ex` +**File:** `lib/berrypod/media.ex` ```elixir -alias SimpleshopTheme.Images.Optimizer -alias SimpleshopTheme.Workers.ImageVariants +alias Berrypod.Images.Optimizer +alias Berrypod.Workers.ImageVariants def upload_image(attrs) do # Convert to lossless WebP before storing @@ -449,10 +449,10 @@ end ### Step 6: Startup Recovery GenServer -**File:** `lib/simpleshop_theme/images/variant_cache.ex` +**File:** `lib/berrypod/images/variant_cache.ex` ```elixir -defmodule SimpleshopTheme.Images.VariantCache do +defmodule Berrypod.Images.VariantCache do @moduledoc """ Ensures all image variants exist on startup. Enqueues Oban jobs for any missing variants. @@ -461,10 +461,10 @@ defmodule SimpleshopTheme.Images.VariantCache do use GenServer require Logger - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Media.Image, as: ImageSchema - alias SimpleshopTheme.Images.Optimizer - alias SimpleshopTheme.Workers.ImageVariants + alias Berrypod.Repo + alias Berrypod.Media.Image, as: ImageSchema + alias Berrypod.Images.Optimizer + alias Berrypod.Workers.ImageVariants import Ecto.Query def start_link(_opts) do @@ -521,7 +521,7 @@ end ### Step 7: Responsive Image Component -**File:** `lib/simpleshop_theme_web/components/shop_components.ex` +**File:** `lib/berrypod_web/components/shop_components.ex` ```elixir @doc """ @@ -547,7 +547,7 @@ attr :height, :integer, default: nil attr :priority, :boolean, default: false def responsive_image(assigns) do - alias SimpleshopTheme.Images.Optimizer + alias Berrypod.Images.Optimizer # Compute available widths from source dimensions available = Optimizer.applicable_widths(assigns.source_width) @@ -596,7 +596,7 @@ end ### Step 8: Update Thumbnail Serving -**File:** `lib/simpleshop_theme_web/controllers/image_controller.ex` +**File:** `lib/berrypod_web/controllers/image_controller.ex` ```elixir def thumbnail(conn, %{"id" => id}) do @@ -750,20 +750,20 @@ end ## File Changes Summary ### Create: -- `lib/simpleshop_theme/images/optimizer.ex` - Core optimization logic -- `lib/simpleshop_theme/images/variant_cache.ex` - Startup recovery GenServer -- `lib/simpleshop_theme/workers/image_variants.ex` - Oban worker +- `lib/berrypod/images/optimizer.ex` - Core optimization logic +- `lib/berrypod/images/variant_cache.ex` - Startup recovery GenServer +- `lib/berrypod/workers/image_variants.ex` - Oban worker - `lib/mix/tasks/optimize_images.ex` - Mockup batch processing - `priv/repo/migrations/*_add_image_metadata.exs` - Schema + Oban tables ### Modify: - `mix.exs` - Add Oban dependency - `config/config.exs` - Oban configuration -- `lib/simpleshop_theme/media/image.ex` - Add source_width/height, remove thumbnail_data -- `lib/simpleshop_theme/media.ex` - Convert to WebP, enqueue Oban job -- `lib/simpleshop_theme/application.ex` - Add Oban + VariantCache to supervision -- `lib/simpleshop_theme_web/components/shop_components.ex` - Responsive image component -- `lib/simpleshop_theme_web/controllers/image_controller.ex` - Serve thumbnails from disk +- `lib/berrypod/media/image.ex` - Add source_width/height, remove thumbnail_data +- `lib/berrypod/media.ex` - Convert to WebP, enqueue Oban job +- `lib/berrypod/application.ex` - Add Oban + VariantCache to supervision +- `lib/berrypod_web/components/shop_components.ex` - Responsive image component +- `lib/berrypod_web/controllers/image_controller.ex` - Serve thumbnails from disk - `.gitignore` - Add `/priv/static/image_cache/` --- @@ -832,14 +832,14 @@ mix phx.server **Files to create/modify:** - `priv/repo/migrations/*_add_image_metadata.exs` - New migration -- `lib/simpleshop_theme/media/image.ex` - Add source_width/height, variants_status; remove thumbnail_data +- `lib/berrypod/media/image.ex` - Add source_width/height, variants_status; remove thumbnail_data -**Tests:** `mix ecto.migrate && mix test test/simpleshop_theme/media_test.exs` (if exists) +**Tests:** `mix ecto.migrate && mix test test/berrypod/media_test.exs` (if exists) **Manual verification:** ```bash # Check migration applied -sqlite3 simpleshop_theme_dev.db ".schema images" +sqlite3 berrypod_dev.db ".schema images" # Should show new columns: source_width, source_height, variants_status # Should NOT have: thumbnail_data ``` @@ -851,17 +851,17 @@ sqlite3 simpleshop_theme_dev.db ".schema images" ### Phase 3: Optimizer Module **Files to create:** -- `lib/simpleshop_theme/images/optimizer.ex` -- `test/simpleshop_theme/images/optimizer_test.exs` +- `lib/berrypod/images/optimizer.ex` +- `test/berrypod/images/optimizer_test.exs` - `test/support/fixtures/image_fixtures.ex` - `test/fixtures/sample_1200x800.jpg` (test image) -**Tests:** `mix test test/simpleshop_theme/images/optimizer_test.exs` +**Tests:** `mix test test/berrypod/images/optimizer_test.exs` **Manual verification:** ```elixir # In iex -S mix -alias SimpleshopTheme.Images.Optimizer +alias Berrypod.Images.Optimizer Optimizer.applicable_widths(1500) # Should return [400, 800, 1200] Optimizer.applicable_widths(300) # Should return [300] ``` @@ -873,13 +873,13 @@ Optimizer.applicable_widths(300) # Should return [300] ### Phase 4: Oban Worker **Files to create:** -- `lib/simpleshop_theme/workers/image_variants.ex` -- `test/simpleshop_theme/workers/image_variants_test.exs` +- `lib/berrypod/workers/image_variants.ex` +- `test/berrypod/workers/image_variants_test.exs` **Files to modify:** -- `lib/simpleshop_theme/application.ex` - Add Oban to supervision tree +- `lib/berrypod/application.ex` - Add Oban to supervision tree -**Tests:** `mix test test/simpleshop_theme/workers/image_variants_test.exs` +**Tests:** `mix test test/berrypod/workers/image_variants_test.exs` **Manual verification:** ```bash @@ -894,15 +894,15 @@ mix phx.server ### Phase 5: Media Module Integration **Files to modify:** -- `lib/simpleshop_theme/media.ex` - Update upload_image to use optimizer + enqueue worker +- `lib/berrypod/media.ex` - Update upload_image to use optimizer + enqueue worker -**Tests:** `mix test test/simpleshop_theme/media_test.exs` (existing tests should pass) +**Tests:** `mix test test/berrypod/media_test.exs` (existing tests should pass) **Manual verification:** 1. Go to `/admin/theme` 2. Upload a new logo image 3. Check `priv/static/image_cache/` for generated variants -4. Check database: `sqlite3 simpleshop_theme_dev.db "SELECT id, source_width, variants_status FROM images ORDER BY inserted_at DESC LIMIT 1"` +4. Check database: `sqlite3 berrypod_dev.db "SELECT id, source_width, variants_status FROM images ORDER BY inserted_at DESC LIMIT 1"` **Commit:** `feat: integrate optimizer with image uploads` @@ -911,10 +911,10 @@ mix phx.server ### Phase 6: VariantCache GenServer **Files to create:** -- `lib/simpleshop_theme/images/variant_cache.ex` +- `lib/berrypod/images/variant_cache.ex` **Files to modify:** -- `lib/simpleshop_theme/application.ex` - Add VariantCache to supervision tree +- `lib/berrypod/application.ex` - Add VariantCache to supervision tree **Tests:** Manual (startup behavior) @@ -934,12 +934,12 @@ mix phx.server ### Phase 7: Responsive Image Component **Files to create:** -- `test/simpleshop_theme_web/components/shop_components_test.exs` +- `test/berrypod_web/components/shop_components_test.exs` **Files to modify:** -- `lib/simpleshop_theme_web/components/shop_components.ex` - Add responsive_image component +- `lib/berrypod_web/components/shop_components.ex` - Add responsive_image component -**Tests:** `mix test test/simpleshop_theme_web/components/shop_components_test.exs` +**Tests:** `mix test test/berrypod_web/components/shop_components_test.exs` **Manual verification:** ```elixir @@ -954,7 +954,7 @@ mix phx.server ### Phase 8: ImageController Disk Serving **Files to modify:** -- `lib/simpleshop_theme_web/controllers/image_controller.ex` - Update thumbnail to serve from disk +- `lib/berrypod_web/controllers/image_controller.ex` - Update thumbnail to serve from disk **Tests:** Existing controller tests should pass @@ -1040,8 +1040,8 @@ ls -la priv/static/mockups/ 6. **Run tests:** ```bash - mix test test/simpleshop_theme/images/ - mix test test/simpleshop_theme/workers/ + mix test test/berrypod/images/ + mix test test/berrypod/workers/ ``` 7. **Re-run Lighthouse:** @@ -1063,12 +1063,12 @@ ls -la priv/static/mockups/ ``` test/ -├── simpleshop_theme/ +├── berrypod/ │ ├── images/ │ │ └── optimizer_test.exs # Core optimization logic │ └── workers/ │ └── image_variants_test.exs # Oban worker -├── simpleshop_theme_web/ +├── berrypod_web/ │ └── components/ │ └── shop_components_test.exs # responsive_image component ├── mix/ @@ -1085,16 +1085,16 @@ test/ **`test/support/fixtures/image_fixtures.ex`:** ```elixir -defmodule SimpleshopTheme.ImageFixtures do - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Media.Image +defmodule Berrypod.ImageFixtures do + alias Berrypod.Repo + alias Berrypod.Media.Image @sample_jpeg File.read!("test/fixtures/sample_1200x800.jpg") def sample_jpeg, do: @sample_jpeg def image_fixture(attrs \\ %{}) do - {:ok, webp, w, h} = SimpleshopTheme.Images.Optimizer.to_lossless_webp(@sample_jpeg) + {:ok, webp, w, h} = Berrypod.Images.Optimizer.to_lossless_webp(@sample_jpeg) defaults = %{ image_type: "product", @@ -1132,23 +1132,23 @@ defmodule SimpleshopTheme.ImageFixtures do def cache_path(id, width, format) do ext = if format == :jpg, do: "jpg", else: Atom.to_string(format) - Path.join(SimpleshopTheme.Images.Optimizer.cache_dir(), "#{id}-#{width}.#{ext}") + Path.join(Berrypod.Images.Optimizer.cache_dir(), "#{id}-#{width}.#{ext}") end def cleanup_cache do - cache_dir = SimpleshopTheme.Images.Optimizer.cache_dir() + cache_dir = Berrypod.Images.Optimizer.cache_dir() if File.exists?(cache_dir), do: File.rm_rf!(cache_dir) end end ``` -**`test/simpleshop_theme/images/optimizer_test.exs`:** +**`test/berrypod/images/optimizer_test.exs`:** ```elixir -defmodule SimpleshopTheme.Images.OptimizerTest do - use SimpleshopTheme.DataCase, async: false +defmodule Berrypod.Images.OptimizerTest do + use Berrypod.DataCase, async: false - alias SimpleshopTheme.Images.Optimizer - import SimpleshopTheme.ImageFixtures + alias Berrypod.Images.Optimizer + import Berrypod.ImageFixtures setup do cleanup_cache() @@ -1256,15 +1256,15 @@ defmodule SimpleshopTheme.Images.OptimizerTest do end ``` -**`test/simpleshop_theme/workers/image_variants_test.exs`:** +**`test/berrypod/workers/image_variants_test.exs`:** ```elixir -defmodule SimpleshopTheme.Workers.ImageVariantsTest do - use SimpleshopTheme.DataCase, async: false - use Oban.Testing, repo: SimpleshopTheme.Repo +defmodule Berrypod.Workers.ImageVariantsTest do + use Berrypod.DataCase, async: false + use Oban.Testing, repo: Berrypod.Repo - alias SimpleshopTheme.Workers.ImageVariants - alias SimpleshopTheme.Media.Image - import SimpleshopTheme.ImageFixtures + alias Berrypod.Workers.ImageVariants + alias Berrypod.Media.Image + import Berrypod.ImageFixtures setup do cleanup_cache() @@ -1297,13 +1297,13 @@ defmodule SimpleshopTheme.Workers.ImageVariantsTest do end ``` -**`test/simpleshop_theme_web/components/shop_components_test.exs`:** +**`test/berrypod_web/components/shop_components_test.exs`:** ```elixir -defmodule SimpleshopThemeWeb.ShopComponentsTest do - use SimpleshopThemeWeb.ConnCase, async: true +defmodule BerrypodWeb.ShopComponentsTest do + use BerrypodWeb.ConnCase, async: true import Phoenix.LiveViewTest - alias SimpleshopThemeWeb.ShopComponents + alias BerrypodWeb.ShopComponents describe "responsive_image/1" do test "builds srcset with all widths for 1200px source" do diff --git a/docs/plans/page-builder.md b/docs/plans/page-builder.md index 0a50737..f9ab750 100644 --- a/docs/plans/page-builder.md +++ b/docs/plans/page-builder.md @@ -51,7 +51,7 @@ PageRenderer module ### PageLayout Schema ```elixir -defmodule SimpleshopTheme.Content.PageLayout do +defmodule Berrypod.Content.PageLayout do use Ecto.Schema schema "page_layouts" do @@ -59,7 +59,7 @@ defmodule SimpleshopTheme.Content.PageLayout do field :name, :string # Display name for the layout field :is_default, :boolean, default: false - has_many :sections, SimpleshopTheme.Content.PageSection + has_many :sections, Berrypod.Content.PageSection timestamps() end @@ -69,7 +69,7 @@ end ### PageSection Schema ```elixir -defmodule SimpleshopTheme.Content.PageSection do +defmodule Berrypod.Content.PageSection do use Ecto.Schema schema "page_sections" do @@ -78,7 +78,7 @@ defmodule SimpleshopTheme.Content.PageSection do field :settings, :map # JSON settings for the section field :enabled, :boolean, default: true - belongs_to :page_layout, SimpleshopTheme.Content.PageLayout + belongs_to :page_layout, Berrypod.Content.PageLayout timestamps() end @@ -88,11 +88,11 @@ end ### Section Types Registry ```elixir -defmodule SimpleshopTheme.Content.SectionTypes do +defmodule Berrypod.Content.SectionTypes do @sections %{ "hero" => %{ name: "Hero Banner", - component: &SimpleshopThemeWeb.ShopComponents.hero_section/1, + component: &BerrypodWeb.ShopComponents.hero_section/1, settings_schema: %{ title: %{type: :string, default: "Welcome"}, description: %{type: :string, default: ""}, @@ -104,7 +104,7 @@ defmodule SimpleshopTheme.Content.SectionTypes do }, "featured_products" => %{ name: "Featured Products", - component: &SimpleshopThemeWeb.ShopComponents.featured_products_section/1, + component: &BerrypodWeb.ShopComponents.featured_products_section/1, settings_schema: %{ title: %{type: :string, default: "Featured products"}, product_count: %{type: :integer, default: 8} @@ -113,13 +113,13 @@ defmodule SimpleshopTheme.Content.SectionTypes do }, "category_nav" => %{ name: "Category Navigation", - component: &SimpleshopThemeWeb.ShopComponents.category_nav/1, + component: &BerrypodWeb.ShopComponents.category_nav/1, settings_schema: %{}, allowed_on: [:home] }, "image_text" => %{ name: "Image + Text Block", - component: &SimpleshopThemeWeb.ShopComponents.image_text_section/1, + component: &BerrypodWeb.ShopComponents.image_text_section/1, settings_schema: %{ title: %{type: :string}, description: %{type: :text}, @@ -131,7 +131,7 @@ defmodule SimpleshopTheme.Content.SectionTypes do }, "content_body" => %{ name: "Rich Text Content", - component: &SimpleshopThemeWeb.ShopComponents.content_body/1, + component: &BerrypodWeb.ShopComponents.content_body/1, settings_schema: %{ image_url: %{type: :image}, content: %{type: :rich_text} @@ -140,13 +140,13 @@ defmodule SimpleshopTheme.Content.SectionTypes do }, "reviews_section" => %{ name: "Customer Reviews", - component: &SimpleshopThemeWeb.ShopComponents.reviews_section/1, + component: &BerrypodWeb.ShopComponents.reviews_section/1, settings_schema: %{}, allowed_on: [:pdp] }, "related_products" => %{ name: "Related Products", - component: &SimpleshopThemeWeb.ShopComponents.related_products_section/1, + component: &BerrypodWeb.ShopComponents.related_products_section/1, settings_schema: %{}, allowed_on: [:pdp] } @@ -157,11 +157,11 @@ end ## Page Renderer ```elixir -defmodule SimpleshopThemeWeb.PageRenderer do +defmodule BerrypodWeb.PageRenderer do use Phoenix.Component - import SimpleshopThemeWeb.ShopComponents + import BerrypodWeb.ShopComponents - alias SimpleshopTheme.Content.SectionTypes + alias Berrypod.Content.SectionTypes @doc """ Renders a page from its layout and data context. @@ -394,6 +394,6 @@ Page layouts should be cached since they change infrequently: ## Related Files -- `lib/simpleshop_theme_web/components/shop_components.ex` - Existing section components -- `lib/simpleshop_theme_web/components/page_templates/` - Current static templates (will become defaults) -- `lib/simpleshop_theme_web/live/theme_live/index.ex` - Theme editor (reference implementation) +- `lib/berrypod_web/components/shop_components.ex` - Existing section components +- `lib/berrypod_web/components/page_templates/` - Current static templates (will become defaults) +- `lib/berrypod_web/live/theme_live/index.ex` - Theme editor (reference implementation) diff --git a/docs/plans/printful-integration.md b/docs/plans/printful-integration.md index 65b755f..b8daabc 100644 --- a/docs/plans/printful-integration.md +++ b/docs/plans/printful-integration.md @@ -36,7 +36,7 @@ This simplification means `provider_data` stores different fields and shipping r ### 1.1 HTTP client -**New file:** `lib/simpleshop_theme/clients/printful.ex` +**New file:** `lib/berrypod/clients/printful.ex` Same pattern as `clients/printify.ex`. Uses `Req` with Bearer token auth. @@ -70,7 +70,7 @@ API key stored in process dictionary (`Process.put(:printful_api_key, key)`) sam ### 1.2 Provider implementation -**New file:** `lib/simpleshop_theme/providers/printful.ex` +**New file:** `lib/berrypod/providers/printful.ex` Implements the `Provider` behaviour. The big difference from Printify is that Printful products don't need a "shop" — they come from the global catalogue. But orders require a store_id. @@ -173,16 +173,16 @@ Alternatively, query rates for all countries in `Shipping.@country_names` to pop ### 1.3 Wire into Provider dispatch -**File:** `lib/simpleshop_theme/providers/provider.ex` +**File:** `lib/berrypod/providers/provider.ex` Change line 97: ```elixir -defp default_for_type("printful"), do: {:ok, SimpleshopTheme.Providers.Printful} +defp default_for_type("printful"), do: {:ok, Berrypod.Providers.Printful} ``` ### 1.4 Order submission: multi-provider routing -**File:** `lib/simpleshop_theme/orders.ex` +**File:** `lib/berrypod/orders.ex` Currently `get_provider_connection/0` is hardcoded to `"printify"`. For multi-provider support, orders need to route to the correct provider based on which connection owns the product. @@ -223,7 +223,7 @@ Already covered in the client (1.1). The flow: ### 2.2 Mockup worker -**New file:** `lib/simpleshop_theme/sync/mockup_generation_worker.ex` +**New file:** `lib/berrypod/sync/mockup_generation_worker.ex` Oban worker that generates mockups for a product after sync: @@ -294,7 +294,7 @@ This works correctly with the existing calculation logic — no changes needed t ### 4.1 Webhook handler -**New file:** `lib/simpleshop_theme_web/controllers/printful_webhook_controller.ex` +**New file:** `lib/berrypod_web/controllers/printful_webhook_controller.ex` Printful webhooks POST JSON to a configured URL. Events we care about: @@ -353,22 +353,22 @@ Identical to Printify — the admin clicks "Sync" and the ProductSyncWorker runs ### New files (6) | File | Purpose | |------|---------| -| `lib/simpleshop_theme/clients/printful.ex` | HTTP client | -| `lib/simpleshop_theme/providers/printful.ex` | Provider behaviour implementation | -| `lib/simpleshop_theme/sync/mockup_generation_worker.ex` | Async mockup generation | -| `lib/simpleshop_theme_web/controllers/printful_webhook_controller.ex` | Webhook handler | -| `test/simpleshop_theme/providers/printful_test.exs` | Provider tests | -| `test/simpleshop_theme/clients/printful_test.exs` | Client tests (with Req mocking) | +| `lib/berrypod/clients/printful.ex` | HTTP client | +| `lib/berrypod/providers/printful.ex` | Provider behaviour implementation | +| `lib/berrypod/sync/mockup_generation_worker.ex` | Async mockup generation | +| `lib/berrypod_web/controllers/printful_webhook_controller.ex` | Webhook handler | +| `test/berrypod/providers/printful_test.exs` | Provider tests | +| `test/berrypod/clients/printful_test.exs` | Client tests (with Req mocking) | ### Modified files (6) | File | Change | |------|--------| -| `lib/simpleshop_theme/providers/provider.ex` | Wire `"printful"` to Printful module | -| `lib/simpleshop_theme/orders.ex` | Route to correct provider per order (not hardcoded "printify") | -| `lib/simpleshop_theme_web/router.ex` | Add Printful webhook route | +| `lib/berrypod/providers/provider.ex` | Wire `"printful"` to Printful module | +| `lib/berrypod/orders.ex` | Route to correct provider per order (not hardcoded "printify") | +| `lib/berrypod_web/router.ex` | Add Printful webhook route | | `config/config.exs` | (optional) Printful-specific config | -| `lib/simpleshop_theme/sync/product_sync_worker.ex` | Enqueue mockup generation for Printful products | -| `lib/simpleshop_theme_web/live/admin/settings.ex` | Provider form tweaks for Printful | +| `lib/berrypod/sync/product_sync_worker.ex` | Enqueue mockup generation for Printful products | +| `lib/berrypod_web/live/admin/settings.ex` | Provider form tweaks for Printful | --- @@ -399,7 +399,7 @@ Identical to Printify — the admin clicks "Sync" and the ProductSyncWorker runs ## Decisions and trade-offs -**Using sync products (not catalogue browsing):** Printful's model expects sellers to set up products in Printful's dashboard first (apply designs, choose products, set pricing). SimpleShop syncs those configured products. This matches the Printify workflow where products exist in the provider's system first. Full catalogue browsing + product creation via API is possible but significantly more complex (need artwork upload, placement positioning, pricing config) — better suited for a v2. +**Using sync products (not catalogue browsing):** Printful's model expects sellers to set up products in Printful's dashboard first (apply designs, choose products, set pricing). Berrypod syncs those configured products. This matches the Printify workflow where products exist in the provider's system first. Full catalogue browsing + product creation via API is possible but significantly more complex (need artwork upload, placement positioning, pricing config) — better suited for a v2. **Reusing ShippingRate schema fields:** `blueprint_id` and `print_provider_id` are Printify-specific names, but they serve as generic "product type ID" and "provider ID" slots. Renaming them would be a migration + touch every query. Not worth it until a third provider makes the naming confusing. diff --git a/docs/plans/printify-integration-research.md b/docs/plans/printify-integration-research.md index 5fcc98f..246facd 100644 --- a/docs/plans/printify-integration-research.md +++ b/docs/plans/printify-integration-research.md @@ -74,17 +74,17 @@ The official Shopify integration handles product identity well through SKUs. - Apply at printify.com/printify-api - ~1 week approval process -- Merchants authorize SimpleShop via OAuth +- Merchants authorize Berrypod via OAuth - We appear in Printify's publishing UI alongside Shopify/Etsy - Products get "published" TO us with lock - Webhooks for real-time updates **How publishing works in Option 2:** -1. Merchant clicks "Publish to SimpleShop" in Printify +1. Merchant clicks "Publish to Berrypod" in Printify 2. Printify sends `product:publish:started` webhook 3. We create the product on our side 4. We call `publishing_succeeded.json` to confirm -5. Product locked in Printify, shows as "Published to SimpleShop" +5. Product locked in Printify, shows as "Published to Berrypod" **Benefits of official integration:** - Publish lock prevents editing after publishing (data consistency) @@ -189,7 +189,7 @@ From Printify documentation: ### The core tension -SimpleShop exists in two forms: +Berrypod exists in two forms: 1. **Open source** - self-hosted by anyone 2. **Managed hosting** - SaaS service run by us @@ -199,7 +199,7 @@ Printify's integration options have different implications for each. **How it works:** - Each merchant creates their own Printify API token -- Token entered in SimpleShop admin +- Token entered in Berrypod admin - Direct API access, no intermediary **Open source:** ✅ Works perfectly @@ -222,7 +222,7 @@ Printify's integration options have different implications for each. ### OAuth Platform Integration **How it works:** -- Register SimpleShop as an app with Printify +- Register Berrypod as an app with Printify - Get OAuth client ID/secret - Merchants click "Connect" and authorize - We receive access tokens, appear in Printify UI @@ -270,7 +270,7 @@ Printify's integration options have different implications for each. | Webhook proxy | Depends on proxy | Full features | **Potential differentiation for managed hosting:** -- Official "Publish to SimpleShop" in Printify UI +- Official "Publish to Berrypod" in Printify UI - Real-time sync via webhooks - Publish lock (data consistency guarantee) - Pre-checkout validation (verify before order) diff --git a/docs/plans/products-context.md b/docs/plans/products-context.md index 05f1a0a..25f6867 100644 --- a/docs/plans/products-context.md +++ b/docs/plans/products-context.md @@ -14,7 +14,7 @@ Build a Products context that syncs products from external POD providers (Printi ## Current Domain Analysis -SimpleShop has **6 well-defined domains** with clear boundaries: +Berrypod has **6 well-defined domains** with clear boundaries: | Domain | Purpose | Schemas | Public Functions | |--------|---------|---------|------------------| @@ -36,12 +36,12 @@ The new **Products** context will be a new top-level domain that: ``` ┌─────────────────────────────────────────────────────────────────────────────┐ -│ SimpleshopTheme │ +│ Berrypod │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ WEB LAYER │ │ -│ │ SimpleshopThemeWeb │ │ +│ │ BerrypodWeb │ │ │ │ ┌────────────────┐ ┌────────────────┐ ┌─────────────────────────┐ │ │ │ │ │ Shop LiveViews │ │ Admin LiveViews│ │ Theme Editor LiveView │ │ │ │ │ │ - ProductShow │ │ - UserLogin │ │ - ThemeLive.Index │ │ │ @@ -299,22 +299,22 @@ Extract reusable helpers into new `Printify.Catalog` module: **Module structure:** ``` -lib/simpleshop_theme/clients/ +lib/berrypod/clients/ ├── printify.ex # Printify HTTP client (moved from printify/client.ex) ├── gelato.ex # Gelato HTTP client └── prodigi.ex # Prodigi HTTP client -lib/simpleshop_theme/providers/ +lib/berrypod/providers/ ├── provider.ex # Behaviour definition ├── printify.ex # Printify implementation (uses Clients.Printify) ├── gelato.ex # Gelato implementation (uses Clients.Gelato) └── prodigi.ex # Prodigi implementation (uses Clients.Prodigi) -lib/simpleshop_theme/mockups/ +lib/berrypod/mockups/ └── generator.ex # Mockup generation (currently uses Clients.Printify) # Provider-agnostic location for future flexibility -lib/simpleshop_theme/printify/ +lib/berrypod/printify/ └── catalog.ex # Blueprint/variant discovery helpers (Printify-specific) ``` @@ -343,7 +343,7 @@ Each provider module uses its corresponding client. The mockup generator is in a - Unique constraint: `[:provider_connection_id, :provider_product_id]` 2. **Credentials encrypted in database** - - Use `SimpleshopTheme.Vault` for at-rest encryption + - Use `Berrypod.Vault` for at-rest encryption - `api_key_encrypted`, `oauth_access_token_encrypted` fields 3. **Cost tracking for profit calculation** @@ -832,46 +832,46 @@ Add to `mix.exs`: - `*_create_admin_notifications.exs` ### Schemas -- `lib/simpleshop_theme/products/provider_connection.ex` -- `lib/simpleshop_theme/products/product.ex` -- `lib/simpleshop_theme/products/product_image.ex` -- `lib/simpleshop_theme/products/product_variant.ex` -- `lib/simpleshop_theme/orders/order.ex` -- `lib/simpleshop_theme/orders/order_fulfillment.ex` -- `lib/simpleshop_theme/orders/order_line_item.ex` -- `lib/simpleshop_theme/orders/order_event.ex` -- `lib/simpleshop_theme/admin_notifications/notification.ex` +- `lib/berrypod/products/provider_connection.ex` +- `lib/berrypod/products/product.ex` +- `lib/berrypod/products/product_image.ex` +- `lib/berrypod/products/product_variant.ex` +- `lib/berrypod/orders/order.ex` +- `lib/berrypod/orders/order_fulfillment.ex` +- `lib/berrypod/orders/order_line_item.ex` +- `lib/berrypod/orders/order_event.ex` +- `lib/berrypod/admin_notifications/notification.ex` ### Contexts -- `lib/simpleshop_theme/products.ex` - Product queries, sync logic -- `lib/simpleshop_theme/orders.ex` - Order creation, submission -- `lib/simpleshop_theme/admin_notifications.ex` - Admin notification management +- `lib/berrypod/products.ex` - Product queries, sync logic +- `lib/berrypod/orders.ex` - Order creation, submission +- `lib/berrypod/admin_notifications.ex` - Admin notification management ### Providers -- `lib/simpleshop_theme/providers/provider.ex` - Behaviour definition -- `lib/simpleshop_theme/providers/printify.ex` - Printify implementation +- `lib/berrypod/providers/provider.ex` - Behaviour definition +- `lib/berrypod/providers/printify.ex` - Printify implementation ### Workers -- `lib/simpleshop_theme/sync/product_sync_worker.ex` - Oban worker +- `lib/berrypod/sync/product_sync_worker.ex` - Oban worker ### Webhooks -- `lib/simpleshop_theme_web/controllers/webhook_controller.ex` -- `lib/simpleshop_theme/webhooks/printify_handler.ex` +- `lib/berrypod_web/controllers/webhook_controller.ex` +- `lib/berrypod/webhooks/printify_handler.ex` ### Notifiers -- `lib/simpleshop_theme_web/notifiers/customer_notifier.ex` - Customer emails +- `lib/berrypod_web/notifiers/customer_notifier.ex` - Customer emails ### Support -- `lib/simpleshop_theme/vault.ex` - Credential encryption +- `lib/berrypod/vault.ex` - Credential encryption --- ## Files to Modify -- `lib/simpleshop_theme/printify/client.ex` → Move to `lib/simpleshop_theme/clients/printify.ex` -- `lib/simpleshop_theme/printify/mockup_generator.ex` → Move to `lib/simpleshop_theme/mockups/generator.ex` -- `lib/simpleshop_theme/theme/preview_data.ex` - Query real products when available -- `lib/simpleshop_theme_web/live/shop_live/*.ex` - Use Products context instead of PreviewData +- `lib/berrypod/printify/client.ex` → Move to `lib/berrypod/clients/printify.ex` +- `lib/berrypod/printify/mockup_generator.ex` → Move to `lib/berrypod/mockups/generator.ex` +- `lib/berrypod/theme/preview_data.ex` - Query real products when available +- `lib/berrypod_web/live/shop_live/*.ex` - Use Products context instead of PreviewData --- @@ -943,10 +943,10 @@ end ``` ### Files to Create -- `lib/simpleshop_theme/admin_notifications.ex` - Admin notification context -- `lib/simpleshop_theme/admin_notifications/notification.ex` - Schema -- `lib/simpleshop_theme/orders/order_event.ex` - Customer-facing event schema -- `lib/simpleshop_theme_web/notifiers/customer_notifier.ex` - Emails +- `lib/berrypod/admin_notifications.ex` - Admin notification context +- `lib/berrypod/admin_notifications/notification.ex` - Schema +- `lib/berrypod/orders/order_event.ex` - Customer-facing event schema +- `lib/berrypod_web/notifiers/customer_notifier.ex` - Emails --- @@ -1012,15 +1012,15 @@ end **Mocking External APIs (Mox pattern):** ```elixir # test/support/mocks.ex -Mox.defmock(SimpleshopTheme.Clients.MockPrintify, for: SimpleshopTheme.Clients.PrintifyBehaviour) +Mox.defmock(Berrypod.Clients.MockPrintify, for: Berrypod.Clients.PrintifyBehaviour) # config/test.exs -config :simpleshop_theme, :printify_client, SimpleshopTheme.Clients.MockPrintify +config :berrypod, :printify_client, Berrypod.Clients.MockPrintify ``` **Oban testing:** ```elixir -use Oban.Testing, repo: SimpleshopTheme.Repo +use Oban.Testing, repo: Berrypod.Repo # Jobs run synchronously in tests via perform_job/2 ``` @@ -1049,7 +1049,7 @@ use Oban.Testing, repo: SimpleshopTheme.Repo ### Example Test Cases ```elixir -# test/simpleshop_theme/products_test.exs +# test/berrypod/products_test.exs describe "sync_products/1" do test "syncs products from provider" do conn = provider_connection_fixture() @@ -1082,7 +1082,7 @@ describe "sync_products/1" do end end -# test/simpleshop_theme/orders_test.exs +# test/berrypod/orders_test.exs describe "create_order_from_cart/1" do test "splits cart into fulfillments by provider" do printify_variant = variant_fixture(provider: :printify) @@ -1098,7 +1098,7 @@ describe "create_order_from_cart/1" do end end -# test/simpleshop_theme/sync/product_sync_worker_test.exs +# test/berrypod/sync/product_sync_worker_test.exs describe "perform/1" do test "retries on API failure" do expect(MockPrintify, :list_products, fn _ -> {:error, :timeout} end) @@ -1197,12 +1197,12 @@ live "/admin/providers/:id/edit", ProviderLive.Index, :edit | File | Purpose | |------|---------| -| `lib/simpleshop_theme_web/live/provider_live/index.ex` | LiveView for provider list + modal forms | -| `lib/simpleshop_theme_web/live/provider_live/index.html.heex` | Template | -| `lib/simpleshop_theme_web/live/provider_live/form_component.ex` | Form component for new/edit | -| `lib/simpleshop_theme/providers/printify.ex` | Add `register_webhooks/1`, `unregister_webhooks/1` | -| `lib/simpleshop_theme/workers/product_sync_worker.ex` | Stub for "Sync Now" (full impl in next task) | -| `test/simpleshop_theme_web/live/provider_live_test.exs` | LiveView tests | +| `lib/berrypod_web/live/provider_live/index.ex` | LiveView for provider list + modal forms | +| `lib/berrypod_web/live/provider_live/index.html.heex` | Template | +| `lib/berrypod_web/live/provider_live/form_component.ex` | Form component for new/edit | +| `lib/berrypod/providers/printify.ex` | Add `register_webhooks/1`, `unregister_webhooks/1` | +| `lib/berrypod/workers/product_sync_worker.ex` | Stub for "Sync Now" (full impl in next task) | +| `test/berrypod_web/live/provider_live_test.exs` | LiveView tests | ### UI Design @@ -1264,11 +1264,11 @@ Single-page admin with modal for add/edit (follows Phoenix generator pattern): **Index LiveView (`provider_live/index.ex`):** ```elixir -defmodule SimpleshopThemeWeb.ProviderLive.Index do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.ProviderLive.Index do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProviderConnection + alias Berrypod.Products + alias Berrypod.Products.ProviderConnection @impl true def mount(_params, _session, socket) do @@ -1300,7 +1300,7 @@ defmodule SimpleshopThemeWeb.ProviderLive.Index do end @impl true - def handle_info({SimpleshopThemeWeb.ProviderLive.FormComponent, {:saved, connection}}, socket) do + def handle_info({BerrypodWeb.ProviderLive.FormComponent, {:saved, connection}}, socket) do {:noreply, stream_insert(socket, :connections, connection)} end @@ -1351,7 +1351,7 @@ end defp test_provider_connection("printify", api_key) do # Build temporary connection struct for testing conn = %ProviderConnection{provider_type: "printify", api_key: api_key} - SimpleshopTheme.Providers.Printify.test_connection(conn) + Berrypod.Providers.Printify.test_connection(conn) end ``` @@ -1404,7 +1404,7 @@ def handle_event("save", %{"provider" => params}, socket) do end defp register_webhooks(%{provider_type: "printify"} = conn) do - SimpleshopTheme.Providers.Printify.register_webhooks(conn) + Berrypod.Providers.Printify.register_webhooks(conn) end ``` @@ -1422,7 +1422,7 @@ def handle_event("delete", %{"id" => id}, socket) do end defp unregister_webhooks(%{provider_type: "printify"} = conn) do - SimpleshopTheme.Providers.Printify.unregister_webhooks(conn) + Berrypod.Providers.Printify.unregister_webhooks(conn) end ``` @@ -1432,7 +1432,7 @@ end @webhook_topics ~w(product:publish:started product:deleted shop:disconnected) def register_webhooks(conn) do - webhook_url = SimpleshopThemeWeb.Endpoint.url() <> "/webhooks/printify" + webhook_url = BerrypodWeb.Endpoint.url() <> "/webhooks/printify" shop_id = get_shop_id(conn) results = Enum.map(@webhook_topics, fn topic -> @@ -1455,7 +1455,7 @@ def unregister_webhooks(conn) do # List existing webhooks and delete ours case Client.get(conn, "/shops/#{shop_id}/webhooks.json") do {:ok, %{"webhooks" => webhooks}} -> - our_url = SimpleshopThemeWeb.Endpoint.url() <> "/webhooks/printify" + our_url = BerrypodWeb.Endpoint.url() <> "/webhooks/printify" webhooks |> Enum.filter(&(&1["url"] == our_url)) @@ -1504,7 +1504,7 @@ Template snippet: ### Context Additions -Add to `lib/simpleshop_theme/products.ex`: +Add to `lib/berrypod/products.ex`: ```elixir @doc """ @@ -1513,7 +1513,7 @@ Returns {:ok, job} or {:error, changeset}. """ def enqueue_sync(%ProviderConnection{} = conn) do %{connection_id: conn.id} - |> SimpleshopTheme.Workers.ProductSyncWorker.new() + |> Berrypod.Workers.ProductSyncWorker.new() |> Oban.insert() end @@ -1543,7 +1543,7 @@ end ### Testing ```elixir -# test/simpleshop_theme_web/live/provider_live_test.exs +# test/berrypod_web/live/provider_live_test.exs describe "Index" do setup :register_and_log_in_user @@ -1619,25 +1619,25 @@ Implement a robust product sync strategy with three mechanisms: | File | Purpose | |------|---------| -| `lib/simpleshop_theme/workers/product_sync_worker.ex` | Oban worker for full/single product sync | -| `lib/simpleshop_theme_web/controllers/webhook_controller.ex` | Receives webhooks from providers | -| `lib/simpleshop_theme/webhooks/printify_handler.ex` | Printify-specific webhook processing | -| `test/simpleshop_theme/workers/product_sync_worker_test.exs` | Worker tests | -| `test/simpleshop_theme_web/controllers/webhook_controller_test.exs` | Webhook endpoint tests | +| `lib/berrypod/workers/product_sync_worker.ex` | Oban worker for full/single product sync | +| `lib/berrypod_web/controllers/webhook_controller.ex` | Receives webhooks from providers | +| `lib/berrypod/webhooks/printify_handler.ex` | Printify-specific webhook processing | +| `test/berrypod/workers/product_sync_worker_test.exs` | Worker tests | +| `test/berrypod_web/controllers/webhook_controller_test.exs` | Webhook endpoint tests | ### Part 1: ProductSyncWorker (~1hr) Oban worker that syncs products from a provider connection. ```elixir -defmodule SimpleshopTheme.Workers.ProductSyncWorker do +defmodule Berrypod.Workers.ProductSyncWorker do use Oban.Worker, queue: :sync, max_attempts: 3, unique: [period: 60, fields: [:args, :queue]] - alias SimpleshopTheme.Products - alias SimpleshopTheme.Providers + alias Berrypod.Products + alias Berrypod.Providers @impl Oban.Worker def perform(%Oban.Job{args: %{"connection_id" => conn_id} = args}) do @@ -1714,10 +1714,10 @@ post "/webhooks/printify", WebhookController, :printify **Controller:** ```elixir -defmodule SimpleshopThemeWeb.WebhookController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.WebhookController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Webhooks.PrintifyHandler + alias Berrypod.Webhooks.PrintifyHandler def printify(conn, params) do with :ok <- verify_printify_signature(conn), @@ -1737,7 +1737,7 @@ defmodule SimpleshopThemeWeb.WebhookController do # Header: X-Printify-Signature signature = get_req_header(conn, "x-printify-signature") |> List.first() body = conn.assigns[:raw_body] - secret = Application.get_env(:simpleshop_theme, :printify_webhook_secret) + secret = Application.get_env(:berrypod, :printify_webhook_secret) expected = :crypto.mac(:hmac, :sha256, secret, body) |> Base.encode16(case: :lower) @@ -1752,9 +1752,9 @@ end **Handler:** ```elixir -defmodule SimpleshopTheme.Webhooks.PrintifyHandler do - alias SimpleshopTheme.Products - alias SimpleshopTheme.Workers.ProductSyncWorker +defmodule Berrypod.Webhooks.PrintifyHandler do + alias Berrypod.Products + alias Berrypod.Workers.ProductSyncWorker def handle(%{"type" => "product:publish:started", "resource" => resource}) do %{"shop_id" => shop_id, "id" => product_id} = resource @@ -1800,16 +1800,16 @@ end Add to Oban config for daily fallback: ```elixir # In config/config.exs -config :simpleshop_theme, Oban, +config :berrypod, Oban, plugins: [ {Oban.Plugins.Cron, crontab: [ - {"0 3 * * *", SimpleshopTheme.Workers.ScheduledSyncWorker} # 3 AM daily + {"0 3 * * *", Berrypod.Workers.ScheduledSyncWorker} # 3 AM daily ]} ] ``` ```elixir -defmodule SimpleshopTheme.Workers.ScheduledSyncWorker do +defmodule Berrypod.Workers.ScheduledSyncWorker do use Oban.Worker, queue: :sync def perform(_job) do @@ -1827,7 +1827,7 @@ end ### Context Additions -Add to `lib/simpleshop_theme/products.ex`: +Add to `lib/berrypod/products.ex`: ```elixir def archive_product_by_provider(connection_id, provider_product_id) do diff --git a/docs/plans/provider-strategy.md b/docs/plans/provider-strategy.md index b48c89a..f31d5ee 100644 --- a/docs/plans/provider-strategy.md +++ b/docs/plans/provider-strategy.md @@ -2,7 +2,7 @@ **Status:** Reference (research notes from Feb 2025) -Research session exploring multi-provider strategy for SimpleShop. Goal: identify the best additional POD providers to complement Printify, with a focus on UK fulfilment coverage. +Research session exploring multi-provider strategy for Berrypod. Goal: identify the best additional POD providers to complement Printify, with a focus on UK fulfilment coverage. --- @@ -104,7 +104,7 @@ Net cost is comparable across providers for UK delivery. Prodigi's higher base c ### Phase 1: Add Printful (revised winner) -Original analysis recommended Prodigi for UK coverage (9/10 types). But Prodigi has a critical gap: **no mockup generation API**. Sellers would need to manually create and upload product mockups, which is too much friction for SimpleShop's target audience. +Original analysis recommended Prodigi for UK coverage (9/10 types). But Prodigi has a critical gap: **no mockup generation API**. Sellers would need to manually create and upload product mockups, which is too much friction for Berrypod's target audience. Printful wins because: - **Mockup generation API** — dedicated async endpoint, generates mockups on actual product blanks @@ -166,7 +166,7 @@ The existing codebase already supports multi-provider through: - **`Provider.for_type/1`** dispatch (currently Printify-only, extensible via app env) Adding Prodigi requires: -1. `lib/simpleshop_theme/clients/prodigi.ex` — HTTP client -2. `lib/simpleshop_theme/providers/prodigi.ex` — Provider behaviour implementation +1. `lib/berrypod/clients/prodigi.ex` — HTTP client +2. `lib/berrypod/providers/prodigi.ex` — Provider behaviour implementation 3. Migration: update provider_connections to support "prodigi" type 4. Admin UI: provider selection during setup diff --git a/docs/plans/search.md b/docs/plans/search.md index de83308..bd9ccfc 100644 --- a/docs/plans/search.md +++ b/docs/plans/search.md @@ -15,7 +15,7 @@ Product maps have: `.name`, `.category`, `.description`, `.slug`, `.price`, `.im ## Changes ### 1. CartHook — add search assigns + event handler -**File:** `lib/simpleshop_theme_web/cart_hook.ex` +**File:** `lib/berrypod_web/cart_hook.ex` - Init assigns in `on_mount`: `search_results: []`, `search_query: ""` - Handle `"search"` event (from `phx-keyup`): @@ -24,7 +24,7 @@ Product maps have: `.name`, `.category`, `.description`, `.slug`, `.price`, `.im - Handle `"close_search"` event → clear query + results + hide modal via JS ### 2. shop_layout + search_modal — add search attrs and UI -**File:** `lib/simpleshop_theme_web/components/shop_components/layout.ex` +**File:** `lib/berrypod_web/components/shop_components/layout.ex` **shop_layout:** - Add optional attrs: `search_results` (default `[]`), `search_query` (default `""`) @@ -41,7 +41,7 @@ Product maps have: `.name`, `.category`, `.description`, `.slug`, `.price`, `.im - Click on result: navigate to product, close modal (JS.hide + close_search event) ### 3. Page templates — thread search assigns -**All 8 files in** `lib/simpleshop_theme_web/components/page_templates/` +**All 8 files in** `lib/berrypod_web/components/page_templates/` Add two lines to each `<.shop_layout>` call: ``` @@ -52,9 +52,9 @@ search_query={assigns[:search_query] || ""} Same pattern as `cart_drawer_open` and `cart_status`. ## Files to modify -1. `lib/simpleshop_theme_web/cart_hook.ex` -2. `lib/simpleshop_theme_web/components/shop_components/layout.ex` (shop_layout + search_modal) -3. All 8 page templates in `lib/simpleshop_theme_web/components/page_templates/` +1. `lib/berrypod_web/cart_hook.ex` +2. `lib/berrypod_web/components/shop_components/layout.ex` (shop_layout + search_modal) +3. All 8 page templates in `lib/berrypod_web/components/page_templates/` ## Verification - Browser: open search modal on multiple pages, type queries, verify results appear and link correctly diff --git a/docs/plans/setup-wizard.md b/docs/plans/setup-wizard.md index c070dc6..3a8e2f8 100644 --- a/docs/plans/setup-wizard.md +++ b/docs/plans/setup-wizard.md @@ -28,7 +28,7 @@ This plan covers the first piece. The other two are separate tasks that build on ## Design: single-admin, closed registration -SimpleShop is single-tenant: one shop, one admin. The setup wizard replaces the generic registration flow entirely. +Berrypod is single-tenant: one shop, one admin. The setup wizard replaces the generic registration flow entirely. ### Fresh install flow @@ -62,28 +62,28 @@ The setup wizard checks three things before allowing "go live": | Step | How to check | Module/function | |------|-------------|-----------------| -| Printify connected | `Products.get_provider_connection_by_type("printify")` returns a connection with a non-nil `api_key_encrypted` | `SimpleshopTheme.Products` | -| Products synced | `Products.count_products_for_connection(conn.id) > 0` | `SimpleshopTheme.Products` | -| Stripe connected | `Settings.has_secret?("stripe_api_key")` | `SimpleshopTheme.Settings` | +| Printify connected | `Products.get_provider_connection_by_type("printify")` returns a connection with a non-nil `api_key_encrypted` | `Berrypod.Products` | +| Products synced | `Products.count_products_for_connection(conn.id) > 0` | `Berrypod.Products` | +| Stripe connected | `Settings.has_secret?("stripe_api_key")` | `Berrypod.Settings` | Optional (nice-to-have, not blocking go-live): - Stripe webhook configured: `Settings.has_secret?("stripe_webhook_signing_secret")` -- Shop name customised: `theme_settings.site_name != "SimpleShop"` (or similar default check) +- Shop name customised: `theme_settings.site_name != "Berrypod"` (or similar default check) ## Changes ### 1. `Accounts.has_admin?/0` and registration lockdown -**File:** `lib/simpleshop_theme/accounts.ex` +**File:** `lib/berrypod/accounts.ex` - Add `has_admin?/0` — `Repo.exists?(User)` (any user = admin exists) - This is the single check that gates registration -**File:** `lib/simpleshop_theme_web/live/user_live/registration.ex` +**File:** `lib/berrypod_web/live/user_live/registration.ex` - In `mount/3`, check `Accounts.has_admin?()` — if true, redirect to `/users/log-in` with a flash like "Registration is closed" -**File:** `lib/simpleshop_theme_web/router.ex` +**File:** `lib/berrypod_web/router.ex` - No route changes needed yet — the LiveView mount handles the redirect @@ -91,14 +91,14 @@ Optional (nice-to-have, not blocking go-live): ### 2. Add `site_live` setting and setup status -**File:** `lib/simpleshop_theme/settings.ex` +**File:** `lib/berrypod/settings.ex` - Add `site_live?/0` — reads `get_setting("shop", "site_live")`, returns boolean (default `false`) - Add `set_site_live/1` — writes `put_setting("shop", "site_live", value)` No migration needed — settings table already stores arbitrary key/value pairs. -**File:** `lib/simpleshop_theme/setup.ex` (new module) +**File:** `lib/berrypod/setup.ex` (new module) - `setup_status/0` returns a map: ```elixir @@ -118,24 +118,24 @@ No migration needed — settings table already stores arbitrary key/value pairs. ### 3. Fresh install redirect (no admin exists) -**File:** `lib/simpleshop_theme_web/hooks/theme_hook.ex` +**File:** `lib/berrypod_web/hooks/theme_hook.ex` ThemeHook already runs on every public shop page mount. Add early check: - If `Accounts.has_admin?()` is false → redirect to `/setup` - This catches the fresh install case before any other logic runs -**File:** `lib/simpleshop_theme_web/live/setup_live.ex` (new) +**File:** `lib/berrypod_web/live/setup_live.ex` (new) A simple public LiveView at `/setup` that: - If admin already exists → redirect to `/users/log-in` -- If no admin → show "Welcome to SimpleShop" with email input form +- If no admin → show "Welcome to Berrypod" with email input form - On submit → calls `Accounts.register_user/1` and sends magic link - Shows "Check your email" confirmation This reuses the existing registration logic but with a different UI (setup-focused, not generic registration). -**File:** `lib/simpleshop_theme_web/router.ex` +**File:** `lib/berrypod_web/router.ex` - Add `/setup` route in a minimal live_session (no ThemeHook, no CartHook — avoids the redirect loop) @@ -143,20 +143,20 @@ This reuses the existing registration logic but with a different UI (setup-focus ### 4. "Coming soon" page for public visitors -**File:** `lib/simpleshop_theme_web/hooks/theme_hook.ex` +**File:** `lib/berrypod_web/hooks/theme_hook.ex` Extend the ThemeHook logic (after the fresh install check): - If `site_live?()` is false AND user is not authenticated → redirect to `/coming-soon` -**File:** `lib/simpleshop_theme_web/live/shop_live/coming_soon.ex` (new) +**File:** `lib/berrypod_web/live/shop_live/coming_soon.ex` (new) Minimal LiveView: - Uses the shop root layout (gets theme styling) but no nav/footer - Shows site name/logo, "Coming soon" heading, optional tagline - No redirect loop — this page itself doesn't trigger the gate -**File:** `lib/simpleshop_theme_web/router.ex` +**File:** `lib/berrypod_web/router.ex` - Add `/coming-soon` route in the public shop live_session but mark it as exempt from the gate (via assign or separate handling in ThemeHook) @@ -164,7 +164,7 @@ Minimal LiveView: ### 5. Admin setup checklist page -**File:** `lib/simpleshop_theme_web/live/admin/setup_live.ex` (new) +**File:** `lib/berrypod_web/live/admin/setup_live.ex` (new) Admin page at `/admin/setup` showing: @@ -177,7 +177,7 @@ Admin page at `/admin/setup` showing: Each step shows what to do and links to where to do it. Feels like guided onboarding, not a settings dump. **Files:** -- `lib/simpleshop_theme_web/live/admin/setup_live.ex` +- `lib/berrypod_web/live/admin/setup_live.ex` - Router update to add the route - Admin nav update to include "Setup" link (prominent when not live) @@ -185,7 +185,7 @@ Each step shows what to do and links to where to do it. Feels like guided onboar ### 6. Admin bar "not live" indicator -**File:** `lib/simpleshop_theme_web/components/shop_components/layout.ex` +**File:** `lib/berrypod_web/components/shop_components/layout.ex` - When shop is not live, show a banner in the admin bar: "Your shop is not live — [Complete setup →]" - When shop is live, the setup page becomes a less prominent settings link @@ -194,7 +194,7 @@ Each step shows what to do and links to where to do it. Feels like guided onboar ### 7. Post-login redirect for fresh admin -**File:** `lib/simpleshop_theme_web/user_auth.ex` +**File:** `lib/berrypod_web/user_auth.ex` - After confirming magic link (first login ever), redirect to `/admin/setup` instead of `/` - Subsequent logins go to `/` as normal (or `/admin/setup` if not live yet) diff --git a/docs/plans/shipping-sync.md b/docs/plans/shipping-sync.md index 49ec1fb..227532c 100644 --- a/docs/plans/shipping-sync.md +++ b/docs/plans/shipping-sync.md @@ -24,7 +24,7 @@ Fetch shipping rates from Printify during product sync, cache them in DB, displa ## 1. Migration + schema: `shipping_rates` -**New file:** `lib/simpleshop_theme/shipping/shipping_rate.ex` +**New file:** `lib/berrypod/shipping/shipping_rate.ex` ``` shipping_rates table: @@ -53,7 +53,7 @@ Update `Order` changeset to cast `:shipping_cost`. Update `total` calculation: ` ## 3. Provider behaviour: add `fetch_shipping_rates/2` -**File:** `lib/simpleshop_theme/providers/provider.ex` +**File:** `lib/berrypod/providers/provider.ex` ```elixir @callback fetch_shipping_rates(ProviderConnection.t(), products :: [map()]) :: @@ -66,7 +66,7 @@ Use `@optional_callbacks [fetch_shipping_rates: 2]` — the sync worker checks ` ## 4. Printify implementation -**File:** `lib/simpleshop_theme/providers/printify.ex` +**File:** `lib/berrypod/providers/printify.ex` New function `fetch_shipping_rates/2`: @@ -90,7 +90,7 @@ New function `fetch_shipping_rates/2`: ## 5. Shipping context -**New file:** `lib/simpleshop_theme/shipping.ex` +**New file:** `lib/berrypod/shipping.ex` Functions: - `upsert_rates(provider_connection_id, rates)` — bulk upsert via `Repo.insert_all` with `on_conflict: :replace` @@ -108,7 +108,7 @@ Functions: ## 6. Wire shipping into ProductSyncWorker -**File:** `lib/simpleshop_theme/sync/product_sync_worker.ex` +**File:** `lib/berrypod/sync/product_sync_worker.ex` In `do_sync_products/1`, after `sync_all_products(conn, products)` and before `update_sync_status(conn, "completed", ...)` (line 99), add: @@ -120,7 +120,7 @@ Private function wraps `provider.fetch_shipping_rates(conn, products)` → `Ship ## 7. Scheduled sync worker -**New file:** `lib/simpleshop_theme/sync/scheduled_sync_worker.ex` +**New file:** `lib/berrypod/sync/scheduled_sync_worker.ex` ```elixir use Oban.Worker, queue: :sync, max_attempts: 1 @@ -130,14 +130,14 @@ Calls `Products.list_provider_connections()`, filters enabled, enqueues `Product **Oban cron config** (`config/config.exs`): ```elixir -{"0 */6 * * *", SimpleshopTheme.Sync.ScheduledSyncWorker} +{"0 */6 * * *", Berrypod.Sync.ScheduledSyncWorker} ``` Every 6 hours. `:sync` queue concurrency 1 serialises with manual syncs. ## 8. Checkout: Stripe shipping_options -**File:** `lib/simpleshop_theme_web/controllers/checkout_controller.ex` +**File:** `lib/berrypod_web/controllers/checkout_controller.ex` Calculate shipping for GB (domestic) and US (international representative). Build `shipping_options` with inline `shipping_rate_data`: @@ -156,13 +156,13 @@ shipping_options: [ If no rates found, omit `shipping_options` (current behaviour preserved). -**File:** `lib/simpleshop_theme_web/controllers/stripe_webhook_controller.ex` +**File:** `lib/berrypod_web/controllers/stripe_webhook_controller.ex` On `checkout.session.completed`, extract `session.shipping_cost.amount_total` and update order's `shipping_cost` and `total`. ## 9. Country detection plug -**New file:** `lib/simpleshop_theme_web/plugs/country_detect.ex` +**New file:** `lib/berrypod_web/plugs/country_detect.ex` Simple plug that runs on the `:browser` pipeline: 1. Check session for existing `country_code` — if present, skip @@ -174,11 +174,11 @@ LiveViews read it from the session in `mount/3` via `get_session(session, "count ## 10. Cart display -**File:** `lib/simpleshop_theme_web/live/shop/cart.ex` +**File:** `lib/berrypod_web/live/shop/cart.ex` Read `country_code` from session (default `"GB"`). Add `shipping_estimate` assign on mount using `Shipping.calculate_for_cart(cart_items, country_code)`. -**File:** `lib/simpleshop_theme_web/components/shop_components/cart.ex` +**File:** `lib/berrypod_web/components/shop_components/cart.ex` Update `order_summary` component — add `attr :shipping_estimate, :integer, default: nil`: - Non-nil → show `"From #{format_price(shipping_estimate)}"` + total includes estimate @@ -194,23 +194,23 @@ Cart drawer unchanged (compact view, no shipping detail). |------|--------| | `priv/repo/migrations/..._create_shipping_rates.exs` | New migration | | `priv/repo/migrations/..._add_shipping_cost_to_orders.exs` | New migration | -| `lib/simpleshop_theme/shipping/shipping_rate.ex` | New schema | -| `lib/simpleshop_theme/shipping.ex` | New context | -| `lib/simpleshop_theme/providers/provider.ex` | Add optional callback | -| `lib/simpleshop_theme/providers/printify.ex` | Implement `fetch_shipping_rates/2` | -| `lib/simpleshop_theme/sync/product_sync_worker.ex` | Wire shipping into sync | -| `lib/simpleshop_theme/sync/scheduled_sync_worker.ex` | New Oban cron worker | +| `lib/berrypod/shipping/shipping_rate.ex` | New schema | +| `lib/berrypod/shipping.ex` | New context | +| `lib/berrypod/providers/provider.ex` | Add optional callback | +| `lib/berrypod/providers/printify.ex` | Implement `fetch_shipping_rates/2` | +| `lib/berrypod/sync/product_sync_worker.ex` | Wire shipping into sync | +| `lib/berrypod/sync/scheduled_sync_worker.ex` | New Oban cron worker | | `config/config.exs` | Add ScheduledSyncWorker to crontab | -| `lib/simpleshop_theme/orders/order.ex` | Add `shipping_cost` field | -| `lib/simpleshop_theme/orders.ex` | Cast shipping_cost, update total logic | -| `lib/simpleshop_theme/products.ex` | Add `get_variants_with_products/1` | -| `lib/simpleshop_theme_web/controllers/checkout_controller.ex` | Stripe shipping_options | -| `lib/simpleshop_theme_web/controllers/stripe_webhook_controller.ex` | Extract shipping from Stripe | -| `lib/simpleshop_theme_web/plugs/country_detect.ex` | New plug: country from Accept-Language | -| `lib/simpleshop_theme_web/router.ex` | Add CountryDetect to `:browser` pipeline | -| `lib/simpleshop_theme_web/live/shop/cart.ex` | Shipping estimate assign + country from session | -| `lib/simpleshop_theme_web/components/shop_components/cart.ex` | Display estimate | -| `lib/simpleshop_theme_web/components/page_templates/cart.html.heex` | Pass shipping_estimate | +| `lib/berrypod/orders/order.ex` | Add `shipping_cost` field | +| `lib/berrypod/orders.ex` | Cast shipping_cost, update total logic | +| `lib/berrypod/products.ex` | Add `get_variants_with_products/1` | +| `lib/berrypod_web/controllers/checkout_controller.ex` | Stripe shipping_options | +| `lib/berrypod_web/controllers/stripe_webhook_controller.ex` | Extract shipping from Stripe | +| `lib/berrypod_web/plugs/country_detect.ex` | New plug: country from Accept-Language | +| `lib/berrypod_web/router.ex` | Add CountryDetect to `:browser` pipeline | +| `lib/berrypod_web/live/shop/cart.ex` | Shipping estimate assign + country from session | +| `lib/berrypod_web/components/shop_components/cart.ex` | Display estimate | +| `lib/berrypod_web/components/page_templates/cart.html.heex` | Pass shipping_estimate | **New files:** 5 (schema, context, worker, plug, 2 migrations) **Modified files:** 14 diff --git a/docs/research/design-philosophy.md b/docs/research/design-philosophy.md index 1d13244..323056f 100644 --- a/docs/research/design-philosophy.md +++ b/docs/research/design-philosophy.md @@ -1,4 +1,4 @@ -# SimpleshopTheme Design Philosophy +# Berrypod Design Philosophy This document captures the design principles and research that informed the theme system architecture. diff --git a/fly.toml b/fly.toml index bf11a25..52413f9 100644 --- a/fly.toml +++ b/fly.toml @@ -1,20 +1,20 @@ -# fly.toml app configuration file generated for simpleshop-theme on 2026-02-08T20:51:20Z +# fly.toml app configuration file generated for berrypod on 2026-02-08T20:51:20Z # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # -app = 'simpleshop-theme' +app = 'berrypod' primary_region = 'lhr' [build] dockerfile = 'Dockerfile' [env] - DATABASE_PATH = '/data/simpleshop_theme.db' + DATABASE_PATH = '/data/berrypod.db' PHX_SERVER = 'true' [[mounts]] - source = 'simpleshop_data' + source = 'berrypod_data' destination = '/data' [http_service] diff --git a/lib/simpleshop_theme.ex b/lib/berrypod.ex similarity index 66% rename from lib/simpleshop_theme.ex rename to lib/berrypod.ex index c13a515..733a70e 100644 --- a/lib/simpleshop_theme.ex +++ b/lib/berrypod.ex @@ -1,6 +1,6 @@ -defmodule SimpleshopTheme do +defmodule Berrypod do @moduledoc """ - SimpleshopTheme keeps the contexts that define your domain + Berrypod keeps the contexts that define your domain and business logic. Contexts are also responsible for managing your data, regardless diff --git a/lib/simpleshop_theme/accounts.ex b/lib/berrypod/accounts.ex similarity index 95% rename from lib/simpleshop_theme/accounts.ex rename to lib/berrypod/accounts.ex index ef7dcab..9cacfef 100644 --- a/lib/simpleshop_theme/accounts.ex +++ b/lib/berrypod/accounts.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopTheme.Accounts do +defmodule Berrypod.Accounts do @moduledoc """ The Accounts context. """ import Ecto.Query, warn: false - alias SimpleshopTheme.Repo + alias Berrypod.Repo - alias SimpleshopTheme.Accounts.{User, UserToken, UserNotifier} + alias Berrypod.Accounts.{User, UserToken, UserNotifier} ## Database getters @@ -63,7 +63,7 @@ defmodule SimpleshopTheme.Accounts do @doc """ Returns whether an admin user exists. - SimpleShop is single-tenant — any user in the database is the admin. + Berrypod is single-tenant — any user in the database is the admin. """ def has_admin? do Repo.exists?(User) @@ -108,7 +108,7 @@ defmodule SimpleshopTheme.Accounts do @doc """ Returns an `%Ecto.Changeset{}` for changing the user email. - See `SimpleshopTheme.Accounts.User.email_changeset/3` for a list of supported options. + See `Berrypod.Accounts.User.email_changeset/3` for a list of supported options. ## Examples @@ -144,7 +144,7 @@ defmodule SimpleshopTheme.Accounts do @doc """ Returns an `%Ecto.Changeset{}` for changing the user password. - See `SimpleshopTheme.Accounts.User.password_changeset/3` for a list of supported options. + See `Berrypod.Accounts.User.password_changeset/3` for a list of supported options. ## Examples diff --git a/lib/simpleshop_theme/accounts/scope.ex b/lib/berrypod/accounts/scope.ex similarity index 84% rename from lib/simpleshop_theme/accounts/scope.ex rename to lib/berrypod/accounts/scope.ex index e34603a..32551d8 100644 --- a/lib/simpleshop_theme/accounts/scope.ex +++ b/lib/berrypod/accounts/scope.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopTheme.Accounts.Scope do +defmodule Berrypod.Accounts.Scope do @moduledoc """ Defines the scope of the caller to be used throughout the app. - The `SimpleshopTheme.Accounts.Scope` allows public interfaces to receive + The `Berrypod.Accounts.Scope` allows public interfaces to receive information about the caller, such as if the call is initiated from an end-user, and if so, which user. Additionally, such a scope can carry fields such as "super user" or other privileges for use as authorization, or to @@ -16,7 +16,7 @@ defmodule SimpleshopTheme.Accounts.Scope do growing application requirements. """ - alias SimpleshopTheme.Accounts.User + alias Berrypod.Accounts.User defstruct user: nil diff --git a/lib/simpleshop_theme/accounts/user.ex b/lib/berrypod/accounts/user.ex similarity index 95% rename from lib/simpleshop_theme/accounts/user.ex rename to lib/berrypod/accounts/user.ex index fea0cc5..67ffb90 100644 --- a/lib/simpleshop_theme/accounts/user.ex +++ b/lib/berrypod/accounts/user.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Accounts.User do +defmodule Berrypod.Accounts.User do use Ecto.Schema import Ecto.Changeset @@ -42,7 +42,7 @@ defmodule SimpleshopTheme.Accounts.User do if Keyword.get(opts, :validate_unique, true) do changeset - |> unsafe_validate_unique(:email, SimpleshopTheme.Repo) + |> unsafe_validate_unique(:email, Berrypod.Repo) |> unique_constraint(:email) |> validate_email_changed() else @@ -122,7 +122,7 @@ defmodule SimpleshopTheme.Accounts.User do If there is no user or the user doesn't have a password, we call `Bcrypt.no_user_verify/0` to avoid timing attacks. """ - def valid_password?(%SimpleshopTheme.Accounts.User{hashed_password: hashed_password}, password) + def valid_password?(%Berrypod.Accounts.User{hashed_password: hashed_password}, password) when is_binary(hashed_password) and byte_size(password) > 0 do Bcrypt.verify_pass(password, hashed_password) end diff --git a/lib/simpleshop_theme/accounts/user_notifier.ex b/lib/berrypod/accounts/user_notifier.ex similarity index 90% rename from lib/simpleshop_theme/accounts/user_notifier.ex rename to lib/berrypod/accounts/user_notifier.ex index 7c94c75..7501f87 100644 --- a/lib/simpleshop_theme/accounts/user_notifier.ex +++ b/lib/berrypod/accounts/user_notifier.ex @@ -1,15 +1,15 @@ -defmodule SimpleshopTheme.Accounts.UserNotifier do +defmodule Berrypod.Accounts.UserNotifier do import Swoosh.Email - alias SimpleshopTheme.Mailer - alias SimpleshopTheme.Accounts.User + alias Berrypod.Mailer + alias Berrypod.Accounts.User # Delivers the email using the application mailer. defp deliver(recipient, subject, body) do email = new() |> to(recipient) - |> from({"SimpleshopTheme", "contact@example.com"}) + |> from({"Berrypod", "contact@example.com"}) |> subject(subject) |> text_body(body) diff --git a/lib/simpleshop_theme/accounts/user_token.ex b/lib/berrypod/accounts/user_token.ex similarity index 97% rename from lib/simpleshop_theme/accounts/user_token.ex rename to lib/berrypod/accounts/user_token.ex index 0cad9b7..07cb495 100644 --- a/lib/simpleshop_theme/accounts/user_token.ex +++ b/lib/berrypod/accounts/user_token.ex @@ -1,7 +1,7 @@ -defmodule SimpleshopTheme.Accounts.UserToken do +defmodule Berrypod.Accounts.UserToken do use Ecto.Schema import Ecto.Query - alias SimpleshopTheme.Accounts.UserToken + alias Berrypod.Accounts.UserToken @hash_algorithm :sha256 @rand_size 32 @@ -19,7 +19,7 @@ defmodule SimpleshopTheme.Accounts.UserToken do field :context, :string field :sent_to, :string field :authenticated_at, :utc_datetime - belongs_to :user, SimpleshopTheme.Accounts.User + belongs_to :user, Berrypod.Accounts.User timestamps(type: :utc_datetime, updated_at: false) end diff --git a/lib/simpleshop_theme/application.ex b/lib/berrypod/application.ex similarity index 55% rename from lib/simpleshop_theme/application.ex rename to lib/berrypod/application.ex index 21abd2e..e13cd3a 100644 --- a/lib/simpleshop_theme/application.ex +++ b/lib/berrypod/application.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Application do +defmodule Berrypod.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications @moduledoc false @@ -8,29 +8,29 @@ defmodule SimpleshopTheme.Application do @impl true def start(_type, _args) do children = [ - SimpleshopThemeWeb.Telemetry, - SimpleshopTheme.Repo, + BerrypodWeb.Telemetry, + Berrypod.Repo, {Ecto.Migrator, - repos: Application.fetch_env!(:simpleshop_theme, :ecto_repos), skip: skip_migrations?()}, + repos: Application.fetch_env!(:berrypod, :ecto_repos), skip: skip_migrations?()}, # Seed default theme settings if none exist (first boot) - Supervisor.child_spec({Task, &SimpleshopTheme.Release.seed_defaults/0}, id: :seed_defaults), + Supervisor.child_spec({Task, &Berrypod.Release.seed_defaults/0}, id: :seed_defaults), # Load encrypted secrets from DB into Application env - {Task, &SimpleshopTheme.Secrets.load_all/0}, - {DNSCluster, query: Application.get_env(:simpleshop_theme, :dns_cluster_query) || :ignore}, - {Phoenix.PubSub, name: SimpleshopTheme.PubSub}, + {Task, &Berrypod.Secrets.load_all/0}, + {DNSCluster, query: Application.get_env(:berrypod, :dns_cluster_query) || :ignore}, + {Phoenix.PubSub, name: Berrypod.PubSub}, # Background job processing - {Oban, Application.fetch_env!(:simpleshop_theme, Oban)}, + {Oban, Application.fetch_env!(:berrypod, Oban)}, # Image variant cache - ensures all variants exist on startup - SimpleshopTheme.Images.VariantCache, + Berrypod.Images.VariantCache, # Start to serve requests - SimpleshopThemeWeb.Endpoint, + BerrypodWeb.Endpoint, # Theme CSS cache - must start after Endpoint for static_path/1 to work - SimpleshopTheme.Theme.CSSCache + Berrypod.Theme.CSSCache ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options - opts = [strategy: :one_for_one, name: SimpleshopTheme.Supervisor] + opts = [strategy: :one_for_one, name: Berrypod.Supervisor] Supervisor.start_link(children, opts) end @@ -38,7 +38,7 @@ defmodule SimpleshopTheme.Application do # whenever the application is updated. @impl true def config_change(changed, _new, removed) do - SimpleshopThemeWeb.Endpoint.config_change(changed, removed) + BerrypodWeb.Endpoint.config_change(changed, removed) :ok end diff --git a/lib/simpleshop_theme/cart.ex b/lib/berrypod/cart.ex similarity index 98% rename from lib/simpleshop_theme/cart.ex rename to lib/berrypod/cart.ex index a3288ec..eea0477 100644 --- a/lib/simpleshop_theme/cart.ex +++ b/lib/berrypod/cart.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Cart do +defmodule Berrypod.Cart do @moduledoc """ The Cart context. @@ -7,8 +7,8 @@ defmodule SimpleshopTheme.Cart do Items are hydrated with full product/variant data when needed for display. """ - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProductImage + alias Berrypod.Products + alias Berrypod.Products.ProductImage @session_key "cart" diff --git a/lib/simpleshop_theme/cldr.ex b/lib/berrypod/cldr.ex similarity index 87% rename from lib/simpleshop_theme/cldr.ex rename to lib/berrypod/cldr.ex index f941dc8..69a241e 100644 --- a/lib/simpleshop_theme/cldr.ex +++ b/lib/berrypod/cldr.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Cldr do +defmodule Berrypod.Cldr do @moduledoc """ CLDR backend for internationalization and currency formatting. diff --git a/lib/simpleshop_theme/clients/printful.ex b/lib/berrypod/clients/printful.ex similarity index 99% rename from lib/simpleshop_theme/clients/printful.ex rename to lib/berrypod/clients/printful.ex index e9cedd4..5216e3d 100644 --- a/lib/simpleshop_theme/clients/printful.ex +++ b/lib/berrypod/clients/printful.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Clients.Printful do +defmodule Berrypod.Clients.Printful do @moduledoc """ HTTP client for the Printful API. diff --git a/lib/simpleshop_theme/clients/printify.ex b/lib/berrypod/clients/printify.ex similarity index 99% rename from lib/simpleshop_theme/clients/printify.ex rename to lib/berrypod/clients/printify.ex index aea6478..72799a5 100644 --- a/lib/simpleshop_theme/clients/printify.ex +++ b/lib/berrypod/clients/printify.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Clients.Printify do +defmodule Berrypod.Clients.Printify do @moduledoc """ HTTP client for the Printify API. diff --git a/lib/simpleshop_theme/exchange_rate.ex b/lib/berrypod/exchange_rate.ex similarity index 97% rename from lib/simpleshop_theme/exchange_rate.ex rename to lib/berrypod/exchange_rate.ex index d72321b..fed67de 100644 --- a/lib/simpleshop_theme/exchange_rate.ex +++ b/lib/berrypod/exchange_rate.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.ExchangeRate do +defmodule Berrypod.ExchangeRate do @moduledoc """ Fetches and caches exchange rates for shipping cost conversion. @@ -7,7 +7,7 @@ defmodule SimpleshopTheme.ExchangeRate do they survive restarts without an API call. """ - alias SimpleshopTheme.Settings + alias Berrypod.Settings require Logger diff --git a/lib/simpleshop_theme/images/optimize_worker.ex b/lib/berrypod/images/optimize_worker.ex similarity index 93% rename from lib/simpleshop_theme/images/optimize_worker.ex rename to lib/berrypod/images/optimize_worker.ex index a5d033a..a52a2e5 100644 --- a/lib/simpleshop_theme/images/optimize_worker.ex +++ b/lib/berrypod/images/optimize_worker.ex @@ -1,11 +1,11 @@ -defmodule SimpleshopTheme.Images.OptimizeWorker do +defmodule Berrypod.Images.OptimizeWorker do @moduledoc """ Oban worker for processing image variants in the background. Handles both database images and filesystem mockups. """ use Oban.Worker, queue: :images, max_attempts: 3 - alias SimpleshopTheme.Images.Optimizer + alias Berrypod.Images.Optimizer @impl Oban.Worker def perform(%Oban.Job{args: %{"type" => "mockup", "source_path" => source_path}}) do diff --git a/lib/simpleshop_theme/images/optimizer.ex b/lib/berrypod/images/optimizer.ex similarity index 96% rename from lib/simpleshop_theme/images/optimizer.ex rename to lib/berrypod/images/optimizer.ex index 6d8424a..5780ca0 100644 --- a/lib/simpleshop_theme/images/optimizer.ex +++ b/lib/berrypod/images/optimizer.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopTheme.Images.Optimizer do +defmodule Berrypod.Images.Optimizer do @moduledoc """ Generates optimized image variants. Only creates sizes ≤ source dimensions. """ require Logger - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Media.Image, as: ImageSchema + alias Berrypod.Repo + alias Berrypod.Media.Image, as: ImageSchema @all_widths [400, 800, 1200] @pregenerated_formats [:avif, :webp, :jpg] @@ -15,8 +15,8 @@ defmodule SimpleshopTheme.Images.Optimizer do @storage_quality 90 def cache_dir do - Application.get_env(:simpleshop_theme, :image_cache_dir) || - Application.app_dir(:simpleshop_theme, "priv/static/image_cache") + Application.get_env(:berrypod, :image_cache_dir) || + Application.app_dir(:berrypod, "priv/static/image_cache") end def all_widths, do: @all_widths diff --git a/lib/simpleshop_theme/images/variant_cache.ex b/lib/berrypod/images/variant_cache.ex similarity index 92% rename from lib/simpleshop_theme/images/variant_cache.ex rename to lib/berrypod/images/variant_cache.ex index 55dd4be..24024c7 100644 --- a/lib/simpleshop_theme/images/variant_cache.ex +++ b/lib/berrypod/images/variant_cache.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Images.VariantCache do +defmodule Berrypod.Images.VariantCache do @moduledoc """ Ensures all image variants exist on startup. @@ -12,14 +12,14 @@ defmodule SimpleshopTheme.Images.VariantCache do use GenServer require Logger - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Media.Image, as: ImageSchema - alias SimpleshopTheme.Images.{Optimizer, OptimizeWorker} - alias SimpleshopTheme.Products - alias SimpleshopTheme.Sync.ImageDownloadWorker + alias Berrypod.Repo + alias Berrypod.Media.Image, as: ImageSchema + alias Berrypod.Images.{Optimizer, OptimizeWorker} + alias Berrypod.Products + alias Berrypod.Sync.ImageDownloadWorker import Ecto.Query - defp mockup_dir, do: Application.app_dir(:simpleshop_theme, "priv/static/mockups") + defp mockup_dir, do: Application.app_dir(:berrypod, "priv/static/mockups") def start_link(opts) do GenServer.start_link(__MODULE__, opts, name: __MODULE__) diff --git a/lib/berrypod/mailer.ex b/lib/berrypod/mailer.ex new file mode 100644 index 0000000..ca7ceba --- /dev/null +++ b/lib/berrypod/mailer.ex @@ -0,0 +1,3 @@ +defmodule Berrypod.Mailer do + use Swoosh.Mailer, otp_app: :berrypod +end diff --git a/lib/simpleshop_theme/media.ex b/lib/berrypod/media.ex similarity index 94% rename from lib/simpleshop_theme/media.ex rename to lib/berrypod/media.ex index 2513cc5..66fa40b 100644 --- a/lib/simpleshop_theme/media.ex +++ b/lib/berrypod/media.ex @@ -1,13 +1,13 @@ -defmodule SimpleshopTheme.Media do +defmodule Berrypod.Media do @moduledoc """ The Media context for managing images and file uploads. """ import Ecto.Query, warn: false - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Media.Image, as: ImageSchema - alias SimpleshopTheme.Images.Optimizer - alias SimpleshopTheme.Images.OptimizeWorker + alias Berrypod.Repo + alias Berrypod.Media.Image, as: ImageSchema + alias Berrypod.Images.Optimizer + alias Berrypod.Images.OptimizeWorker @doc """ Uploads an image and stores it in the database. diff --git a/lib/simpleshop_theme/media/image.ex b/lib/berrypod/media/image.ex similarity index 97% rename from lib/simpleshop_theme/media/image.ex rename to lib/berrypod/media/image.ex index 5529699..d38b00e 100644 --- a/lib/simpleshop_theme/media/image.ex +++ b/lib/berrypod/media/image.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Media.Image do +defmodule Berrypod.Media.Image do use Ecto.Schema import Ecto.Changeset diff --git a/lib/simpleshop_theme/media/svg_recolorer.ex b/lib/berrypod/media/svg_recolorer.ex similarity index 98% rename from lib/simpleshop_theme/media/svg_recolorer.ex rename to lib/berrypod/media/svg_recolorer.ex index d2022e4..bbbb52a 100644 --- a/lib/simpleshop_theme/media/svg_recolorer.ex +++ b/lib/berrypod/media/svg_recolorer.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Media.SVGRecolorer do +defmodule Berrypod.Media.SVGRecolorer do @moduledoc """ Recolors SVG images by replacing fill and stroke colors with a target color. diff --git a/lib/simpleshop_theme/mockups/generator.ex b/lib/berrypod/mockups/generator.ex similarity index 99% rename from lib/simpleshop_theme/mockups/generator.ex rename to lib/berrypod/mockups/generator.ex index 2c9b2e0..3be6df8 100644 --- a/lib/simpleshop_theme/mockups/generator.ex +++ b/lib/berrypod/mockups/generator.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Mockups.Generator do +defmodule Berrypod.Mockups.Generator do @moduledoc """ Generates product mockups using the Printify API. @@ -11,7 +11,7 @@ defmodule SimpleshopTheme.Mockups.Generator do 6. Optionally cleaning up created products """ - alias SimpleshopTheme.Clients.Printify, as: Client + alias Berrypod.Clients.Printify, as: Client @output_dir "priv/static/mockups" @@ -382,7 +382,7 @@ defmodule SimpleshopTheme.Mockups.Generator do Sources are saved for regeneration on startup via VariantCache. """ def download_mockups(product_slug, mockup_urls) do - alias SimpleshopTheme.Images.Optimizer + alias Berrypod.Images.Optimizer File.mkdir_p!(@output_dir) diff --git a/lib/simpleshop_theme/mockups/printful_generator.ex b/lib/berrypod/mockups/printful_generator.ex similarity index 98% rename from lib/simpleshop_theme/mockups/printful_generator.ex rename to lib/berrypod/mockups/printful_generator.ex index 8f52e0f..14238f0 100644 --- a/lib/simpleshop_theme/mockups/printful_generator.ex +++ b/lib/berrypod/mockups/printful_generator.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Mockups.PrintfulGenerator do +defmodule Berrypod.Mockups.PrintfulGenerator do @moduledoc """ Generates product mockups and/or creates demo products using the Printful API. @@ -11,9 +11,9 @@ defmodule SimpleshopTheme.Mockups.PrintfulGenerator do v1 store products API. These can later be synced into the shop. """ - alias SimpleshopTheme.Clients.Printful, as: Client - alias SimpleshopTheme.Images.Optimizer - alias SimpleshopTheme.Mockups.Generator + alias Berrypod.Clients.Printful, as: Client + alias Berrypod.Images.Optimizer + alias Berrypod.Mockups.Generator @output_dir "priv/static/mockups" @poll_interval_ms 2_000 diff --git a/lib/simpleshop_theme/orders.ex b/lib/berrypod/orders.ex similarity index 98% rename from lib/simpleshop_theme/orders.ex rename to lib/berrypod/orders.ex index ef72abf..0ef1acc 100644 --- a/lib/simpleshop_theme/orders.ex +++ b/lib/berrypod/orders.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders do +defmodule Berrypod.Orders do @moduledoc """ The Orders context. @@ -8,10 +8,10 @@ defmodule SimpleshopTheme.Orders do """ import Ecto.Query - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Orders.{Order, OrderItem, OrderNotifier} - alias SimpleshopTheme.Products - alias SimpleshopTheme.Providers.Provider + alias Berrypod.Repo + alias Berrypod.Orders.{Order, OrderItem, OrderNotifier} + alias Berrypod.Products + alias Berrypod.Providers.Provider require Logger diff --git a/lib/simpleshop_theme/orders/fulfilment_status_worker.ex b/lib/berrypod/orders/fulfilment_status_worker.ex similarity index 92% rename from lib/simpleshop_theme/orders/fulfilment_status_worker.ex rename to lib/berrypod/orders/fulfilment_status_worker.ex index 254b1fc..336e52f 100644 --- a/lib/simpleshop_theme/orders/fulfilment_status_worker.ex +++ b/lib/berrypod/orders/fulfilment_status_worker.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders.FulfilmentStatusWorker do +defmodule Berrypod.Orders.FulfilmentStatusWorker do @moduledoc """ Oban Cron worker that polls the fulfilment provider for status updates. @@ -9,7 +9,7 @@ defmodule SimpleshopTheme.Orders.FulfilmentStatusWorker do use Oban.Worker, queue: :sync, max_attempts: 1 - alias SimpleshopTheme.Orders + alias Berrypod.Orders require Logger diff --git a/lib/simpleshop_theme/orders/order.ex b/lib/berrypod/orders/order.ex similarity index 95% rename from lib/simpleshop_theme/orders/order.ex rename to lib/berrypod/orders/order.ex index acd50c7..ca7020d 100644 --- a/lib/simpleshop_theme/orders/order.ex +++ b/lib/berrypod/orders/order.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders.Order do +defmodule Berrypod.Orders.Order do use Ecto.Schema import Ecto.Changeset @@ -34,7 +34,7 @@ defmodule SimpleshopTheme.Orders.Order do field :shipped_at, :utc_datetime field :delivered_at, :utc_datetime - has_many :items, SimpleshopTheme.Orders.OrderItem + has_many :items, Berrypod.Orders.OrderItem timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/orders/order_item.ex b/lib/berrypod/orders/order_item.ex similarity index 87% rename from lib/simpleshop_theme/orders/order_item.ex rename to lib/berrypod/orders/order_item.ex index 3f7e401..0c8c222 100644 --- a/lib/simpleshop_theme/orders/order_item.ex +++ b/lib/berrypod/orders/order_item.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders.OrderItem do +defmodule Berrypod.Orders.OrderItem do use Ecto.Schema import Ecto.Changeset @@ -12,7 +12,7 @@ defmodule SimpleshopTheme.Orders.OrderItem do field :quantity, :integer field :unit_price, :integer - belongs_to :order, SimpleshopTheme.Orders.Order + belongs_to :order, Berrypod.Orders.Order timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/orders/order_notifier.ex b/lib/berrypod/orders/order_notifier.ex similarity index 95% rename from lib/simpleshop_theme/orders/order_notifier.ex rename to lib/berrypod/orders/order_notifier.ex index 171004d..8f8e610 100644 --- a/lib/simpleshop_theme/orders/order_notifier.ex +++ b/lib/berrypod/orders/order_notifier.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders.OrderNotifier do +defmodule Berrypod.Orders.OrderNotifier do @moduledoc """ Sends transactional emails for orders. @@ -7,8 +7,8 @@ defmodule SimpleshopTheme.Orders.OrderNotifier do import Swoosh.Email - alias SimpleshopTheme.Cart - alias SimpleshopTheme.Mailer + alias Berrypod.Cart + alias Berrypod.Mailer require Logger @@ -73,7 +73,7 @@ defmodule SimpleshopTheme.Orders.OrderNotifier do email = new() |> to(recipient) - |> from({"SimpleshopTheme", "contact@example.com"}) + |> from({"Berrypod", "contact@example.com"}) |> subject(subject) |> text_body(body) diff --git a/lib/simpleshop_theme/orders/order_submission_worker.ex b/lib/berrypod/orders/order_submission_worker.ex similarity index 94% rename from lib/simpleshop_theme/orders/order_submission_worker.ex rename to lib/berrypod/orders/order_submission_worker.ex index be2354c..ad0291a 100644 --- a/lib/simpleshop_theme/orders/order_submission_worker.ex +++ b/lib/berrypod/orders/order_submission_worker.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Orders.OrderSubmissionWorker do +defmodule Berrypod.Orders.OrderSubmissionWorker do @moduledoc """ Oban worker for submitting paid orders to the fulfilment provider. @@ -9,7 +9,7 @@ defmodule SimpleshopTheme.Orders.OrderSubmissionWorker do use Oban.Worker, queue: :checkout, max_attempts: 3 - alias SimpleshopTheme.Orders + alias Berrypod.Orders require Logger diff --git a/lib/simpleshop_theme/products.ex b/lib/berrypod/products.ex similarity index 98% rename from lib/simpleshop_theme/products.ex rename to lib/berrypod/products.ex index 4d251df..cfb4605 100644 --- a/lib/simpleshop_theme/products.ex +++ b/lib/berrypod/products.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Products do +defmodule Berrypod.Products do @moduledoc """ The Products context. @@ -7,8 +7,8 @@ defmodule SimpleshopTheme.Products do """ import Ecto.Query - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Products.{ProviderConnection, Product, ProductImage, ProductVariant} + alias Berrypod.Repo + alias Berrypod.Products.{ProviderConnection, Product, ProductImage, ProductVariant} # ============================================================================= # Provider Connections @@ -105,7 +105,7 @@ defmodule SimpleshopTheme.Products do Returns `{:ok, job}` or `{:error, changeset}`. """ def enqueue_sync(%ProviderConnection{} = conn) do - SimpleshopTheme.Sync.ProductSyncWorker.enqueue(conn.id) + Berrypod.Sync.ProductSyncWorker.enqueue(conn.id) end # ============================================================================= @@ -669,7 +669,7 @@ defmodule SimpleshopTheme.Products do defp cleanup_orphaned_images([]), do: :ok defp cleanup_orphaned_images(image_ids) do - alias SimpleshopTheme.Media.Image, as: ImageSchema + alias Berrypod.Media.Image, as: ImageSchema from(i in ImageSchema, where: i.id in ^image_ids) |> Repo.delete_all() diff --git a/lib/simpleshop_theme/products/product.ex b/lib/berrypod/products/product.ex similarity index 95% rename from lib/simpleshop_theme/products/product.ex rename to lib/berrypod/products/product.ex index 21e8dc1..25e7bb7 100644 --- a/lib/simpleshop_theme/products/product.ex +++ b/lib/berrypod/products/product.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Products.Product do +defmodule Berrypod.Products.Product do @moduledoc """ Schema for products synced from POD providers. @@ -31,9 +31,9 @@ defmodule SimpleshopTheme.Products.Product do field :in_stock, :boolean, default: true field :on_sale, :boolean, default: false - belongs_to :provider_connection, SimpleshopTheme.Products.ProviderConnection - has_many :images, SimpleshopTheme.Products.ProductImage - has_many :variants, SimpleshopTheme.Products.ProductVariant + belongs_to :provider_connection, Berrypod.Products.ProviderConnection + has_many :images, Berrypod.Products.ProductImage + has_many :variants, Berrypod.Products.ProductVariant timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/products/product_image.ex b/lib/berrypod/products/product_image.ex similarity index 91% rename from lib/simpleshop_theme/products/product_image.ex rename to lib/berrypod/products/product_image.ex index 6108567..038495d 100644 --- a/lib/simpleshop_theme/products/product_image.ex +++ b/lib/berrypod/products/product_image.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Products.ProductImage do +defmodule Berrypod.Products.ProductImage do @moduledoc """ Schema for product images. @@ -18,8 +18,8 @@ defmodule SimpleshopTheme.Products.ProductImage do field :color, :string field :image_id, :binary_id - belongs_to :product, SimpleshopTheme.Products.Product - belongs_to :image, SimpleshopTheme.Media.Image, define_field: false + belongs_to :product, Berrypod.Products.Product + belongs_to :image, Berrypod.Media.Image, define_field: false timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/products/product_variant.ex b/lib/berrypod/products/product_variant.ex similarity index 95% rename from lib/simpleshop_theme/products/product_variant.ex rename to lib/berrypod/products/product_variant.ex index a6353a8..e337066 100644 --- a/lib/simpleshop_theme/products/product_variant.ex +++ b/lib/berrypod/products/product_variant.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Products.ProductVariant do +defmodule Berrypod.Products.ProductVariant do @moduledoc """ Schema for product variants. @@ -34,7 +34,7 @@ defmodule SimpleshopTheme.Products.ProductVariant do field :is_enabled, :boolean, default: true field :is_available, :boolean, default: true - belongs_to :product, SimpleshopTheme.Products.Product + belongs_to :product, Berrypod.Products.Product timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/products/provider_connection.ex b/lib/berrypod/products/provider_connection.ex similarity index 94% rename from lib/simpleshop_theme/products/provider_connection.ex rename to lib/berrypod/products/provider_connection.ex index 1951ff1..04db3cf 100644 --- a/lib/simpleshop_theme/products/provider_connection.ex +++ b/lib/berrypod/products/provider_connection.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Products.ProviderConnection do +defmodule Berrypod.Products.ProviderConnection do @moduledoc """ Schema for POD provider connections. @@ -9,7 +9,7 @@ defmodule SimpleshopTheme.Products.ProviderConnection do use Ecto.Schema import Ecto.Changeset - alias SimpleshopTheme.Vault + alias Berrypod.Vault @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id @@ -29,7 +29,7 @@ defmodule SimpleshopTheme.Products.ProviderConnection do # Virtual field for setting API key field :api_key, :string, virtual: true - has_many :products, SimpleshopTheme.Products.Product + has_many :products, Berrypod.Products.Product timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/providers.ex b/lib/berrypod/providers.ex similarity index 82% rename from lib/simpleshop_theme/providers.ex rename to lib/berrypod/providers.ex index a0aabec..a1635d9 100644 --- a/lib/simpleshop_theme/providers.ex +++ b/lib/berrypod/providers.ex @@ -1,10 +1,10 @@ -defmodule SimpleshopTheme.Providers do +defmodule Berrypod.Providers do @moduledoc """ Convenience functions for working with POD providers. """ - alias SimpleshopTheme.Products.ProviderConnection - alias SimpleshopTheme.Providers.Provider + alias Berrypod.Products.ProviderConnection + alias Berrypod.Providers.Provider @doc """ Tests a provider connection. diff --git a/lib/simpleshop_theme/providers/printful.ex b/lib/berrypod/providers/printful.ex similarity index 99% rename from lib/simpleshop_theme/providers/printful.ex rename to lib/berrypod/providers/printful.ex index b938470..0574fee 100644 --- a/lib/simpleshop_theme/providers/printful.ex +++ b/lib/berrypod/providers/printful.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Providers.Printful do +defmodule Berrypod.Providers.Printful do @moduledoc """ Printful provider implementation. @@ -6,10 +6,10 @@ defmodule SimpleshopTheme.Providers.Printful do Uses v2 API endpoints where available, v1 for sync products. """ - @behaviour SimpleshopTheme.Providers.Provider + @behaviour Berrypod.Providers.Provider - alias SimpleshopTheme.Clients.Printful, as: Client - alias SimpleshopTheme.Products.ProviderConnection + alias Berrypod.Clients.Printful, as: Client + alias Berrypod.Products.ProviderConnection require Logger diff --git a/lib/simpleshop_theme/providers/printify.ex b/lib/berrypod/providers/printify.ex similarity index 98% rename from lib/simpleshop_theme/providers/printify.ex rename to lib/berrypod/providers/printify.ex index 15aa0d6..6169219 100644 --- a/lib/simpleshop_theme/providers/printify.ex +++ b/lib/berrypod/providers/printify.ex @@ -1,14 +1,14 @@ -defmodule SimpleshopTheme.Providers.Printify do +defmodule Berrypod.Providers.Printify do @moduledoc """ Printify provider implementation. Handles product sync and order submission for Printify. """ - @behaviour SimpleshopTheme.Providers.Provider + @behaviour Berrypod.Providers.Provider - alias SimpleshopTheme.Clients.Printify, as: Client - alias SimpleshopTheme.Products.ProviderConnection + alias Berrypod.Clients.Printify, as: Client + alias Berrypod.Products.ProviderConnection require Logger diff --git a/lib/simpleshop_theme/providers/provider.ex b/lib/berrypod/providers/provider.ex similarity index 90% rename from lib/simpleshop_theme/providers/provider.ex rename to lib/berrypod/providers/provider.ex index 9976116..d011b4b 100644 --- a/lib/simpleshop_theme/providers/provider.ex +++ b/lib/berrypod/providers/provider.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Providers.Provider do +defmodule Berrypod.Providers.Provider do @moduledoc """ Behaviour for POD provider integrations. @@ -21,7 +21,7 @@ defmodule SimpleshopTheme.Providers.Provider do - Images are maps with keys: `src`, `position`, `alt` """ - alias SimpleshopTheme.Products.ProviderConnection + alias Berrypod.Products.ProviderConnection @doc """ Returns the provider type identifier (e.g., "printify", "gelato"). @@ -79,7 +79,7 @@ defmodule SimpleshopTheme.Providers.Provider do overrides via Mox. Falls back to hardcoded dispatch. """ def for_type(type) do - case Application.get_env(:simpleshop_theme, :provider_modules, %{}) do + case Application.get_env(:berrypod, :provider_modules, %{}) do modules when is_map(modules) -> case Map.get(modules, type) do nil -> default_for_type(type) @@ -91,10 +91,10 @@ defmodule SimpleshopTheme.Providers.Provider do end end - defp default_for_type("printify"), do: {:ok, SimpleshopTheme.Providers.Printify} + defp default_for_type("printify"), do: {:ok, Berrypod.Providers.Printify} defp default_for_type("gelato"), do: {:error, :not_implemented} defp default_for_type("prodigi"), do: {:error, :not_implemented} - defp default_for_type("printful"), do: {:ok, SimpleshopTheme.Providers.Printful} + defp default_for_type("printful"), do: {:ok, Berrypod.Providers.Printful} defp default_for_type(type), do: {:error, {:unknown_provider, type}} @doc """ diff --git a/lib/simpleshop_theme/release.ex b/lib/berrypod/release.ex similarity index 85% rename from lib/simpleshop_theme/release.ex rename to lib/berrypod/release.ex index 1f8d4c6..849b9f4 100644 --- a/lib/simpleshop_theme/release.ex +++ b/lib/berrypod/release.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopTheme.Release do +defmodule Berrypod.Release do @moduledoc """ - Release tasks that can be run via `bin/migrate` or `bin/simpleshop_theme eval`. + Release tasks that can be run via `bin/migrate` or `bin/berrypod eval`. Migrations run automatically on startup (see Application), so this is mainly useful as a standalone tool for debugging or manual recovery. """ - @app :simpleshop_theme + @app :berrypod def migrate do load_app() @@ -23,7 +23,7 @@ defmodule SimpleshopTheme.Release do (when the settings table is empty). Safe to call repeatedly. """ def seed_defaults do - alias SimpleshopTheme.Settings + alias Berrypod.Settings case Settings.get_setting("theme_settings") do nil -> diff --git a/lib/berrypod/repo.ex b/lib/berrypod/repo.ex new file mode 100644 index 0000000..9d1542a --- /dev/null +++ b/lib/berrypod/repo.ex @@ -0,0 +1,5 @@ +defmodule Berrypod.Repo do + use Ecto.Repo, + otp_app: :berrypod, + adapter: Ecto.Adapters.SQLite3 +end diff --git a/lib/simpleshop_theme/search.ex b/lib/berrypod/search.ex similarity index 98% rename from lib/simpleshop_theme/search.ex rename to lib/berrypod/search.ex index fa400a5..81a734b 100644 --- a/lib/simpleshop_theme/search.ex +++ b/lib/berrypod/search.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Search do +defmodule Berrypod.Search do @moduledoc """ Full-text product search backed by SQLite FTS5. @@ -8,8 +8,8 @@ defmodule SimpleshopTheme.Search do import Ecto.Query - alias SimpleshopTheme.Products.Product - alias SimpleshopTheme.Repo + alias Berrypod.Products.Product + alias Berrypod.Repo @listing_preloads [images: :image] diff --git a/lib/simpleshop_theme/secrets.ex b/lib/berrypod/secrets.ex similarity index 94% rename from lib/simpleshop_theme/secrets.ex rename to lib/berrypod/secrets.ex index bf2f778..be2e1ee 100644 --- a/lib/simpleshop_theme/secrets.ex +++ b/lib/berrypod/secrets.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Secrets do +defmodule Berrypod.Secrets do @moduledoc """ Loads encrypted secrets from the database into Application env at runtime. @@ -9,7 +9,7 @@ defmodule SimpleshopTheme.Secrets do The only external dependency is `SECRET_KEY_BASE` (used to derive encryption keys). """ - alias SimpleshopTheme.Settings + alias Berrypod.Settings require Logger diff --git a/lib/simpleshop_theme/settings.ex b/lib/berrypod/settings.ex similarity index 95% rename from lib/simpleshop_theme/settings.ex rename to lib/berrypod/settings.ex index a7b05b0..f2b6118 100644 --- a/lib/simpleshop_theme/settings.ex +++ b/lib/berrypod/settings.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopTheme.Settings do +defmodule Berrypod.Settings do @moduledoc """ The Settings context for managing site-wide configuration. """ import Ecto.Query, warn: false - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Settings.{Setting, ThemeSettings} - alias SimpleshopTheme.Vault + alias Berrypod.Repo + alias Berrypod.Settings.{Setting, ThemeSettings} + alias Berrypod.Vault @doc """ Gets a setting by key with an optional default value. @@ -86,7 +86,7 @@ defmodule SimpleshopTheme.Settings do put_setting("theme_settings", json, "json") # Invalidate and rewarm CSS cache - alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator} + alias Berrypod.Theme.{CSSCache, CSSGenerator} CSSCache.invalidate() css = CSSGenerator.generate(settings) CSSCache.put(css) @@ -107,7 +107,7 @@ defmodule SimpleshopTheme.Settings do """ def apply_preset(preset_name) when is_atom(preset_name) do - preset = SimpleshopTheme.Theme.Presets.get(preset_name) + preset = Berrypod.Theme.Presets.get(preset_name) if preset do update_theme_settings(preset) diff --git a/lib/simpleshop_theme/settings/setting.ex b/lib/berrypod/settings/setting.ex similarity index 95% rename from lib/simpleshop_theme/settings/setting.ex rename to lib/berrypod/settings/setting.ex index 7399ddd..1ba45bf 100644 --- a/lib/simpleshop_theme/settings/setting.ex +++ b/lib/berrypod/settings/setting.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Settings.Setting do +defmodule Berrypod.Settings.Setting do use Ecto.Schema import Ecto.Changeset diff --git a/lib/simpleshop_theme/settings/theme_settings.ex b/lib/berrypod/settings/theme_settings.ex similarity index 98% rename from lib/simpleshop_theme/settings/theme_settings.ex rename to lib/berrypod/settings/theme_settings.ex index c6e098c..445125f 100644 --- a/lib/simpleshop_theme/settings/theme_settings.ex +++ b/lib/berrypod/settings/theme_settings.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Settings.ThemeSettings do +defmodule Berrypod.Settings.ThemeSettings do use Ecto.Schema import Ecto.Changeset diff --git a/lib/simpleshop_theme/setup.ex b/lib/berrypod/setup.ex similarity index 91% rename from lib/simpleshop_theme/setup.ex rename to lib/berrypod/setup.ex index 7822ddb..943a361 100644 --- a/lib/simpleshop_theme/setup.ex +++ b/lib/berrypod/setup.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopTheme.Setup do +defmodule Berrypod.Setup do @moduledoc """ Aggregates setup status checks for the admin setup flow. """ - alias SimpleshopTheme.{Accounts, Products, Settings} + alias Berrypod.{Accounts, Products, Settings} @doc """ Returns a map describing the current setup status. diff --git a/lib/simpleshop_theme/shipping.ex b/lib/berrypod/shipping.ex similarity index 97% rename from lib/simpleshop_theme/shipping.ex rename to lib/berrypod/shipping.ex index 3c18141..0477568 100644 --- a/lib/simpleshop_theme/shipping.ex +++ b/lib/berrypod/shipping.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Shipping do +defmodule Berrypod.Shipping do @moduledoc """ The Shipping context. @@ -7,11 +7,11 @@ defmodule SimpleshopTheme.Shipping do """ import Ecto.Query - alias SimpleshopTheme.ExchangeRate - alias SimpleshopTheme.Repo - alias SimpleshopTheme.Shipping.ShippingRate - alias SimpleshopTheme.Products - alias SimpleshopTheme.Settings + alias Berrypod.ExchangeRate + alias Berrypod.Repo + alias Berrypod.Shipping.ShippingRate + alias Berrypod.Products + alias Berrypod.Settings require Logger diff --git a/lib/simpleshop_theme/shipping/shipping_rate.ex b/lib/berrypod/shipping/shipping_rate.ex similarity index 90% rename from lib/simpleshop_theme/shipping/shipping_rate.ex rename to lib/berrypod/shipping/shipping_rate.ex index 7db064e..a740b28 100644 --- a/lib/simpleshop_theme/shipping/shipping_rate.ex +++ b/lib/berrypod/shipping/shipping_rate.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Shipping.ShippingRate do +defmodule Berrypod.Shipping.ShippingRate do use Ecto.Schema import Ecto.Changeset @@ -14,7 +14,7 @@ defmodule SimpleshopTheme.Shipping.ShippingRate do field :currency, :string, default: "USD" field :handling_time_days, :integer - belongs_to :provider_connection, SimpleshopTheme.Products.ProviderConnection + belongs_to :provider_connection, Berrypod.Products.ProviderConnection timestamps(type: :utc_datetime) end diff --git a/lib/simpleshop_theme/stripe/setup.ex b/lib/berrypod/stripe/setup.ex similarity index 94% rename from lib/simpleshop_theme/stripe/setup.ex rename to lib/berrypod/stripe/setup.ex index c92e15a..811f4a8 100644 --- a/lib/simpleshop_theme/stripe/setup.ex +++ b/lib/berrypod/stripe/setup.ex @@ -1,11 +1,11 @@ -defmodule SimpleshopTheme.Stripe.Setup do +defmodule Berrypod.Stripe.Setup do @moduledoc """ Handles Stripe account setup: key verification, automatic webhook endpoint creation, and teardown. """ - alias SimpleshopTheme.Settings - alias SimpleshopTheme.Secrets + alias Berrypod.Settings + alias Berrypod.Secrets require Logger @@ -75,14 +75,14 @@ defmodule SimpleshopTheme.Stripe.Setup do Returns the webhook URL for this app. """ def webhook_url do - "#{SimpleshopThemeWeb.Endpoint.url()}/webhooks/stripe" + "#{BerrypodWeb.Endpoint.url()}/webhooks/stripe" end @doc """ Returns true if the app is running on localhost (Stripe can't reach it). """ def localhost? do - url = SimpleshopThemeWeb.Endpoint.url() + url = BerrypodWeb.Endpoint.url() uri = URI.parse(url) uri.host in ["localhost", "127.0.0.1", "0.0.0.0", "::1"] end diff --git a/lib/simpleshop_theme/sync/image_download_worker.ex b/lib/berrypod/sync/image_download_worker.ex similarity index 97% rename from lib/simpleshop_theme/sync/image_download_worker.ex rename to lib/berrypod/sync/image_download_worker.ex index e2139b9..8fa342f 100644 --- a/lib/simpleshop_theme/sync/image_download_worker.ex +++ b/lib/berrypod/sync/image_download_worker.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Sync.ImageDownloadWorker do +defmodule Berrypod.Sync.ImageDownloadWorker do @moduledoc """ Oban worker for downloading product images from external URLs. @@ -17,8 +17,8 @@ defmodule SimpleshopTheme.Sync.ImageDownloadWorker do use Oban.Worker, queue: :images, max_attempts: 3 - alias SimpleshopTheme.Products - alias SimpleshopTheme.Media + alias Berrypod.Products + alias Berrypod.Media require Logger diff --git a/lib/simpleshop_theme/sync/mockup_enricher.ex b/lib/berrypod/sync/mockup_enricher.ex similarity index 97% rename from lib/simpleshop_theme/sync/mockup_enricher.ex rename to lib/berrypod/sync/mockup_enricher.ex index 7fc6e1f..4873fad 100644 --- a/lib/simpleshop_theme/sync/mockup_enricher.ex +++ b/lib/berrypod/sync/mockup_enricher.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Sync.MockupEnricher do +defmodule Berrypod.Sync.MockupEnricher do @moduledoc """ Oban worker that enriches Printful products with extra mockup angle images. @@ -16,10 +16,10 @@ defmodule SimpleshopTheme.Sync.MockupEnricher do use Oban.Worker, queue: :images, max_attempts: 5 - alias SimpleshopTheme.Clients.Printful, as: Client - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProviderConnection - alias SimpleshopTheme.Sync.ImageDownloadWorker + alias Berrypod.Clients.Printful, as: Client + alias Berrypod.Products + alias Berrypod.Products.ProviderConnection + alias Berrypod.Sync.ImageDownloadWorker require Logger diff --git a/lib/simpleshop_theme/sync/product_sync_worker.ex b/lib/berrypod/sync/product_sync_worker.ex similarity index 93% rename from lib/simpleshop_theme/sync/product_sync_worker.ex rename to lib/berrypod/sync/product_sync_worker.ex index 8f65e2a..16029d5 100644 --- a/lib/simpleshop_theme/sync/product_sync_worker.ex +++ b/lib/berrypod/sync/product_sync_worker.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Sync.ProductSyncWorker do +defmodule Berrypod.Sync.ProductSyncWorker do @moduledoc """ Oban worker for syncing products from POD providers. @@ -17,11 +17,11 @@ defmodule SimpleshopTheme.Sync.ProductSyncWorker do use Oban.Worker, queue: :sync, max_attempts: 3 - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProviderConnection - alias SimpleshopTheme.Providers.Provider - alias SimpleshopTheme.Sync.ImageDownloadWorker - alias SimpleshopTheme.Sync.MockupEnricher + alias Berrypod.Products + alias Berrypod.Products.ProviderConnection + alias Berrypod.Providers.Provider + alias Berrypod.Sync.ImageDownloadWorker + alias Berrypod.Sync.MockupEnricher require Logger @@ -110,7 +110,7 @@ defmodule SimpleshopTheme.Sync.ProductSyncWorker do broadcast_sync(conn.id, {:sync_status, "completed", product_count}) # Rebuild search index after successful sync - SimpleshopTheme.Search.rebuild_index() + Berrypod.Search.rebuild_index() :ok else @@ -165,7 +165,7 @@ defmodule SimpleshopTheme.Sync.ProductSyncWorker do end defp broadcast_sync(conn_id, message) do - Phoenix.PubSub.broadcast(SimpleshopTheme.PubSub, "sync:#{conn_id}", message) + Phoenix.PubSub.broadcast(Berrypod.PubSub, "sync:#{conn_id}", message) end defp sync_product_associations(product, product_data) do @@ -214,11 +214,11 @@ defmodule SimpleshopTheme.Sync.ProductSyncWorker do defp sync_shipping_rates(conn, provider, products) do if function_exported?(provider, :fetch_shipping_rates, 2) do # Fetch live exchange rates so shipping costs are stored in GBP - {:ok, exchange_rates} = SimpleshopTheme.ExchangeRate.fetch_and_cache() + {:ok, exchange_rates} = Berrypod.ExchangeRate.fetch_and_cache() case provider.fetch_shipping_rates(conn, products) do {:ok, rates} when rates != [] -> - SimpleshopTheme.Shipping.upsert_rates(conn.id, rates, exchange_rates) + Berrypod.Shipping.upsert_rates(conn.id, rates, exchange_rates) {:ok, []} -> Logger.info("No shipping rates returned for #{conn.provider_type}") diff --git a/lib/simpleshop_theme/sync/scheduled_sync_worker.ex b/lib/berrypod/sync/scheduled_sync_worker.ex similarity index 90% rename from lib/simpleshop_theme/sync/scheduled_sync_worker.ex rename to lib/berrypod/sync/scheduled_sync_worker.ex index 4eb2f0d..5a17db4 100644 --- a/lib/simpleshop_theme/sync/scheduled_sync_worker.ex +++ b/lib/berrypod/sync/scheduled_sync_worker.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Sync.ScheduledSyncWorker do +defmodule Berrypod.Sync.ScheduledSyncWorker do @moduledoc """ Oban cron worker for periodic product + shipping rate sync. @@ -9,7 +9,7 @@ defmodule SimpleshopTheme.Sync.ScheduledSyncWorker do use Oban.Worker, queue: :sync, max_attempts: 1 - alias SimpleshopTheme.Products + alias Berrypod.Products require Logger diff --git a/lib/simpleshop_theme/theme/css_cache.ex b/lib/berrypod/theme/css_cache.ex similarity index 91% rename from lib/simpleshop_theme/theme/css_cache.ex rename to lib/berrypod/theme/css_cache.ex index 781af1b..7f66df7 100644 --- a/lib/simpleshop_theme/theme/css_cache.ex +++ b/lib/berrypod/theme/css_cache.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Theme.CSSCache do +defmodule Berrypod.Theme.CSSCache do @moduledoc """ GenServer that maintains an ETS table for caching generated theme CSS. @@ -80,13 +80,13 @@ defmodule SimpleshopTheme.Theme.CSSCache do """ def warm do - alias SimpleshopTheme.Settings - alias SimpleshopTheme.Theme.CSSGenerator + alias Berrypod.Settings + alias Berrypod.Theme.CSSGenerator settings = Settings.get_theme_settings() # Use endpoint's static_path for digested URLs in production - path_resolver = &SimpleshopThemeWeb.Endpoint.static_path/1 + path_resolver = &BerrypodWeb.Endpoint.static_path/1 css = CSSGenerator.generate(settings, path_resolver) put(css) diff --git a/lib/simpleshop_theme/theme/css_generator.ex b/lib/berrypod/theme/css_generator.ex similarity index 98% rename from lib/simpleshop_theme/theme/css_generator.ex rename to lib/berrypod/theme/css_generator.ex index 4c5b552..158b670 100644 --- a/lib/simpleshop_theme/theme/css_generator.ex +++ b/lib/berrypod/theme/css_generator.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Theme.CSSGenerator do +defmodule Berrypod.Theme.CSSGenerator do @moduledoc """ Generates CSS custom properties (Layer 2: Theme Tokens) from theme settings. @@ -10,8 +10,8 @@ defmodule SimpleshopTheme.Theme.CSSGenerator do The theme editor still uses those selectors for live preview switching. """ - alias SimpleshopTheme.Settings.ThemeSettings - alias SimpleshopTheme.Theme.Fonts + alias Berrypod.Settings.ThemeSettings + alias Berrypod.Theme.Fonts @doc """ Generates CSS for theme settings. @@ -23,7 +23,7 @@ defmodule SimpleshopTheme.Theme.CSSGenerator do Also includes @font-face declarations for the fonts used by the typography preset. Accepts an optional path_resolver function for digested font paths. - In production, pass `&SimpleshopThemeWeb.Endpoint.static_path/1`. + In production, pass `&BerrypodWeb.Endpoint.static_path/1`. """ def generate(%ThemeSettings{} = settings, path_resolver \\ fn path -> path end) do """ diff --git a/lib/simpleshop_theme/theme/fonts.ex b/lib/berrypod/theme/fonts.ex similarity index 97% rename from lib/simpleshop_theme/theme/fonts.ex rename to lib/berrypod/theme/fonts.ex index 4824c16..dcf2e10 100644 --- a/lib/simpleshop_theme/theme/fonts.ex +++ b/lib/berrypod/theme/fonts.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Theme.Fonts do +defmodule Berrypod.Theme.Fonts do @moduledoc """ Centralized font configuration for the theme system. @@ -116,7 +116,7 @@ defmodule SimpleshopTheme.Theme.Fonts do Only includes the fonts needed for that preset. Accepts an optional path_resolver function to transform font URLs. - In production, pass `&SimpleshopThemeWeb.Endpoint.static_path/1` for digested paths. + In production, pass `&BerrypodWeb.Endpoint.static_path/1` for digested paths. """ def generate_font_faces(typography, path_resolver \\ &default_path_resolver/1) do %{heading: heading_key, body: body_key} = fonts_for_typography(typography) @@ -188,7 +188,7 @@ defmodule SimpleshopTheme.Theme.Fonts do Returns a list of maps with href, as, type, and crossorigin attributes. Accepts an optional path_resolver function for digested paths. - In production, pass `&SimpleshopThemeWeb.Endpoint.static_path/1`. + In production, pass `&BerrypodWeb.Endpoint.static_path/1`. """ def preload_links(typography, path_resolver \\ &default_path_resolver/1) do typography diff --git a/lib/simpleshop_theme/theme/presets.ex b/lib/berrypod/theme/presets.ex similarity index 98% rename from lib/simpleshop_theme/theme/presets.ex rename to lib/berrypod/theme/presets.ex index ede3a02..2dfafa8 100644 --- a/lib/simpleshop_theme/theme/presets.ex +++ b/lib/berrypod/theme/presets.ex @@ -1,6 +1,6 @@ -defmodule SimpleshopTheme.Theme.Presets do +defmodule Berrypod.Theme.Presets do @moduledoc """ - Defines the 8 curated theme presets for SimpleShop. + Defines the 8 curated theme presets for Berrypod. """ @presets %{ diff --git a/lib/simpleshop_theme/theme/preview_data.ex b/lib/berrypod/theme/preview_data.ex similarity index 99% rename from lib/simpleshop_theme/theme/preview_data.ex rename to lib/berrypod/theme/preview_data.ex index 93f2d96..8f2bbf0 100644 --- a/lib/simpleshop_theme/theme/preview_data.ex +++ b/lib/berrypod/theme/preview_data.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Theme.PreviewData do +defmodule Berrypod.Theme.PreviewData do @moduledoc """ Provides preview data for theme customization. @@ -6,7 +6,7 @@ defmodule SimpleshopTheme.Theme.PreviewData do This allows users to preview themes before adding products to their shop. """ - alias SimpleshopTheme.Products + alias Berrypod.Products @doc """ Returns products for preview. @@ -105,7 +105,7 @@ defmodule SimpleshopTheme.Theme.PreviewData do %{ type: :lead, text: - "This is a sample about page for your SimpleShop store. You're reading it as Robin, a fictional nature photographer – but this is where your own story goes." + "This is a sample about page for your Berrypod store. You're reading it as Robin, a fictional nature photographer – but this is where your own story goes." }, %{ type: :paragraph, diff --git a/lib/simpleshop_theme/vault.ex b/lib/berrypod/vault.ex similarity index 93% rename from lib/simpleshop_theme/vault.ex rename to lib/berrypod/vault.ex index 2f7a595..260eafa 100644 --- a/lib/simpleshop_theme/vault.ex +++ b/lib/berrypod/vault.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopTheme.Vault do +defmodule Berrypod.Vault do @moduledoc """ Handles encryption and decryption of sensitive data. @@ -6,7 +6,7 @@ defmodule SimpleshopTheme.Vault do Keys are derived from the application's secret_key_base. """ - @aad "SimpleshopTheme.Vault" + @aad "Berrypod.Vault" @doc """ Encrypts a string value. @@ -87,7 +87,7 @@ defmodule SimpleshopTheme.Vault do end defp get_secret_key_base do - case Application.get_env(:simpleshop_theme, SimpleshopThemeWeb.Endpoint)[:secret_key_base] do + case Application.get_env(:berrypod, BerrypodWeb.Endpoint)[:secret_key_base] do nil -> raise """ Secret key base is not configured. diff --git a/lib/simpleshop_theme/webhooks.ex b/lib/berrypod/webhooks.ex similarity index 96% rename from lib/simpleshop_theme/webhooks.ex rename to lib/berrypod/webhooks.ex index 817ba33..42b310c 100644 --- a/lib/simpleshop_theme/webhooks.ex +++ b/lib/berrypod/webhooks.ex @@ -1,13 +1,13 @@ -defmodule SimpleshopTheme.Webhooks do +defmodule Berrypod.Webhooks do @moduledoc """ Handles incoming webhook events from POD providers. """ - alias SimpleshopTheme.Orders - alias SimpleshopTheme.Orders.OrderNotifier - alias SimpleshopTheme.Products - alias SimpleshopTheme.Sync.ProductSyncWorker - alias SimpleshopTheme.Webhooks.ProductDeleteWorker + alias Berrypod.Orders + alias Berrypod.Orders.OrderNotifier + alias Berrypod.Products + alias Berrypod.Sync.ProductSyncWorker + alias Berrypod.Webhooks.ProductDeleteWorker require Logger diff --git a/lib/simpleshop_theme/webhooks/product_delete_worker.ex b/lib/berrypod/webhooks/product_delete_worker.ex similarity index 92% rename from lib/simpleshop_theme/webhooks/product_delete_worker.ex rename to lib/berrypod/webhooks/product_delete_worker.ex index d5f9b05..679e354 100644 --- a/lib/simpleshop_theme/webhooks/product_delete_worker.ex +++ b/lib/berrypod/webhooks/product_delete_worker.ex @@ -1,11 +1,11 @@ -defmodule SimpleshopTheme.Webhooks.ProductDeleteWorker do +defmodule Berrypod.Webhooks.ProductDeleteWorker do @moduledoc """ Oban worker for deleting products removed from POD providers. """ use Oban.Worker, queue: :sync, max_attempts: 3 - alias SimpleshopTheme.Products + alias Berrypod.Products require Logger diff --git a/lib/simpleshop_theme_web.ex b/lib/berrypod_web.ex similarity index 81% rename from lib/simpleshop_theme_web.ex rename to lib/berrypod_web.ex index 1bee8fa..ed089fc 100644 --- a/lib/simpleshop_theme_web.ex +++ b/lib/berrypod_web.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopThemeWeb do +defmodule BerrypodWeb do @moduledoc """ The entrypoint for defining your web interface, such as controllers, components, channels, and so on. This can be used in your application as: - use SimpleshopThemeWeb, :controller - use SimpleshopThemeWeb, :html + use BerrypodWeb, :controller + use BerrypodWeb, :html The definitions below will be executed for every controller, component, etc, so keep them short and clean, focused @@ -41,7 +41,7 @@ defmodule SimpleshopThemeWeb do quote do use Phoenix.Controller, formats: [:html, :json] - use Gettext, backend: SimpleshopThemeWeb.Gettext + use Gettext, backend: BerrypodWeb.Gettext import Plug.Conn @@ -81,18 +81,18 @@ defmodule SimpleshopThemeWeb do defp html_helpers do quote do # Translation - use Gettext, backend: SimpleshopThemeWeb.Gettext + use Gettext, backend: BerrypodWeb.Gettext # HTML escaping functionality import Phoenix.HTML # Core UI components - import SimpleshopThemeWeb.CoreComponents + import BerrypodWeb.CoreComponents # Shop UI components - use SimpleshopThemeWeb.ShopComponents + use BerrypodWeb.ShopComponents # Common modules used in templates alias Phoenix.LiveView.JS - alias SimpleshopThemeWeb.Layouts + alias BerrypodWeb.Layouts # Routes generation with the ~p sigil unquote(verified_routes()) @@ -102,9 +102,9 @@ defmodule SimpleshopThemeWeb do def verified_routes do quote do use Phoenix.VerifiedRoutes, - endpoint: SimpleshopThemeWeb.Endpoint, - router: SimpleshopThemeWeb.Router, - statics: SimpleshopThemeWeb.static_paths() + endpoint: BerrypodWeb.Endpoint, + router: BerrypodWeb.Router, + statics: BerrypodWeb.static_paths() end end diff --git a/lib/simpleshop_theme_web/admin_layout_hook.ex b/lib/berrypod_web/admin_layout_hook.ex similarity index 92% rename from lib/simpleshop_theme_web/admin_layout_hook.ex rename to lib/berrypod_web/admin_layout_hook.ex index bedd7f0..62ed2c8 100644 --- a/lib/simpleshop_theme_web/admin_layout_hook.ex +++ b/lib/berrypod_web/admin_layout_hook.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.AdminLayoutHook do +defmodule BerrypodWeb.AdminLayoutHook do @moduledoc """ LiveView on_mount hook that assigns the current path for admin sidebar navigation. """ diff --git a/lib/simpleshop_theme_web/cart_hook.ex b/lib/berrypod_web/cart_hook.ex similarity index 96% rename from lib/simpleshop_theme_web/cart_hook.ex rename to lib/berrypod_web/cart_hook.ex index 3b885ca..ffbfd62 100644 --- a/lib/simpleshop_theme_web/cart_hook.ex +++ b/lib/berrypod_web/cart_hook.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.CartHook do +defmodule BerrypodWeb.CartHook do @moduledoc """ LiveView on_mount hook for cart state and shared event handling. @@ -19,8 +19,8 @@ defmodule SimpleshopThemeWeb.CartHook do import Phoenix.Component, only: [assign: 3] import Phoenix.LiveView, only: [attach_hook: 4, connected?: 1, push_event: 3] - alias SimpleshopTheme.Cart - alias SimpleshopTheme.Shipping + alias Berrypod.Cart + alias Berrypod.Shipping def on_mount(:mount_cart, _params, session, socket) do cart_items = Cart.get_from_session(session) @@ -41,7 +41,7 @@ defmodule SimpleshopThemeWeb.CartHook do if connected?(socket) do csrf_token = Map.get(session, "_csrf_token", "default") topic = "cart:#{csrf_token}" - Phoenix.PubSub.subscribe(SimpleshopTheme.PubSub, topic) + Phoenix.PubSub.subscribe(Berrypod.PubSub, topic) assign(socket, :cart_topic, topic) else assign(socket, :cart_topic, nil) @@ -152,7 +152,7 @@ defmodule SimpleshopThemeWeb.CartHook do def broadcast_and_update(socket, cart) do if socket.assigns.cart_topic do Phoenix.PubSub.broadcast_from( - SimpleshopTheme.PubSub, + Berrypod.PubSub, self(), socket.assigns.cart_topic, {:cart_updated, cart} diff --git a/lib/simpleshop_theme_web/components/core_components.ex b/lib/berrypod_web/components/core_components.ex similarity index 98% rename from lib/simpleshop_theme_web/components/core_components.ex rename to lib/berrypod_web/components/core_components.ex index 46b7447..314c64f 100644 --- a/lib/simpleshop_theme_web/components/core_components.ex +++ b/lib/berrypod_web/components/core_components.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.CoreComponents do +defmodule BerrypodWeb.CoreComponents do @moduledoc """ Provides core UI components. @@ -18,7 +18,7 @@ defmodule SimpleshopThemeWeb.CoreComponents do """ use Phoenix.Component - use Gettext, backend: SimpleshopThemeWeb.Gettext + use Gettext, backend: BerrypodWeb.Gettext alias Phoenix.LiveView.JS @@ -448,9 +448,9 @@ defmodule SimpleshopThemeWeb.CoreComponents do # with our gettext backend as first argument. Translations are # available in the errors.po file (as we use the "errors" domain). if count = opts[:count] do - Gettext.dngettext(SimpleshopThemeWeb.Gettext, "errors", msg, msg, count, opts) + Gettext.dngettext(BerrypodWeb.Gettext, "errors", msg, msg, count, opts) else - Gettext.dgettext(SimpleshopThemeWeb.Gettext, "errors", msg, opts) + Gettext.dgettext(BerrypodWeb.Gettext, "errors", msg, opts) end end diff --git a/lib/simpleshop_theme_web/components/layouts.ex b/lib/berrypod_web/components/layouts.ex similarity index 98% rename from lib/simpleshop_theme_web/components/layouts.ex rename to lib/berrypod_web/components/layouts.ex index 08c8e1f..cdbc2c6 100644 --- a/lib/simpleshop_theme_web/components/layouts.ex +++ b/lib/berrypod_web/components/layouts.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.Layouts do +defmodule BerrypodWeb.Layouts do @moduledoc """ This module holds layouts and related functionality used by your application. """ - use SimpleshopThemeWeb, :html + use BerrypodWeb, :html # Embed all files in layouts/* within this module. # The default root.html.heex file contains the HTML diff --git a/lib/simpleshop_theme_web/components/layouts/admin.html.heex b/lib/berrypod_web/components/layouts/admin.html.heex similarity index 97% rename from lib/simpleshop_theme_web/components/layouts/admin.html.heex rename to lib/berrypod_web/components/layouts/admin.html.heex index c1f75f0..8734c43 100644 --- a/lib/simpleshop_theme_web/components/layouts/admin.html.heex +++ b/lib/berrypod_web/components/layouts/admin.html.heex @@ -12,7 +12,7 @@ > <.icon name="hero-bars-3" class="size-5" /> - SimpleShop + Berrypod <.link href={~p"/"} class="admin-btn admin-btn-ghost admin-btn-sm"> <.icon name="hero-arrow-top-right-on-square-mini" class="size-4" /> Shop @@ -33,7 +33,7 @@ <%!-- sidebar header --%>
<.link navigate={~p"/admin"} class="text-lg font-bold tracking-tight"> - SimpleShop + Berrypod

{@current_scope.user.email} diff --git a/lib/simpleshop_theme_web/components/layouts/admin_root.html.heex b/lib/berrypod_web/components/layouts/admin_root.html.heex similarity index 96% rename from lib/simpleshop_theme_web/components/layouts/admin_root.html.heex rename to lib/berrypod_web/components/layouts/admin_root.html.heex index 33f8b19..78a5c8b 100644 --- a/lib/simpleshop_theme_web/components/layouts/admin_root.html.heex +++ b/lib/berrypod_web/components/layouts/admin_root.html.heex @@ -4,7 +4,7 @@ - <.live_title default="Admin" suffix=" · SimpleShop"> + <.live_title default="Admin" suffix=" · Berrypod"> {assigns[:page_title]} diff --git a/lib/simpleshop_theme_web/components/layouts/root.html.heex b/lib/berrypod_web/components/layouts/root.html.heex similarity index 94% rename from lib/simpleshop_theme_web/components/layouts/root.html.heex rename to lib/berrypod_web/components/layouts/root.html.heex index ef6c73e..eff7964 100644 --- a/lib/simpleshop_theme_web/components/layouts/root.html.heex +++ b/lib/berrypod_web/components/layouts/root.html.heex @@ -4,7 +4,7 @@ - <.live_title default="SimpleshopTheme" suffix=" · Phoenix Framework"> + <.live_title default="Berrypod" suffix=" · Phoenix Framework"> {assigns[:page_title]} diff --git a/lib/simpleshop_theme_web/components/layouts/shop.html.heex b/lib/berrypod_web/components/layouts/shop.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/layouts/shop.html.heex rename to lib/berrypod_web/components/layouts/shop.html.heex diff --git a/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex b/lib/berrypod_web/components/layouts/shop_root.html.heex similarity index 94% rename from lib/simpleshop_theme_web/components/layouts/shop_root.html.heex rename to lib/berrypod_web/components/layouts/shop_root.html.heex index d0c0571..6d1d247 100644 --- a/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex +++ b/lib/berrypod_web/components/layouts/shop_root.html.heex @@ -13,9 +13,9 @@ /> <.live_title>{assigns[:page_title] || @theme_settings.site_name} - <%= for preload <- SimpleshopTheme.Theme.Fonts.preload_links( + <%= for preload <- Berrypod.Theme.Fonts.preload_links( @theme_settings.typography, - &SimpleshopThemeWeb.Endpoint.static_path/1 + &BerrypodWeb.Endpoint.static_path/1 ) do %> <% end %> diff --git a/lib/simpleshop_theme_web/components/page_templates.ex b/lib/berrypod_web/components/page_templates.ex similarity index 88% rename from lib/simpleshop_theme_web/components/page_templates.ex rename to lib/berrypod_web/components/page_templates.ex index 0127dc7..454bd00 100644 --- a/lib/simpleshop_theme_web/components/page_templates.ex +++ b/lib/berrypod_web/components/page_templates.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.PageTemplates do +defmodule BerrypodWeb.PageTemplates do @moduledoc """ Shared page templates used by both the public shop and theme preview. @@ -15,7 +15,7 @@ defmodule SimpleshopThemeWeb.PageTemplates do - `cart_count` - Number of items in cart """ use Phoenix.Component - use SimpleshopThemeWeb.ShopComponents + use BerrypodWeb.ShopComponents embed_templates "page_templates/*" end diff --git a/lib/simpleshop_theme_web/components/page_templates/cart.html.heex b/lib/berrypod_web/components/page_templates/cart.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/page_templates/cart.html.heex rename to lib/berrypod_web/components/page_templates/cart.html.heex diff --git a/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex b/lib/berrypod_web/components/page_templates/checkout_success.html.heex similarity index 96% rename from lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex rename to lib/berrypod_web/components/page_templates/checkout_success.html.heex index ecee4f7..741c0d0 100644 --- a/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex +++ b/lib/berrypod_web/components/page_templates/checkout_success.html.heex @@ -52,7 +52,7 @@

- {SimpleshopTheme.Cart.format_price(item.unit_price * item.quantity)} + {Berrypod.Cart.format_price(item.unit_price * item.quantity)} <% end %> @@ -62,7 +62,7 @@
Total - {SimpleshopTheme.Cart.format_price(@order.total)} + {Berrypod.Cart.format_price(@order.total)}
diff --git a/lib/simpleshop_theme_web/components/page_templates/collection.html.heex b/lib/berrypod_web/components/page_templates/collection.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/page_templates/collection.html.heex rename to lib/berrypod_web/components/page_templates/collection.html.heex diff --git a/lib/simpleshop_theme_web/components/page_templates/contact.html.heex b/lib/berrypod_web/components/page_templates/contact.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/page_templates/contact.html.heex rename to lib/berrypod_web/components/page_templates/contact.html.heex diff --git a/lib/simpleshop_theme_web/components/page_templates/content.html.heex b/lib/berrypod_web/components/page_templates/content.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/page_templates/content.html.heex rename to lib/berrypod_web/components/page_templates/content.html.heex diff --git a/lib/simpleshop_theme_web/components/page_templates/error.html.heex b/lib/berrypod_web/components/page_templates/error.html.heex similarity index 100% rename from lib/simpleshop_theme_web/components/page_templates/error.html.heex rename to lib/berrypod_web/components/page_templates/error.html.heex diff --git a/lib/simpleshop_theme_web/components/page_templates/home.html.heex b/lib/berrypod_web/components/page_templates/home.html.heex similarity index 85% rename from lib/simpleshop_theme_web/components/page_templates/home.html.heex rename to lib/berrypod_web/components/page_templates/home.html.heex index 3f62527..3e215b2 100644 --- a/lib/simpleshop_theme_web/components/page_templates/home.html.heex +++ b/lib/berrypod_web/components/page_templates/home.html.heex @@ -2,7 +2,7 @@
<.hero_section title="Original designs, printed on demand" - description="Welcome to the SimpleShop demo store. This is where your hero text goes – something short and punchy about what makes your shop worth a browse." + description="Welcome to the Berrypod demo store. This is where your hero text goes – something short and punchy about what makes your shop worth a browse." cta_text="Shop the collection" cta_page="collection" cta_href="/collections/all" diff --git a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex b/lib/berrypod_web/components/page_templates/pdp.html.heex similarity index 96% rename from lib/simpleshop_theme_web/components/page_templates/pdp.html.heex rename to lib/berrypod_web/components/page_templates/pdp.html.heex index 94bcb5e..d96b780 100644 --- a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex +++ b/lib/berrypod_web/components/page_templates/pdp.html.heex @@ -52,7 +52,7 @@ <.reviews_section :if={@theme_settings.pdp_reviews} - reviews={SimpleshopTheme.Theme.PreviewData.reviews()} + reviews={Berrypod.Theme.PreviewData.reviews()} average_rating={5} total_count={24} /> diff --git a/lib/simpleshop_theme_web/components/shop_components.ex b/lib/berrypod_web/components/shop_components.ex similarity index 54% rename from lib/simpleshop_theme_web/components/shop_components.ex rename to lib/berrypod_web/components/shop_components.ex index 2694992..7771862 100644 --- a/lib/simpleshop_theme_web/components/shop_components.ex +++ b/lib/berrypod_web/components/shop_components.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.ShopComponents do +defmodule BerrypodWeb.ShopComponents do @moduledoc """ Facade module for shop/storefront UI components. - `use SimpleshopThemeWeb.ShopComponents` imports all sub-modules: + `use BerrypodWeb.ShopComponents` imports all sub-modules: - `Base` — themed inputs, buttons, cards - `Layout` — header, footer, mobile nav, shop_layout wrapper @@ -13,11 +13,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do defmacro __using__(_opts \\ []) do quote do - import SimpleshopThemeWeb.ShopComponents.Base - import SimpleshopThemeWeb.ShopComponents.Cart - import SimpleshopThemeWeb.ShopComponents.Content - import SimpleshopThemeWeb.ShopComponents.Layout - import SimpleshopThemeWeb.ShopComponents.Product + import BerrypodWeb.ShopComponents.Base + import BerrypodWeb.ShopComponents.Cart + import BerrypodWeb.ShopComponents.Content + import BerrypodWeb.ShopComponents.Layout + import BerrypodWeb.ShopComponents.Product end end end diff --git a/lib/simpleshop_theme_web/components/shop_components/base.ex b/lib/berrypod_web/components/shop_components/base.ex similarity index 99% rename from lib/simpleshop_theme_web/components/shop_components/base.ex rename to lib/berrypod_web/components/shop_components/base.ex index 17de761..8f776ad 100644 --- a/lib/simpleshop_theme_web/components/shop_components/base.ex +++ b/lib/berrypod_web/components/shop_components/base.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.ShopComponents.Base do +defmodule BerrypodWeb.ShopComponents.Base do use Phoenix.Component @doc """ diff --git a/lib/simpleshop_theme_web/components/shop_components/cart.ex b/lib/berrypod_web/components/shop_components/cart.ex similarity index 96% rename from lib/simpleshop_theme_web/components/shop_components/cart.ex rename to lib/berrypod_web/components/shop_components/cart.ex index e855f15..457dbbf 100644 --- a/lib/simpleshop_theme_web/components/shop_components/cart.ex +++ b/lib/berrypod_web/components/shop_components/cart.ex @@ -1,11 +1,11 @@ -defmodule SimpleshopThemeWeb.ShopComponents.Cart do +defmodule BerrypodWeb.ShopComponents.Cart do @moduledoc false use Phoenix.Component - import SimpleshopThemeWeb.ShopComponents.Base + import BerrypodWeb.ShopComponents.Base - alias SimpleshopTheme.Products.{Product, ProductImage} + alias Berrypod.Products.{Product, ProductImage} defp close_cart_drawer_js do Phoenix.LiveView.JS.push("close_cart_drawer") @@ -248,7 +248,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do

- {SimpleshopTheme.Cart.format_price(@item.price * @item.quantity)} + {Berrypod.Cart.format_price(@item.price * @item.quantity)}

@@ -370,7 +370,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do

- {SimpleshopTheme.Cart.format_price(@item.product.cheapest_price * @item.quantity)} + {Berrypod.Cart.format_price(@item.product.cheapest_price * @item.quantity)}

@@ -406,11 +406,11 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do <% else %> - {SimpleshopTheme.Shipping.country_name(@country_code)} + {Berrypod.Shipping.country_name(@country_code)} <% end %> <%= if @shipping_estimate do %> - {SimpleshopTheme.Cart.format_price(@shipping_estimate)} + {Berrypod.Cart.format_price(@shipping_estimate)} <% else %> Calculated at checkout <% end %> @@ -453,7 +453,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
Subtotal - {SimpleshopTheme.Cart.format_price(@subtotal)} + {Berrypod.Cart.format_price(@subtotal)}
<.delivery_line @@ -468,7 +468,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do {if @shipping_estimate, do: "Estimated total", else: "Subtotal"} - {SimpleshopTheme.Cart.format_price(@estimated_total)} + {Berrypod.Cart.format_price(@estimated_total)} diff --git a/lib/simpleshop_theme_web/components/shop_components/content.ex b/lib/berrypod_web/components/shop_components/content.ex similarity index 99% rename from lib/simpleshop_theme_web/components/shop_components/content.ex rename to lib/berrypod_web/components/shop_components/content.ex index d21013c..83c6a49 100644 --- a/lib/simpleshop_theme_web/components/shop_components/content.ex +++ b/lib/berrypod_web/components/shop_components/content.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.ShopComponents.Content do +defmodule BerrypodWeb.ShopComponents.Content do @moduledoc false use Phoenix.Component - import SimpleshopThemeWeb.ShopComponents.Base + import BerrypodWeb.ShopComponents.Base @default_social_links [ %{platform: :instagram, url: "https://instagram.com", label: "Instagram"}, @@ -966,7 +966,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do attr :priority, :boolean, default: false def responsive_image(assigns) do - alias SimpleshopTheme.Images.Optimizer + alias Berrypod.Images.Optimizer # Compute available widths from source dimensions (no upscaling) available = Optimizer.applicable_widths(assigns.source_width) diff --git a/lib/simpleshop_theme_web/components/shop_components/layout.ex b/lib/berrypod_web/components/shop_components/layout.ex similarity index 99% rename from lib/simpleshop_theme_web/components/shop_components/layout.ex rename to lib/berrypod_web/components/shop_components/layout.ex index 5566ebc..5ebae71 100644 --- a/lib/simpleshop_theme_web/components/shop_components/layout.ex +++ b/lib/berrypod_web/components/shop_components/layout.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.ShopComponents.Layout do +defmodule BerrypodWeb.ShopComponents.Layout do use Phoenix.Component - import SimpleshopThemeWeb.ShopComponents.Cart - import SimpleshopThemeWeb.ShopComponents.Content + import BerrypodWeb.ShopComponents.Cart + import BerrypodWeb.ShopComponents.Content @doc """ Renders the announcement bar. @@ -350,8 +350,8 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do attr :search_open, :boolean, default: false def search_modal(assigns) do - alias SimpleshopTheme.Cart - alias SimpleshopTheme.Products.{Product, ProductImage} + alias Berrypod.Cart + alias Berrypod.Products.{Product, ProductImage} assigns = assign( diff --git a/lib/simpleshop_theme_web/components/shop_components/product.ex b/lib/berrypod_web/components/shop_components/product.ex similarity index 98% rename from lib/simpleshop_theme_web/components/shop_components/product.ex rename to lib/berrypod_web/components/shop_components/product.ex index c45e172..25a8a00 100644 --- a/lib/simpleshop_theme_web/components/shop_components/product.ex +++ b/lib/berrypod_web/components/shop_components/product.ex @@ -1,10 +1,10 @@ -defmodule SimpleshopThemeWeb.ShopComponents.Product do +defmodule BerrypodWeb.ShopComponents.Product do use Phoenix.Component - import SimpleshopThemeWeb.ShopComponents.Base - import SimpleshopThemeWeb.ShopComponents.Content, only: [responsive_image: 1] + import BerrypodWeb.ShopComponents.Base + import BerrypodWeb.ShopComponents.Content, only: [responsive_image: 1] - alias SimpleshopTheme.Products.{Product, ProductImage} + alias Berrypod.Products.{Product, ProductImage} @doc """ Renders a product card with configurable variants. @@ -298,14 +298,14 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
<%= if @product.on_sale do %> - {SimpleshopTheme.Cart.format_price(@product.cheapest_price)} + {Berrypod.Cart.format_price(@product.cheapest_price)} - {SimpleshopTheme.Cart.format_price(@product.compare_at_price)} + {Berrypod.Cart.format_price(@product.compare_at_price)} <% else %> - {SimpleshopTheme.Cart.format_price(@product.cheapest_price)} + {Berrypod.Cart.format_price(@product.cheapest_price)} <% end %>
@@ -313,18 +313,18 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do

<%= if @product.on_sale do %> - {SimpleshopTheme.Cart.format_price(@product.compare_at_price)} + {Berrypod.Cart.format_price(@product.compare_at_price)} <% end %> - {SimpleshopTheme.Cart.format_price(@product.cheapest_price)} + {Berrypod.Cart.format_price(@product.cheapest_price)}

<% :compact -> %>

- {SimpleshopTheme.Cart.format_price(@product.cheapest_price)} + {Berrypod.Cart.format_price(@product.cheapest_price)}

<% :minimal -> %>

- {SimpleshopTheme.Cart.format_price(@product.cheapest_price)} + {Berrypod.Cart.format_price(@product.cheapest_price)}

<% end %> """ @@ -1294,17 +1294,17 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
<%= if @product.on_sale do %> - {SimpleshopTheme.Cart.format_price(@price)} + {Berrypod.Cart.format_price(@price)} - {SimpleshopTheme.Cart.format_price(@product.compare_at_price)} + {Berrypod.Cart.format_price(@product.compare_at_price)} SAVE {round((@product.compare_at_price - @price) / @product.compare_at_price * 100)}% <% else %> - {SimpleshopTheme.Cart.format_price(@price)} + {Berrypod.Cart.format_price(@price)} <% end %>
diff --git a/lib/berrypod_web/controllers/admin_controller.ex b/lib/berrypod_web/controllers/admin_controller.ex new file mode 100644 index 0000000..0cbb552 --- /dev/null +++ b/lib/berrypod_web/controllers/admin_controller.ex @@ -0,0 +1,7 @@ +defmodule BerrypodWeb.AdminController do + use BerrypodWeb, :controller + + def index(conn, _params) do + redirect(conn, to: ~p"/admin/orders") + end +end diff --git a/lib/simpleshop_theme_web/controllers/cart_controller.ex b/lib/berrypod_web/controllers/cart_controller.ex similarity index 85% rename from lib/simpleshop_theme_web/controllers/cart_controller.ex rename to lib/berrypod_web/controllers/cart_controller.ex index dc287fe..091fa9a 100644 --- a/lib/simpleshop_theme_web/controllers/cart_controller.ex +++ b/lib/berrypod_web/controllers/cart_controller.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.CartController do +defmodule BerrypodWeb.CartController do @moduledoc """ API controller for cart session persistence. @@ -6,9 +6,9 @@ defmodule SimpleshopThemeWeb.CartController do via this API endpoint called from a JS hook after each cart modification. """ - use SimpleshopThemeWeb, :controller + use BerrypodWeb, :controller - alias SimpleshopTheme.Cart + alias Berrypod.Cart @doc """ Updates the cart in session. diff --git a/lib/simpleshop_theme_web/controllers/checkout_controller.ex b/lib/berrypod_web/controllers/checkout_controller.ex similarity index 93% rename from lib/simpleshop_theme_web/controllers/checkout_controller.ex rename to lib/berrypod_web/controllers/checkout_controller.ex index 92267b3..a247b46 100644 --- a/lib/simpleshop_theme_web/controllers/checkout_controller.ex +++ b/lib/berrypod_web/controllers/checkout_controller.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.CheckoutController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.CheckoutController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Cart - alias SimpleshopTheme.Orders - alias SimpleshopTheme.Shipping + alias Berrypod.Cart + alias Berrypod.Orders + alias Berrypod.Shipping require Logger @@ -53,7 +53,7 @@ defmodule SimpleshopThemeWeb.CheckoutController do } end) - base_url = SimpleshopThemeWeb.Endpoint.url() + base_url = BerrypodWeb.Endpoint.url() params = %{ diff --git a/lib/simpleshop_theme_web/controllers/error_html.ex b/lib/berrypod_web/controllers/error_html.ex similarity index 92% rename from lib/simpleshop_theme_web/controllers/error_html.ex rename to lib/berrypod_web/controllers/error_html.ex index 9abc51c..7c482ee 100644 --- a/lib/simpleshop_theme_web/controllers/error_html.ex +++ b/lib/berrypod_web/controllers/error_html.ex @@ -1,16 +1,16 @@ -defmodule SimpleshopThemeWeb.ErrorHTML do +defmodule BerrypodWeb.ErrorHTML do @moduledoc """ This module is invoked by your endpoint in case of errors on HTML requests. See config/config.exs. """ - use SimpleshopThemeWeb, :html + use BerrypodWeb, :html - alias SimpleshopTheme.Settings - alias SimpleshopTheme.Settings.ThemeSettings - alias SimpleshopTheme.Media - alias SimpleshopTheme.Products - alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator} + alias Berrypod.Settings + alias Berrypod.Settings.ThemeSettings + alias Berrypod.Media + alias Berrypod.Products + alias Berrypod.Theme.{CSSCache, CSSGenerator} def render("404.html", assigns) do render_error_page( @@ -84,7 +84,7 @@ defmodule SimpleshopThemeWeb.ErrorHTML do data-layout={@theme_settings.layout_width} data-shadow={@theme_settings.card_shadow} > - put_status(:not_found) - |> put_view(SimpleshopThemeWeb.ErrorHTML) + |> put_view(BerrypodWeb.ErrorHTML) |> render("404.html") end def server_error(conn, _params) do conn |> put_status(:internal_server_error) - |> put_view(SimpleshopThemeWeb.ErrorHTML) + |> put_view(BerrypodWeb.ErrorHTML) |> render("500.html") end end diff --git a/lib/berrypod_web/controllers/health_controller.ex b/lib/berrypod_web/controllers/health_controller.ex new file mode 100644 index 0000000..6785328 --- /dev/null +++ b/lib/berrypod_web/controllers/health_controller.ex @@ -0,0 +1,7 @@ +defmodule BerrypodWeb.HealthController do + use BerrypodWeb, :controller + + def show(conn, _params) do + json(conn, %{status: "ok"}) + end +end diff --git a/lib/simpleshop_theme_web/controllers/image_controller.ex b/lib/berrypod_web/controllers/image_controller.ex similarity index 88% rename from lib/simpleshop_theme_web/controllers/image_controller.ex rename to lib/berrypod_web/controllers/image_controller.ex index 17fb283..04fe0d7 100644 --- a/lib/simpleshop_theme_web/controllers/image_controller.ex +++ b/lib/berrypod_web/controllers/image_controller.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.ImageController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.ImageController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Media - alias SimpleshopTheme.Media.SVGRecolorer + alias Berrypod.Media + alias Berrypod.Media.SVGRecolorer @doc """ Serves an SVG image recolored with the specified color. diff --git a/lib/berrypod_web/controllers/page_controller.ex b/lib/berrypod_web/controllers/page_controller.ex new file mode 100644 index 0000000..6abf24b --- /dev/null +++ b/lib/berrypod_web/controllers/page_controller.ex @@ -0,0 +1,7 @@ +defmodule BerrypodWeb.PageController do + use BerrypodWeb, :controller + + def home(conn, _params) do + render(conn, :home) + end +end diff --git a/lib/simpleshop_theme_web/controllers/page_html.ex b/lib/berrypod_web/controllers/page_html.ex similarity index 71% rename from lib/simpleshop_theme_web/controllers/page_html.ex rename to lib/berrypod_web/controllers/page_html.ex index b21c5a5..95e5a26 100644 --- a/lib/simpleshop_theme_web/controllers/page_html.ex +++ b/lib/berrypod_web/controllers/page_html.ex @@ -1,10 +1,10 @@ -defmodule SimpleshopThemeWeb.PageHTML do +defmodule BerrypodWeb.PageHTML do @moduledoc """ This module contains pages rendered by PageController. See the `page_html` directory for all templates available. """ - use SimpleshopThemeWeb, :html + use BerrypodWeb, :html embed_templates "page_html/*" end diff --git a/lib/simpleshop_theme_web/controllers/page_html/home.html.heex b/lib/berrypod_web/controllers/page_html/home.html.heex similarity index 100% rename from lib/simpleshop_theme_web/controllers/page_html/home.html.heex rename to lib/berrypod_web/controllers/page_html/home.html.heex diff --git a/lib/simpleshop_theme_web/controllers/stripe_webhook_controller.ex b/lib/berrypod_web/controllers/stripe_webhook_controller.ex similarity index 94% rename from lib/simpleshop_theme_web/controllers/stripe_webhook_controller.ex rename to lib/berrypod_web/controllers/stripe_webhook_controller.ex index a02a5ce..13418be 100644 --- a/lib/simpleshop_theme_web/controllers/stripe_webhook_controller.ex +++ b/lib/berrypod_web/controllers/stripe_webhook_controller.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.StripeWebhookController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.StripeWebhookController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Orders - alias SimpleshopTheme.Orders.{OrderNotifier, OrderSubmissionWorker} + alias Berrypod.Orders + alias Berrypod.Orders.{OrderNotifier, OrderSubmissionWorker} require Logger @@ -64,7 +64,7 @@ defmodule SimpleshopThemeWeb.StripeWebhookController do # Broadcast to success page via PubSub Phoenix.PubSub.broadcast( - SimpleshopTheme.PubSub, + Berrypod.PubSub, "order:#{order.id}:status", {:order_paid, order} ) diff --git a/lib/simpleshop_theme_web/controllers/user_session_controller.ex b/lib/berrypod_web/controllers/user_session_controller.ex similarity index 92% rename from lib/simpleshop_theme_web/controllers/user_session_controller.ex rename to lib/berrypod_web/controllers/user_session_controller.ex index ee0177f..3b40b7a 100644 --- a/lib/simpleshop_theme_web/controllers/user_session_controller.ex +++ b/lib/berrypod_web/controllers/user_session_controller.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.UserSessionController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.UserSessionController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Accounts - alias SimpleshopThemeWeb.UserAuth + alias Berrypod.Accounts + alias BerrypodWeb.UserAuth def create(conn, %{"_action" => "confirmed"} = params) do create(conn, params, "User confirmed successfully.") diff --git a/lib/simpleshop_theme_web/controllers/webhook_controller.ex b/lib/berrypod_web/controllers/webhook_controller.ex similarity index 93% rename from lib/simpleshop_theme_web/controllers/webhook_controller.ex rename to lib/berrypod_web/controllers/webhook_controller.ex index a6e5513..b1e42e7 100644 --- a/lib/simpleshop_theme_web/controllers/webhook_controller.ex +++ b/lib/berrypod_web/controllers/webhook_controller.ex @@ -1,7 +1,7 @@ -defmodule SimpleshopThemeWeb.WebhookController do - use SimpleshopThemeWeb, :controller +defmodule BerrypodWeb.WebhookController do + use BerrypodWeb, :controller - alias SimpleshopTheme.Webhooks + alias Berrypod.Webhooks require Logger diff --git a/lib/simpleshop_theme_web/endpoint.ex b/lib/berrypod_web/endpoint.ex similarity index 79% rename from lib/simpleshop_theme_web/endpoint.ex rename to lib/berrypod_web/endpoint.ex index bac0e84..102a008 100644 --- a/lib/simpleshop_theme_web/endpoint.ex +++ b/lib/berrypod_web/endpoint.ex @@ -1,12 +1,12 @@ -defmodule SimpleshopThemeWeb.Endpoint do - use Phoenix.Endpoint, otp_app: :simpleshop_theme +defmodule BerrypodWeb.Endpoint do + use Phoenix.Endpoint, otp_app: :berrypod # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. @session_options [ store: :cookie, - key: "_simpleshop_theme_key", + key: "_berrypod_key", signing_salt: "JNwRcD7y", same_site: "Lax" ] @@ -22,11 +22,11 @@ defmodule SimpleshopThemeWeb.Endpoint do # In dev, we omit the option to get the Plug.Static default ("public"). plug Plug.Static, at: "/", - from: :simpleshop_theme, + from: :berrypod, gzip: true, - only: SimpleshopThemeWeb.static_paths(), + only: BerrypodWeb.static_paths(), cache_control_for_etags: - if(Application.compile_env(:simpleshop_theme, :env) == :prod, + if(Application.compile_env(:berrypod, :env) == :prod, do: "public, max-age=31536000, immutable", else: "public" ) @@ -41,7 +41,7 @@ defmodule SimpleshopThemeWeb.Endpoint do socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket plug Phoenix.LiveReloader plug Phoenix.CodeReloader - plug Phoenix.Ecto.CheckRepoStatus, otp_app: :simpleshop_theme + plug Phoenix.Ecto.CheckRepoStatus, otp_app: :berrypod end plug Phoenix.LiveDashboard.RequestLogger, @@ -54,11 +54,11 @@ defmodule SimpleshopThemeWeb.Endpoint do plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], - body_reader: {SimpleshopThemeWeb.Plugs.CacheRawBody, :read_body, []}, + body_reader: {BerrypodWeb.Plugs.CacheRawBody, :read_body, []}, json_decoder: Phoenix.json_library() plug Plug.MethodOverride plug Plug.Head plug Plug.Session, @session_options - plug SimpleshopThemeWeb.Router + plug BerrypodWeb.Router end diff --git a/lib/simpleshop_theme_web/gettext.ex b/lib/berrypod_web/gettext.ex similarity index 82% rename from lib/simpleshop_theme_web/gettext.ex rename to lib/berrypod_web/gettext.ex index 1ff831f..003098b 100644 --- a/lib/simpleshop_theme_web/gettext.ex +++ b/lib/berrypod_web/gettext.ex @@ -1,4 +1,4 @@ -defmodule SimpleshopThemeWeb.Gettext do +defmodule BerrypodWeb.Gettext do @moduledoc """ A module providing Internationalization with a gettext-based API. @@ -6,7 +6,7 @@ defmodule SimpleshopThemeWeb.Gettext do that you can use in your application. To use this Gettext backend module, call `use Gettext` and pass it as an option: - use Gettext, backend: SimpleshopThemeWeb.Gettext + use Gettext, backend: BerrypodWeb.Gettext # Simple translation gettext("Here is the string to translate") @@ -21,5 +21,5 @@ defmodule SimpleshopThemeWeb.Gettext do See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage. """ - use Gettext.Backend, otp_app: :simpleshop_theme + use Gettext.Backend, otp_app: :berrypod end diff --git a/lib/simpleshop_theme_web/live/admin/dashboard.ex b/lib/berrypod_web/live/admin/dashboard.ex similarity index 98% rename from lib/simpleshop_theme_web/live/admin/dashboard.ex rename to lib/berrypod_web/live/admin/dashboard.ex index 9e2559c..f95a45e 100644 --- a/lib/simpleshop_theme_web/live/admin/dashboard.ex +++ b/lib/berrypod_web/live/admin/dashboard.ex @@ -1,10 +1,10 @@ -defmodule SimpleshopThemeWeb.Admin.Dashboard do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Dashboard do + use BerrypodWeb, :live_view - alias SimpleshopTheme.{Cart, Orders, Products, Settings, Setup} - alias SimpleshopTheme.Products.ProviderConnection - alias SimpleshopTheme.Providers - alias SimpleshopTheme.Stripe.Setup, as: StripeSetup + alias Berrypod.{Cart, Orders, Products, Settings, Setup} + alias Berrypod.Products.ProviderConnection + alias Berrypod.Providers + alias Berrypod.Stripe.Setup, as: StripeSetup @impl true def mount(_params, _session, socket) do @@ -16,7 +16,7 @@ defmodule SimpleshopThemeWeb.Admin.Dashboard do conn = Products.get_provider_connection_by_type("printify") if conn && connected?(socket) do - Phoenix.PubSub.subscribe(SimpleshopTheme.PubSub, "sync:#{conn.id}") + Phoenix.PubSub.subscribe(Berrypod.PubSub, "sync:#{conn.id}") end active_step = determine_active_step(status) @@ -100,7 +100,7 @@ defmodule SimpleshopThemeWeb.Admin.Dashboard do Products.enqueue_sync(connection) if connected?(socket) do - Phoenix.PubSub.subscribe(SimpleshopTheme.PubSub, "sync:#{connection.id}") + Phoenix.PubSub.subscribe(Berrypod.PubSub, "sync:#{connection.id}") end status = %{socket.assigns.setup | printify_connected: true} @@ -759,7 +759,7 @@ defmodule SimpleshopThemeWeb.Admin.Dashboard do end defp encrypt_api_key(api_key) do - case SimpleshopTheme.Vault.encrypt(api_key) do + case Berrypod.Vault.encrypt(api_key) do {:ok, encrypted} -> encrypted _ -> nil end diff --git a/lib/simpleshop_theme_web/live/admin/order_show.ex b/lib/berrypod_web/live/admin/order_show.ex similarity index 98% rename from lib/simpleshop_theme_web/live/admin/order_show.ex rename to lib/berrypod_web/live/admin/order_show.ex index 8d2ac13..db56135 100644 --- a/lib/simpleshop_theme_web/live/admin/order_show.ex +++ b/lib/berrypod_web/live/admin/order_show.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.Admin.OrderShow do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.OrderShow do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Orders - alias SimpleshopTheme.Cart + alias Berrypod.Orders + alias Berrypod.Cart @impl true def mount(%{"id" => id}, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/orders.ex b/lib/berrypod_web/live/admin/orders.ex similarity index 97% rename from lib/simpleshop_theme_web/live/admin/orders.ex rename to lib/berrypod_web/live/admin/orders.ex index cc2f77e..90f8049 100644 --- a/lib/simpleshop_theme_web/live/admin/orders.ex +++ b/lib/berrypod_web/live/admin/orders.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.Admin.Orders do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Orders do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Orders - alias SimpleshopTheme.Cart + alias Berrypod.Orders + alias Berrypod.Cart @impl true def mount(_params, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/product_show.ex b/lib/berrypod_web/live/admin/product_show.ex similarity index 98% rename from lib/simpleshop_theme_web/live/admin/product_show.ex rename to lib/berrypod_web/live/admin/product_show.ex index 43d2d73..3674e31 100644 --- a/lib/simpleshop_theme_web/live/admin/product_show.ex +++ b/lib/berrypod_web/live/admin/product_show.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.Admin.ProductShow do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.ProductShow do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.{Product, ProductImage, ProductVariant} - alias SimpleshopTheme.Cart + alias Berrypod.Products + alias Berrypod.Products.{Product, ProductImage, ProductVariant} + alias Berrypod.Cart @impl true def mount(%{"id" => id}, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/products.ex b/lib/berrypod_web/live/admin/products.ex similarity index 97% rename from lib/simpleshop_theme_web/live/admin/products.ex rename to lib/berrypod_web/live/admin/products.ex index 3ad2201..2036835 100644 --- a/lib/simpleshop_theme_web/live/admin/products.ex +++ b/lib/berrypod_web/live/admin/products.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.Admin.Products do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Products do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.{Product, ProductImage} - alias SimpleshopTheme.Cart + alias Berrypod.Products + alias Berrypod.Products.{Product, ProductImage} + alias Berrypod.Cart @impl true def mount(_params, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/providers/form.ex b/lib/berrypod_web/live/admin/providers/form.ex similarity index 95% rename from lib/simpleshop_theme_web/live/admin/providers/form.ex rename to lib/berrypod_web/live/admin/providers/form.ex index 5b0c33e..c15e1e1 100644 --- a/lib/simpleshop_theme_web/live/admin/providers/form.ex +++ b/lib/berrypod_web/live/admin/providers/form.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.Admin.Providers.Form do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Providers.Form do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProviderConnection - alias SimpleshopTheme.Providers + alias Berrypod.Products + alias Berrypod.Products.ProviderConnection + alias Berrypod.Providers @supported_types ~w(printify printful) @@ -136,7 +136,7 @@ defmodule SimpleshopThemeWeb.Admin.Providers.Form do end defp encrypt_api_key(api_key) do - case SimpleshopTheme.Vault.encrypt(api_key) do + case Berrypod.Vault.encrypt(api_key) do {:ok, encrypted} -> encrypted _ -> nil end diff --git a/lib/simpleshop_theme_web/live/admin/providers/form.html.heex b/lib/berrypod_web/live/admin/providers/form.html.heex similarity index 100% rename from lib/simpleshop_theme_web/live/admin/providers/form.html.heex rename to lib/berrypod_web/live/admin/providers/form.html.heex diff --git a/lib/simpleshop_theme_web/live/admin/providers/index.ex b/lib/berrypod_web/live/admin/providers/index.ex similarity index 93% rename from lib/simpleshop_theme_web/live/admin/providers/index.ex rename to lib/berrypod_web/live/admin/providers/index.ex index 37ee029..7938000 100644 --- a/lib/simpleshop_theme_web/live/admin/providers/index.ex +++ b/lib/berrypod_web/live/admin/providers/index.ex @@ -1,8 +1,8 @@ -defmodule SimpleshopThemeWeb.Admin.Providers.Index do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Providers.Index do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Products - alias SimpleshopTheme.Products.ProviderConnection + alias Berrypod.Products + alias Berrypod.Products.ProviderConnection @impl true def mount(_params, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/providers/index.html.heex b/lib/berrypod_web/live/admin/providers/index.html.heex similarity index 100% rename from lib/simpleshop_theme_web/live/admin/providers/index.html.heex rename to lib/berrypod_web/live/admin/providers/index.html.heex diff --git a/lib/simpleshop_theme_web/live/admin/settings.ex b/lib/berrypod_web/live/admin/settings.ex similarity index 98% rename from lib/simpleshop_theme_web/live/admin/settings.ex rename to lib/berrypod_web/live/admin/settings.ex index 9a044c9..12ea7b4 100644 --- a/lib/simpleshop_theme_web/live/admin/settings.ex +++ b/lib/berrypod_web/live/admin/settings.ex @@ -1,10 +1,10 @@ -defmodule SimpleshopThemeWeb.Admin.Settings do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Settings do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Accounts - alias SimpleshopTheme.Products - alias SimpleshopTheme.Settings - alias SimpleshopTheme.Stripe.Setup, as: StripeSetup + alias Berrypod.Accounts + alias Berrypod.Products + alias Berrypod.Settings + alias Berrypod.Stripe.Setup, as: StripeSetup @impl true def mount(_params, _session, socket) do diff --git a/lib/simpleshop_theme_web/live/admin/theme/index.ex b/lib/berrypod_web/live/admin/theme/index.ex similarity index 93% rename from lib/simpleshop_theme_web/live/admin/theme/index.ex rename to lib/berrypod_web/live/admin/theme/index.ex index d79ee8e..13e6b25 100644 --- a/lib/simpleshop_theme_web/live/admin/theme/index.ex +++ b/lib/berrypod_web/live/admin/theme/index.ex @@ -1,9 +1,9 @@ -defmodule SimpleshopThemeWeb.Admin.Theme.Index do - use SimpleshopThemeWeb, :live_view +defmodule BerrypodWeb.Admin.Theme.Index do + use BerrypodWeb, :live_view - alias SimpleshopTheme.Settings - alias SimpleshopTheme.Media - alias SimpleshopTheme.Theme.{CSSGenerator, Presets, PreviewData} + alias Berrypod.Settings + alias Berrypod.Media + alias Berrypod.Theme.{CSSGenerator, Presets, PreviewData} @impl true def mount(_params, _session, socket) do @@ -329,12 +329,12 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do defp preview_page(%{page: :home} = assigns) do assigns = preview_assigns(assigns) - ~H"" + ~H"" end defp preview_page(%{page: :collection} = assigns) do assigns = preview_assigns(assigns) - ~H"" + ~H"" end defp preview_page(%{page: :pdp} = assigns) do @@ -369,7 +369,7 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do |> assign(:display_price, display_price) |> assign(:quantity, 1) - ~H"" + ~H"" end defp preview_page(%{page: :cart} = assigns) do @@ -386,7 +386,7 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do |> assign(:cart_page_items, cart_items) |> assign(:cart_page_subtotal, subtotal) - ~H"" + ~H"" end defp preview_page(%{page: :about} = assigns) do @@ -403,7 +403,7 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do content_blocks: PreviewData.about_content() }) - ~H"" + ~H"" end defp preview_page(%{page: :delivery} = assigns) do @@ -417,7 +417,7 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do content_blocks: PreviewData.delivery_content() }) - ~H"" + ~H"" end defp preview_page(%{page: :privacy} = assigns) do @@ -431,7 +431,7 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do content_blocks: PreviewData.privacy_content() }) - ~H"" + ~H"" end defp preview_page(%{page: :terms} = assigns) do @@ -445,12 +445,12 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do content_blocks: PreviewData.terms_content() }) - ~H"" + ~H"" end defp preview_page(%{page: :contact} = assigns) do assigns = preview_assigns(assigns) - ~H"" + ~H"" end defp preview_page(%{page: :error} = assigns) do @@ -464,11 +464,11 @@ defmodule SimpleshopThemeWeb.Admin.Theme.Index do "Sorry, we couldn't find the page you're looking for. Perhaps you've mistyped the URL or the page has been moved." }) - ~H"" + ~H"" end defp build_gallery_images(product) do - alias SimpleshopTheme.Products.ProductImage + alias Berrypod.Products.ProductImage (Map.get(product, :images) || []) |> Enum.sort_by(& &1.position) diff --git a/lib/simpleshop_theme_web/live/admin/theme/index.html.heex b/lib/berrypod_web/live/admin/theme/index.html.heex similarity index 99% rename from lib/simpleshop_theme_web/live/admin/theme/index.html.heex rename to lib/berrypod_web/live/admin/theme/index.html.heex index 9227652..ab986b5 100644 --- a/lib/simpleshop_theme_web/live/admin/theme/index.html.heex +++ b/lib/berrypod_web/live/admin/theme/index.html.heex @@ -1161,8 +1161,8 @@ >