Skip to content

Commit

Permalink
🌸 Marketplace: Improve ManagementComponent iconography (zinc-coll…
Browse files Browse the repository at this point in the history
…ective#2221)

- zinc-collective#2220

The icons for `TaxeRates#index` and `Flyers#show` were the same, plus
`Products#index` will conflict with `Tags#index`.

So now `Products#index` is 🍰 and `Flyers#show` is :qr_code:

While I was doing this, I also made the following tidyings:

- ✨ `SvgComponent` has `#building_storefront` icon!
- ✨ `SvgComponent` has `#qr_code` icon!
- 🧹 `SvgComponent` icon-method names match Heroicon's label!
- 🧹 `SvgComponent#cake` does not need a wrapping `<svg ...>` tag!
- 🥗 `ManagementComponent` has every link it's supposed to
- 🧹 `ManagementComponent::Spec` uses `have_link` instead of `have_css`
- 🧹 `ManagementComponent` eliminates usage of `ButtonComponent`

We originally added the `ButtonComponent` to inject the tailwind CSS
classes in Ruby, but with the changes @anaulin made, we now can use the
`.button` and `.button.--primary`/`.button.--secondary` classes.

Now, when I notice the `ButtonComponent` being used, I pull it out so we
can (eventually) delete it.
  • Loading branch information
zspencer committed Mar 25, 2024
1 parent 36fee4c commit e9b5cf5
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 53 deletions.
45 changes: 17 additions & 28 deletions app/components/svg_component.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,6 @@
class SvgComponent < ApplicationComponent
# Mapping of icon name symbols to methods returning the SVG path for that icon.
#
# We've been getting these SVG paths from https://heroicons.com/, using
# the "Outline" style.
# Feel free to add more as needed, from other libraries as appropriate,
# as long as they match the intended aesthetic and are appropriately licensed.
#
# Format: { symbol: method returning path for symbol }
ICON_MAPPINGS = {
cake: :cake,
cart: :cart,
money: :money,
exclamation_triangle: :exclamation_triangle,
gear: :gear,
map: :map,
receipt_percent: :receipt_percent,
bell: :ringing_bell,
tag: :tag,
plus: :plus,
trash: :trash,
pencil: :pencil
}.with_indifferent_access.freeze

# We've been getting SVG paths from https://heroicons.com/, using the
# "Outline" style. Add more as needed.
attr_reader :icon

def initialize(icon: nil, **kwargs)
Expand All @@ -35,7 +14,7 @@ def call

def content
if icon.present?
raw(send(ICON_MAPPINGS[icon])) # rubocop:disable Rails/OutputSafety
raw(send(icon)) # rubocop:disable Rails/OutputSafety
else
super
end
Expand All @@ -53,6 +32,12 @@ def options
})
end

def building_storefront
<<~SVG
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 21v-7.5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349M3.75 21V9.349m0 0a3.001 3.001 0 0 0 3.75-.615A2.993 2.993 0 0 0 9.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 0 0 2.25 1.016c.896 0 1.7-.393 2.25-1.015a3.001 3.001 0 0 0 3.75.614m-16.5 0a3.004 3.004 0 0 1-.621-4.72l1.189-1.19A1.5 1.5 0 0 1 5.378 3h13.243a1.5 1.5 0 0 1 1.06.44l1.19 1.189a3 3 0 0 1-.621 4.72M6.75 18h3.75a.75.75 0 0 0 .75-.75V13.5a.75.75 0 0 0-.75-.75H6.75a.75.75 0 0 0-.75.75v3.75c0 .414.336.75.75.75Z" />
SVG
end

def gear
<<~SVG
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
Expand Down Expand Up @@ -91,7 +76,7 @@ def cart
SVG
end

def ringing_bell
def bell_alert
<<~SVG
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0M3.124 7.5A8.969 8.969 0 015.292 3m13.416 0a8.969 8.969 0 012.168 4.5" />
SVG
Expand Down Expand Up @@ -123,10 +108,14 @@ def pencil

