From 079bcc8d1df2546a63e9a98f6213265d2cd9333c Mon Sep 17 00:00:00 2001 From: Emi Matchu Date: Mon, 3 Nov 2025 00:44:12 +0000 Subject: [PATCH] [WV2] Add item removal --- app/assets/stylesheets/outfits/new_v2.css | 42 +++++++++++++++++++++++ app/helpers/outfits_helper.rb | 21 ++++++++++++ app/views/outfits/new_v2.html.haml | 9 +++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/outfits/new_v2.css b/app/assets/stylesheets/outfits/new_v2.css index e8089565..3db4fe48 100644 --- a/app/assets/stylesheets/outfits/new_v2.css +++ b/app/assets/stylesheets/outfits/new_v2.css @@ -217,11 +217,16 @@ body.wardrobe-v2 { border-radius: 8px; color: #333; transition: background 0.2s, box-shadow 0.2s; + position: relative; &:hover { background: #f0f0f0; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } + + &:hover .item-remove-button { + opacity: 1; + } } .item-thumbnail { @@ -262,6 +267,43 @@ body.wardrobe-v2 { gap: 0.375rem; flex-wrap: wrap; } + + .item-remove-button { + position: absolute; + top: 0.5rem; + right: 0.5rem; + padding: 0; + margin: 0; + border: none; + background: rgba(255, 255, 255, 0.9); + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + line-height: 1; + width: 1.75rem; + height: 1.75rem; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.2s, background 0.2s, transform 0.1s; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + + &:hover { + background: rgba(255, 255, 255, 1); + transform: scale(1.1); + } + + &:active { + transform: scale(0.95); + } + + &:focus { + opacity: 1; + outline: 2px solid #448844; + outline-offset: 2px; + } + } } @keyframes fade-in { diff --git a/app/helpers/outfits_helper.rb b/app/helpers/outfits_helper.rb index 498ca9a2..f8c9523a 100644 --- a/app/helpers/outfits_helper.rb +++ b/app/helpers/outfits_helper.rb @@ -65,6 +65,27 @@ module OutfitsHelper text_field_tag 'name', nil, options end + # Generate hidden fields to preserve outfit state in URL params. + # Options: + # - exclude_item_id: Item ID to exclude from objects[] array + def outfit_state_params(exclude_item_id: nil) + fields = [] + + # Preserve species and color + fields << hidden_field_tag(:species, params[:species]) if params[:species].present? + fields << hidden_field_tag(:color, params[:color]) if params[:color].present? + + # Preserve item IDs, optionally excluding one + if params[:objects].present? + params[:objects].each do |item_id| + next if exclude_item_id && item_id.to_s == exclude_item_id.to_s + fields << hidden_field_tag("objects[]", item_id) + end + end + + safe_join(fields) + end + def outfit_viewer(...) render partial: "outfit_viewer", locals: parse_outfit_viewer_options(...) diff --git a/app/views/outfits/new_v2.html.haml b/app/views/outfits/new_v2.html.haml index b26fdbe8..ec93f327 100644 --- a/app/views/outfits/new_v2.html.haml +++ b/app/views/outfits/new_v2.html.haml @@ -30,6 +30,7 @@ %species-color-picker = form_with url: wardrobe_v2_path, method: :get do |f| + = outfit_state_params = select_tag :color, options_from_collection_for_select(@colors, "id", "human_name", @selected_color&.id), @@ -40,11 +41,6 @@ "aria-label": "Pet species" = submit_tag "Go", name: nil - -# Preserve item IDs in the URL - - if params[:objects].present? - - params[:objects].each do |item_id| - = hidden_field_tag "objects[]", item_id - .outfit-controls-section %h1 Customize your pet @@ -65,3 +61,6 @@ .item-badges = render "items/badges/kind", item: item = render "items/badges/first_seen", item: item + = button_to wardrobe_v2_path, method: :get, class: "item-remove-button", title: "Remove #{item.name}", "aria-label": "Remove #{item.name}" do + ❌ + = outfit_state_params exclude_item_id: item.id