Skip to content

Commit

Permalink
Add new admin store_credits edit_amount flow
Browse files Browse the repository at this point in the history
  • Loading branch information
MadelineCollier committed Dec 11, 2024
1 parent bbc5904 commit 2eefd30
Show file tree
Hide file tree
Showing 13 changed files with 332 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<%= turbo_frame_tag :edit_amount_modal do %>
<%= render component("ui/modal").new(title: t(".title")) do |modal| %>
<%= form_for @store_credit, url: solidus_admin.update_amount_user_store_credit_path(@user, @store_credit), method: :put, html: { id: form_id } do |f| %>
<div class="flex flex-col gap-6 pb-4">
<%= render component("ui/forms/field").text_field(f, :amount, class: "required") %>
<%= render component("ui/forms/field").select(
f,
:store_credit_reason_id,
store_credit_reasons_select_options.html_safe,
include_blank: t('spree.choose_reason'),
html: { required: true }
) %>
</div>
<% modal.with_actions do %>
<form method="dialog">
<%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
</form>
<%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= render component("users/store_credits/show").new(user: @user, store_credit: @store_credit, events: @store_credit_events) %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class SolidusAdmin::Users::StoreCredits::EditAmount::Component < SolidusAdmin::BaseComponent
def initialize(user:, store_credit:, events:, reasons:)
@user = user
@store_credit = store_credit
@store_credit_events = events
@store_credit_reasons = reasons
end

def form_id
dom_id(@store_credit, "#{stimulus_id}_edit_amount_form")
end

def store_credit_reasons_select_options
# Placeholder + Store Credit Reasons
"<option value>#{t('.choose_reason')}</option>" + options_from_collection_for_select(@store_credit_reasons, :id, :name)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
en:
title: Edit Store Credit
cancel: Cancel
submit: Update Store Credit
choose_reason: Choose Reason For Changing Amount
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def rows
end

def row_url(store_credit)
spree.admin_user_store_credit_path(@user, store_credit)
solidus_admin.user_store_credit_path(@user, store_credit)
end

def columns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@
<%= page_header do %>
<%= page_header_back(solidus_admin.users_path) %>
<%= page_header_title(t(".title", email: @user.email, amount: @store_credit.display_amount)) %>

<%= page_header_actions do %>
<%# TODO: can? actions in admin %>
<%# if @store_credit.editable? && can?(:edit, @store_credit) %>
<% if @store_credit.editable? %>
<%= render component("ui/button").new(tag: :a, text: t(".change_amount"), href: spree.edit_amount_admin_user_store_credit_path(@user, @store_credit)) %>
<% end %>
<%# TODO: can? actions in admin %>
<%# if @store_credit.invalidateable? && can?(:invalidate, @store_credit) %>
<% if @store_credit.invalidateable? %>
<%= render component("ui/button").new(scheme: :danger, tag: :a, text: t(".invalidate"), href: spree.edit_validity_admin_user_store_credit_path(@user, @store_credit)) %>
<% end %>

<% end %>
<% end %>

<%= page_header do %>
Expand All @@ -26,17 +12,40 @@

<%= page_with_sidebar do %>
<%= page_with_sidebar_main do %>
<%= render component('ui/panel').new(title: t(".store_credit")) do %>
<%= render component('ui/details_list').new(
items: [
{ label: t('.credited'), value: @store_credit.display_amount },
{ label: t('.created_by'), value: @store_credit.created_by_email },
{ label: t('.type'), value: @store_credit.category_name },
{ label: t('.memo'), value: @store_credit.memo }
]
) %>
<% end %>
<%= render component('ui/panel').new(title: t(".store_credit")) do |panel| %>
<% panel.with_section do %>
<%= render component('ui/details_list').new(
items: [
{ label: t('.credited'), value: @store_credit.display_amount },
{ label: t('.created_by'), value: @store_credit.created_by_email },
{ label: t('.type'), value: @store_credit.category_name },
{ label: t('.memo'), value: @store_credit.memo }
]
) %>
<% end %>