def cake
<<~SVG
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 8.25v-1.5m0 1.5c-1.355 0-2.697.056-4.024.166C6.845 8.51 6 9.473 6 10.608v2.513m6-4.871c1.355 0 2.697.056 4.024.166C17.155 8.51 18 9.473 18 10.608v2.513M15 8.25v-1.5m-6 1.5v-1.5m12 9.75-1.5.75a3.354 3.354 0 0 1-3 0 3.354 3.354 0 0 0-3 0 3.354 3.354 0 0 1-3 0 3.354 3.354 0 0 0-3 0 3.354 3.354 0 0 1-3 0L3 16.5m15-3.379a48.474 48.474 0 0 0-6-.371c-2.032 0-4.034.126-6 .371m12 0c.39.049.777.102 1.163.16 1.07.16 1.837 1.094 1.837 2.175v5.169c0 .621-.504 1.125-1.125 1.125H4.125A1.125 1.125 0 0 1 3 20.625v-5.17c0-1.08.768-2.014 1.837-2.174A47.78 47.78 0 0 1 6 13.12M12.265 3.11a.375.375 0 1 1-.53 0L12 2.845l.265.265Zm-3 0a.375.375 0 1 1-.53 0L9 2.845l.265.265Zm6 0a.375.375 0 1 1-.53 0L15 2.845l.265.265Z" />
</svg>
<path stroke-linecap="round" stroke-linejoin="round" d="M12 8.25v-1.5m0 1.5c-1.355 0-2.697.056-4.024.166C6.845 8.51 6 9.473 6 10.608v2.513m6-4.871c1.355 0 2.697.056 4.024.166C17.155 8.51 18 9.473 18 10.608v2.513M15 8.25v-1.5m-6 1.5v-1.5m12 9.75-1.5.75a3.354 3.354 0 0 1-3 0 3.354 3.354 0 0 0-3 0 3.354 3.354 0 0 1-3 0 3.354 3.354 0 0 0-3 0 3.354 3.354 0 0 1-3 0L3 16.5m15-3.379a48.474 48.474 0 0 0-6-.371c-2.032 0-4.034.126-6 .371m12 0c.39.049.777.102 1.163.16 1.07.16 1.837 1.094 1.837 2.175v5.169c0 .621-.504 1.125-1.125 1.125H4.125A1.125 1.125 0 0 1 3 20.625v-5.17c0-1.08.768-2.014 1.837-2.174A47.78 47.78 0 0 1 6 13.12M12.265 3.11a.375.375 0 1 1-.53 0L12 2.845l.265.265Zm-3 0a.375.375 0 1 1-.53 0L9 2.845l.265.265Zm6 0a.375.375 0 1 1-.53 0L15 2.845l.265.265Z" />
SVG
end

def qr_code
<<~SVG
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z" />
SVG
end
end
16 changes: 8 additions & 8 deletions app/furniture/marketplace/management_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
<%= content %>
<% card.with_footer do %>
<nav class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
<%= render button({child: :payment_settings}, icon: :money) if policy(marketplace).edit? %>
<%= render button({child: :products}, icon: :tag) if policy(marketplace.products).index? %>
<%= render button({child: :delivery_areas}, icon: :map) if policy(marketplace.delivery_areas).index? %>
<%= render button({child: :tax_rates}, icon: :receipt_percent) if policy(marketplace.tax_rates).index? %>
<%= render button({child: :orders}, icon: :cart) if policy(marketplace.orders).index? %>
<%= render button({child: :notification_methods}, icon: :bell) if policy(marketplace.notification_methods).index? %>
<%= render button({child: :flyer}, icon: :receipt_percent) if policy(marketplace.flyer).show? %>
<%= render button({child: :vendor_representatives}, icon: :cake) if policy(marketplace.vendor_representatives).index? %>
<%= link_to_child(:payment_settings, icon: :money) if policy(marketplace).edit? %>
<%= link_to_child(:products, icon: :cake) if policy(marketplace.products).index? %>
<%= link_to_child(:delivery_areas, icon: :map) if policy(marketplace.delivery_areas).index? %>
<%= link_to_child(:tax_rates, icon: :receipt_percent) if policy(marketplace.tax_rates).index? %>
<%= link_to_child(:orders, icon: :cart) if policy(marketplace.orders).index? %>
<%= link_to_child(:notification_methods, icon: :bell_alert) if policy(marketplace.notification_methods).index? %>
<%= link_to_child(:flyer, icon: :qr_code) if policy(marketplace.flyer).show? %>
<%= link_to_child(:vendor_representatives, icon: :building_storefront) if policy(marketplace.vendor_representatives).index? %>
</nav>
<% end %>
<% end %>
Expand Down
20 changes: 10 additions & 10 deletions app/furniture/marketplace/management_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ def onboarding_component
OnboardingComponent.new(marketplace: marketplace)
end

