Display provider merchants alongside family merchants (#418)

* Display provider merchants alongside family merchants

* Styling

* Rabbit suggestion
This commit is contained in:
Juan José Mata
2025-12-05 22:15:07 +01:00
committed by GitHub
parent a91a4397e9
commit a790009290
11 changed files with 210 additions and 69 deletions

View File

@@ -6,6 +6,7 @@ class FamilyMerchantsController < ApplicationController
# Show all merchants for this family
@family_merchants = Current.family.merchants.alphabetically
@provider_merchants = Current.family.assigned_merchants.where(type: "ProviderMerchant").alphabetically
render layout: "settings"
end

View File

@@ -1,20 +1,22 @@
<%# locals: (family_merchant:) %>
<div class="flex justify-between items-center p-4 bg-container">
<div class="flex w-full items-center gap-2.5">
<% if family_merchant.logo_url %>
<div class="w-8 h-8 rounded-full flex justify-center items-center">
<%= image_tag family_merchant.logo_url, class: "w-8 h-8 rounded-full" %>
</div>
<% else %>
<%= render partial: "shared/color_avatar", locals: { name: family_merchant.name, color: family_merchant.color } %>
<% end %>
<tr class="border-b border-subdued last:border-0 hover:bg-surface-hover">
<td class="py-3 px-4 text-sm text-primary">
<div class="flex w-full items-center gap-2.5">
<% if family_merchant.logo_url %>
<div class="w-8 h-8 rounded-full flex justify-center items-center">
<%= image_tag family_merchant.logo_url, class: "w-8 h-8 rounded-full" %>
</div>
<% else %>
<%= render partial: "shared/color_avatar", locals: { name: family_merchant.name, color: family_merchant.color } %>
<% end %>
<p class="text-primary text-sm truncate">
<%= family_merchant.name %>
</p>
</div>
<div class="justify-self-end">
<p class="font-medium truncate">
<%= family_merchant.name %>
</p>
</div>
</td>
<td class="py-3 px-4 text-sm text-right align-middle">
<%= render DS::Menu.new do |menu| %>
<% menu.with_item(variant: "link", text: "Edit", href: edit_family_merchant_path(family_merchant), icon: "pencil", data: { turbo_frame: "modal" }) %>
<% menu.with_item(
@@ -25,5 +27,5 @@
method: :delete,
confirm: CustomConfirm.for_resource_deletion(family_merchant.name)) %>
<% end %>
</div>
</div>
</td>
</tr>

View File

@@ -0,0 +1,24 @@
<%# locals: (provider_merchant:) %>
<tr class="border-b border-subdued last:border-0 hover:bg-surface-hover">
<td class="py-3 px-4 text-sm text-primary">
<div class="flex w-full items-center gap-2.5">
<% if provider_merchant.logo_url %>
<div class="w-8 h-8 rounded-full flex justify-center items-center">
<%= image_tag provider_merchant.logo_url, class: "w-8 h-8 rounded-full" %>
</div>
<% else %>
<div class="w-8 h-8 rounded-full flex items-center justify-center bg-container-inset text-secondary text-sm font-medium">
<%= provider_merchant.name&.first&.upcase || "?" %>
</div>
<% end %>
<p class="font-medium truncate">
<%= provider_merchant.name %>
</p>
</div>
</td>
<td class="py-3 px-4 text-sm text-secondary align-middle">
<%= provider_merchant.source&.titleize %>
</td>
</tr>

View File

@@ -9,33 +9,80 @@
) %>
</header>
<div class="bg-container rounded-xl shadow-border-xs p-4">
<% if @family_merchants.any? %>
<div class="rounded-xl bg-container-inset space-y-1 p-1">
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-secondary uppercase">
<p><%= t(".title") %></p>
<span class="text-subdued">&middot;</span>
<p><%= @family_merchants.count %></p>
</div>
<div class="bg-container rounded-xl shadow-border-xs p-4 space-y-6">
<section class="space-y-3">
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-secondary uppercase">
<p><%= t(".family_title") %></p>
<span class="text-subdued">&middot;</span>
<p><%= @family_merchants.count %></p>
</div>
<div class="bg-container rounded-lg shadow-border-xs">
<div class="overflow-hidden rounded-lg">
<%= render partial: "family_merchants/family_merchant", collection: @family_merchants, spacer_template: "shared/ruler" %>
<% if @family_merchants.any? %>
<div class="rounded-xl bg-container-inset space-y-1 p-1">
<div class="bg-container rounded-lg shadow-border-xs overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-xs uppercase font-medium text-secondary border-b border-divider">
<th scope="col" class="text-left py-3 px-4"><%= t(".table.merchant") %></th>
<th scope="col" class="text-right py-3 px-4"><%= t(".table.actions") %></th>
</tr>
</thead>
<tbody>
<%= render partial: "family_merchants/family_merchant", collection: @family_merchants %>
</tbody>
</table>
</div>
</div>
</div>
<% else %>
<div class="flex justify-center items-center py-20">
<div class="text-center flex flex-col items-center max-w-[300px]">
<p class="text-primary mb-1 font-medium text-sm"><%= t(".empty") %></p>
<% else %>
<div class="flex justify-center items-center py-12">
<div class="text-center flex flex-col items-center max-w-[300px]">
<p class="text-primary mb-1 font-medium text-sm"><%= t(".family_empty") %></p>
<%= render DS::Link.new(
text: t(".new"),
icon: "plus",
href: new_family_merchant_path,
frame: :modal
) %>
<%= render DS::Link.new(
text: t(".new"),
icon: "plus",
href: new_family_merchant_path,
frame: :modal
) %>
</div>
</div>
<% end %>
</section>
<section class="space-y-3">
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-secondary uppercase">
<p><%= t(".provider_title") %></p>
<span class="text-subdued">&middot;</span>
<p><%= @provider_merchants.count %></p>
</div>
<div class="p-4 bg-container-inset border border-secondary rounded-lg">
<div class="flex items-start gap-2">
<%= icon "info", class: "w-5 h-5 text-link mt-0.5 flex-shrink-0" %>
<p class="text-xs text-secondary leading-relaxed"><%= t(".provider_read_only") %></p>
</div>
</div>
<% end %>
<% if @provider_merchants.any? %>
<div class="rounded-xl bg-container-inset space-y-1 p-1">
<div class="bg-container rounded-lg shadow-border-xs overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-xs uppercase font-medium text-secondary border-b border-divider">
<th scope="col" class="text-left py-3 px-4"><%= t(".table.merchant") %></th>
<th scope="col" class="text-left py-3 px-4"><%= t(".table.source") %></th>
</tr>
</thead>
<tbody>
<%= render partial: "family_merchants/provider_merchant", collection: @provider_merchants %>
</tbody>
</table>
</div>
</div>
<% else %>
<div class="flex justify-center items-center py-8">
<p class="text-secondary text-sm text-center"><%= t(".provider_empty") %></p>
</div>
<% end %>
</section>
</div>

