From c96b726a6118bc2b82c32c018cc2d73a171c4724 Mon Sep 17 00:00:00 2001 From: Matchu Date: Tue, 9 Jul 2024 13:04:22 -0700 Subject: [PATCH 1/6] Rebrand the "Item Getting Guide" as "Shopping List" Two reasons for this new title: 1. The pitch for "Get these items!" is weaker, now that we're not getting the power-user integrations we'd planned around. 2. I literally only just thought of it now! --- app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js | 8 ++++---- app/views/items/sources.html.haml | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js index db361aa6..5d1bfd29 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js +++ b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js @@ -280,8 +280,8 @@ function ItemZoneGroupSkeleton({ itemCount }) { /** * GetTheseItemsButton shows the "Get these items!" button, to link to the - * Item Getting Guide page for the items in this outfit. If there are no items - * being worn, this is disabled. + * Shopping List page for the items in this outfit. If there are no items being + * worn, this is disabled. */ function GetTheseItemsButton({ outfitState }) { const [searchParams] = useSearchParams(); @@ -305,13 +305,13 @@ function GetTheseItemsButton({ outfitState }) { return ( Date: Tue, 9 Jul 2024 13:14:22 -0700 Subject: [PATCH 2/6] Use a shopping bag icon for the "Shopping List" button Shopping bag with check! Heck yeah! --- app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js index 5d1bfd29..9dcd1a29 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js +++ b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js @@ -34,7 +34,7 @@ import { QuestionIcon, WarningTwoIcon, } from "@chakra-ui/icons"; -import { FaCartPlus } from "react-icons/fa6"; +import { IoBagCheck } from "react-icons/io5"; import { CSSTransition, TransitionGroup } from "react-transition-group"; import { useSearchParams } from "react-router-dom"; @@ -315,7 +315,7 @@ function GetTheseItemsButton({ outfitState }) { as={isDisabled ? "button" : "a"} href={isDisabled ? undefined : targetUrl} target={isDisabled ? undefined : "_blank"} - icon={} + icon={} colorScheme="purple" size="sm" isRound From 81c6a4a0232d205e8f9fd3c9c8e81da2c30d4278 Mon Sep 17 00:00:00 2001 From: Matchu Date: Tue, 9 Jul 2024 13:19:23 -0700 Subject: [PATCH 3/6] Add outfit name to Shopping List page title Just some extra flair! I had considered something like this before, but felt it didn't flow well with the old title. --- .../wardrobe-2020/WardrobePage/ItemsPanel.js | 14 ++++++++++---- app/views/items/sources.html.haml | 6 ++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js index 9dcd1a29..927f0c38 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js +++ b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js @@ -295,14 +295,20 @@ function GetTheseItemsButton({ outfitState }) { } }, [searchParams, setIsVisible]); - const itemIds = [...outfitState.wornItemIds].sort(); - const targetUrl = `/items/sources/${itemIds.join(",")}`; - const isDisabled = itemIds.length === 0; - if (!isVisible) { return null; } + const itemIds = [...outfitState.wornItemIds].sort(); + const isDisabled = itemIds.length === 0; + + let targetUrl = `/items/sources/${itemIds.join(",")}`; + if (outfitState.name != null && outfitState.name.trim().length > 0) { + const params = new URLSearchParams(); + params.append("for", outfitState.name); + targetUrl += "?" + params.toString(); + } + return ( Date: Tue, 9 Jul 2024 13:30:28 -0700 Subject: [PATCH 4/6] Link to the NC Mall homepage from the Shopping List We were previously planning a more interesting "Add to Cart" integration with TNT, but it hasn't panned out! For now, we'll just link to the NC Mall homepage. --- app/helpers/application_helper.rb | 16 ++++++++++++++-- app/views/items/sources.html.haml | 20 ++++++++++---------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 01cd3d9c..3ec615ff 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -21,12 +21,24 @@ module ApplicationHelper end end - def button_link_to(content, url, icon: nil, **options) + def button_link_to(content_or_url, url = nil, icon: nil, **options) + if url.present? + content = content_or_url + url = url + else + content = nil + url = content_or_url + end + klass = options.fetch(:class, "") + " button" link_to url, class: klass, **options do concat icon concat " " - concat content + if block_given? + yield + else + concat content + end end end diff --git a/app/views/items/sources.html.haml b/app/views/items/sources.html.haml index fe854b66..9e6f51e5 100644 --- a/app/views/items/sources.html.haml +++ b/app/views/items/sources.html.haml @@ -27,16 +27,16 @@ %td.actions-cell - if @items_needed[:nc_mall].present? - %button{ - onclick: "alert('Todo!')", - data: {"action-kind": "bulk-nc-mall"}, - } + = button_link_to "https://ncmall.neopets.com/", + target: "_blank", + data: {"action-kind": "bulk-nc-mall"} do = cart_icon alt: "" Buy all in NC Mall %tbody - @items[:nc_mall].each do |item| = render "item_list_row", item: do - %button{onclick: "alert('Todo!')"} + = button_link_to "https://ncmall.neopets.com/", + target: "_blank" do = cart_icon alt: "" Buy (#{item.current_nc_price} NC) @@ -74,10 +74,9 @@ (~#{dyeworks_estimated_potions_cost_for @items_needed[:dyeworks]} NC) %td.actions-cell - if @items_needed[:dyeworks].present? - %button{ - onclick: "alert('Todo!')", - data: {"action-kind": "bulk-nc-mall"}, - } + = button_link_to "https://ncmall.neopets.com/", + target: "_blank", + data: {"action-kind": "bulk-nc-mall"} do = cart_icon alt: "" Buy all in NC Mall %tbody @@ -112,7 +111,8 @@ } (Limited-time) - %button{onclick: "alert('Todo!')"} + = button_link_to "https://ncmall.neopets.com/", + target: "_blank" do = cart_icon alt: "" Buy base (#{item.dyeworks_base_item.current_nc_price} NC) From c55f71a000c73f77a622efc878d8755dd58d485e Mon Sep 17 00:00:00 2001 From: Matchu Date: Tue, 9 Jul 2024 13:36:42 -0700 Subject: [PATCH 5/6] Rename GetTheseItemsButton -> ShoppingListButton Just for consistency with the user-facing branding! --- .../wardrobe-2020/WardrobePage/ItemsPanel.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js index 927f0c38..d84058be 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js +++ b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js @@ -279,11 +279,11 @@ function ItemZoneGroupSkeleton({ itemCount }) { } /** - * GetTheseItemsButton shows the "Get these items!" button, to link to the - * Shopping List page for the items in this outfit. If there are no items being - * worn, this is disabled. + * ShoppingListButton shows the "Shopping list" button, to link to the Shopping= + * List page for the items in this outfit. If there are no items being worn, + * this is disabled. */ -function GetTheseItemsButton({ outfitState }) { +function ShoppingListButton({ outfitState }) { const [searchParams] = useSearchParams(); const [isVisible, setIsVisible] = useLocalStorage("DTIShowGetTheseItems"); @@ -466,7 +466,7 @@ function OutfitHeading({ outfitState, outfitSaving, dispatchToOutfit }) { - + Date: Tue, 9 Jul 2024 13:39:20 -0700 Subject: [PATCH 6/6] Release the Shopping List button to everyone Deleting the feature-flag code to gate it, it just now always appears! Happy launch day! --- .../wardrobe-2020/WardrobePage/ItemsPanel.js | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js index d84058be..0b430fa3 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js +++ b/app/javascript/wardrobe-2020/WardrobePage/ItemsPanel.js @@ -36,15 +36,8 @@ import { } from "@chakra-ui/icons"; import { IoBagCheck } from "react-icons/io5"; import { CSSTransition, TransitionGroup } from "react-transition-group"; -import { useSearchParams } from "react-router-dom"; -import { - Delay, - ErrorMessage, - Heading1, - Heading2, - useLocalStorage, -} from "../util"; +import { Delay, ErrorMessage, Heading1, Heading2 } from "../util"; import Item, { ItemListContainer, ItemListSkeleton } from "./Item"; import { BiRename } from "react-icons/bi"; import { IoCloudUploadOutline } from "react-icons/io5"; @@ -284,21 +277,6 @@ function ItemZoneGroupSkeleton({ itemCount }) { * this is disabled. */ function ShoppingListButton({ outfitState }) { - const [searchParams] = useSearchParams(); - const [isVisible, setIsVisible] = useLocalStorage("DTIShowGetTheseItems"); - - // Enable this feature by visiting `/outfits/new?features=get-these-items`. - React.useEffect(() => { - const features = searchParams.get("features") ?? ""; - if (features.split(",").includes("get-these-items")) { - setIsVisible(true); - } - }, [searchParams, setIsVisible]); - - if (!isVisible) { - return null; - } - const itemIds = [...outfitState.wornItemIds].sort(); const isDisabled = itemIds.length === 0;