<% if @store_credit.editable? || @store_credit.invalidateable? %>
<% panel.with_section do %>
<div class="w-[100%] text-right">
<% if @store_credit.invalidateable? %>
<%= render component("ui/button").new(
scheme: :danger,
tag: :a,
text: t(".invalidate"),
href: spree.edit_validity_admin_user_store_credit_path(@user, @store_credit)
)%>
<% end %>
<% if @store_credit.editable? %>
<%= render component("ui/button").new(
"data-action": "click->#{stimulus_id}#actionButtonClicked",
"data-#{stimulus_id}-url-param": solidus_admin.edit_amount_user_store_credit_path(@user, @store_credit, _turbo_frame: :edit_amount_modal),
text: t(".edit"),
)%>
<% end %>
</div>
<% end %>
<% end %>
<% end %>

<% if @events.present? %>
<h1 class="font-semibold text-base text-center w-[100%]"><%= t(".store_credit_history") %></h1>
Expand All @@ -56,4 +65,8 @@
<%= render component("users/stats").new(user: @user) %>
<% end %>
<% end %>

<% turbo_frames.each do |frame| %>
<%= turbo_frame_tag frame %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
actionButtonClicked(event) {
const url = new URL(event.params.url, "http://dummy.com")
const params = new URLSearchParams(url.search)
const frameId = params.get('_turbo_frame')
const frame = frameId ? { frame: frameId } : {}
// remove the custom _turbo_frame param from url search:
params.delete('_turbo_frame')
url.search = params.toString()

window.Turbo.visit(url.pathname + url.search, frame)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ def tabs
]
end

def turbo_frames
%w[
edit_amount_modal
]
end

def form_id
@form_id ||= "#{stimulus_id}--form-#{@store_credit.id}"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ en:
store_credit: Store Credit
last_active: Last Active
add_store_credit: Add Store Credit
change_amount: Change Amount
edit: Edit Amount
invalidate: Invalidate
store_credit_history: Store Credit History
credited: Credited
Expand Down
86 changes: 85 additions & 1 deletion admin/app/controllers/solidus_admin/store_credits_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
module SolidusAdmin
class StoreCreditsController < SolidusAdmin::BaseController
before_action :set_user
before_action :set_store_credit, only: [:show]
before_action :set_store_credit, only: [:show, :edit_amount, :update_amount]
before_action :set_store_credit_reasons, only: [:edit_amount, :update_amount]

def index
@store_credits = Spree::StoreCredit.where(user_id: @user.id).order(id: :desc)
Expand All @@ -21,6 +22,42 @@ def show
end
end

def edit_amount
@store_credit_events = @store_credit.store_credit_events.chronological

respond_to do |format|
format.html {
render component("users/store_credits/edit_amount").new(
user: @user,
store_credit: @store_credit,
events: @store_credit_events,
reasons: @store_credit_reasons
)
}
end
end

def update_amount
return unless ensure_amount
return unless ensure_store_credit_reason

if @store_credit.update_amount(permitted_store_credit_params[:amount], @store_credit_reason, spree_current_user)
respond_to do |format|
flash[:notice] = t('.success')

format.html do
redirect_to solidus_admin.user_store_credit_path(@user, @store_credit), status: :see_other
end

format.turbo_stream do
render turbo_stream: '<turbo-stream action="refresh" />'
end
end
else
render_edit_page_with_errors and return

Check warning on line 57 in admin/app/controllers/solidus_admin/store_credits_controller.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/controllers/solidus_admin/store_credits_controller.rb#L57

Added line #L57 was not covered by tests
end
end

private

def set_store_credit
Expand All @@ -30,5 +67,52 @@ def set_store_credit
def set_user
@user = Spree.user_class.find(params[:user_id])
end

def set_store_credit_reasons
@store_credit_reasons = Spree::StoreCreditReason.active.order(:name)
end