def button(location, icon:)
label, href = if location.is_a?(Symbol)
[t("marketplace.marketplace.#{location}.link_to"),
marketplace.location(location)]
elsif location[:child].to_s.pluralize == location[:child].to_s
[t("marketplace.#{location[:child]}.index.link_to"),
marketplace.location(**location)]
def link_to_child(child, icon:)
label, href = if child.to_s.pluralize == child.to_s
[t("marketplace.#{child}.index.link_to"),
marketplace.location(child:)]
else
[t("marketplace.#{location[:child].to_s.pluralize}.show.link_to"),
marketplace.location(**location)]
[t("marketplace.#{child.to_s.pluralize}.show.link_to"),
marketplace.location(child:)]
end

ButtonComponent.new(label: label, icon: icon, href: href, turbo_stream: false, method: :get, scheme: :secondary)
link_to(href, class: "button --secondary w-full text-left") do
render(SvgComponent.new(icon:, classes: "w-6 h-6 mr-2 inline-block")) +
label
end
end
end
end
15 changes: 8 additions & 7 deletions spec/furniture/marketplace/management_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
let(:component) { described_class.new(marketplace: marketplace, current_person: operator) }
let(:marketplace) { create(:marketplace) }

it { is_expected.to have_css("a[href='#{polymorphic_path(marketplace.location(child: :products))}']", text: I18n.t("marketplace.products.index.link_to")) }

it { is_expected.to have_css("a[href='#{polymorphic_path(marketplace.location(child: :delivery_areas))}']", text: I18n.t("marketplace.delivery_areas.index.link_to")) }

it { is_expected.to have_css("a[href='#{polymorphic_path(marketplace.location(child: :tax_rates))}']", text: I18n.t("marketplace.tax_rates.index.link_to")) }

it { is_expected.to have_css("a[href='#{polymorphic_path(marketplace.location(child: :orders))}']", text: I18n.t("marketplace.orders.index.link_to")) }
it { is_expected.to have_link(I18n.t("marketplace.payment_settings.index.link_to"), href: polymorphic_path(marketplace.location(child: :payment_settings))) }
it { is_expected.to have_link(I18n.t("marketplace.products.index.link_to"), href: polymorphic_path(marketplace.location(child: :products))) }
it { is_expected.to have_link(I18n.t("marketplace.delivery_areas.index.link_to"), href: polymorphic_path(marketplace.location(child: :delivery_areas))) }
it { is_expected.to have_link(I18n.t("marketplace.tax_rates.index.link_to"), href: polymorphic_path(marketplace.location(child: :tax_rates))) }
it { is_expected.to have_link(I18n.t("marketplace.orders.index.link_to"), href: polymorphic_path(marketplace.location(child: :orders))) }
it { is_expected.to have_link(I18n.t("marketplace.notification_methods.index.link_to"), href: polymorphic_path(marketplace.location(child: :notification_methods))) }
it { is_expected.to have_link(I18n.t("marketplace.vendor_representatives.index.link_to"), href: polymorphic_path(marketplace.location(child: :vendor_representatives))) }
it { is_expected.to have_link(I18n.t("marketplace.flyers.show.link_to"), href: polymorphic_path(marketplace.location(child: :flyer))) }
end

0 comments on commit e9b5cf5

Please sign in to comment.