Skip to content

Commit

Permalink
WIP store credit refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
MadelineCollier committed Dec 9, 2024
1 parent 2d5bda7 commit 9dc1797
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def self.select(form, method, choices, object: nil, hint: nil, tip: nil, size: :
tag: :select,
choices:,
size:,
value: object.public_send(method),
value: (object.public_send(method) if object.respond_to?(method)),
error: (errors.to_sentence.capitalize if errors),
**attributes,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<%= 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, data: { turbo: false }, 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 }
) %>
<!-- Display error messages from :base -->
<% if @store_credit.errors.any? %>
<div class="alert alert-error">
<ul>
<% @store_credit.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render component("ui/forms/field").text_field(f, :memo, class: "required") %>
</div>
<% modal.with_actions do %>
<form method="dialog">
<%= render component("ui/button").new(scheme: :secondary, tag: :a, href: solidus_admin.user_store_credit_path(@user, @store_credit), text: t('.cancel')) %>
</form>
<%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
<% 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_store_credit_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,31 @@

<%= 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, "data-action": "click->#{stimulus_id}#confirmDelete", 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(tag: :a, "data-action": "click->#{stimulus_id}#confirmDelete", text: t(".edit"), href: solidus_admin.edit_amount_user_store_credit_path(@user, @store_credit)) %>
<% end %>
</div>
<% end %>
<% end %>
<% end %>

<% if @events.present? %>
<h1 class="font-semibold text-base text-center w-[100%]"><%= t(".store_credit_history") %></h1>
Expand Down
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 @@ -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 Store Credit
invalidate: Invalidate
store_credit_history: Store Credit History
credited: Credited
Expand Down
120 changes: 119 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,8 +3,10 @@
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]

SolidusAdmin::StoreCreditsController
def index
@store_credits = Spree::StoreCredit.where(user_id: @user.id).order(id: :desc)

Expand All @@ -18,17 +20,133 @@ def show

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

format.turbo_stream do
render turbo_stream: turbo_stream.replace(
"store_credit_details", # Target a container ID in your HTML
partial: "users/store_credits/show", # Use the appropriate partial
locals: { user: @user, store_credit: @store_credit, events: @store_credit_events }
)
end
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
# binding.pry
#
# @store_credit_reason = Spree::StoreCreditReason.find_by(id: params[:store_credit_reason_id])
# unless @store_credit_reason
# @store_credit.errors.add(:base, t('spree.admin.store_credits.errors.store_credit_reason_required'))
# render_edit_page
# end
#
# amount = params.require(:store_credit).require(:amount)
# if @store_credit.update_amount(amount, @store_credit_reason, spree_current_user)
# flash[:success] = flash_message_for(@store_credit, :successfully_updated)
# redirect_to admin_user_store_credit_path(@user, @store_credit)
# else
# flash[:error] = "#{t("spree.admin.store_credits.unable_to_update")}: #{@store_credit.errors.full_messages.join(', ')}"
# render(:edit_amount) && return
# end
# end

def wip_old_update_amount
if @store_credit.update(permitted_store_credit_params)
flash[:notice] = t('.success')
redirect_to solidus_admin.user_store_credit_path(@user, @store_credit), status: :see_other
else
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
),
status: :unprocessable_entity
}
end
end
end

def update_amount
@store_credit_reason = Spree::StoreCreditReason.find_by(id: params[:store_credit_reason_id])
amount = params.require(:store_credit).require(:amount)

if amount_changed?
if @store_credit_reason.blank?
@store_credit.errors.add(:base, "Store Credit reason must be provided")
render_edit_page_with_errors and return
end

unless @store_credit.update_amount(amount, @store_credit_reason, spree_current_user)
render_edit_page_with_errors and return
end
end

@store_credit.update(memo: permitted_store_credit_params[:memo])

flash[:notice] = t('.success')
redirect_to solidus_admin.user_store_credit_path(@user, @store_credit), status: :see_other
end

private

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 permitted_store_credit_params
params.require(:store_credit).permit([:amount, :currency, :category_id, :memo]).
merge(created_by: spree_current_user)
end

def set_store_credit
@store_credit = Spree::StoreCredit.find(params[:id])
end

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 amount_changed?
# Add error if the amount is blank or nil. Let the model validation handle all other cases.
if permitted_store_credit_params[:amount].blank?
@store_credit.errors.add(:amount, :greater_than, count: 0, value: permitted_store_credit_params[:amount])
return false
end

old_amount = @store_credit.amount
new_amount = BigDecimal(permitted_store_credit_params[:amount])
old_amount != new_amount
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."
9 changes: 8 additions & 1 deletion admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@
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
# get :edit_validity
# put :invalidate
end
end
end

admin_resources :promotions, only: [:index, :destroy]
Expand Down
Loading

0 comments on commit 9dc1797

Please sign in to comment.