1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-07 06:25:19 +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,6 +1,3 @@
<div class="flex items-center py-0.5 px-0.5 gap-1 fixed bottom-2 right-2 shadow-xs border border-alpha-black-50 rounded-md bg-white">
<div class="flex items-center py-0.5 px-0.5 gap-1 fixed right-1 top-1 shadow-xs border border-alpha-black-50 rounded-md bg-white">
<p class="text-xs text-secondary pl-2">Version: <%= Maybe.version.to_release_tag %></p>
<%= link_to settings_hosting_path, class: "flex gap-1 items-center hover:bg-gray-50 rounded-md p-2" do %>
<%= lucide_icon("settings", class: "w-4 h-4 text-secondary shrink-0") %>
<% end %>
</div>

View file

@ -1,7 +0,0 @@
<% flash.each do |type, msg| %>
<div class="p-4 <%= type == "notice" ? "bg-blue-200" : "bg-red-200" %> rounded-lg"><%= msg %></div>
<% end %>
<% errors.each do |message| %>
<div class="p-4 bg-red-200 rounded-lg"><%= message %></div>
<% end %>

View file

@ -7,7 +7,7 @@
"full" => "w-full h-full"
} %>
<%= tag.div style: mixed_hex_styles(hex),
<%= tag.div style: mixed_hex_styles(hex || "#1570EF"),
class: [size_classes[size], "flex shrink-0 items-center justify-center rounded-full"] do %>
<%= tag.span (name.presence&.first || "T").upcase, class: ["font-medium", size == "sm" ? "text-xs" : "text-sm"] %>
<% end %>

View file

@ -1,7 +1,7 @@
<%# locals: (content:, reload_on_close: false) %>
<%= turbo_frame_tag "drawer" do %>
<dialog class="ml-auto bg-white border border-alpha-black-25 rounded-2xl max-w-[480px] w-full shadow-xs h-full mt-4 mr-4 focus-visible:outline-hidden"
<dialog class="ml-auto bg-white shadow-border-xs rounded-2xl max-w-[480px] h-full w-full mt-4 mr-4 focus-visible:outline-hidden"
data-controller="modal"
data-action="click->modal#clickOutside"
data-modal-reload-on-close-value="<%= reload_on_close %>">

View file

@ -1,12 +0,0 @@
<%# locals: (series:) %>
<% if series %>
<div
id="lineChart"
class="w-full h-full"
data-controller="time-series-chart"
data-time-series-chart-data-value="<%= series.to_json %>"></div>
<% else %>
<div class="w-full h-full flex items-center justify-center">
<p class="text-secondary">No data available for the selected period.</p>
</div>
<% end %>

View file

@ -1,9 +0,0 @@
<%# locals: (header:, content:) %>
<div class="bg-gray-25 rounded-xl p-1 w-full">
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-secondary">
<%= header %>
</div>
<div class="bg-white shadow-xs rounded-md border border-alpha-black-25 divide-y divide-alpha-black-50">
<%= content %>
</div>
</div>

View file

@ -1,6 +1,6 @@
<%# locals: (content:, classes:) -%>
<%= turbo_frame_tag "modal" do %>
<dialog class="m-auto bg-white border border-alpha-black-25 rounded-2xl max-w-[580px] w-min-content shadow-xs h-fit <%= classes %>" data-controller="modal" data-action="click->modal#clickOutside">
<dialog class="m-auto bg-white shadow-border-xs rounded-2xl max-w-[580px] w-min-content h-fit <%= classes %>" data-controller="modal" data-action="click->modal#clickOutside">
<div class="flex flex-col">
<%= content %>
</div>

View file

@ -1,15 +0,0 @@
<div class="flex justify-center items-center h-[800px]">
<div class="text-center flex flex-col gap-4 items-center max-w-[300px]">
<%= lucide_icon "layers", class: "w-6 h-6 text-secondary" %>
<div class="space-y-1 text-sm">
<p class="text-primary font-medium"><%= t(".no_account_title") %></p>
<p class="text-secondary"><%= t(".no_account_subtitle") %></p>
</div>
<%= link_to new_account_path, class: "btn btn--primary flex items-center gap-1", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<span><%= t(".new_account") %></span>
<% end %>
</div>
</div>

View file

