diff --git a/rails_application/.mutant.yml b/rails_application/.mutant.yml index c0914a61..2510e3ca 100644 --- a/rails_application/.mutant.yml +++ b/rails_application/.mutant.yml @@ -31,6 +31,7 @@ matcher: - ClientOrders::ChangeProductPrice* - ClientOrders::RegisterProduct* - ClientOrders::ShowOrder* + - ClientOrders::EditOrder* - Orders::Broadcaster* - Orders::AddItemToOrder* - Orders::RemoveItemFromOrder* diff --git a/rails_application/app/controllers/client/orders_controller.rb b/rails_application/app/controllers/client/orders_controller.rb index ffc59a5b..7f45388c 100644 --- a/rails_application/app/controllers/client/orders_controller.rb +++ b/rails_application/app/controllers/client/orders_controller.rb @@ -6,9 +6,8 @@ def index end def new - @order_id = SecureRandom.uuid - @products = ClientOrders::Product.all - render 'edit' + order_id = SecureRandom.uuid + redirect_to edit_client_order_path(order_id) end def create @@ -29,9 +28,10 @@ def show end def edit - @order_id = params[:id] - @order_lines = ClientOrders::OrderLine.where(order_uid: params[:id]) - @products = ClientOrders::Product.all + order_id = params[:id] + order_lines = ClientOrders::OrderLine.where(order_uid: params[:id]) + products = ClientOrders::Product.all + render html: ClientOrders::EditOrder.build(view_context, order_id, order_lines, products), layout: true end def add_item diff --git a/rails_application/app/read_models/client_orders/edit_order.rb b/rails_application/app/read_models/client_orders/edit_order.rb new file mode 100644 index 00000000..590c6d51 --- /dev/null +++ b/rails_application/app/read_models/client_orders/edit_order.rb @@ -0,0 +1,79 @@ +module ClientOrders + class EditOrder < Arbre::Component + include Rails.application.routes.url_helpers + include ActionView::Helpers::FormTagHelper + include ActionView::Helpers::UrlHelper + + def self.build(view_context, order_id, order_lines, products) + new(Arbre::Context.new(nil, view_context)).build(order_id, order_lines, products) + end + + def build(order_id, order_lines, products, attributes = {}) + super(attributes) + div do + products_table(order_id, products, order_lines) + submit_form(order_id) + end + end + + private + + def products_table(order_id, products, order_lines) + table class: "w-full" do + headers_row + tbody do + text_node turbo_stream_from "client_orders_#{order_id}" + products.each do |product| + product_row(order_id, product, order_lines) + end + end + end + end + + def headers_row + thead do + tr do + th(class: "text-left py-2") { "Product" } + th(class: "text-left py-2") { "" } + th(class: "text-left py-2") { "Quantity" } + th(class: "text-left py-2") { "Price" } + th(class: "text-left py-2", colspan: 3) { "Value" } + end + end + end + + def product_row(order_id, product, order_lines) + order_line = order_lines&.find { |order_line| order_line.product_id == product.uid } + tr class: "border-b" do + td(class: "py-2") { product.name } + td(class: "py-2") { out_of_stock_badge unless product.available? } + td(class: "py-2", id: "client_orders_#{product.uid}_product_quantity") { order_line.try(&:product_quantity) || 0 } + td(class: "py-2") { number_to_currency(product.price) } + td(class: "py-2", id: "client_orders_#{product.uid}_value") { number_to_currency(order_line.try(&:value)) } + td(class: "py-2 text-right") { add_item_button(order_id, product.uid) } + td(class: "py-2 text-right", id: "client_orders_#{product.uid}_remove_item_button") { remove_item_button(order_id, product.uid) if order_line } + end + end + + def out_of_stock_badge + span "out of stock", class: "rounded-lg bg-yellow-400 text-yellow-900 px-2 py-0.5" + end + + def add_item_button(order_id, product_id) + button_to "Add", add_item_client_order_path(id: order_id, product_id: product_id), class: "hover:underline text-blue-500" + end + + def remove_item_button(order_id, product_id) + button_to "Remove", remove_item_client_order_path(id: order_id, product_id: product_id), class: "hover:underline text-blue-500" + end + + def submit_form(order_id) + form(id: "form", action: client_orders_path, method: :post) do + input(type: :hidden, name: :order_id, value: order_id) + div(class: "mt-8") do + input type: :submit, value: "Create Order", class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" + end + end + end + end +end diff --git a/rails_application/app/views/client/orders/edit.html.erb b/rails_application/app/views/client/orders/edit.html.erb deleted file mode 100644 index 0ef9f3d3..00000000 --- a/rails_application/app/views/client/orders/edit.html.erb +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - <%= turbo_stream_from "client_orders_#{@order_id}" %> - <% @products.each do |product| %> - - <% order_line = @order_lines&.find{|order_line| order_line.product_id == product.uid} %> - - - - - - - <% if order_line.nil? %> - - <% else %> - - <% end %> - - <% end %> - -
ProductQuantityPriceValue
<%= product.name %> - <% unless product.available? %> - out of stock - <% end %> - "><%= order_line.try(&:product_quantity) || 0 %><%= number_to_currency(product.price) %>"><%= number_to_currency(order_line.try(&:value)) %> - <%= button_to "Add", add_item_client_order_path(id: @order_id, product_id: product.uid), class: "hover:underline text-blue-500" %> - ">"> - <%= button_to("Remove", remove_item_client_order_path(id: @order_id, product_id: product.uid), class: "hover:underline text-blue-500") %> -
- -<%= form_tag({controller: "client/orders", action: "create"}, method: "post", id: "form") do %> - <%= hidden_field_tag(:order_id, @order_id) %> - -
- <%= submit_tag("Create Order", class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded") %> -
-<% end %> diff --git a/rails_application/test/integration/client_orders_test.rb b/rails_application/test/integration/client_orders_test.rb index 7cc46162..ec9e1d6b 100644 --- a/rails_application/test/integration/client_orders_test.rb +++ b/rails_application/test/integration/client_orders_test.rb @@ -183,6 +183,7 @@ def test_shows_out_of_stock_badge as_client_submit_order_for_customer(order_id) get "/client_orders/new" + follow_redirect! assert_select "td span", "out of stock" end