diff --git a/admin/app/components/solidus_admin/layout/page_helpers.rb b/admin/app/components/solidus_admin/layout/page_helpers.rb
new file mode 100644
index 00000000000..5226902d967
--- /dev/null
+++ b/admin/app/components/solidus_admin/layout/page_helpers.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module SolidusAdmin::Layout::PageHelpers
+ def page(&block)
+ tag.div(capture(&block), class: "px-4 relative", "data-controller": stimulus_id)
+ end
+
+ def page_header_actions(&block)
+ tag.div(safe_join([
+ render(component("feedback").new),
+ capture(&block),
+ ]), class: "flex gap-2 items-center")
+ end
+
+ def page_header_back(back_path)
+ render component("ui/button").new(
+ tag: :a,
+ title: t(".back"),
+ icon: "arrow-left-line",
+ scheme: :secondary,
+ href: back_path
+ )
+ end
+
+ def page_header_title(title, &block)
+ tag.h1(safe_join([
+ tag.span(title, class: "body-title"),
+ (capture(&block) if block_given?) || "",
+ ]), class: "flex-1 text-2xl font-bold")
+ end
+
+ def page_header(&block)
+ tag.header(capture(&block), class: "py-6 flex items-center gap-4")
+ end
+
+ def page_with_sidebar(&block)
+ tag.div(capture(&block), class: "flex gap-4 items-start pb-4")
+ end
+
+ def page_with_sidebar_main(&block)
+ tag.div(capture(&block), class: "justify-center items-start gap-4 flex flex-col w-full")
+ end
+
+ def page_with_sidebar_aside(&block)
+ tag.aside(capture(&block), class: "justify-center items-start gap-4 flex flex-col w-full max-w-sm")
+ end
+
+ def page_footer(&block)
+ tag.div(capture(&block), class: "mt-4 py-4 px-2 pb-8 border-t border-gray-100 flex")
+ end
+
+ def page_footer_actions(&block)
+ tag.div(capture(&block), class: "flex gap-2 grow")
+ end
+end
diff --git a/admin/app/components/solidus_admin/orders/new/component.html.erb b/admin/app/components/solidus_admin/orders/new/component.html.erb
index 32d156165f1..37a13c33309 100644
--- a/admin/app/components/solidus_admin/orders/new/component.html.erb
+++ b/admin/app/components/solidus_admin/orders/new/component.html.erb
@@ -1,20 +1,13 @@
-
-
- <%= render component("ui/button").new(
- tag: :a,
- title: t(".back"),
- icon: "arrow-left-line",
- scheme: :secondary,
- href: solidus_admin.orders_path
- ) %>
-
- <%= t(".create_order") %>
-
+<%= page do %>
+ <%= page_header do %>
+ <%= page_header_back solidus_admin.orders_path %>
-
+ <%= page_header_title t(".create_order") %>
+
+ <%= page_header_actions do %>
<%= render component("feedback").new %>
<%= render component("ui/button").new(tag: :button, scheme: :secondary, text: t(".discard"), form: form_id) %>
<%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %>
-
-
-
+ <% end %>
+ <% end %>
+<% end %>
diff --git a/admin/app/components/solidus_admin/orders/new/component.rb b/admin/app/components/solidus_admin/orders/new/component.rb
index 0008f6fce94..7d98d44eb30 100644
--- a/admin/app/components/solidus_admin/orders/new/component.rb
+++ b/admin/app/components/solidus_admin/orders/new/component.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class SolidusAdmin::Orders::New::Component < SolidusAdmin::BaseComponent
+ include SolidusAdmin::Layout::PageHelpers
+
def initialize(order:)
@order = order
end
diff --git a/admin/app/components/solidus_admin/products/index/component.html.erb b/admin/app/components/solidus_admin/products/index/component.html.erb
index 31310639e31..b35b6ff4fb4 100644
--- a/admin/app/components/solidus_admin/products/index/component.html.erb
+++ b/admin/app/components/solidus_admin/products/index/component.html.erb
@@ -1,10 +1,7 @@
-
-
-
- <%= title %>
-
-
-
+<%= page do %>
+ <%= page_header do %>
+ <%= page_header_title title %>
+ <%= page_header_actions do %>
<%= render component("feedback").new %>
<%= render component("ui/button").new(
tag: :a,
@@ -12,8 +9,8 @@
href: spree.new_admin_product_path,
icon: "add-line",
) %>
-
-
+ <% end %>
+ <% end %>
<%= render component('ui/table').new(
id: 'products-list',
@@ -28,4 +25,4 @@
prev_page_link: prev_page_link,
next_page_link: next_page_link,
) %>
-
+<% end %>
diff --git a/admin/app/components/solidus_admin/products/index/component.rb b/admin/app/components/solidus_admin/products/index/component.rb
index 67ddee3c3fe..5061741de40 100644
--- a/admin/app/components/solidus_admin/products/index/component.rb
+++ b/admin/app/components/solidus_admin/products/index/component.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class SolidusAdmin::Products::Index::Component < SolidusAdmin::BaseComponent
+ include SolidusAdmin::Layout::PageHelpers
+
def initialize(page:)
@page = page
end
diff --git a/admin/app/components/solidus_admin/products/show/component.html.erb b/admin/app/components/solidus_admin/products/show/component.html.erb
index 4daed1eda2a..da4e347bb71 100644
--- a/admin/app/components/solidus_admin/products/show/component.html.erb
+++ b/admin/app/components/solidus_admin/products/show/component.html.erb
@@ -1,19 +1,10 @@
-
-
- <%= render component("ui/button").new(
- tag: :a,
- title: t(".back"),
- icon: "arrow-left-line",
- scheme: :secondary,
- href: solidus_admin.products_path
- ) %>
-
- <%= @product.name %>
+<%= page do %>
+ <%= page_header do %>
+ <%= page_header_back(solidus_admin.products_path) %>
+ <%= page_header_title(@product.name) do %>
<%= render component("products/status").from_product(@product) %>
-
-
-
- <%= render component("feedback").new %>
+ <% end %>
+ <%= page_header_actions do %>
<%= render component("ui/button").new(
tag: :a,
text: t(".duplicate"),
@@ -29,12 +20,12 @@
scheme: :ghost
) %>
<%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %>
-
-
+ <% end %>
+ <% end %>
<%= form_for @product, url: solidus_admin.product_path(@product), html: { id: form_id } do |f| %>
-
-
+ <%= page_with_sidebar do %>
+ <%= page_with_sidebar_main do %>
<%= render component('ui/panel').new do %>
<%= render component("ui/forms/field").text_field(f, :name) %>
<%= render component("ui/forms/field").text_field(f, :slug) %>
@@ -105,9 +96,9 @@
href: spree.admin_product_product_properties_path(@product)
) %>
<% end %>
-
+ <% end %>
-
-
+ <% end %>
+ <% end %>
<% end %>
-
-
+ <%= page_footer do %>
+ <%= page_footer_actions do %>
<%= form_for @product, url: solidus_admin.product_path(@product), method: :delete do %>
<%= render component("ui/button").new(
tag: :button,
@@ -140,7 +131,7 @@
"data-#{stimulus_id}-message-param": t(".delete_confirmation"),
) %>
<% end %>
-
+ <% end %>
<%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %>
-
-
+ <% end %>
+<% end %>
diff --git a/admin/app/components/solidus_admin/products/show/component.rb b/admin/app/components/solidus_admin/products/show/component.rb
index 42b227a0f00..08d200d17d8 100644
--- a/admin/app/components/solidus_admin/products/show/component.rb
+++ b/admin/app/components/solidus_admin/products/show/component.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class SolidusAdmin::Products::Show::Component < SolidusAdmin::BaseComponent
+ include SolidusAdmin::Layout::PageHelpers
+
def initialize(product:)
@product = product
end
diff --git a/admin/app/components/solidus_admin/ui/table/component.html.erb b/admin/app/components/solidus_admin/ui/table/component.html.erb
index df6f1474c89..736c2ae1ecb 100644
--- a/admin/app/components/solidus_admin/ui/table/component.html.erb
+++ b/admin/app/components/solidus_admin/ui/table/component.html.erb
@@ -11,14 +11,8 @@
<%= component("ui/table/ransack_filter").stimulus_id %>:showSearch-><%= stimulus_id %>#showSearch
"
>
- <% toolbar_classes = "
- h-14 p-2 bg-white border-b border-gray-100
- justify-start items-center gap-2
- visible:flex hidden:hidden
- rounded-t-lg
- " %>
-
-target="searchToolbar">
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "searchToolbar") do %>
<%= form_with(
url: @search_url,
method: :get,
@@ -47,17 +41,17 @@
"data-action": "#{stimulus_id}#cancelSearch",
) %>
-
+ <% end %>
<% if @filters.any? %>
- -target="filterToolbar">
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "filterToolbar") do %>
<% @filters.each_with_index do |filter, index| %>
<%= render_ransack_filter_dropdown(filter, index) %>
<% end %>
-
+ <% end %>
<% end %>
-
+ <% end %>
- -target="batchToolbar" role="toolbar" aria-label="<%= t(".batch_actions") %>">
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "batchToolbar", role: "toolbar", "aria-label": t(".batch_actions")) do %>
<%= form_tag '', id: batch_actions_form_id %>
<% @batch_actions.each do |batch_action| %>
<%= render_batch_action_button(batch_action) %>
<% end %>
-
+ <% end %>
<%= turbo_frame_tag table_frame_id, target: "_top" do %>
diff --git a/admin/app/components/solidus_admin/ui/table/toolbar/component.rb b/admin/app/components/solidus_admin/ui/table/toolbar/component.rb
new file mode 100644
index 00000000000..70e287ef759
--- /dev/null
+++ b/admin/app/components/solidus_admin/ui/table/toolbar/component.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class SolidusAdmin::UI::Table::Toolbar::Component < SolidusAdmin::BaseComponent
+ erb_template <<~ERB
+
+ <%= content %>
+
+ ERB
+end