def permitted_store_credit_params
permitted_params = [:amount, :currency, :category_id, :memo]
permitted_params << :store_credit_reason_id if action_name.to_sym == :update_amount

params.require(:store_credit).permit(permitted_params).merge(created_by: spree_current_user)
end

def render_edit_page_with_errors
@store_credit_events = @store_credit.store_credit_events.chronological

respond_to do |format|
format.html do
render component("users/store_credits/edit_amount").new(
user: @user,
store_credit: @store_credit,
events: @store_credit_events,
reasons: @store_credit_reasons
),
status: :unprocessable_entity
end
end
end

def ensure_amount
if permitted_store_credit_params[:amount].blank?
@store_credit.errors.add(:amount, :greater_than, count: 0, value: permitted_store_credit_params[:amount])
render_edit_page_with_errors
return false
end
true
end

def ensure_store_credit_reason
@store_credit_reason = Spree::StoreCreditReason.find_by(id: permitted_store_credit_params[:store_credit_reason_id])

if @store_credit_reason.blank?
@store_credit.errors.add(:store_credit_reason_id, "Store Credit reason must be provided")
render_edit_page_with_errors
return false
end
true
end
end
end
10 changes: 10 additions & 0 deletions admin/config/locales/store_credits.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
en:
solidus_admin:
store_credits:
title: "Store Credits"
destroy:
success: "Store credit was successfully removed."
create:
success: "Store credit was successfully created."
update_amount:
success: "Store credit was successfully updated."
7 changes: 6 additions & 1 deletion admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@
get :items
end

resources :store_credits, only: [:index, :show], controller: "store_credits"
resources :store_credits, only: [:index, :show], constraints: { id: /\d+/ }, controller: "store_credits" do
member do
get :edit_amount
put :update_amount
end
end
end

admin_resources :promotions, only: [:index, :destroy]
Expand Down
56 changes: 55 additions & 1 deletion admin/spec/features/users_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,17 @@

before do
stub_authorization!(admin)
find_row("$199.00").click
end

it "shows individual store credit details" do
find_row("$199.00").click
expect(page).to have_content("Users / customer@example.com / Store Credit / $199.00")
expect(page).to have_content("Store Credit History")
expect(page).to have_content("Action")
expect(page).to have_content("Added")
end

it "allows invalidating of the store credit" do
click_on "Invalidate"
select "credit given in error", from: "store_credit_reason_id"
click_on "Invalidate"
Expand All @@ -328,6 +331,57 @@
expect(page).to have_content("Reason for updating")
expect(page).to have_content("credit given in error")
end

context "when editing the store credit amount" do
context "with invalid amount" do
it "shows the appropriate error message" do
click_on "Edit Amount"
expect(page).to have_selector("dialog", wait: 5)
expect(page).to have_content("Edit Store Credit")

within("dialog") do
fill_in "Amount", with: ""
click_on "Update Store Credit"
expect(page).to have_content("must be greater than 0")
click_on "Cancel"
end
end
end

context "without a valid reason" do
it "shows the appropriate error message" do
click_on "Edit Amount"
expect(page).to have_selector("dialog", wait: 5)
expect(page).to have_content("Edit Store Credit")

within("dialog") do
fill_in "Amount", with: "100"
click_on "Update Store Credit"
expect(page).to have_content("Store Credit reason must be provided")
click_on "Cancel"
end
end
end

context "with valid params" do
it "allows editing of the store credit amount" do
click_on "Edit Amount"
expect(page).to have_selector("dialog", wait: 5)
expect(page).to have_content("Edit Store Credit")

# Invalid amount
within("dialog") do
fill_in "Amount", with: "666"
select "credit given in error", from: "store_credit[store_credit_reason_id]"
click_on "Update Store Credit"
end

expect(page).to have_content("Users / customer@example.com / Store Credit / $666.00")
expect(page).to have_content("Adjustment")
expect(page).to have_content("credit given in error")
end
end
end
end
end
end
Expand Down
Loading

0 comments on commit 2eefd30

Please sign in to comment.