solidus_admin 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.prettierrc +4 -0
  3. data/app/assets/builds/solidus_admin/tailwind.css +164 -132
  4. data/app/components/solidus_admin/adjustment_reasons/edit/component.html.erb +2 -3
  5. data/app/components/solidus_admin/adjustment_reasons/edit/component.rb +1 -9
  6. data/app/components/solidus_admin/adjustment_reasons/index/component.rb +22 -8
  7. data/app/components/solidus_admin/adjustment_reasons/new/component.html.erb +2 -4
  8. data/app/components/solidus_admin/adjustment_reasons/new/component.rb +1 -9
  9. data/app/components/solidus_admin/base_component.rb +7 -9
  10. data/app/components/solidus_admin/layout/navigation/account/component.rb +2 -2
  11. data/app/components/solidus_admin/layout/navigation/component.js +1 -1
  12. data/app/components/solidus_admin/layout/navigation/component.rb +1 -1
  13. data/app/components/solidus_admin/layout/navigation/item/component.html.erb +2 -2
  14. data/app/components/solidus_admin/layout/navigation/item/component.rb +3 -6
  15. data/app/components/solidus_admin/orders/index/component.rb +3 -3
  16. data/app/components/solidus_admin/orders/show/address/component.js +2 -2
  17. data/app/components/solidus_admin/orders/show/adjustments/index/adjustable/component.rb +1 -1
  18. data/app/components/solidus_admin/orders/show/adjustments/index/source/component.rb +1 -1
  19. data/app/components/solidus_admin/orders/show/component.js +2 -2
  20. data/app/components/solidus_admin/orders/show/customer_search/component.js +5 -4
  21. data/app/components/solidus_admin/orders/show/summary/component.html.erb +6 -6
  22. data/app/components/solidus_admin/products/show/component.html.erb +7 -1
  23. data/app/components/solidus_admin/products/show/component.rb +6 -0
  24. data/app/components/solidus_admin/products/status/component.rb +1 -1
  25. data/app/components/solidus_admin/properties/edit/component.html.erb +16 -0
  26. data/app/components/solidus_admin/properties/edit/component.rb +4 -0
  27. data/app/components/solidus_admin/properties/edit/component.yml +4 -0
  28. data/app/components/solidus_admin/properties/index/component.rb +19 -6
  29. data/app/components/solidus_admin/properties/new/component.html.erb +16 -0
  30. data/app/components/solidus_admin/properties/new/component.rb +4 -0
  31. data/app/components/solidus_admin/properties/new/component.yml +4 -0
  32. data/app/components/solidus_admin/refund_reasons/edit/component.html.erb +2 -3
  33. data/app/components/solidus_admin/refund_reasons/edit/component.rb +1 -9
  34. data/app/components/solidus_admin/refund_reasons/index/component.rb +22 -8
  35. data/app/components/solidus_admin/refund_reasons/new/component.html.erb +2 -4
  36. data/app/components/solidus_admin/refund_reasons/new/component.rb +1 -9
  37. data/app/components/solidus_admin/resources/base_component.rb +20 -0
  38. data/app/components/solidus_admin/resources/edit/component.rb +11 -0
  39. data/app/components/solidus_admin/resources/new/component.rb +11 -0
  40. data/app/components/solidus_admin/return_reasons/edit/component.html.erb +2 -3
  41. data/app/components/solidus_admin/return_reasons/edit/component.rb +1 -9
  42. data/app/components/solidus_admin/return_reasons/index/component.rb +13 -7
  43. data/app/components/solidus_admin/return_reasons/new/component.html.erb +2 -4
  44. data/app/components/solidus_admin/return_reasons/new/component.rb +1 -9
  45. data/app/components/solidus_admin/roles/edit/component.html.erb +2 -4
  46. data/app/components/solidus_admin/roles/edit/component.rb +1 -10
  47. data/app/components/solidus_admin/roles/index/component.rb +16 -8
  48. data/app/components/solidus_admin/roles/new/component.html.erb +2 -4
  49. data/app/components/solidus_admin/roles/new/component.rb +1 -10
  50. data/app/components/solidus_admin/shipping_categories/edit/component.html.erb +2 -3
  51. data/app/components/solidus_admin/shipping_categories/edit/component.rb +1 -9
  52. data/app/components/solidus_admin/shipping_categories/index/component.rb +14 -17
  53. data/app/components/solidus_admin/shipping_categories/new/component.html.erb +2 -4
  54. data/app/components/solidus_admin/shipping_categories/new/component.rb +1 -9
  55. data/app/components/solidus_admin/stock_items/edit/component.html.erb +74 -73
  56. data/app/components/solidus_admin/stock_items/edit/component.js +4 -3
  57. data/app/components/solidus_admin/stock_items/edit/component.rb +1 -10
  58. data/app/components/solidus_admin/stock_items/index/component.rb +10 -6
  59. data/app/components/solidus_admin/stock_locations/index/component.rb +2 -2
  60. data/app/components/solidus_admin/store_credit_reasons/edit/component.html.erb +2 -3
  61. data/app/components/solidus_admin/store_credit_reasons/edit/component.rb +1 -9
  62. data/app/components/solidus_admin/store_credit_reasons/index/component.rb +14 -7
  63. data/app/components/solidus_admin/store_credit_reasons/new/component.html.erb +2 -4
  64. data/app/components/solidus_admin/store_credit_reasons/new/component.rb +1 -9
  65. data/app/components/solidus_admin/tax_categories/edit/component.html.erb +2 -4
  66. data/app/components/solidus_admin/tax_categories/edit/component.rb +1 -9
  67. data/app/components/solidus_admin/tax_categories/index/component.rb +30 -9
  68. data/app/components/solidus_admin/tax_categories/new/component.html.erb +2 -4
  69. data/app/components/solidus_admin/tax_categories/new/component.rb +1 -9
  70. data/app/components/solidus_admin/ui/dropdown/component.js +3 -3
  71. data/app/components/solidus_admin/ui/forms/address/component.js +5 -6
  72. data/app/components/solidus_admin/ui/forms/field/component.rb +18 -18
  73. data/app/components/solidus_admin/ui/forms/input/component.js +3 -4
  74. data/app/components/solidus_admin/ui/forms/input/component.rb +15 -4
  75. data/app/components/solidus_admin/ui/icon/component.rb +3 -1
  76. data/app/components/solidus_admin/ui/modal/component.js +2 -2
  77. data/app/components/solidus_admin/ui/pages/index/component.html.erb +3 -3
  78. data/app/components/solidus_admin/ui/pages/index/component.rb +11 -6
  79. data/app/components/solidus_admin/ui/table/component.html.erb +4 -3
  80. data/app/components/solidus_admin/ui/table/component.js +13 -17
  81. data/app/components/solidus_admin/ui/table/component.rb +1 -1
  82. data/app/components/solidus_admin/ui/table/ransack_filter/component.js +18 -16
  83. data/app/components/solidus_admin/ui/thumbnail_with_caption/component.rb +1 -1
  84. data/app/components/solidus_admin/ui/toast/component.html.erb +1 -1
  85. data/app/components/solidus_admin/ui/toast/component.js +3 -3
  86. data/app/components/solidus_admin/ui/toggletip/component.js +14 -12
  87. data/app/components/solidus_admin/users/index/component.rb +1 -1
  88. data/app/components/solidus_admin/users/orders/component.rb +1 -1
  89. data/app/components/solidus_admin/users/store_credits/edit_amount/component.html.erb +22 -0
  90. data/app/components/solidus_admin/users/store_credits/edit_amount/component.rb +22 -0
  91. data/app/components/solidus_admin/users/store_credits/edit_amount/component.yml +5 -0
  92. data/app/components/solidus_admin/users/store_credits/edit_memo/component.html.erb +15 -0
  93. data/app/components/solidus_admin/users/store_credits/edit_memo/component.rb +16 -0
  94. data/app/components/solidus_admin/users/store_credits/edit_memo/component.yml +4 -0
  95. data/app/components/solidus_admin/users/store_credits/edit_validity/component.html.erb +21 -0
  96. data/app/components/solidus_admin/users/store_credits/edit_validity/component.rb +22 -0
  97. data/app/components/solidus_admin/users/store_credits/edit_validity/component.yml +5 -0
  98. data/app/components/solidus_admin/users/store_credits/index/component.html.erb +65 -0
  99. data/app/components/solidus_admin/users/store_credits/index/component.rb +114 -0
  100. data/app/components/solidus_admin/users/store_credits/index/component.yml +12 -0
  101. data/app/components/solidus_admin/users/store_credits/new/component.html.erb +30 -0
  102. data/app/components/solidus_admin/users/store_credits/new/component.rb +22 -0
  103. data/app/components/solidus_admin/users/store_credits/new/component.yml +5 -0
  104. data/app/components/solidus_admin/users/store_credits/show/component.html.erb +83 -0
  105. data/app/components/solidus_admin/users/store_credits/show/component.rb +120 -0
  106. data/app/components/solidus_admin/users/store_credits/show/component.yml +18 -0
  107. data/app/controllers/solidus_admin/adjustment_reasons_controller.rb +3 -105
  108. data/app/controllers/solidus_admin/authentication_adapters/backend.rb +1 -1
  109. data/app/controllers/solidus_admin/base_controller.rb +12 -1
  110. data/app/controllers/solidus_admin/controller_helpers/search.rb +4 -4
  111. data/app/controllers/solidus_admin/properties_controller.rb +6 -24
  112. data/app/controllers/solidus_admin/refund_reasons_controller.rb +5 -105
  113. data/app/controllers/solidus_admin/resources_controller.rb +152 -0
  114. data/app/controllers/solidus_admin/return_reasons_controller.rb +4 -104
  115. data/app/controllers/solidus_admin/roles_controller.rb +3 -105
  116. data/app/controllers/solidus_admin/shipping_categories_controller.rb +3 -107
  117. data/app/controllers/solidus_admin/stock_items_controller.rb +12 -29
  118. data/app/controllers/solidus_admin/store_credit_reasons_controller.rb +5 -105
  119. data/app/controllers/solidus_admin/store_credits_controller.rb +231 -0
  120. data/app/controllers/solidus_admin/tax_categories_controller.rb +3 -109
  121. data/app/helpers/solidus_admin/void_elements_helper.rb +13 -0
  122. data/app/views/layouts/solidus_admin/application.html.erb +3 -0
  123. data/config/locales/menu_item.en.yml +0 -1
  124. data/config/locales/properties.en.yml +4 -0
  125. data/config/locales/store_credits.en.yml +16 -0
  126. data/config/routes.rb +12 -1
  127. data/lib/generators/solidus_admin/install/install_generator.rb +2 -0
  128. data/lib/solidus_admin/component_registry.rb +1 -1
  129. data/lib/solidus_admin/configuration.rb +3 -8
  130. data/lib/solidus_admin/engine.rb +6 -0
  131. data/lib/solidus_admin/install_tailwindcss.rb +1 -1
  132. data/lib/solidus_admin/testing_support/component_helpers.rb +3 -9
  133. data/lib/solidus_admin/testing_support/feature_helpers.rb +1 -1
  134. data/lib/solidus_admin/testing_support/shared_examples/bulk_delete_resources.rb +20 -0
  135. data/lib/solidus_admin/testing_support/shared_examples/crud_resource_requests.rb +138 -0
  136. data/lib/solidus_admin/testing_support/shared_examples/promotion_categories_features.rb +72 -0
  137. data/lib/solidus_admin/version.rb +1 -1
  138. data/solidus_admin.gemspec +2 -2
  139. metadata +39 -8
  140. data/bin/rails +0 -13
