Files
sure/app/views/reports/_breakdown_table.html.erb
2026-01-21 22:07:14 +01:00

121 lines
6.1 KiB
Plaintext

<%# Renders a breakdown table for income or expense groups %>
<%# Local variables: groups, total, type (:income or :expense), amount_sort_params, current_sort_by, current_sort_direction %>
<%
color_class = type == :income ? "text-success" : "text-destructive"
icon_name = type == :income ? "trending-up" : "trending-down"
title_key = type == :income ? "reports.transactions_breakdown.table.income" : "reports.transactions_breakdown.table.expense"
%>
<div>
<h3 class="text-base font-semibold <%= color_class %> mb-4 flex items-center gap-2">
<%= icon(icon_name, class: "w-5 h-5") %>
<%= t(title_key) %>
<span class="text-sm font-normal text-tertiary">(<%= Money.new(total, Current.family.currency).format %>)</span>
</h3>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-tertiary">
<th class="text-left py-3 pr-4 font-medium text-secondary"><%= t("reports.transactions_breakdown.table.category") %></th>
<th class="text-right py-3 px-4 font-medium text-secondary">
<%= link_to reports_path(amount_sort_params), class: "inline-flex items-center gap-1 hover:text-primary" do %>
<%= t("reports.transactions_breakdown.table.amount") %>
<% if current_sort_by == "amount" %>
<%= icon(current_sort_direction == "desc" ? "chevron-down" : "chevron-up", class: "w-3 h-3") %>
<% end %>
<% end %>
</th>
<th class="text-right py-3 pl-4 font-medium text-secondary"><%= t("reports.transactions_breakdown.table.percentage") %></th>
</tr>
</thead>
<tbody>
<% groups.each do |group| %>
<% percentage = total.zero? ? 0 : (group[:total].to_f / total * 100).round(1) %>
<% has_subcategories = group[:subcategories].present? && group[:subcategories].any? %>
<tr class="border-b border-tertiary hover:bg-surface-inset">
<td class="py-3 pr-4">
<div class="flex items-center gap-2">
<% if group[:category_icon] %>
<div class="h-7 w-7 flex-shrink-0 group-hover:scale-105 transition-all duration-300 rounded-full flex justify-center items-center"
style="
background-color: color-mix(in oklab, <%= group[:category_color] %> 10%, transparent);
border-color: color-mix(in oklab, <%= group[:category_color] %> 10%, transparent);
color: <%= group[:category_color] %>;">
<%= icon(group[:category_icon], color: "current", size: "sm") %>
</div>
<% else %>
<%= render DS::FilledIcon.new(
variant: :text,
hex_color: group[:category_color],
text: group[:category_name],
size: "md",
rounded: true
) %>
<% end %>
<span class="font-medium text-primary"><%= group[:category_name] %></span>
<span class="text-xs text-tertiary whitespace-nowrap">(<%= t("reports.transactions_breakdown.table.entries", count: group[:count]) %>)</span>
</div>
</td>
<td class="py-3 px-4 text-right">
<span class="font-semibold <%= color_class %>">
<%= Money.new(group[:total], Current.family.currency).format %>
</span>
</td>
<td class="py-3 pl-4 text-right">
<span class="text-sm text-secondary">
<%= percentage %>%
</span>
</td>
</tr>
<%# Render subcategories if present %>
<% if has_subcategories %>
<% group[:subcategories].each do |subcategory| %>
<% sub_percentage = total.zero? ? 0 : (subcategory[:total].to_f / total * 100).round(1) %>
<tr class="border-b border-tertiary hover:bg-surface-inset bg-surface-inset/30">
<td class="p-2 pl-3">
<div class="flex items-center gap-2">
<% if subcategory[:category_icon] %>
<div class="flex items-center justify-center text-subdued">
<%= icon "corner-down-right" %>
</div>
<div class="h-7 w-7 flex-shrink-0 group-hover:scale-105 transition-all duration-300 rounded-full flex justify-center items-center"
style="
background-color: color-mix(in oklab, <%= subcategory[:category_color] %> 10%, transparent);
border-color: color-mix(in oklab, <%= subcategory[:category_color] %> 10%, transparent);
color: <%= subcategory[:category_color] %>;">
<%= icon(subcategory[:category_icon], color: "current", size: "sm") %>
</div>
<% else %>
<%= render DS::FilledIcon.new(
variant: :text,
hex_color: subcategory[:category_color],
text: subcategory[:category_name],
size: "md",
rounded: true
) %>
<% end %>
<span class="text-sm text-secondary"><%= subcategory[:category_name] %></span>
<span class="text-xs text-tertiary whitespace-nowrap">(<%= t("reports.transactions_breakdown.table.entries", count: subcategory[:count]) %>)</span>
</div>
</td>
<td class="py-2 px-4 text-right">
<span class="text-sm <%= color_class %>">
<%= Money.new(subcategory[:total], Current.family.currency).format %>
</span>
</td>
<td class="py-2 pl-4 text-right">
<span class="text-xs text-tertiary">
<%= sub_percentage %>%
</span>
</td>
</tr>
<% end %>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>