1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-07 22:45:20 +02:00

New Design System + Codebase Refresh (#1823)

Since the very first 0.1.0-alpha.1 release, we've been moving quickly to add new features to the Maybe app. In doing so, some parts of the codebase have become outdated, unnecessary, or overly-complex as a natural result of this feature prioritization.

Now that "core" Maybe is complete, we're moving into a second phase of development where we'll be working hard to improve the accuracy of existing features and build additional features on top of "core". This PR is a quick overhaul of the existing codebase aimed to:

- Establish the brand new and simplified dashboard view (pictured above)
- Establish and move towards the conventions introduced in Cursor rules and project design overview #1788
- Consolidate layouts and improve the performance of layout queries
- Organize the core models of the Maybe domain (i.e. Account::Entry, Account::Transaction, etc.) and break out specific traits of each model into dedicated concerns for better readability
- Remove stale / dead code from codebase
- Remove overly complex code paths in favor of simpler ones
This commit is contained in:
Zach Gollwitzer 2025-02-21 11:57:59 -05:00 committed by GitHub
parent 8539ac7dec
commit d75be2282b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
278 changed files with 3428 additions and 4354 deletions

View file

@ -4,26 +4,24 @@
<div class="p-4 border-b border-gray-100">
<h3 class="text-sm text-secondary mb-2">Income</h3>
<% income_totals = budget.income_categories_with_totals %>
<% income_categories = income_totals.category_totals.reject { |ct| ct.amount_money.zero? }.sort_by { |ct| ct.percentage }.reverse %>
<span class="inline-block mb-2 text-xl font-medium text-primary">
<%= format_money(income_totals.total_money) %>
<%= budget.actual_income_money.format %>
</span>
<% if income_categories.any? %>
<% if budget.income_category_totals.any? %>
<div>
<div class="flex h-1.5 mb-3 gap-1">
<% income_categories.each do |item| %>
<div class="h-full rounded-xs" style="background-color: <%= item.category.color %>; width: <%= item.percentage %>%"></div>
<% budget.income_category_totals.each do |category_total| %>
<div class="h-full rounded-xs" style="background-color: <%= category_total.category.color %>; width: <%= category_total.weight %>%"></div>
<% end %>
</div>
<div class="flex flex-wrap gap-x-2.5 gap-y-1 text-xs">
<% income_categories.each do |item| %>
<% budget.income_category_totals.each do |category_total| %>
<div class="flex items-center gap-1.5">
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div>
<span class="text-secondary"><%= item.category.name %></span>
<span class="text-primary"><%= number_to_percentage(item.percentage, precision: 0) %></span>
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= category_total.category.color %>"></div>
<span class="text-secondary"><%= category_total.category.name %></span>
<span class="text-primary"><%= number_to_percentage(category_total.weight, precision: 0) %></span>
</div>
<% end %>
</div>
@ -34,25 +32,22 @@
<div class="p-4">
<h3 class="text-sm text-secondary mb-2">Expenses</h3>
<% expense_totals = budget.expense_categories_with_totals %>
<% expense_categories = expense_totals.category_totals.reject { |ct| ct.amount_money.zero? || ct.category.subcategory? }.sort_by { |ct| ct.percentage }.reverse %>
<span class="inline-block mb-2 text-xl font-medium text-primary"><%= budget.actual_spending_money.format %></span>
<span class="inline-block mb-2 text-xl font-medium text-primary"><%= format_money(expense_totals.total_money) %></span>
<% if expense_categories.any? %>
<% if budget.expense_category_totals.any? %>
<div>
<div class="flex h-1.5 mb-3 gap-1">
<% expense_categories.each do |item| %>
<div class="h-full rounded-xs" style="background-color: <%= item.category.color %>; width: <%= item.percentage %>%"></div>
<% budget.expense_category_totals.each do |category_total| %>
<div class="h-full rounded-xs" style="background-color: <%= category_total.category.color %>; width: <%= category_total.weight %>%"></div>
<% end %>
</div>
<div class="flex flex-wrap gap-x-2.5 gap-y-1 text-xs">
<% expense_categories.each do |item| %>
<% budget.expense_category_totals.each do |category_total| %>
<div class="flex items-center gap-1.5">
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div>
<span class="text-secondary"><%= item.category.name %></span>
<span class="text-primary"><%= number_to_percentage(item.percentage, precision: 0) %></span>
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= category_total.category.color %>"></div>
<span class="text-secondary"><%= category_total.category.name %></span>
<span class="text-primary"><%= number_to_percentage(category_total.weight, precision: 0) %></span>
</div>
<% end %>
</div>

View file

@ -9,7 +9,7 @@
<p class="ml-auto">Amount</p>
</div>
<div class="bg-white py-1 shadow-xs border border-gray-100 rounded-md">
<div class="bg-white py-1 shadow-border-xs rounded-md">
<% if budget.family.categories.expenses.empty? %>
<div class="py-8">
<%= render "budget_categories/no_categories" %>

View file

@ -2,16 +2,16 @@
<div class="flex items-center gap-1 mb-4">
<div class="flex items-center gap-2">
<% if @previous_budget %>
<%= link_to budget_path(@previous_budget) do %>
<% if budget.previous_budget_param %>
<%= link_to budget_path(budget.previous_budget_param) do %>
<%= lucide_icon "chevron-left" %>
<% end %>
<% else %>
<%= lucide_icon "chevron-left", class: "text-subdued" %>
<% end %>
<% if @next_budget %>
<%= link_to budget_path(@next_budget) do %>
<% if budget.next_budget_param %>
<%= link_to budget_path(budget.next_budget_param) do %>
<%= lucide_icon "chevron-right" %>
<% end %>
<% else %>
@ -20,13 +20,13 @@
</div>
<div data-controller="menu" data-menu-placement-value="bottom-start">
<%= tag.button data: { menu_target: "button" }, class: "flex items-center gap-1 hover:bg-gray-50 rounded-md p-2" do %>
<%= tag.button data: { menu_target: "button" }, class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %>
<span class="text-primary font-medium"><%= @budget.name %></span>
<%= lucide_icon "chevron-down", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %>
<div data-menu-target="content" class="hidden z-10">
<%= render "budgets/picker", family: Current.family, year: Date.current.year %>
<%= render "budgets/picker", family: Current.family, year: budget.start_date.year %>
</div>
</div>
@ -34,7 +34,7 @@
<% if @budget.current? %>
<span class="border border-secondary text-primary text-sm font-medium px-3 py-2 rounded-lg">Today</span>
<% else %>
<%= link_to "Today", budget_path(@latest_budget), class: "btn btn--outline" %>
<%= link_to "Today", budget_path(Budget.date_to_param(Date.current)), class: "btn btn--outline" %>
<% end %>
</div>
</div>

View file

@ -1,9 +1,11 @@
<%# locals: (family:, year:) %>
<%= turbo_frame_tag "budget_picker" do %>
<div class="bg-white shadow-md border border-alpha-black-25 p-3 rounded-xl space-y-4">
<div class="bg-white shadow-border-xs p-3 rounded-xl space-y-4">
<div class="flex items-center gap-2 justify-between">
<% if year > family.oldest_entry_date.year %>
<% last_month_of_previous_year = Date.new(year - 1, 12, 1) %>
<% if Budget.budget_date_valid?(last_month_of_previous_year, family: family) %>
<%= link_to picker_budgets_path(year: year - 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %>
<%= lucide_icon "chevron-left", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %>
@ -17,7 +19,9 @@
<%= year %>
</span>
<% if year < Date.current.year %>
<% first_month_of_next_year = Date.new(year + 1, 1, 1) %>
<% if Budget.budget_date_valid?(first_month_of_next_year, family: family) %>
<%= link_to picker_budgets_path(year: year + 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %>
<%= lucide_icon "chevron-right", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %>
@ -29,17 +33,12 @@
</div>
<div class="grid grid-cols-3 gap-2 text-sm text-center font-medium">
<% Date::ABBR_MONTHNAMES.compact.each_with_index do |month_name, index| %>
<% month_number = index + 1 %>
<% start_date = Date.new(year, month_number) %>
<% budget = family.budgets.for_date(start_date) %>
<% Date::ABBR_MONTHNAMES.compact.each do |month_name| %>
<% date = Date.strptime("#{month_name}-#{year}", "%b-%Y") %>
<% param_key = Budget.date_to_param(date) %>
<% if budget %>
<%= link_to month_name, budget_path(budget), data: { turbo_frame: "_top" }, class: "block px-3 py-2 text-sm text-primary hover:bg-gray-100 rounded-md" %>
<% elsif start_date >= family.oldest_entry_date.beginning_of_month && start_date <= Date.current %>
<%= button_to budgets_path(budget: { start_date: start_date }), data: { turbo_frame: "_top" }, class: "block w-full px-3 py-2 text-primary hover:bg-gray-100 rounded-md" do %>
<%= month_name %>
<% end %>
<% if Budget.budget_date_valid?(date, family: family) %>
<%= link_to month_name, budget_path(param_key), data: { turbo_frame: "_top" }, class: "block px-3 py-2 text-sm text-primary hover:bg-gray-100 rounded-md" %>
<% else %>
<span class="px-3 py-2 text-subdued rounded-md"><%= month_name %></span>
<% end %>

View file

@ -7,7 +7,7 @@
<div class="flex items-start gap-4">
<div class="w-[300px] space-y-4">
<div class="h-[300px] bg-white rounded-xl shadow-xs p-8 border border-gray-100">
<div class="h-[300px] bg-white rounded-xl shadow-border-xs p-8">
<% if @budget.available_to_allocate.negative? %>
<%= render "budgets/over_allocation_warning", budget: @budget %>
<% else %>
@ -38,18 +38,18 @@
) %>
</div>
<div class="bg-white rounded-xl shadow-xs border border-gray-100">
<div class="bg-white rounded-xl shadow-border-xs">
<%= render selected_tab == "budgeted" ? "budgets/budgeted_summary" : "budgets/actuals_summary", budget: @budget %>
</div>
<% else %>
<div class="bg-white rounded-xl shadow-xs border border-gray-100">
<div class="bg-white rounded-xl shadow-border-xs">
<%= render "budgets/actuals_summary", budget: @budget %>
</div>
<% end %>
</div>
</div>
<div class="grow bg-white rounded-xl shadow-xs p-4 border border-gray-100">
<div class="grow bg-white rounded-xl shadow-border-xs p-4">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium">Categories</h2>