1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-08 23:15:24 +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

@ -1,75 +1,98 @@
<%# locals: (entry:, selectable: true, balance_trend: nil) %>
<%# locals: (entry:, balance_trend: nil, view_ctx: "global") %>
<div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4 <%= @focused_record == entry ? "border border-gray-900 rounded-lg" : "" %>">
<div class="pr-10 flex items-center gap-4 <%= balance_trend ? "col-span-6" : "col-span-8" %>">
<% if selectable %>
<%= check_box_tag dom_id(entry, "selection"),
disabled: entry.entryable.transfer?,
class: "checkbox checkbox--light",
data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %>
<% end %>
<% transaction = entry.entryable %>
<div class="max-w-full">
<%= content_tag :div, class: ["flex items-center gap-2"] do %>
<% if entry.entryable.merchant&.icon_url %>
<%= image_tag entry.entryable.merchant.icon_url, class: "w-6 h-6 rounded-full", loading: "lazy" %>
<% else %>
<%= render "shared/circle_logo", name: entry.display_name, size: "sm" %>
<% end %>
<%= turbo_frame_tag dom_id(entry) do %>
<%= turbo_frame_tag dom_id(transaction) do %>
<div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4
<%= @focused_record == entry || @focused_record == transaction ?
"border border-gray-900 rounded-lg" : "" %>">
<div class="truncate">
<div class="space-y-0.5">
<div class="flex items-center gap-1">
<% if entry.new_record? %>
<%= content_tag :p, entry.display_name %>
<% else %>
<%= link_to entry.entryable.transfer? ? entry.entryable.transfer.name : entry.display_name,
entry.entryable.transfer? ? transfer_path(entry.entryable.transfer) : account_entry_path(entry),
data: { turbo_frame: "drawer", turbo_prefetch: false },
class: "hover:underline hover:text-gray-800" %>
<% end %>
<div class="pr-10 flex items-center gap-4
<%= balance_trend ? "col-span-6" : "col-span-8" %>">
<%= check_box_tag dom_id(entry, "selection"),
disabled: transaction.transfer?,
class: "checkbox checkbox--light",
data: {
id: entry.id,
"bulk-select-target": "row",
action: "bulk-select#toggleRowSelection"
} %>
<% if entry.excluded %>
<span title="One-time <%= entry.amount.negative? ? "income" : "expense" %> (excluded from averages)">
<%= lucide_icon "asterisk", class: "w-4 h-4 shrink-0 text-orange-500" %>
</span>
<% end %>
<div class="max-w-full">
<%= content_tag :div, class: ["flex items-center gap-2"] do %>
<% if transaction.merchant&.icon_url %>
<%= image_tag transaction.merchant.icon_url,
class: "w-6 h-6 rounded-full",
loading: "lazy" %>
<% else %>
<%= render "shared/circle_logo",
name: entry.display_name,
size: "sm" %>
<% end %>
<% if entry.entryable.transfer? %>
<%= render "account/transactions/transfer_match", entry: entry %>
<% end %>
<div class="truncate">
<div class="space-y-0.5">
<div class="flex items-center gap-1">
<%= link_to(
transaction.transfer? ? transaction.transfer.name : entry.display_name,
transaction.transfer? ? transfer_path(transaction.transfer) : account_entry_path(entry),
data: {
turbo_frame: "drawer",
turbo_prefetch: false
},
class: "hover:underline hover:text-gray-800"
) %>
<% if entry.excluded %>
<span title="One-time <%= entry.amount.negative? ? "income" : "expense" %> (excluded from averages)">
<%= lucide_icon "asterisk", class: "w-4 h-4 shrink-0 text-orange-500" %>
</span>
<% end %>
<% if transaction.transfer? %>
<%= render "account/transactions/transfer_match", transaction: transaction %>
<% end %>
</div>
<div class="text-secondary text-xs font-normal">
<% if transaction.transfer? %>
<%= render "transfers/account_links",
transfer: transaction.transfer,
is_inflow: transaction.transfer_as_inflow.present? %>
<% else %>
<%= link_to entry.account.name,
account_path(entry.account, tab: "transactions", focused_record_id: entry.id),
data: { turbo_frame: "_top" },
class: "hover:underline" %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="text-secondary text-xs font-normal">
<% if entry.entryable.transfer? %>
<%= render "transfers/account_links", transfer: entry.entryable.transfer, is_inflow: entry.entryable.transfer_as_inflow.present? %>
<% else %>
<%= link_to entry.account.name, account_path(entry.account, tab: "transactions", focused_record_id: entry.id), data: { turbo_frame: "_top" }, class: "hover:underline" %>
<% end %>
</div>
</div>
<div class="flex items-center gap-1 col-span-2">
<%= render "account/transactions/transaction_category", transaction: transaction %>
</div>
<div class="col-span-2 ml-auto">
<%= content_tag :p,
transaction.transfer? && view_ctx == "global" ? "+/- #{format_money(entry.amount_money.abs)}" : format_money(-entry.amount_money),
class: ["text-green-600": entry.amount.negative?] %>
</div>
<% if balance_trend %>
<div class="col-span-2 justify-self-end">
<% if balance_trend.trend %>
<%= tag.p format_money(balance_trend.trend.current),
class: "font-medium text-sm text-primary" %>
<% else %>
<%= tag.p "--", class: "font-medium text-sm text-gray-400" %>
<% end %>
</div>
<% end %>
</div>
</div>
<div class="flex items-center gap-1 col-span-2">
<%= render "account/transactions/transaction_category", entry: entry %>
</div>
<div class="col-span-2 ml-auto">
<%= content_tag :p,
format_money(-entry.amount_money),
class: ["text-green-600": entry.amount.negative?] %>
</div>
<% if balance_trend %>
<div class="col-span-2 justify-self-end">
<% if balance_trend.trend %>
<%= tag.p format_money(balance_trend.trend.current), class: "font-medium text-sm text-primary" %>
<% else %>
<%= tag.p "--", class: "font-medium text-sm text-subdued" %>
<% end %>
</div>
<% end %>
</div>
<% end %>