View File

@@ -14,9 +14,19 @@ ca:
empty: Encara no hi ha comerços
new: Nou comerç
title: Comerços
family_title: Comerços familiars
family_empty: Encara no hi ha comerços familiars
provider_title: Comerços del proveïdor
provider_empty: Encara no hi ha comerços del proveïdor vinculats a aquesta família
provider_read_only: Els comerços del proveïdor se sincronitzen automàticament amb les institucions connectades. No es poden editar aquí.
table:
merchant: Comerç
actions: Accions
source: Origen
merchant:
confirm_accept: Elimina el comerç
confirm_body: Segur que vols eliminar aquest comerç? Si l'elimines, es desvincularan totes les transaccions associades i pot afectar els teus informes.
confirm_body: Segur que vols eliminar aquest comerç? Si l'elimines, es desvincularan
totes les transaccions associades i pot afectar els teus informes.
confirm_title: Vols eliminar el comerç?
delete: Elimina el comerç
edit: Edita el comerç

View File

@@ -14,9 +14,19 @@ de:
empty: Noch keine Händler vorhanden
new: Neuer Händler
title: Händler
family_title: Händler der Familie
family_empty: Noch keine Händler der Familie vorhanden
provider_title: Anbieter-Händler
provider_empty: Noch keine Anbieter-Händler mit dieser Familie verbunden
provider_read_only: Anbieter-Händler werden von deinen verbundenen Institutionen synchronisiert. Sie können hier nicht bearbeitet werden.
table:
merchant: Händler
actions: Aktionen
source: Quelle
merchant:
confirm_accept: Händler löschen
confirm_body: Bist du sicher dass du diesen Händler löschen möchtest Das Entfernen dieses Händlers wird alle zugehörigen Transaktionen trennen und kann deine Auswertungen beeinflussen
confirm_body: Bist du sicher, dass du diesen Händler löschen möchtest? Das Entfernen dieses Händlers
wird alle zugehörigen Transaktionen trennen und kann deine Auswertungen beeinflussen.
confirm_title: Händler löschen
delete: Händler löschen
edit: Händler bearbeiten

View File

@@ -14,6 +14,15 @@ en:
empty: No merchants yet
new: New merchant
title: Merchants
family_title: Family merchants
family_empty: No family merchants yet
provider_title: Provider merchants
provider_empty: No provider merchants linked to this family yet
provider_read_only: Provider merchants are synced from your connected institutions. They cannot be edited here.
table:
merchant: Merchant
actions: Actions
source: Source
merchant:
confirm_accept: Delete merchant
confirm_body: Are you sure you want to delete this merchant? Removing this merchant

View File

