mirror of
https://github.com/we-promise/sure.git
synced 2026-04-26 15:34:13 +00:00
121 lines
6.1 KiB
Plaintext
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>
|