@@ -1,11 +1,11 @@
1
- import { Controller } from '@hotwired/stimulus'
2
- import { useClickOutside, useDebounce } from 'stimulus-use'
1
+ import { Controller } from "@hotwired/stimulus"
2
+ import { useClickOutside, useDebounce } from "stimulus-use"
3
3
 
4
- const BG_GRAY = 'bg-gray-100'
4
+ const BG_GRAY = "bg-gray-100"
5
5
 
6
6
  export default class extends Controller {
7
- static targets = ['details', 'summary', 'option', 'checkbox', 'menu']
8
- static debounces = ['init']
7
+ static targets = ["details", "summary", "option", "checkbox", "menu"]
8
+ static debounces = ["init"]
9
9
 
10
10
  connect() {
11
11
  useDebounce(this, { wait: 50 })
@@ -37,7 +37,7 @@ export default class extends Controller {
37
37
  filterOptions(event) {
38
38
  const query = event.currentTarget.value.toLowerCase()
39
39
  this.optionTargets.forEach((option) => {
40
- option.style.display = option.textContent.toLowerCase().includes(query) ? 'block' : 'none'
40
+ option.style.display = option.textContent.toLowerCase().includes(query) ? "block" : "none"
41
41
  })
42
42
  }
43
43
 
@@ -50,24 +50,26 @@ export default class extends Controller {
50
50
  this.checkboxTargets.forEach((checkbox) => {
51
51
  const hiddenElements = checkbox.parentElement.querySelectorAll("input[type='hidden']")
52
52
  checkbox.checked
53
- ? hiddenElements.forEach(e => e.removeAttribute("disabled"))
54
- : hiddenElements.forEach(e => e.setAttribute("disabled", true))
53
+ ? hiddenElements.forEach((e) => e.removeAttribute("disabled"))
54
+ : hiddenElements.forEach((e) => e.setAttribute("disabled", true))
55
55
  })
56
56
  }
57
57
 
58
58
  sortCheckboxes() {
59
59
  const checkboxes = this.checkboxTargets
60
60
 
61
- checkboxes.sort((a, b) => {
62
- if (a.checked && !b.checked) return -1
63
- if (!a.checked && b.checked) return 1
64
- return 0
65
- }).forEach(checkbox => {
66
- this.menuTarget.appendChild(checkbox.closest('div'))
67
- })
61
+ checkboxes
62
+ .sort((a, b) => {
63
+ if (a.checked && !b.checked) return -1
64
+ if (!a.checked && b.checked) return 1
65
+ return 0
66
+ })
67
+ .forEach((checkbox) => {
68
+ this.menuTarget.appendChild(checkbox.closest("div"))
69
+ })
68
70
  }
69
71
 
70
72
  isAnyCheckboxChecked() {
71
- return this.checkboxTargets.some(checkbox => checkbox.checked)
73
+ return this.checkboxTargets.some((checkbox) => checkbox.checked)
72
74
  }
73
75
  }
@@ -10,6 +10,6 @@ class SolidusAdmin::UI::ThumbnailWithCaption::Component < SolidusAdmin::BaseComp
10
10
  end
11
11
 
12
12
  def icon_thumbnail
13
- render component("ui/thumbnail").new(icon: icon)
13
+ render component("ui/thumbnail").new(icon:)
14
14
  end
15
15
  end
@@ -8,7 +8,7 @@
8
8
  "
9
9
  data-controller="<%= stimulus_id %>"
10
10
  data-<%= stimulus_id %>-animation-class="translate-y-full opacity-0"
11
- data-<%= stimulus_id %>-transition-value="500"
11
+ data-<%= stimulus_id %>-transition-value="<%= Rails.env.test? ? 1000 : 500 %>"
12
12
  role="dialog"
13
13
  aria-label="<%= t(".#{@scheme}_label") %>"
14
14
  aria-live="polite"
@@ -1,8 +1,8 @@
1
- import { Controller } from '@hotwired/stimulus'
1
+ import { Controller } from "@hotwired/stimulus"
2
2
 
3
3
  export default class extends Controller {
4
- static targets = ['closeButton']
5
- static classes = ['animation']
4
+ static targets = ["closeButton"]
5
+ static classes = ["animation"]
6
6
  static values = { transition: Number }
7
7
 
8
8
  connect() {
@@ -1,30 +1,30 @@
1
- import { Controller } from '@hotwired/stimulus'
2
- import { useClickOutside } from 'stimulus-use'
1
+ import { Controller } from "@hotwired/stimulus"
2
+ import { useClickOutside } from "stimulus-use"
3
3
 
4
4
  export default class extends Controller {
5
- static targets = ['bubble']
5
+ static targets = ["bubble"]
6
6
 
7
- connect () {
7
+ connect() {
8
8
  useClickOutside(this)
9
9
  this.open = false
10
10
  }
11
11
 
12
- clickOutside () {
12
+ clickOutside() {
13
13
  this.close()
14
14
  }
15
15
 
16
- toggle (e) {
16
+ toggle(e) {
17
17
  e.preventDefault()
18
18
  this.open = !this.open
19
19
  this.render()
20
20
  }
21
21
 
22
- open () {
22
+ open() {
23
23
  this.open = true
24
24
  this.render()
25
25
  }
26
26
 
27
- close () {
27
+ close() {
28
28
  this.open = false
29
29
  this.render()
30
30
  }
@@ -35,10 +35,12 @@ export default class extends Controller {
35
35
 
36
36
  if (needsPositioning) {
37
37
  const bubbleRect = this.bubbleTarget.getBoundingClientRect()
38
- if (bubbleRect.right > window.innerWidth) this.bubbleTarget.style.left = `${window.innerWidth - bubbleRect.width}px`
39
- if (bubbleRect.bottom > window.innerHeight) this.bubbleTarget.style.top = `${window.innerHeight - bubbleRect.height}px`
40
- if (bubbleRect.left < 0) this.bubbleTarget.style.left = '0px'
41
- if (bubbleRect.top < 0) this.bubbleTarget.style.top = '0px'
38
+ if (bubbleRect.right > window.innerWidth)
39
+ this.bubbleTarget.style.left = `${window.innerWidth - bubbleRect.width}px`
40
+ if (bubbleRect.bottom > window.innerHeight)
41
+ this.bubbleTarget.style.top = `${window.innerHeight - bubbleRect.height}px`
42
+ if (bubbleRect.left < 0) this.bubbleTarget.style.left = "0px"
43
+ if (bubbleRect.top < 0) this.bubbleTarget.style.top = "0px"
42
44
  }
43
45
  }
44
46
  }
@@ -77,7 +77,7 @@ class SolidusAdmin::Users::Index::Component < SolidusAdmin::UsersAndRoles::Compo
77
77
  when 'customer' then :green
78
78
  else :graphite_light
79
79
  end
80
- render component('ui/badge').new(name: _1.name, color: color)
80
+ render component('ui/badge').new(name: _1.name, color:)
81
81
  })
82
82
  end,
83
83
  },
@@ -106,7 +106,7 @@ class SolidusAdmin::Users::Orders::Component < SolidusAdmin::BaseComponent
106
106
  {
107
107
  header: :total,
108
108
  data: ->(order) do
109
- content_tag :div, number_to_currency(order.total)
109
+ content_tag :div, order.display_total
110
110
  end
111
111
  }
112
112
  end
@@ -0,0 +1,22 @@
1
+ <%= turbo_frame_tag :resource_modal, target: "_top" do %>
2
+ <%= render component("ui/modal").new(title: t(".title")) do |modal| %>
3
+ <%= form_for @store_credit, url: form_url, method: :put, html: { id: form_id } do |f| %>
4
+ <div class="flex flex-col gap-6 pb-4">
5
+ <%= render component("ui/forms/field").text_field(f, :amount, class: "required") %>
6
+ <%= render component("ui/forms/field").select(
7
+ f,
8
+ :store_credit_reason_id,
9
+ store_credit_reasons_select_options.html_safe,
10
+ include_blank: t('spree.choose_reason'),
11
+ html: { required: true }
12
+ ) %>
13
+ </div>
14
+ <% modal.with_actions do %>
15
+ <form method="dialog">
16
+ <%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
17
+ </form>
18
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
19
+ <% end %>
20
+ <% end %>
21
+ <% end %>
22
+ <% end %>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::Users::StoreCredits::EditAmount::Component < SolidusAdmin::Resources::Edit::Component
4
+ def initialize(user:, store_credit:, reasons:)
5
+ @user = user
6
+ super(store_credit)
7
+ @store_credit_reasons = reasons
8
+ end
9
+
10
+ def form_id
11
+ dom_id(@store_credit, "#{stimulus_id}_edit_amount_form")
12
+ end
13
+
14
+ def form_url
15
+ solidus_admin.update_amount_user_store_credit_path(@user, @store_credit, **search_filter_params)
16
+ end
17
+
18
+ def store_credit_reasons_select_options
19
+ # Placeholder + Store Credit Reasons
20
+ "<option value>#{t('.choose_reason')}</option>" + options_from_collection_for_select(@store_credit_reasons, :id, :name)
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ title: Edit Store Credit Amount
3
+ cancel: Cancel
4
+ submit: Update Store Credit
5
+ choose_reason: Choose Reason For Changing Amount
@@ -0,0 +1,15 @@
1
+ <%= turbo_frame_tag :resource_modal, target: "_top" do %>
2
+ <%= render component("ui/modal").new(title: t(".title")) do |modal| %>
3
+ <%= form_for @store_credit, url: form_url, method: :put, html: { id: form_id } do |f| %>
4
+ <div class="flex flex-col gap-6 pb-4">
5
+ <%= render component("ui/forms/field").text_field(f, :memo) %>
6
+ </div>
7
+ <% modal.with_actions do %>
8
+ <form method="dialog">
9
+ <%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
10
+ </form>
11
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
12
+ <% end %>
13
+ <% end %>
14
+ <% end %>
15
+ <% end %>
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::Users::StoreCredits::EditMemo::Component < SolidusAdmin::Resources::Edit::Component
4
+ def initialize(user:, store_credit:)
5
+ @user = user
6
+ super(store_credit)
7
+ end
8
+
9
+ def form_id
10
+ dom_id(@store_credit, "#{stimulus_id}_edit_memo_form")
11
+ end
12
+
13
+ def form_url
14
+ solidus_admin.update_memo_user_store_credit_path(@user, @store_credit, **search_filter_params)
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ title: Edit Store Credit Memo
3
+ cancel: Cancel
4
+ submit: Update Store Credit
@@ -0,0 +1,21 @@
1
+ <%= turbo_frame_tag :resource_modal, target: "_top" do %>
2
+ <%= render component("ui/modal").new(title: t(".title")) do |modal| %>
3
+ <%= form_for @store_credit, url: form_url, method: :put, html: { id: form_id } do |f| %>
4
+ <div class="flex flex-col gap-6 pb-4">
5
+ <%= render component("ui/forms/field").select(
6
+ f,
7
+ :store_credit_reason_id,
8
+ store_credit_reasons_select_options.html_safe,
9
+ include_blank: t('spree.choose_reason'),
10
+ html: { required: true }
11
+ ) %>
12
+ </div>
13
+ <% modal.with_actions do %>
14
+ <form method="dialog">
15
+ <%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
16
+ </form>
17
+ <%= render component("ui/button").new(form: form_id, scheme: :danger, type: :submit, text: t('.submit')) %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <% end %>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::Users::StoreCredits::EditValidity::Component < SolidusAdmin::Resources::Edit::Component
4
+ def initialize(user:, store_credit:, reasons:)
5
+ @user = user
6
+ super(store_credit)
7
+ @store_credit_reasons = reasons
8
+ end
9
+
10
+ def form_id
11
+ dom_id(@store_credit, "#{stimulus_id}_edit_validity_form")
12
+ end
13
+
14
+ def form_url
15
+ solidus_admin.invalidate_user_store_credit_path(@user, @store_credit, **search_filter_params)
16
+ end
17
+
18
+ def store_credit_reasons_select_options
19
+ # Placeholder + Store Credit Reasons
20
+ "<option value>#{t('.choose_reason')}</option>" + options_from_collection_for_select(@store_credit_reasons, :id, :name)
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ title: Invalidate Store Credit
3
+ cancel: Cancel
4
+ submit: Invalidate
5
+ choose_reason: Choose Reason For Invalidating
@@ -0,0 +1,65 @@
1
+ <%= page do %>
2
+ <%= page_header do %>
3
+ <%= page_header_back(solidus_admin.users_path) %>
4
+ <%= page_header_title(t(".title", email: @user.email)) %>
5
+
6
+ <%= page_header_actions do %>
7
+ <%= render component("ui/button").new(
8
+ tag: :a,
9
+ href: new_store_credit_path,
10
+ data: {
11
+ turbo_frame: :resource_modal
12
+ },
13
+ text: t(".add_store_credit"),
14
+ icon: "add-line"
15
+ )%>
16
+ <% end %>
17
+ <% end %>
18
+
19
+ <%= page_header do %>
20
+ <% tabs.each do |tab| %>
21
+ <%= render(component("ui/button").new(tag: :a, scheme: :ghost, text: tab[:text], 'aria-current': tab[:current], href: tab[:href])) %>
22
+ <% end %>
23
+ <% end %>
24
+
25
+ <%= page_with_sidebar do %>
26
+ <%= page_with_sidebar_main do %>
27
+
28
+ <% if @store_credits.present? %>
29
+ <% @store_credits.group_by(&:currency).each do |currency, credits| %>
30
+ <% title = [t('spree.admin.store_credits.current_balance'), Spree::Money.new(credits.sum(&:amount_remaining), currency: currency)].join(" ") %>
31
+
32
+ <%= render component('ui/panel').new(title: title) do %>
33
+ <%= render component('ui/table').new(
34
+ id: stimulus_id,
35
+ data: {
36
+ class: model_class,
37
+ rows: credits,
38
+ fade: -> (_order) { false },
39
+ columns: columns
40
+ }
41
+ ) %>
42
+ <% end %>
43
+ <% end %>
44
+ <% else %>
45
+ <%= render component('ui/panel').new(title: t(".store_credit")) do %>
46
+ <%= t(".no_credits_found") %>
47
+ <%= render component("ui/button").new(
48
+ tag: :a,
49
+ data: {
50
+ turbo_frame: :resource_modal
51
+ },
52
+ href: new_store_credit_path,
53
+ text: t(".create_one"),
54
+ )%>
55
+ <% end %>
56
+ <% end %>
57
+ <% end %>
58
+
59
+ <%= page_with_sidebar_aside do %>
60
+ <%= render component("users/stats").new(user: @user) %>
61
+ <% end %>
62
+ <% end %>
63
+
64
+ <%= turbo_frame_tag :resource_modal, target: "_top" %>
65
+ <% end %>
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::Users::StoreCredits::Index::Component < SolidusAdmin::BaseComponent
4
+ include SolidusAdmin::Layout::PageHelpers
5
+
6
+ def initialize(user:, store_credits:)
7
+ @user = user
8
+ @store_credits = store_credits
9
+ end
10
+
11
+ def model_class
12
+ Spree::StoreCredit
13
+ end
14
+
15
+ def tabs
16
+ [
17
+ {
18
+ text: t('.account'),
19
+ href: solidus_admin.user_path(@user),
20
+ current: false,
21
+ },
22
+ {
23
+ text: t('.addresses'),
24
+ href: solidus_admin.addresses_user_path(@user),
25
+ current: false,
26
+ },
27
+ {
28
+ text: t('.order_history'),
29
+ href: solidus_admin.orders_user_path(@user),
30
+ current: false,
31
+ },
32
+ {
33
+ text: t('.items'),
34
+ href: spree.items_admin_user_path(@user),
35
+ current: false,
36
+ },
37
+ {
38
+ text: t('.store_credit'),
39
+ href: solidus_admin.user_store_credits_path(@user),
40
+ current: true,
41
+ },
42
+ ]
43
+ end
44
+
45
+ def rows
46
+ @store_credits
47
+ end
48
+
49
+ def show_path(store_credit)
50
+ solidus_admin.user_store_credit_path(@user, store_credit)
51
+ end
52
+
53
+ def new_store_credit_path
54
+ solidus_admin.new_user_store_credit_path(user_id: @user.id)
55
+ end
56
+
57
+ def columns
58
+ [
59
+ {
60
+ header: :credited,
61
+ col: { class: "w-[12%]" },
62
+ data: ->(store_credit) do
63
+ link_to store_credit.display_amount.to_html, show_path(store_credit), class: "body-link text-sm"
64
+ end
65
+ },
66
+ {
67
+ header: :authorized,
68
+ col: { class: "w-[13%]" },
69
+ data: ->(store_credit) do
70
+ link_to store_credit.display_amount_authorized.to_html, show_path(store_credit), class: "body-link text-sm"
71
+ end
72
+ },
73
+ {
74
+ header: :used,
75
+ col: { class: "w-[9%]" },
76
+ data: ->(store_credit) do
77
+ link_to store_credit.display_amount_used.to_html, show_path(store_credit), class: "body-link text-sm"
78
+ end
79
+ },
80
+ {
81
+ header: :type,
82
+ col: { class: "w-[13%]" },
83
+ data: ->(store_credit) do
84
+ component('ui/badge').new(name: store_credit.credit_type.name, color: :blue)
85
+ end
86
+ },
87
+ {
88
+ header: :created_by,
89
+ col: { class: "w-[22%]" },
90
+ data: ->(store_credit) do
91
+ content_tag :div, store_credit.created_by_email, class: "text-sm"
92
+ end
93
+ },
94
+ {
95
+ header: :issued_on,
96
+ col: { class: "w-[16%]" },
97
+ data: ->(store_credit) do
98
+ content_tag :span, I18n.l(store_credit.created_at.to_date), class: "text-sm"
99
+ end
100
+ },
101
+ {
102
+ header: :invalidated,
103
+ col: { class: "w-[15%]" },
104
+ data: ->(store_credit) do
105
+ if store_credit.invalidated?
106
+ component('ui/badge').new(name: :yes, color: :red, size: :m)
107
+ else
108
+ component('ui/badge').new(name: :no, color: :green, size: :m)
109
+ end
110
+ end
111
+ }
112
+ ]
113
+ end
114
+ end
@@ -0,0 +1,12 @@
1
+ en:
2
+ title: "Users / %{email} / Store Credit"
3
+ account: Account
4
+ addresses: Addresses
5
+ order_history: Order History
6
+ items: Items
7
+ store_credit: Store Credit
8
+ last_active: Last Active
9
+ add_store_credit: Add Store Credit
10
+ no_credits_found: No Store Credits found.
11
+ create_one: Create One
12
+ back: Back
@@ -0,0 +1,30 @@
1
+ <%= turbo_frame_tag :resource_modal, target: "_top" do %>
2
+ <%= render component("ui/modal").new(title: t(".title")) do |modal| %>
3
+ <%= form_for @store_credit, url: form_url, method: :post, html: { id: form_id } do |f| %>
4
+ <div class="flex flex-col gap-6 pb-4">
5
+ <%= render component("ui/forms/field").text_field(f, :amount, class: "required") %>
6
+ <%= render component("ui/forms/field").select(
7
+ f,
8
+ :currency,
9
+ currency_select_options.html_safe,
10
+ include_blank: t("spree.currency"),
11
+ html: { required: true }
12
+ ) %>
13
+ <%= render component("ui/forms/field").select(
14
+ f,
15
+ :category_id,
16
+ store_credit_categories_select_options.html_safe,
17
+ include_blank: t("spree.category"),
18
+ html: { required: true }
19
+ ) %>
20
+ <%= render component("ui/forms/field").text_field(f, :memo) %>
21
+ </div>
22
+ <% modal.with_actions do %>
23
+ <form method="dialog">
24
+ <%= render component("ui/button").new(scheme: :secondary, text: t(".cancel")) %>
25
+ </form>
26
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t(".submit")) %>
27
+ <% end %>
28
+ <% end %>
29
+ <% end %>
30
+ <% end %>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SolidusAdmin::Users::StoreCredits::New::Component < SolidusAdmin::Resources::New::Component
4
+ def initialize(user:, store_credit:, categories:)
5
+ @user = user
6
+ super(store_credit)
7
+ @store_credit_categories = categories
8
+ end
9
+
10
+ def form_url
11
+ solidus_admin.user_store_credits_path(@user, **search_filter_params)
12
+ end
13
+
14
+ def currency_select_options
15
+ options_from_collection_for_select(Spree::Config.available_currencies, :iso_code, :iso_code, Spree::Config.currency)
16
+ end
17
+
18
+ def store_credit_categories_select_options
19
+ # Placeholder + Store Credit Categories
20
+ "<option value>#{t('.choose_category')}</option>" + options_from_collection_for_select(@store_credit_categories, :id, :name)
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ title: New Store Credit
3
+ cancel: Cancel
4
+ submit: Create
5
+ choose_category: Choose Store Credit Category
@@ -0,0 +1,83 @@
1
+ <%= page do %>
2
+ <%= page_header do %>
3
+ <%= page_header_back(solidus_admin.users_path) %>
4
+ <%= page_header_title(t(".title", email: @user.email, amount: @store_credit.display_amount)) %>
5
+ <% end %>
6
+
7
+ <%= page_header do %>
8
+ <% tabs.each do |tab| %>
9
+ <%= render(component("ui/button").new(tag: :a, scheme: :ghost, text: tab[:text], 'aria-current': tab[:current], href: tab[:href])) %>
10
+ <% end %>
11
+ <% end %>
12
+
13
+ <%= page_with_sidebar do %>
14
+ <%= page_with_sidebar_main do %>
15
+ <%= render component('ui/panel').new(title: t(".store_credit")) do |panel| %>
16
+ <% panel.with_section do %>
17
+ <%= render component('ui/details_list').new(
18
+ items: [
19
+ { label: t('.credited'), value: @store_credit.display_amount },
20
+ { label: t('.created_by'), value: @store_credit.created_by_email },
21
+ { label: t('.type'), value: @store_credit.category_name },
22
+ { label: t('.memo'), value: @store_credit.memo }
23
+ ]
24
+ ) %>
25
+ <% end %>
26
+
27
+ <% panel.with_section do %>
28
+ <div class="w-[100%] text-right">
29
+ <% if @store_credit.invalidateable? %>
30
+ <%= render component("ui/button").new(
31
+ tag: :a,
32
+ scheme: :danger,
33
+ data: {
34
+ turbo_frame: :resource_modal
35
+ },
36
+ href: edit_validity_url,
37
+ text: t(".invalidate"),
38
+ ) %>
39
+ <% end %>
40
+
41
+ <%= render component("ui/button").new(
42
+ tag: :a,
43
+ data: {
44
+ turbo_frame: :resource_modal
45
+ },
46
+ href: edit_memo_url,
47
+ text: t(".edit_memo"),
48
+ ) %>
49
+
50
+ <% if @store_credit.editable? %>
51
+ <%= render component("ui/button").new(
52
+ tag: :a,
53
+ data: {
54
+ turbo_frame: :resource_modal
55
+ },
56
+ href: edit_amount_url,
57
+ text: t(".edit_amount"),
58
+ ) %>
59
+ <% end %>
60
+ </div>
61
+ <% end %>
62
+ <% end %>
63
+
64
+ <% if @events.present? %>
65
+ <h1 class="font-semibold text-base text-center w-[100%]"><%= t(".store_credit_history") %></h1>
66
+ <%= render component('ui/table').new(
67
+ id: stimulus_id,
68
+ data: {
69
+ class: event_model_class,
70
+ rows: @events,
71
+ columns: columns,
72
+ },
73
+ )%>
74
+ <% end %>
75
+ <% end %>
76
+
77
+ <%= page_with_sidebar_aside do %>
78
+ <%= render component("users/stats").new(user: @user) %>
79
+ <% end %>
80
+ <% end %>
81
+
82
+ <%= turbo_frame_tag :resource_modal, target: "_top" %>
83
+ <% end %>