View file

@ -1,9 +1,9 @@
<%# locals: (entry:) %>
<%# locals: (transaction:) %>
<div id="<%= dom_id(entry, "category_menu") %>">
<% if entry.account_transaction.transfer&.categorizable? || entry.account_transaction.transfer.nil? %>
<%= render "categories/menu", transaction: entry.account_transaction %>
<div id="<%= dom_id(transaction, "category_menu") %>">
<% if transaction.transfer&.categorizable? || transaction.transfer.nil? %>
<%= render "categories/menu", transaction: transaction %>
<% else %>
<%= render "categories/badge", category: entry.account_transaction.transfer&.payment? ? payment_category : transfer_category %>
<%= render "categories/badge", category: transaction.transfer&.payment? ? payment_category : transfer_category %>
<% end %>
</div>

View file

@ -1,26 +1,26 @@
<%# locals: (entry:) %>
<%# locals: (transaction:) %>
<div id="<%= dom_id(entry, "transfer_match") %>" class="flex items-center gap-1">
<% if entry.account_transaction.transfer.confirmed? %>
<span title="<%= entry.account_transaction.transfer.payment? ? "Payment" : "Transfer" %> is confirmed">
<div id="<%= dom_id(transaction, "transfer_match") %>" class="flex items-center gap-1">
<% if transaction.transfer.confirmed? %>
<span title="<%= transaction.transfer.payment? ? "Payment" : "Transfer" %> is confirmed">
<%= lucide_icon "link-2", class: "w-4 h-4 text-indigo-600" %>
</span>
<% elsif entry.account_transaction.transfer.pending? %>
<% elsif transaction.transfer.pending? %>
<span class="inline-flex items-center rounded-full bg-indigo-50 px-2 py-0.5 text-xs font-medium text-indigo-700">
Auto-matched
</span>
<%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "confirmed" }),
<%= button_to transfer_path(transaction.transfer, transfer: { status: "confirmed" }),
method: :patch,
class: "text-secondary hover:text-gray-800 flex items-center justify-center",
class: "text-secondary hover:text-gray-800 flex items-center justify-center cursor-pointer",
title: "Confirm match" do %>
<%= lucide_icon "check", class: "w-4 h-4 text-indigo-400 hover:text-indigo-600" %>
<% end %>
<%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "rejected" }),
<%= button_to transfer_path(transaction.transfer, transfer: { status: "rejected" }),
method: :patch,
data: { turbo: false },
class: "text-secondary hover:text-gray-800 flex items-center justify-center",
class: "text-secondary hover:text-gray-800 flex items-center justify-center cursor-pointer",
title: "Reject match" do %>
<%= lucide_icon "x", class: "w-4 h-4 text-subdued hover:text-gray-600" %>
<% end %>

View file

@ -1,7 +1,7 @@
<%= turbo_frame_tag "bulk_transaction_edit_drawer" do %>
<dialog data-controller="modal"
data-action="click->modal#clickOutside"
class="bg-white border border-alpha-black-25 rounded-2xl max-h-[calc(100vh-32px)] max-w-[480px] w-full shadow-xs h-full mt-4 mr-4 ml-auto">
class="bg-white shadow-border-xs rounded-2xl max-h-[calc(100vh-32px)] max-w-[480px] w-full mt-4 mr-4 ml-auto">
<%= styled_form_with url: bulk_update_account_transactions_path, scope: "bulk_update", class: "h-full", data: { turbo_frame: "_top" } do |form| %>
<div class="flex h-full flex-col justify-between p-4">
<div>

View file

@ -1,32 +0,0 @@
<%= turbo_frame_tag dom_id(@account, "transactions") do %>
<div class="bg-white space-y-4 p-5 border border-alpha-black-25 rounded-xl shadow-xs">
<div class="flex justify-between items-center">
<h3 class="font-medium text-lg"><%= t(".transactions") %></h3>
<%= link_to new_account_transaction_path(account_id: @account),
class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg",
data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
<span class="text-sm"><%= t(".new") %></span>
<% end %>
</div>
<div id="transactions" data-controller="bulk-select" data-bulk-select-resource-value="<%= t(".transaction") %>">
<div id="transaction-selection-bar" data-bulk-select-target="selectionBar" class="flex justify-center hidden">
<%= render "selection_bar" %>
</div>
<% if @entries.empty? %>
<p class="text-secondary py-4"><%= t(".no_transactions") %></p>
<% else %>
<div class="space-y-6">
<%= entries_by_date(@entries) do |entries, _transfers| %>
<%= render entries %>
<% end %>
</div>
<div class="pt-4">
<%= render "pagination", pagy: @pagy %>
</div>
<% end %>
</div>
</div>
<% end %>