@@ -14,9 +14,19 @@ es:
empty: Aún no hay comercios
new: Nuevo comercio
title: Comercios
family_title: Comercios familiares
family_empty: Aún no hay comercios familiares
provider_title: Comercios del proveedor
provider_empty: Ningún comercio del proveedor vinculado a esta familia todavía
provider_read_only: Los comercios del proveedor se sincronizan desde tus instituciones conectadas. No se pueden editar aquí.
table:
merchant: Comercio
actions: Acciones
source: Origen
merchant:
confirm_accept: Eliminar comercio
confirm_body: ¿Estás seguro de que deseas eliminar este comercio? Eliminar este comercio desvinculará todas las transacciones asociadas y puede afectar a tus informes.
confirm_body: ¿Estás seguro de que deseas eliminar este comercio? Eliminar este comercio
desvinculará todas las transacciones asociadas y puede afectar a tus informes.
confirm_title: ¿Eliminar comercio?
delete: Eliminar comercio
edit: Editar comercio

View File

@@ -1,27 +1,36 @@
---
nb:
family_merchants:
create:
error: 'Feil ved oppretting av forhandler: %{error}'
success: Ny forhandler opprettet vellykket
destroy:
success: Forhandler slettet vellykket
edit:
title: Rediger forhandler
form:
name_placeholder: Forhandlernavn
index:
empty: Ingen forhandlere ennå
new: Ny forhandler
title: Forhandlere
merchant:
confirm_accept: Slett forhandler
confirm_body: Er du sikker på at du vil slette denne forhandleren? Fjerning av denne forhandleren
vil fjerne koblingen til alle tilknyttede transaksjoner og kan påvirke rapporteringen din.
confirm_title: Slett forhandler?
delete: Slett forhandler
edit: Rediger forhandler
new:
title: Ny forhandler
update:
---
nb:
family_merchants:
create:
error: 'Feil ved oppretting av forhandler: %{error}'
success: Ny forhandler opprettet vellykket
destroy:
success: Forhandler slettet vellykket
edit:
title: Rediger forhandler
form:
name_placeholder: Forhandlernavn
index:
empty: Ingen forhandlere ennå
new: Ny forhandler
title: Forhandlere
family_title: Familieforhandlere
family_empty: Ingen familieforhandlere ennå
provider_title: Leverandørforhandlere
provider_empty: Ingen leverandørforhandlere er koblet til denne familien ennå
provider_read_only: Leverandørforhandlere synkroniseres fra dine tilkoblede institusjoner. De kan ikke redigeres her.
table:
merchant: Forhandler
actions: Handlinger
source: Kilde
merchant:
confirm_accept: Slett forhandler
confirm_body: Er du sikker på at du vil slette denne forhandleren? Fjerning av denne forhandleren
vil fjerne koblingen til alle tilknyttede transaksjoner og kan påvirke rapporteringen din.
confirm_title: Slett forhandler?
delete: Slett forhandler
edit: Rediger forhandler
new:
title: Ny forhandler
update:
success: Forhandler oppdatert vellykket

View File

@@ -14,6 +14,15 @@ ro:
empty: Niciun comerciant încă
new: Comerciant nou
title: Comercianți
family_title: Comercianți ai familiei
family_empty: Încă nu există comercianți ai familiei
provider_title: Comercianți furnizor
provider_empty: Niciun comerciant furnizor asociat încă acestei familii
provider_read_only: Comercianții furnizor sunt sincronizați din instituțiile tale conectate. Nu pot fi editați aici.
table:
merchant: Comerciant
actions: Acțiuni
source: Sursă
merchant:
confirm_accept: Șterge comerciantul
confirm_body: Ești sigur că vrei să ștergi acest comerciant? Eliminarea acestui comerciant

View File

@@ -14,9 +14,19 @@ tr:
empty: "Henüz satıcı yok"
new: "Yeni satıcı"
title: "Satıcılar"
family_title: "Aile satıcıları"
family_empty: "Henüz aile satıcısı yok"
provider_title: "Sağlayıcı satıcıları"
provider_empty: "Bu aileye bağlı sağlayıcı satıcısı yok"
provider_read_only: "Sağlayıcı satıcılar bağlı olduğunuz kurumlarla otomatik olarak eşitlenir. Burada düzenlenemezler."
table:
merchant: "Satıcı"
actions: "İşlemler"
source: "Kaynak"
merchant:
confirm_accept: "Satıcıyı sil"
confirm_body: "Bu satıcıyı silmek istediğinizden emin misiniz? Satıcıyı kaldırmak, ilişkili tüm işlemlerin bağlantısını kaldıracak ve raporlamanızı etkileyebilir."
confirm_body: "Bu satıcıyı silmek istediğinizden emin misiniz? Satıcıyı kaldırmak
ilişkili tüm işlemlerin bağlantısını kaldıracak ve raporlamanızı etkileyebilir."
confirm_title: "Satıcı silinsin mi?"
delete: "Satıcıyı sil"
edit: "Satıcıyı düzenle"