mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 03:54:08 +00:00
Fix budgets page UI (#427)
* fix: Budget UI improvements * feat: Reduce padding for sub-categories * fix: Adjust padding for sub-category arrow * Revert "feat: Reduce padding for sub-categories" This reverts commit7516c5a8e0. * Revert "fix: Adjust padding for sub-category arrow" This reverts commitebc82542cf. * fix: adjust padding for sub-categories * fix: Add padding to uncategorized budget * fix: Remove unnecessary HTML tag * feat: Add translation keys for budgeted/actual
This commit is contained in:
@@ -1,44 +1,53 @@
|
||||
<%# locals: (budget_category:) %>
|
||||
|
||||
<%= turbo_frame_tag dom_id(budget_category), class: "w-full block" do %>
|
||||
<%= link_to budget_budget_category_path(budget_category.budget, budget_category), class: "group block w-full p-4 bg-container hover:bg-surface-inset transition-colors", data: { turbo_frame: "drawer" } do %>
|
||||
<%= turbo_frame_tag dom_id(budget_category), class: "flex-1 min-w-0 block" do %>
|
||||
<%= link_to budget_budget_category_path(budget_category.budget, budget_category), class: "group block w-full px-4 py-2 bg-container", data: { turbo_frame: "drawer" } do %>
|
||||
|
||||
<% if budget_category.initialized? %>
|
||||
<%# Category Header with Status Badge %>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 mb-3">
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<div class="w-3 h-3 rounded-full flex-shrink-0" style="background-color: <%= budget_category.category.color %>"></div>
|
||||
<h3 class="font-medium text-primary truncate"><%= budget_category.category.name %></h3>
|
||||
<div class="flex items-center lg:justify-between gap-2 mb-3">
|
||||
<div class="h-9 w-9 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, <%= budget_category.category.color %> 10%, transparent);
|
||||
border-color: color-mix(in oklab, <%= budget_category.category.color %> 10%, transparent);
|
||||
color: <%= budget_category.category.color %>;">
|
||||
<% if budget_category.category.lucide_icon %>
|
||||
<%= icon(budget_category.category.lucide_icon, color: "current") %>
|
||||
<% else %>
|
||||
<%= render DS::FilledIcon.new(
|
||||
variant: :text,
|
||||
hex_color: budget_category.category.color,
|
||||
text: budget_category.category.name,
|
||||
size: "md",
|
||||
rounded: true
|
||||
) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3 flex-shrink-0">
|
||||
<h3 class="flex-1 min-w-0 font-medium text-primary truncate"><%= budget_category.category.name %></h3>
|
||||
<div class="flex items-center gap-3 flex-shrink-0 ml-auto">
|
||||
<% if budget_category.over_budget? %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-danger/10 text-danger text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("alert-circle", class: "w-3 h-3") %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-red-500/10 text-red-500 text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("alert-circle", size: "sm", color: "red") %>
|
||||
<%= t("reports.budget_performance.status.over") %>
|
||||
</span>
|
||||
<% elsif budget_category.near_limit? %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-warning/10 text-warning text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("alert-triangle", class: "w-3 h-3") %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-yellow-500/10 text-warning text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("alert-triangle", size: "sm", color: "yellow") %>
|
||||
<%= t("reports.budget_performance.status.warning") %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-success/10 text-success text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("check-circle", class: "w-3 h-3") %>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-1 bg-green-500/10 text-success text-xs font-medium rounded-full whitespace-nowrap">
|
||||
<%= icon("check-circle", size: "sm", color: "green") %>
|
||||
<%= t("reports.budget_performance.status.good") %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<span class="text-sm font-semibold text-primary whitespace-nowrap">
|
||||
<%= budget_category.percent_of_budget_spent.round(0) %>%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%# Progress Bar %>
|
||||
<div class="mb-3">
|
||||
<div class="h-3 bg-container-inset rounded-full overflow-hidden">
|
||||
<% bar_color = budget_category.over_budget? ? "bg-danger" : (budget_category.near_limit? ? "bg-warning" : "bg-success") %>
|
||||
<div class="h-1.5 bg-container-inset rounded-full overflow-hidden">
|
||||
<% bar_color = budget_category.over_budget? ? "bg-red-500" : (budget_category.near_limit? ? "bg-yellow-500" : "bg-green-500") %>
|
||||
<div class="h-full <%= bar_color %> rounded-full transition-all duration-500"
|
||||
style="width: <%= budget_category.bar_width_percent %>%"></div>
|
||||
</div>
|
||||
@@ -46,27 +55,27 @@
|
||||
|
||||
<%# Budget Details %>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 text-sm">
|
||||
<div class="whitespace-nowrap">
|
||||
<span class="text-tertiary"><%= t("reports.budget_performance.spent") %>:</span>
|
||||
<div class="whitespace-nowrap w-full sm:w-auto">
|
||||
<span class="text-sm text-secondary"><%= t("reports.budget_performance.spent") %>:</span>
|
||||
<span class="font-medium text-primary">
|
||||
<%= format_money(budget_category.actual_spending_money) %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="whitespace-nowrap">
|
||||
<span class="text-tertiary"><%= t("reports.budget_performance.budgeted") %>:</span>
|
||||
<span class="font-medium text-secondary">
|
||||
<div class="whitespace-nowrap w-full sm:w-auto">
|
||||
<span class="text-sm text-secondary"><%= t("reports.budget_performance.budgeted") %>:</span>
|
||||
<span class="font-medium text-primary">
|
||||
<%= format_money(budget_category.budgeted_spending_money) %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="whitespace-nowrap ml-auto">
|
||||
<div class="whitespace-nowrap w-full sm:w-auto lg:ml-auto">
|
||||
<% if budget_category.available_to_spend >= 0 %>
|
||||
<span class="text-tertiary"><%= t("reports.budget_performance.remaining") %>:</span>
|
||||
<span class="font-medium text-success">
|
||||
<span class="text-sm text-secondary"><%= t("reports.budget_performance.remaining") %>:</span>
|
||||
<span class="font-medium <%= (budget_category.near_limit? ? "text-yellow-500" : "text-green-500") %>">
|
||||
<%= format_money(budget_category.available_to_spend_money) %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="text-tertiary"><%= t("reports.budget_performance.over_by") %>:</span>
|
||||
<span class="font-medium text-danger">
|
||||
<span class="text-sm text-secondary"><%= t("reports.budget_performance.over_by") %>:</span>
|
||||
<span class="font-medium text-red-500">
|
||||
<%= format_money(budget_category.available_to_spend_money.abs) %>
|
||||
</span>
|
||||
<% end %>
|
||||
@@ -76,8 +85,8 @@
|
||||
<%# Suggested Daily Limit (if remaining days in month) %>
|
||||
<% if budget_category.suggested_daily_spending.present? %>
|
||||
<% daily_info = budget_category.suggested_daily_spending %>
|
||||
<div class="mt-3 pt-3 border-t border-tertiary">
|
||||
<p class="text-xs text-tertiary break-words">
|
||||
<div class="py-2">
|
||||
<p class="text-xs text-subdued break-words">
|
||||
<%= t("reports.budget_performance.suggested_daily",
|
||||
amount: daily_info[:amount].format,
|
||||
days: daily_info[:days_remaining]) %>
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
<% category_groups = BudgetCategory::Group.for(budget.budget_categories) %>
|
||||
|
||||
<% category_groups.each_with_index do |group, index| %>
|
||||
<div>
|
||||
<div class="py-2">
|
||||
<%= render "budget_categories/budget_category", budget_category: group.budget_category %>
|
||||
|
||||
<div>
|
||||
<% group.budget_subcategories.each do |budget_subcategory| %>
|
||||
<div class="w-full flex items-center -mt-4">
|
||||
<div class="ml-8 flex items-center justify-center text-subdued">
|
||||
<div class="w-full flex items-start">
|
||||
<div class="ml-8 pt-4 flex items-center justify-center text-subdued">
|
||||
<%= icon "corner-down-right" %>
|
||||
</div>
|
||||
|
||||
@@ -36,8 +36,9 @@
|
||||
|
||||
<%= render "shared/ruler" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "budget_categories/budget_category", budget_category: budget.uncategorized_budget_category %>
|
||||
<div class="py-2">
|
||||
<%= render "budget_categories/budget_category", budget_category: budget.uncategorized_budget_category %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,30 +18,30 @@
|
||||
</div>
|
||||
|
||||
<%# Actuals Summary %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<% if @budget.initialized? && @budget.available_to_allocate.positive? %>
|
||||
<%= render DS::Tabs.new(active_tab: params[:tab].presence || "budgeted") do |tabs| %>
|
||||
<% tabs.with_nav do |nav| %>
|
||||
<% nav.with_btn(id: "budgeted", label: "Budgeted") %>
|
||||
<% nav.with_btn(id: "actuals", label: "Actual") %>
|
||||
<% end %>
|
||||
|
||||
<% tabs.with_panel(tab_id: "budgeted") do %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<%= render "budgets/budgeted_summary", budget: @budget %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% tabs.with_panel(tab_id: "actuals") do %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<%= render "budgets/actuals_summary", budget: @budget %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @budget.initialized? && @budget.available_to_allocate.positive? %>
|
||||
<%= render DS::Tabs.new(active_tab: params[:tab].presence || "budgeted") do |tabs| %>
|
||||
<% tabs.with_nav do |nav| %>
|
||||
<% nav.with_btn(id: "budgeted", label: t("budgets.show.tabs.budgeted")) %>
|
||||
<% nav.with_btn(id: "actuals", label: t("budgets.show.tabs.actual")) %>
|
||||
<% end %>
|
||||
|
||||
<% tabs.with_panel(tab_id: "budgeted") do %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<%= render "budgets/budgeted_summary", budget: @budget %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% tabs.with_panel(tab_id: "actuals") do %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<%= render "budgets/actuals_summary", budget: @budget %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render "budgets/actuals_summary", budget: @budget %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-container rounded-xl shadow-border-xs">
|
||||
<%= render "budgets/actuals_summary", budget: @budget %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%# Bottom Section: Categories full width %>
|
||||
|
||||
Reference in New Issue
Block a user