mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-22 06:39:39 +02:00
Fix merchants color picker (#1134)
* Fix merchants color picker * Lint fixes
This commit is contained in:
parent
166ed4b1ea
commit
f82ce59dad
8 changed files with 52 additions and 71 deletions
|
@ -6,7 +6,7 @@ module MenusHelper
|
|||
end
|
||||
end
|
||||
|
||||
def contextual_menu_modal_action_item(label, url, icon: "pencil-line", turbo_frame: nil)
|
||||
def contextual_menu_modal_action_item(label, url, icon: "pencil-line", turbo_frame: :modal)
|
||||
link_to url, class: "flex items-center rounded-lg text-gray-900 hover:bg-gray-50 py-2 px-3 gap-2", data: { turbo_frame: } do
|
||||
concat(lucide_icon(icon, class: "shrink-0 w-5 h-5 text-gray-500"))
|
||||
concat(tag.span(label, class: "text-sm"))
|
||||
|
|
|
@ -5,25 +5,22 @@ import {Controller} from "@hotwired/stimulus";
|
|||
export default class extends Controller {
|
||||
static targets = [
|
||||
"name",
|
||||
"color",
|
||||
"avatar"
|
||||
];
|
||||
|
||||
connect() {
|
||||
this.nameTarget.addEventListener("input", this.handleNameChange);
|
||||
this.colorTarget.addEventListener("input", this.handleColorChange);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.nameTarget.removeEventListener("input", this.handleNameChange);
|
||||
this.colorTarget.removeEventListener("input", this.handleColorChange);
|
||||
}
|
||||
|
||||
handleNameChange = (e) => {
|
||||
this.avatarTarget.textContent = (e.currentTarget.value?.[0] || "?").toUpperCase();
|
||||
}
|
||||
|
||||
handleColorChange = (e) => {
|
||||
handleColorChange(e) {
|
||||
const color = e.currentTarget.value;
|
||||
this.avatarTarget.style.backgroundColor = `color-mix(in srgb, ${color} 5%, white)`;
|
||||
this.avatarTarget.style.borderColor = `color-mix(in srgb, ${color} 10%, white)`;
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
<% is_editing = @merchant.id.present? %>
|
||||
<div data-controller="merchant-avatar">
|
||||
<%= styled_form_with model: @merchant, url: is_editing ? merchant_path(@merchant) : merchants_path, method: is_editing ? :patch : :post, scope: :merchant, class: "space-y-4", data: { turbo: false } do |f| %>
|
||||
<%= styled_form_with model: @merchant, class: "space-y-4", data: { turbo: false } do |f| %>
|
||||
<section class="space-y-4">
|
||||
<div class="w-fit m-auto">
|
||||
<%= render partial: "merchants/avatar", locals: { merchant: } %>
|
||||
<%= render partial: "merchants/avatar", locals: { merchant: @merchant } %>
|
||||
</div>
|
||||
<div data-controller="select" data-select-active-class="bg-gray-200" data-select-selected-value="<%= @merchant&.color || Merchant::COLORS[0] %>">
|
||||
<%= f.hidden_field :color, data: { select_target: "input", merchant_avatar_target: "color" } %>
|
||||
<ul data-select-target="list" class="flex gap-2 items-center">
|
||||
<div class="flex gap-2 items-center justify-center">
|
||||
<% Merchant::COLORS.each do |color| %>
|
||||
<li tabindex="0" data-select-target="option" data-action="click->select#selectOption" data-value="<%= color %>" class="flex shrink-0 justify-center items-center w-6 h-6 cursor-pointer hover:bg-gray-200 rounded-full">
|
||||
<div style="background-color: <%= color %>" class="shrink-0 w-4 h-4 rounded-full"></div>
|
||||
</li>
|
||||
<label class="relative">
|
||||
<%= f.radio_button :color, color, class: "sr-only peer", data: { action: "change->merchant-avatar#handleColorChange" } %>
|
||||
<div class="w-6 h-6 rounded-full cursor-pointer peer-checked:ring-2 peer-checked:ring-offset-2 peer-checked:ring-blue-500" style="background-color: <%= color %>"></div>
|
||||
</label>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="relative flex items-center border border-gray-200 rounded-lg">
|
||||
<%= f.text_field :name, placeholder: t(".name_placeholder"), class: "text-sm font-normal placeholder:text-gray-500 h-10 relative pl-3 w-full border-none rounded-lg", required: true, data: { merchant_avatar_target: "name" } %>
|
||||
|
@ -21,7 +18,7 @@
|
|||
</section>
|
||||
|
||||
<section>
|
||||
<%= f.submit(is_editing ? t(".submit_edit") : t(".submit_create")) %>
|
||||
<%= f.submit %>
|
||||
</section>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<%# locals: (merchants:) %>
|
||||
<% merchants.each.with_index do |merchant, index| %>
|
||||
<div class="flex justify-between items-center p-4 bg-white">
|
||||
<div class="flex w-full items-center gap-2.5">
|
||||
<%= render partial: "merchants/avatar", locals: { merchant: } %>
|
||||
<p class="text-gray-900 text-sm truncate">
|
||||
<%= merchant.name %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative cursor-pointer" data-controller="menu">
|
||||
<button data-menu-target="button" class="flex hover:bg-gray-100 p-2 rounded">
|
||||
<%= lucide_icon("more-horizontal", class: "w-5 h-5 text-gray-500") %>
|
||||
</button>
|
||||
<div data-menu-target="content" class="absolute z-10 top-10 right-0 border border-alpha-black-25 bg-white rounded-lg shadow-xs w-48 hidden">
|
||||
<div class="border-t border-b border-alpha-black-100 p-1">
|
||||
<%= button_to edit_merchant_path(merchant),
|
||||
method: :get,
|
||||
class: "flex w-full gap-1 items-center text-sm hover:bg-gray-50 rounded-lg px-3 py-2",
|
||||
data: { turbo_frame: "modal" } do %>
|
||||
<%= lucide_icon("pencil-line", class: "w-5 h-5 mr-2") %> <%= t(".edit") %>
|
||||
<% end %>
|
||||
<%= button_to merchant_path(merchant),
|
||||
method: :delete,
|
||||
class: "flex w-full gap-1 items-center text-sm text-red-600 hover:text-red-800 hover:bg-gray-50 rounded-lg px-3 py-2",
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: t(".confirm_title"),
|
||||
body: t(".confirm_body"),
|
||||
accept: t(".confirm_accept")
|
||||
}
|
||||
} do %>
|
||||
<%= lucide_icon("trash-2", class: "w-5 h-5 mr-1") %> <%= t(".delete") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% unless index == merchants.size - 1 %>
|
||||
<div class="h-px bg-alpha-black-50 ml-14 mr-6"></div>
|
||||
<% end %>
|
||||
<% end %>
|
26
app/views/merchants/_merchant.html.erb
Normal file
26
app/views/merchants/_merchant.html.erb
Normal file
|
@ -0,0 +1,26 @@
|
|||
<%# locals: (merchant:) %>
|
||||
|
||||
<div class="flex justify-between items-center p-4 bg-white">
|
||||
<div class="flex w-full items-center gap-2.5">
|
||||
<%= render partial: "merchants/avatar", locals: { merchant: } %>
|
||||
<p class="text-gray-900 text-sm truncate">
|
||||
<%= merchant.name %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="justify-self-end">
|
||||
<%= contextual_menu do %>
|
||||
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
|
||||
<%= contextual_menu_modal_action_item t(".edit"), edit_merchant_path(merchant) %>
|
||||
|
||||
<%= contextual_menu_destructive_item t(".delete"),
|
||||
merchant_path(merchant),
|
||||
turbo_frame: "_top",
|
||||
turbo_confirm: {
|
||||
title: t(".confirm_title"),
|
||||
body: t(".confirm_body"),
|
||||
accept: t(".confirm_accept")
|
||||
} %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
3
app/views/merchants/_ruler.html.erb
Normal file
3
app/views/merchants/_ruler.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="bg-white">
|
||||
<div class="h-px bg-alpha-black-50 ml-14 mr-6"></div>
|
||||
</div>
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<%= link_to new_merchant_path, class: "rounded-lg bg-gray-900 text-white flex items-center gap-1 justify-center hover:bg-gray-700 px-3 py-2", data: { turbo_frame: :modal } do %>
|
||||
<%= lucide_icon("plus", class: "w-5 h-5") %>
|
||||
<span><%= t(".new_short") %></span>
|
||||
<span><%= t(".new") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4">
|
||||
|
@ -18,18 +18,20 @@
|
|||
<p class="text-gray-900 mb-1 font-medium text-sm"><%= t(".empty") %></p>
|
||||
<%= link_to new_merchant_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %>
|
||||
<%= lucide_icon("plus", class: "w-5 h-5") %>
|
||||
<span><%= t(".new_long") %></span>
|
||||
<span><%= t(".new") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-gray-25 p-1 rounded-xl">
|
||||
<div class="flex items-center px-4 py-2 text-xs font-medium text-gray-500">
|
||||
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-gray-500">
|
||||
<p><%= t(".title") %></p>
|
||||
<span class="text-gray-400 mx-2">·</span>
|
||||
<span class="text-gray-400">·</span>
|
||||
<p><%= @merchants.count %></p>
|
||||
</div>
|
||||
<%= render partial: "merchants/list", locals: { merchants: @merchants } %>
|
||||
<div class="overflow-hidden rounded-lg">
|
||||
<%= render partial: @merchants, spacer_template: "merchants/ruler" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -9,14 +9,11 @@ en:
|
|||
title: Edit merchant
|
||||
form:
|
||||
name_placeholder: Merchant name
|
||||
submit_create: Add merchant
|
||||
submit_edit: Update
|
||||
index:
|
||||
empty: No merchants yet
|
||||
new_long: New merchant
|
||||
new_short: New
|
||||
new: New merchant
|
||||
title: Merchants
|
||||
list:
|
||||
merchant:
|
||||
confirm_accept: Delete merchant
|
||||
confirm_body: Are you sure you want to delete this merchant? Removing this merchant
|
||||
will unlink all associated transactions and may effect your reporting.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue