rename project from SimpleshopTheme to Berrypod
All modules, configs, paths, and references updated. 836 tests pass, zero warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Cldr do
|
||||
defmodule Berrypod.Cldr do
|
||||
@moduledoc """
|
||||
CLDR backend for internationalization and currency formatting.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Clients.Printful do
|
||||
defmodule Berrypod.Clients.Printful do
|
||||
@moduledoc """
|
||||
HTTP client for the Printful API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Clients.Printify do
|
||||
defmodule Berrypod.Clients.Printify do
|
||||
@moduledoc """
|
||||
HTTP client for the Printify API.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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__)
|
||||
3
lib/berrypod/mailer.ex
Normal file
3
lib/berrypod/mailer.ex
Normal file
@@ -0,0 +1,3 @@
|
||||
defmodule Berrypod.Mailer do
|
||||
use Swoosh.Mailer, otp_app: :berrypod
|
||||
end
|
||||
@@ -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.
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Media.Image do
|
||||
defmodule Berrypod.Media.Image do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 """
|
||||
@@ -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 ->
|
||||
5
lib/berrypod/repo.ex
Normal file
5
lib/berrypod/repo.ex
Normal file
@@ -0,0 +1,5 @@
|
||||
defmodule Berrypod.Repo do
|
||||
use Ecto.Repo,
|
||||
otp_app: :berrypod,
|
||||
adapter: Ecto.Adapters.SQLite3
|
||||
end
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Settings.Setting do
|
||||
defmodule Berrypod.Settings.Setting do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopTheme.Settings.ThemeSettings do
|
||||
defmodule Berrypod.Settings.ThemeSettings do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}")
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
"""
|
||||
@@ -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
|
||||
@@ -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 %{
|
||||
@@ -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,
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
@@ -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}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -12,7 +12,7 @@
|
||||
>
|
||||
<.icon name="hero-bars-3" class="size-5" />
|
||||
</label>
|
||||
<span class="admin-topbar-title">SimpleShop</span>
|
||||
<span class="admin-topbar-title">Berrypod</span>
|
||||
<.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
|
||||
</.link>
|
||||
@@ -33,7 +33,7 @@
|
||||
<%!-- sidebar header --%>
|
||||
<div class="p-4 border-b border-base-300">
|
||||
<.link navigate={~p"/admin"} class="text-lg font-bold tracking-tight">
|
||||
SimpleShop
|
||||
Berrypod
|
||||
</.link>
|
||||
<p class="text-xs text-base-content/60 mt-0.5 truncate">
|
||||
{@current_scope.user.email}
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="csrf-token" content={get_csrf_token()} />
|
||||
<.live_title default="Admin" suffix=" · SimpleShop">
|
||||
<.live_title default="Admin" suffix=" · Berrypod">
|
||||
{assigns[:page_title]}
|
||||
</.live_title>
|
||||
<!-- Pre-declare layer order so shop reset < Tailwind base regardless of load order -->
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="csrf-token" content={get_csrf_token()} />
|
||||
<.live_title default="SimpleshopTheme" suffix=" · Phoenix Framework">
|
||||
<.live_title default="Berrypod" suffix=" · Phoenix Framework">
|
||||
{assigns[:page_title]}
|
||||
</.live_title>
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/css/admin.css"} />
|
||||
@@ -13,9 +13,9 @@
|
||||
/>
|
||||
<.live_title>{assigns[:page_title] || @theme_settings.site_name}</.live_title>
|
||||
<!-- Preload critical fonts for the current typography preset -->
|
||||
<%= 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 %>
|
||||
<link rel="preload" href={preload.href} as="font" type="font/woff2" crossorigin />
|
||||
<% end %>
|
||||
@@ -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
|
||||
@@ -52,7 +52,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<span class="checkout-item-price">
|
||||
{SimpleshopTheme.Cart.format_price(item.unit_price * item.quantity)}
|
||||
{Berrypod.Cart.format_price(item.unit_price * item.quantity)}
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
@@ -62,7 +62,7 @@
|
||||
<div class="checkout-total">
|
||||
<span class="checkout-total-label">Total</span>
|
||||
<span class="checkout-total-amount">
|
||||
{SimpleshopTheme.Cart.format_price(@order.total)}
|
||||
{Berrypod.Cart.format_price(@order.total)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,7 +2,7 @@
|
||||
<main id="main-content">
|
||||
<.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"
|
||||
@@ -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}
|
||||
/>
|
||||
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopThemeWeb.ShopComponents.Base do
|
||||
defmodule BerrypodWeb.ShopComponents.Base do
|
||||
use Phoenix.Component
|
||||
|
||||
@doc """
|
||||
@@ -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
|
||||
|
||||
<div class="cart-item-price-col">
|
||||
<p class="cart-item-price" data-size={if @size == :compact, do: "compact"}>
|
||||
{SimpleshopTheme.Cart.format_price(@item.price * @item.quantity)}
|
||||
{Berrypod.Cart.format_price(@item.price * @item.quantity)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -370,7 +370,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
|
||||
|
||||
<div class="cart-page-item-price-col">
|
||||
<p class="cart-page-item-price">
|
||||
{SimpleshopTheme.Cart.format_price(@item.product.cheapest_price * @item.quantity)}
|
||||
{Berrypod.Cart.format_price(@item.product.cheapest_price * @item.quantity)}
|
||||
</p>
|
||||
</div>
|
||||
</.shop_card>
|
||||
@@ -406,11 +406,11 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
|
||||
</select>
|
||||
</form>
|
||||
<% else %>
|
||||
<span>{SimpleshopTheme.Shipping.country_name(@country_code)}</span>
|
||||
<span>{Berrypod.Shipping.country_name(@country_code)}</span>
|
||||
<% end %>
|
||||
</span>
|
||||
<%= if @shipping_estimate do %>
|
||||
<span>{SimpleshopTheme.Cart.format_price(@shipping_estimate)}</span>
|
||||
<span>{Berrypod.Cart.format_price(@shipping_estimate)}</span>
|
||||
<% else %>
|
||||
<span>Calculated at checkout</span>
|
||||
<% end %>
|
||||
@@ -453,7 +453,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
|
||||
<div class="order-summary-line">
|
||||
<span>Subtotal</span>
|
||||
<span>
|
||||
{SimpleshopTheme.Cart.format_price(@subtotal)}
|
||||
{Berrypod.Cart.format_price(@subtotal)}
|
||||
</span>
|
||||
</div>
|
||||
<.delivery_line
|
||||
@@ -468,7 +468,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
|
||||
{if @shipping_estimate, do: "Estimated total", else: "Subtotal"}
|
||||
</span>
|
||||
<span>
|
||||
{SimpleshopTheme.Cart.format_price(@estimated_total)}
|
||||
{Berrypod.Cart.format_price(@estimated_total)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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)
|
||||
@@ -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(
|
||||
@@ -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
|
||||
<div>
|
||||
<%= if @product.on_sale do %>
|
||||
<span class="product-price--sale">
|
||||
{SimpleshopTheme.Cart.format_price(@product.cheapest_price)}
|
||||
{Berrypod.Cart.format_price(@product.cheapest_price)}
|
||||
</span>
|
||||
<span class="product-price--compare">
|
||||
{SimpleshopTheme.Cart.format_price(@product.compare_at_price)}
|
||||
{Berrypod.Cart.format_price(@product.compare_at_price)}
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="product-price--regular">
|
||||
{SimpleshopTheme.Cart.format_price(@product.cheapest_price)}
|
||||
{Berrypod.Cart.format_price(@product.cheapest_price)}
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -313,18 +313,18 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
|
||||
<p class="product-price--secondary">
|
||||
<%= if @product.on_sale do %>
|
||||
<span class="product-price--compare">
|
||||
{SimpleshopTheme.Cart.format_price(@product.compare_at_price)}
|
||||
{Berrypod.Cart.format_price(@product.compare_at_price)}
|
||||
</span>
|
||||
<% end %>
|
||||
{SimpleshopTheme.Cart.format_price(@product.cheapest_price)}
|
||||
{Berrypod.Cart.format_price(@product.cheapest_price)}
|
||||
</p>
|
||||
<% :compact -> %>
|
||||
<p class="product-price--regular">
|
||||
{SimpleshopTheme.Cart.format_price(@product.cheapest_price)}
|
||||
{Berrypod.Cart.format_price(@product.cheapest_price)}
|
||||
</p>
|
||||
<% :minimal -> %>
|
||||
<p class="product-price--secondary">
|
||||
{SimpleshopTheme.Cart.format_price(@product.cheapest_price)}
|
||||
{Berrypod.Cart.format_price(@product.cheapest_price)}
|
||||
</p>
|
||||
<% end %>
|
||||
"""
|
||||
@@ -1294,17 +1294,17 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
|
||||
<div class="pdp-price-row">
|
||||
<%= if @product.on_sale do %>
|
||||
<span class="product-price--sale">
|
||||
{SimpleshopTheme.Cart.format_price(@price)}
|
||||
{Berrypod.Cart.format_price(@price)}
|
||||
</span>
|
||||
<span class="product-price--compare">
|
||||
{SimpleshopTheme.Cart.format_price(@product.compare_at_price)}
|
||||
{Berrypod.Cart.format_price(@product.compare_at_price)}
|
||||
</span>
|
||||
<span class="sale-badge">
|
||||
SAVE {round((@product.compare_at_price - @price) / @product.compare_at_price * 100)}%
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="product-price--regular">
|
||||
{SimpleshopTheme.Cart.format_price(@price)}
|
||||
{Berrypod.Cart.format_price(@price)}
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
7
lib/berrypod_web/controllers/admin_controller.ex
Normal file
7
lib/berrypod_web/controllers/admin_controller.ex
Normal file
@@ -0,0 +1,7 @@
|
||||
defmodule BerrypodWeb.AdminController do
|
||||
use BerrypodWeb, :controller
|
||||
|
||||
def index(conn, _params) do
|
||||
redirect(conn, to: ~p"/admin/orders")
|
||||
end
|
||||
end
|
||||
@@ -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.
|
||||
@@ -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 =
|
||||
%{
|
||||
@@ -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}
|
||||
>
|
||||
<SimpleshopThemeWeb.PageTemplates.error
|
||||
<BerrypodWeb.PageTemplates.error
|
||||
theme_settings={@theme_settings}
|
||||
logo_image={@logo_image}
|
||||
header_image={@header_image}
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule SimpleshopThemeWeb.ErrorJSON do
|
||||
defmodule BerrypodWeb.ErrorJSON do
|
||||
@moduledoc """
|
||||
This module is invoked by your endpoint in case of errors on JSON requests.
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
defmodule SimpleshopThemeWeb.ErrorPreviewController do
|
||||
defmodule BerrypodWeb.ErrorPreviewController do
|
||||
@moduledoc """
|
||||
Development-only controller for previewing error pages.
|
||||
"""
|
||||
use SimpleshopThemeWeb, :controller
|
||||
use BerrypodWeb, :controller
|
||||
|
||||
def not_found(conn, _params) do
|
||||
conn
|
||||
|> 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
|
||||
7
lib/berrypod_web/controllers/health_controller.ex
Normal file
7
lib/berrypod_web/controllers/health_controller.ex
Normal file
@@ -0,0 +1,7 @@
|
||||
defmodule BerrypodWeb.HealthController do
|
||||
use BerrypodWeb, :controller
|
||||
|
||||
def show(conn, _params) do
|
||||
json(conn, %{status: "ok"})
|
||||
end
|
||||
end
|
||||
@@ -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.
|
||||
7
lib/berrypod_web/controllers/page_controller.ex
Normal file
7
lib/berrypod_web/controllers/page_controller.ex
Normal file
@@ -0,0 +1,7 @@
|
||||
defmodule BerrypodWeb.PageController do
|
||||
use BerrypodWeb, :controller
|
||||
|
||||
def home(conn, _params) do
|
||||
render(conn, :home)
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
@@ -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}
|
||||
)
|
||||
@@ -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.")
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user