@ -0,0 +1,57 @@
<%# locals: (pagy:) %>
<nav class="flex w-full items-center justify-between">
<div class="flex items-center gap-1">
<div>
<% if pagy.prev %>
<%= link_to pagy_url_for(pagy, pagy.prev),
data: { turbo_frame: :_top },
class: "inline-flex items-center p-2 text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-secondary") %>
<% end %>
<% else %>
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-200") %>
</div>
<% end %>
</div>
<div class="rounded-xl p-1 bg-gray-25">
<% pagy.series.each do |series_item| %>
<% if series_item.is_a?(Integer) %>
<%= link_to pagy_url_for(pagy, series_item),
data: { turbo_frame: :_top },
class: "rounded-md px-2 py-1 inline-flex items-center text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= series_item %>
<% end %>
<% elsif series_item.is_a?(String) %>
<%= link_to pagy_url_for(pagy, series_item),
data: { turbo_frame: :_top },
class: "rounded-md px-2 py-1 bg-white border border-alpha-black-25 shadow-xs inline-flex items-center text-sm font-medium text-primary" do %>
<%= series_item %>
<% end %>
<% elsif series_item == :gap %>
<span class="inline-flex items-center px-2 py-1 text-sm font-medium text-secondary">...</span>
<% end %>
<% end %>
</div>
<div>
<% if pagy.next %>
<%= link_to pagy_url_for(pagy, pagy.next),
data: { turbo_frame: :_top },
class: "inline-flex items-center p-2 text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-secondary") %>
<% end %>
<% else %>
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-200") %>
</div>
<% end %>
</div>
</div>
<div class="flex items-center gap-4">
<%= select_tag :per_page,
options_for_select(["10", "20", "30", "50"], pagy.limit),
data: { controller: "selectable-link" },
class: "py-1.5 pr-8 text-sm text-primary font-medium border border-gray-200 rounded-lg focus:border-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900" %>
</div>
</nav>

View file

@ -1,4 +1,4 @@
<%# locals: (progress:, radius: 7, stroke: 2, text_class: "text-green-500") %>
<%# locals: (progress:, radius: 7, stroke: 2, color: nil) %>
<%
circumference = Math::PI * 2 * radius
@ -18,7 +18,8 @@
<!-- Foreground Circle -->
<circle
class="fill-transparent stroke-current <%= text_class %>"
class="fill-transparent"
style="stroke: <%= color || "var(--color-blue-500)" %>"
r="<%= radius %>"
cx="<%= center %>"
cy="<%= center %>"

View file

@ -1,6 +1,6 @@
<div data-controller="modal" data-modal-open-value="true" class="absolute inset-0 z-50 flex items-center justify-center bg-white/90" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div data-controller="modal" data-modal-open-value="true" class="h-full flex items-center justify-center bg-white/90" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="w-[400px] rounded-xl relative overflow-hidden">
<div class="bg-white shadow-xl border border-gray-200 rounded-xl relative z-10">
<div class="bg-white shadow-border-xs rounded-xl relative z-10">
<div class="rounded-xl" style="background-image: url('<%= asset_path("maybe-plus-background.svg") %>'); background-size: cover; background-position: center top;">
<div class="text-center rounded-xl" style="background-image: linear-gradient(to bottom, rgba(197,161,119,0.15) 0%, rgba(255,255,255,0.8) 30%, white 40%);">
<div class="p-4 pt-2 rounded-xl">

View file

@ -1,14 +1,14 @@
<%# locals: { trend: } %>
<% styles = trend_styles(trend) %>
<p class="text-sm <%= styles[:text_class] %>">
<p class="text-sm" style="color: <%= trend.color %>">
<% if trend.direction.flat? %>
<span>No change</span>
<% else %>
<span><%= styles[:symbol] %><%= trend.value.is_a?(Money) ? format_money(trend.value.abs) : trend.value.abs.round(2) %></span>
<span>
<%= trend.value.is_a?(Money) ? format_money(trend.value) : trend.value.round(2) %>
</span>
<% unless trend.percent.infinite? %>
<span>(<%= lucide_icon(styles[:icon], class: "w-4 h-4 align-text-bottom inline") %><%= trend.percent.abs %>%)</span>
<span>(<%= lucide_icon(trend.icon, class: "w-4 h-4 align-text-bottom inline") %><%= trend.percent_formatted %>)</span>
<% end %>
<% end %>
</p>

View file

@ -1,5 +1,5 @@
<%# locals: (upgrade:) %>
<div class="bg-white space-y-4 text-right fixed bottom-10 right-10 p-5 border border-secondary shadow-xs rounded-md z-50 max-w-[350px]">
<div class="bg-white space-y-4 text-right fixed bottom-10 right-10 p-5 shadow-border-xs rounded-md z-50 max-w-[350px]">
<div>
<p><%= link_to upgrade.to_s, upgrade.url, class: "text-sm text-blue-500 underline hover:text-blue-700", target: "_blank" %></p>
<% if upgrade.complete? %>

View file

@ -1,21 +0,0 @@
<%# locals: (label:, period:, value:, trend:, size: "lg", is_percentage: false)%>
<div class="space-y-2">
<p class="text-sm text-secondary font-medium"><%= label %></p>
<p class="text-primary -space-x-0.5">
<% if value.is_a?(Money) %>
<span class="<%= size == "lg" ? "text-xl" : "text-lg" %> font-medium"><%= format_money value %></span>
<% else %>
<span class="<%= size == "lg" ? "text-xl" : "text-lg" %> font-medium"><%= is_percentage ? number_to_percentage(value, precision: 2) : value %></span>
<% end %>
</p>
<% if trend.nil? %>
<p class="text-sm text-secondary">Data not available for the selected period</p>
<% elsif trend.direction.flat? %>
<p class="text-sm text-secondary">No change vs. prior period</p>
<% else %>
<div class="flex items-center gap-2">
<%= render partial: "shared/trend_change", locals: { trend: trend } %>
<span class="text-sm text-secondary"><%= period_label(period) %></span>
</div>
<% end %>
</div>