2026-02-18 21:23:15 +00:00
|
|
|
defmodule BerrypodWeb.Admin.OrderShow do
|
|
|
|
|
use BerrypodWeb, :live_view
|
2026-02-07 21:59:14 +00:00
|
|
|
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
alias Berrypod.{ActivityLog, Orders}
|
2026-02-18 21:23:15 +00:00
|
|
|
alias Berrypod.Cart
|
2026-02-07 21:59:14 +00:00
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def mount(%{"id" => id}, _session, socket) do
|
|
|
|
|
case Orders.get_order(id) do
|
|
|
|
|
nil ->
|
|
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> put_flash(:error, "Order not found")
|
|
|
|
|
|> push_navigate(to: ~p"/admin/orders")
|
|
|
|
|
|
|
|
|
|
{:ok, socket}
|
|
|
|
|
|
|
|
|
|
order ->
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
if connected?(socket), do: ActivityLog.subscribe(order.id)
|
|
|
|
|
|
|
|
|
|
timeline = ActivityLog.list_for_order(order.id)
|
|
|
|
|
|
2026-02-07 21:59:14 +00:00
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:page_title, order.order_number)
|
|
|
|
|
|> assign(:order, order)
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
|> assign(:timeline, timeline)
|
2026-02-07 21:59:14 +00:00
|
|
|
|
|
|
|
|
{:ok, socket}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:new_activity, entry}, socket) do
|
|
|
|
|
{:noreply, assign(socket, :timeline, socket.assigns.timeline ++ [entry])}
|
|
|
|
|
end
|
|
|
|
|
|
2026-02-07 21:59:14 +00:00
|
|
|
@impl true
|
|
|
|
|
def render(assigns) do
|
|
|
|
|
~H"""
|
2026-02-12 08:35:22 +00:00
|
|
|
<.header>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<.link navigate={~p"/admin/orders"} class="admin-back-link">
|
2026-02-12 08:35:22 +00:00
|
|
|
← Orders
|
|
|
|
|
</.link>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-product-header">
|
|
|
|
|
<span class="admin-product-title">{@order.order_number}</span>
|
2026-02-12 08:35:22 +00:00
|
|
|
<.status_badge status={@order.payment_status} />
|
|
|
|
|
</div>
|
|
|
|
|
</.header>
|
|
|
|
|
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-grid order-detail-grid">
|
2026-02-12 08:35:22 +00:00
|
|
|
<%!-- order info --%>
|
2026-02-17 23:05:01 +00:00
|
|
|
<div class="admin-card">
|
|
|
|
|
<div class="admin-card-body">
|
|
|
|
|
<h3 class="admin-card-title">Order details</h3>
|
2026-02-12 08:35:22 +00:00
|
|
|
<.list>
|
|
|
|
|
<:item title="Date">{format_date(@order.inserted_at)}</:item>
|
|
|
|
|
<:item title="Customer">{@order.customer_email || "—"}</:item>
|
|
|
|
|
<:item title="Payment status">
|
|
|
|
|
<.status_badge status={@order.payment_status} />
|
|
|
|
|
</:item>
|
|
|
|
|
<:item :if={@order.stripe_payment_intent_id} title="Stripe payment">
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<code class="admin-code-sm">{@order.stripe_payment_intent_id}</code>
|
2026-02-12 08:35:22 +00:00
|
|
|
</:item>
|
|
|
|
|
<:item title="Currency">{String.upcase(@order.currency)}</:item>
|
|
|
|
|
</.list>
|
2026-02-07 21:59:14 +00:00
|
|
|
</div>
|
2026-02-12 08:35:22 +00:00
|
|
|
</div>
|
2026-02-07 21:59:14 +00:00
|
|
|
|
2026-02-12 08:35:22 +00:00
|
|
|
<%!-- shipping address --%>
|
2026-02-17 23:05:01 +00:00
|
|
|
<div class="admin-card">
|
|
|
|
|
<div class="admin-card-body">
|
|
|
|
|
<h3 class="admin-card-title">Shipping address</h3>
|
2026-02-12 08:35:22 +00:00
|
|
|
<%= if @order.shipping_address != %{} do %>
|
2026-02-07 21:59:14 +00:00
|
|
|
<.list>
|
2026-02-12 08:35:22 +00:00
|
|
|
<:item :if={@order.shipping_address["name"]} title="Name">
|
|
|
|
|
{@order.shipping_address["name"]}
|
|
|
|
|
</:item>
|
|
|
|
|
<:item :if={@order.shipping_address["line1"]} title="Address">
|
|
|
|
|
{@order.shipping_address["line1"]}
|
|
|
|
|
<span :if={@order.shipping_address["line2"]}>
|
|
|
|
|
<br />{@order.shipping_address["line2"]}
|
|
|
|
|
</span>
|
|
|
|
|
</:item>
|
|
|
|
|
<:item :if={@order.shipping_address["city"]} title="City">
|
|
|
|
|
{@order.shipping_address["city"]}
|
|
|
|
|
</:item>
|
|
|
|
|
<:item :if={@order.shipping_address["state"] not in [nil, ""]} title="State">
|
|
|
|
|
{@order.shipping_address["state"]}
|
2026-02-07 21:59:14 +00:00
|
|
|
</:item>
|
2026-02-12 08:35:22 +00:00
|
|
|
<:item :if={@order.shipping_address["postal_code"]} title="Postcode">
|
|
|
|
|
{@order.shipping_address["postal_code"]}
|
|
|
|
|
</:item>
|
|
|
|
|
<:item :if={@order.shipping_address["country"]} title="Country">
|
|
|
|
|
{@order.shipping_address["country"]}
|
2026-02-07 21:59:14 +00:00
|
|
|
</:item>
|
|
|
|
|
</.list>
|
2026-02-12 08:35:22 +00:00
|
|
|
<% else %>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<p class="admin-section-desc admin-section-desc-flush">No shipping address provided</p>
|
2026-02-12 08:35:22 +00:00
|
|
|
<% end %>
|
2026-02-07 21:59:14 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-02-12 08:35:22 +00:00
|
|
|
</div>
|
2026-02-07 21:59:14 +00:00
|
|
|
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
<%!-- timeline --%>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-card admin-card-spaced">
|
2026-02-17 23:05:01 +00:00
|
|
|
<div class="admin-card-body">
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-row admin-row-between">
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
<h3 class="admin-card-title">Timeline</h3>
|
2026-02-12 08:35:22 +00:00
|
|
|
<.fulfilment_badge status={@order.fulfilment_status} />
|
|
|
|
|
</div>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-row order-timeline-actions">
|
2026-02-12 08:35:22 +00:00
|
|
|
<button
|
|
|
|
|
:if={can_submit?(@order)}
|
|
|
|
|
phx-click="submit_to_provider"
|
2026-02-17 23:05:01 +00:00
|
|
|
class="admin-btn admin-btn-primary admin-btn-sm"
|
2026-02-12 08:35:22 +00:00
|
|
|
>
|
|
|
|
|
<.icon name="hero-paper-airplane-mini" class="size-4" />
|
|
|
|
|
{if @order.fulfilment_status == "failed",
|
|
|
|
|
do: "Retry submission",
|
|
|
|
|
else: "Submit to provider"}
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
:if={can_refresh?(@order)}
|
|
|
|
|
phx-click="refresh_status"
|
2026-02-17 23:05:01 +00:00
|
|
|
class="admin-btn admin-btn-ghost admin-btn-sm"
|
2026-02-12 08:35:22 +00:00
|
|
|
>
|
|
|
|
|
<.icon name="hero-arrow-path-mini" class="size-4" /> Refresh status
|
|
|
|
|
</button>
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
</div>
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
<div
|
|
|
|
|
:if={@order.tracking_number not in [nil, ""]}
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
class="admin-row order-tracking"
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
>
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
<span class="admin-text-secondary"><.icon name="hero-truck-mini" class="size-4" /></span>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<span class="admin-text-medium">{@order.tracking_number}</span>
|
add external link UX: icons, rel attributes, screen reader labels
New external_link component in core_components handles target="_blank",
rel="noopener noreferrer", external-link icon, and sr-only "(opens in
new tab)" text. Migrated admin providers form, settings (Stripe),
order tracking, onboarding setup links to use it. Fixed rel="noopener"
to "noopener noreferrer" on remaining links (email settings, product
show, core_components card radio). Added sr-only text to shop social
link cards and aria-label to page renderer tracking link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:55:09 +00:00
|
|
|
<.external_link
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
:if={@order.tracking_url not in [nil, ""]}
|
|
|
|
|
href={@order.tracking_url}
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
class="admin-link"
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
>
|
add external link UX: icons, rel attributes, screen reader labels
New external_link component in core_components handles target="_blank",
rel="noopener noreferrer", external-link icon, and sr-only "(opens in
new tab)" text. Migrated admin providers form, settings (Stripe),
order tracking, onboarding setup links to use it. Fixed rel="noopener"
to "noopener noreferrer" on remaining links (email settings, product
show, core_components card radio). Added sr-only text to shop social
link cards and aria-label to page renderer tracking link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:55:09 +00:00
|
|
|
Track shipment
|
|
|
|
|
</.external_link>
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
</div>
|
|
|
|
|
<.order_timeline entries={@timeline} />
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
</div>
|
2026-02-12 08:35:22 +00:00
|
|
|
</div>
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
|
2026-02-12 08:35:22 +00:00
|
|
|
<%!-- line items --%>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div class="admin-card admin-card-spaced">
|
2026-02-17 23:05:01 +00:00
|
|
|
<div class="admin-card-body">
|
|
|
|
|
<h3 class="admin-card-title">Items</h3>
|
|
|
|
|
<table class="admin-table admin-table-zebra">
|
2026-02-12 08:35:22 +00:00
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Product</th>
|
|
|
|
|
<th>Variant</th>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<th class="admin-cell-end">Qty</th>
|
|
|
|
|
<th class="admin-cell-end">Unit price</th>
|
|
|
|
|
<th class="admin-cell-end">Total</th>
|
2026-02-12 08:35:22 +00:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr :for={item <- @order.items}>
|
|
|
|
|
<td>{item.product_name}</td>
|
|
|
|
|
<td>{item.variant_title}</td>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<td class="admin-cell-numeric">{item.quantity}</td>
|
|
|
|
|
<td class="admin-cell-numeric">{Cart.format_price(item.unit_price)}</td>
|
|
|
|
|
<td class="admin-cell-numeric">{Cart.format_price(item.unit_price * item.quantity)}</td>
|
2026-02-12 08:35:22 +00:00
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
<tfoot>
|
|
|
|
|
<tr>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<td colspan="4" class="admin-cell-end admin-text-medium">Subtotal</td>
|
|
|
|
|
<td class="admin-cell-end admin-text-medium">{Cart.format_price(@order.subtotal)}</td>
|
2026-02-12 08:35:22 +00:00
|
|
|
</tr>
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<tr class="order-total-row">
|
|
|
|
|
<td colspan="4" class="admin-cell-end admin-text-bold">Total</td>
|
|
|
|
|
<td class="admin-cell-end admin-text-bold">{Cart.format_price(@order.total)}</td>
|
2026-02-12 08:35:22 +00:00
|
|
|
</tr>
|
|
|
|
|
</tfoot>
|
|
|
|
|
</table>
|
2026-02-07 21:59:14 +00:00
|
|
|
</div>
|
2026-02-12 08:35:22 +00:00
|
|
|
</div>
|
2026-02-07 21:59:14 +00:00
|
|
|
"""
|
|
|
|
|
end
|
|
|
|
|
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
@impl true
|
|
|
|
|
def handle_event("submit_to_provider", _params, socket) do
|
|
|
|
|
order = socket.assigns.order
|
|
|
|
|
|
|
|
|
|
case Orders.submit_to_provider(order) do
|
|
|
|
|
{:ok, updated} ->
|
|
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:order, updated)
|
|
|
|
|
|> put_flash(:info, "Order submitted to provider")
|
|
|
|
|
|
|
|
|
|
{:noreply, socket}
|
|
|
|
|
|
|
|
|
|
{:error, _reason} ->
|
|
|
|
|
order = Orders.get_order(order.id)
|
|
|
|
|
|
|
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:order, order)
|
|
|
|
|
|> put_flash(:error, order.fulfilment_error || "Submission failed")
|
|
|
|
|
|
|
|
|
|
{:noreply, socket}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def handle_event("refresh_status", _params, socket) do
|
|
|
|
|
order = socket.assigns.order
|
|
|
|
|
|
|
|
|
|
case Orders.refresh_fulfilment_status(order) do
|
|
|
|
|
{:ok, updated} ->
|
|
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:order, updated)
|
|
|
|
|
|> put_flash(:info, "Status refreshed")
|
|
|
|
|
|
|
|
|
|
{:noreply, socket}
|
|
|
|
|
|
|
|
|
|
{:error, reason} ->
|
|
|
|
|
{:noreply, put_flash(socket, :error, "Failed to refresh: #{inspect(reason)}")}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
# ── Components ──
|
|
|
|
|
|
|
|
|
|
defp order_timeline(assigns) do
|
|
|
|
|
~H"""
|
complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones)
- Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid
primitives and gap variants (sm, md, lg, xl)
- Add transitions.css import and layout.css import to admin.css entry point
- Replace all Tailwind utility classes across 26 admin templates with
semantic admin-*/theme-*/page-specific CSS classes
- Replace all non-dynamic inline styles with semantic classes
- Add ~100 new semantic classes to components.css (analytics, dashboard,
order detail, settings, theme editor, generic utilities)
- Fix stray text-error → admin-text-error in media.ex
- Add missing .truncate definition to admin CSS
- Only remaining inline styles are dynamic data values (progress bars,
chart dimensions) and one JS.toggle target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:40:21 +00:00
|
|
|
<div :if={@entries == []} class="admin-section-desc order-timeline-empty">
|
add activity log with order timeline and global feed
Single activity_log table powering two views: chronological timeline
on each order detail page (replacing the old fulfilment card) and a
global feed at /admin/activity with tabs, category filters, search,
and pagination. Real-time via PubSub — new entries appear instantly,
nav badge updates across all admin pages.
Instrumented across all event points: Stripe webhooks, order notifier,
submission worker, fulfilment status worker, product sync worker, and
Oban exhausted-job telemetry. Contextual action buttons (retry
submission, retry sync, dismiss) with Oban unique constraints to
prevent double-enqueue. 90-day pruning via cron.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:09:08 +00:00
|
|
|
No activity recorded yet.
|
|
|
|
|
</div>
|
|
|
|
|
<ol :if={@entries != []} class="admin-timeline" id="order-timeline">
|
|
|
|
|
<li :for={entry <- @entries} class="admin-timeline-item">
|
|
|
|
|
<div class={["admin-timeline-dot", timeline_dot_class(entry.level)]}></div>
|
|
|
|
|
<div class="admin-timeline-content">
|
|
|
|
|
<p class="admin-timeline-message">{entry.message}</p>
|
|
|
|
|
<time class="admin-timeline-time" datetime={DateTime.to_iso8601(entry.occurred_at)}>
|
|
|
|
|
{format_timeline_time(entry.occurred_at)}
|
|
|
|
|
</time>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
"""
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp timeline_dot_class("error"), do: "admin-timeline-dot-error"
|
|
|
|
|
defp timeline_dot_class("warning"), do: "admin-timeline-dot-warning"
|
|
|
|
|
defp timeline_dot_class(_), do: "admin-timeline-dot-info"
|
|
|
|
|
|
|
|
|
|
defp format_timeline_time(datetime) do
|
|
|
|
|
today = Date.utc_today()
|
|
|
|
|
event_date = DateTime.to_date(datetime)
|
|
|
|
|
diff_days = Date.diff(today, event_date)
|
|
|
|
|
|
|
|
|
|
cond do
|
|
|
|
|
diff_days == 0 -> Calendar.strftime(datetime, "%H:%M")
|
|
|
|
|
diff_days < 7 -> Calendar.strftime(datetime, "%d %b %H:%M")
|
|
|
|
|
true -> Calendar.strftime(datetime, "%d %b %Y")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
defp can_submit?(order) do
|
|
|
|
|
order.payment_status == "paid" and order.fulfilment_status in ["unfulfilled", "failed"]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp can_refresh?(order) do
|
|
|
|
|
not is_nil(order.provider_order_id) and
|
|
|
|
|
order.fulfilment_status in ["submitted", "processing", "shipped"]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp fulfilment_badge(assigns) do
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
{color, icon} =
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
case assigns.status do
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
"submitted" -> {"admin-status-pill-blue", "hero-paper-airplane-mini"}
|
|
|
|
|
"processing" -> {"admin-status-pill-amber", "hero-cog-6-tooth-mini"}
|
|
|
|
|
"shipped" -> {"admin-status-pill-purple", "hero-truck-mini"}
|
|
|
|
|
"delivered" -> {"admin-status-pill-green", "hero-check-circle-mini"}
|
|
|
|
|
"failed" -> {"admin-status-pill-red", "hero-x-circle-mini"}
|
|
|
|
|
"cancelled" -> {"admin-status-pill-zinc", "hero-no-symbol-mini"}
|
|
|
|
|
_ -> {"admin-status-pill-zinc", "hero-minus-circle-mini"}
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
end
|
|
|
|
|
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
assigns = assign(assigns, color: color, icon: icon)
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
|
|
|
|
|
~H"""
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
<span class={["admin-status-pill", @color]}>
|
feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.
- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
|
|
|
<.icon name={@icon} class="size-3" /> {@status}
|
|
|
|
|
</span>
|
|
|
|
|
"""
|
|
|
|
|
end
|
|
|
|
|
|
2026-02-07 21:59:14 +00:00
|
|
|
defp status_badge(assigns) do
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
{color, icon} =
|
2026-02-07 21:59:14 +00:00
|
|
|
case assigns.status do
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
"paid" -> {"admin-status-pill-green", "hero-check-circle-mini"}
|
|
|
|
|
"pending" -> {"admin-status-pill-amber", "hero-clock-mini"}
|
|
|
|
|
"failed" -> {"admin-status-pill-red", "hero-x-circle-mini"}
|
|
|
|
|
"refunded" -> {"admin-status-pill-zinc", "hero-arrow-uturn-left-mini"}
|
|
|
|
|
_ -> {"admin-status-pill-zinc", "hero-question-mark-circle-mini"}
|
2026-02-07 21:59:14 +00:00
|
|
|
end
|
|
|
|
|
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
assigns = assign(assigns, color: color, icon: icon)
|
2026-02-07 21:59:14 +00:00
|
|
|
|
|
|
|
|
~H"""
|
refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.
Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
|
|
|
<span class={["admin-status-pill", @color]}>
|
2026-02-07 21:59:14 +00:00
|
|
|
<.icon name={@icon} class="size-3" /> {@status}
|
|
|
|
|
</span>
|
|
|
|
|
"""
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp format_date(datetime) do
|
|
|
|
|
Calendar.strftime(datetime, "%d %b %Y %H:%M")
|
|
|
|
|
end
|
|
|
|
|
end
|