Files
sure/app/views/pages/dashboard/_outflows_donut.html.erb
soky srm a4f70f4d4a Support uncategorized investments (#593)
* Support uncategorized investments

* FIX sankey id collision

* Fix reports

* Fix hardcoded string and i8n

* FIX plurals

* Remove spending patterns section

add net worth section to reports
2026-01-09 19:45:42 +01:00

128 lines
6.3 KiB
Plaintext

<%# locals: (outflows_data:, period:) %>
<div id="outflows-donut-section">
<div class="flex justify-end items-center gap-4 px-4 mb-4">
<%= form_with url: root_path, method: :get, data: { controller: "auto-submit-form", turbo_frame: "_top" } do |form| %>
<%= form.select :period,
Period.as_options,
{ selected: period.key },
data: { "auto-submit-form-target": "auto" },
class: "bg-container border border-secondary font-medium rounded-lg px-3 py-2 text-sm pr-7 cursor-pointer text-primary focus:outline-hidden focus:ring-0" %>
<% end %>
</div>
<div class="px-4">
<div class="flex flex-col lg:flex-row gap-8 items-center">
<!-- Donut Chart -->
<div class="w-full lg:w-1/3 max-w-[300px] p-4">
<div class="h-[300px] relative"
data-controller="donut-chart"
data-donut-chart-segments-value="<%= outflows_data[:categories].to_json %>"
data-donut-chart-segment-opacity-value="0.9"
data-donut-chart-extended-hover-value="true"
data-donut-chart-hover-extension-value="3"
data-donut-chart-enable-click-value="true"
data-donut-chart-start-date-value="<%= period.date_range.first %>"
data-donut-chart-end-date-value="<%= period.date_range.last %>">
<div data-donut-chart-target="chartContainer" class="absolute inset-0 pointer-events-none"></div>
<div data-donut-chart-target="contentContainer" class="flex justify-center items-center h-full">
<div data-donut-chart-target="defaultContent" class="flex flex-col items-center">
<div class="text-secondary text-sm mb-2">
<span><%= t("pages.dashboard.outflows_donut.total_outflows") %></span>
</div>
<div class="text-3xl font-medium text-primary">
<%= format_money Money.new(outflows_data[:total], outflows_data[:currency]) %>
</div>
</div>
<% outflows_data[:categories].each do |category| %>
<div id="segment_<%= category[:id] %>" class="hidden">
<div class="flex flex-col gap-2 items-center">
<p class="text-sm text-secondary"><%= category[:name] %></p>
<p class="text-3xl font-medium text-primary">
<%= outflows_data[:currency_symbol] %><%= number_with_delimiter(category[:amount], delimiter: ",") %>
</p>
<p class="text-sm text-secondary"><%= category[:percentage] %>%</p>
</div>
</div>
<% end %>
</div>
</div>
</div>
<!-- Category List -->
<div class="w-full lg:w-2/3 bg-container-inset rounded-xl p-1 space-y-1 overflow-x-auto">
<div class="px-4 py-2 flex items-center uppercase text-xs font-medium text-secondary">
<div class="w-16 lg:w-40">
<p><%= t("pages.dashboard.outflows_donut.categories") %><span class="text-subdued mx-1">&middot;</span><%= outflows_data[:categories].count %></p>
</div>
<div class="ml-auto text-right flex items-center gap-6">
<div class="w-16 lg:w-40">
<p><%= t("pages.dashboard.outflows_donut.value") %></p>
</div>
<div class="w-16">
<p><%= t("pages.dashboard.outflows_donut.weight") %></p>
</div>
</div>
</div>
<div class="py-3 shadow-border-xs rounded-lg bg-container font-medium text-sm max-w-full">
<% outflows_data[:categories].each_with_index do |category, idx| %>
<%
category_content = capture do
%>
<div class="flex items-center gap-3 flex-1 min-w-0">
<div class="h-6 w-6 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, <%= category[:color] %> 10%, transparent);
border-color: color-mix(in oklab, <%= category[:color] %> 10%, transparent);
color: <%= category[:color] %>;">
<% if category[:icon] %>
<%= icon(category[:icon], color: "current", size: "sm") %>
<% else %>
<%= render DS::FilledIcon.new(
variant: :text,
hex_color: category[:color],
text: category[:name],
size: "sm",
rounded: true
) %>
<% end %>
</div>
<span class="text-sm font-medium text-primary truncate"><%= category[:name] %></span>
</div>
<div class="flex items-center gap-4 flex-shrink-0 text-right">
<span class="text-sm font-medium text-primary whitespace-nowrap"><%= format_money Money.new(category[:amount], category[:currency]) %></span>
<span class="text-sm text-secondary whitespace-nowrap w-10 lg:w-15"><%= category[:percentage] %>%</span>
</div>
<% end %>
<% if category[:clickable] != false %>
<%= link_to transactions_path(q: { categories: [category[:name]], start_date: period.date_range.first, end_date: period.date_range.last }),
class: "flex items-center justify-between mx-3 p-3 rounded-lg cursor-pointer group gap-3",
data: {
turbo_frame: "_top",
category_id: category[:id],
action: "mouseenter->donut-chart#highlightSegment mouseleave->donut-chart#unhighlightSegment"
} do %>
<%= category_content %>
<% end %>
<% else %>
<div class="flex items-center justify-between mx-3 p-3 rounded-lg group gap-3"
data-category-id="<%= category[:id] %>"
data-action="mouseenter->donut-chart#highlightSegment mouseleave->donut-chart#unhighlightSegment">
<%= category_content %>
</div>
<% end %>
<% if idx < outflows_data[:categories].size - 1 %>
<%= render "shared/ruler", classes: "mx-3 lg:mx-4" %>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
</div>