mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-03 04:25:21 +02:00
Account Activity View + Account Forms (#1406)
* Remove balance mode, sketch out refactor * Activity view checkpoint * Entry partials, checkpoint * Finish txn partial * Give entries context when editing for different turbo responses * Calculate change of balance for each entry * Account tabs consolidation * Translations, linting, brakeman updates * Account actions concern * Finalize forms, get account system tests passing * Get tests passing * Lint, rubocop, schema updates * Improve routing and stream responses * Fix broken routes * Add import option for adding accounts * Fix system test * Fix test specificity * Fix sparklines * Improve account redirects
This commit is contained in:
parent
12e4f1067d
commit
65db49273c
216 changed files with 2043 additions and 1620 deletions
5
app/views/accounts/show/_activity.html.erb
Normal file
5
app/views/accounts/show/_activity.html.erb
Normal file
|
@ -0,0 +1,5 @@
|
|||
<%# locals: (account:) %>
|
||||
|
||||
<%= turbo_frame_tag dom_id(account, :entries), src: account_entries_path(account) do %>
|
||||
<%= render "account/entries/loading" %>
|
||||
<% end %>
|
40
app/views/accounts/show/_chart.html.erb
Normal file
40
app/views/accounts/show/_chart.html.erb
Normal file
|
@ -0,0 +1,40 @@
|
|||
<%# locals: (account:, title: nil, tooltip: nil) %>
|
||||
|
||||
<% period = Period.from_param(params[:period]) %>
|
||||
<% series = account.series(period: period) %>
|
||||
<% trend = series.trend %>
|
||||
<% default_value_title = account.asset? ? t(".balance") : t(".owed") %>
|
||||
|
||||
<div class="bg-white shadow-xs rounded-xl border border-alpha-black-25 rounded-lg">
|
||||
<div class="p-4 flex justify-between">
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<%= tag.p title || default_value_title, class: "text-sm font-medium text-gray-500" %>
|
||||
<%= tooltip %>
|
||||
</div>
|
||||
|
||||
<%= tag.p format_money(account.value), class: "text-gray-900 text-3xl font-medium" %>
|
||||
|
||||
<div>
|
||||
<% if trend.direction.flat? %>
|
||||
<%= tag.span t(".no_change"), class: "text-gray-500" %>
|
||||
<% else %>
|
||||
<%= tag.span "#{trend.value.positive? ? "+" : ""}#{format_money(trend.value)}", style: "color: #{trend.color}" %>
|
||||
<% unless trend.percent.infinite? %>
|
||||
<%= tag.span "(#{trend.percent}%)", style: "color: #{trend.color}" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= tag.span period_label(period), class: "text-gray-500" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form_with url: request.path, method: :get, data: { controller: "auto-submit-form" } do |form| %>
|
||||
<%= period_select form: form, selected: period.name %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="h-64 flex items-center justify-center text-2xl font-bold">
|
||||
<%= render "shared/line_chart", series: series %>
|
||||
</div>
|
||||
</div>
|
34
app/views/accounts/show/_header.html.erb
Normal file
34
app/views/accounts/show/_header.html.erb
Normal file
|
@ -0,0 +1,34 @@
|
|||
<%# locals: (account:, title: nil, subtitle: nil) %>
|
||||
|
||||
<header class="space-y-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<% content = yield %>
|
||||
|
||||
<% if content.present? %>
|
||||
<%= content %>
|
||||
<% else %>
|
||||
<div class="flex items-center gap-3">
|
||||
<%= render "accounts/logo", account: account %>
|
||||
|
||||
<div>
|
||||
<h2 class="font-medium text-xl"><%= title || account.name %></h2>
|
||||
<% if subtitle.present? %>
|
||||
<p class="text-sm text-gray-500"><%= subtitle %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="flex items-center gap-3 ml-auto">
|
||||
<%= button_to sync_account_path(account), method: :post, class: "flex items-center gap-2", title: "Sync Account" do %>
|
||||
<%= lucide_icon "refresh-cw", class: "w-4 h-4 text-gray-500 hover:text-gray-400" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "accounts/show/menu", account: account %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if account.highest_priority_issue %>
|
||||
<%= render partial: "issues/issue", locals: { issue: account.highest_priority_issue } %>
|
||||
<% end %>
|
||||
</header>
|
3
app/views/accounts/show/_loading.html.erb
Normal file
3
app/views/accounts/show/_loading.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="p-5">
|
||||
<p class="text-gray-500 animate-pulse">Loading account...</p>
|
||||
</div>
|
35
app/views/accounts/show/_menu.html.erb
Normal file
35
app/views/accounts/show/_menu.html.erb
Normal file
|
@ -0,0 +1,35 @@
|
|||
<%# locals: (account:) %>
|
||||
|
||||
<%= contextual_menu do %>
|
||||
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
|
||||
<%= link_to edit_account_path(account),
|
||||
data: { turbo_frame: :modal },
|
||||
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %>
|
||||
<%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %>
|
||||
|
||||
<span><%= t(".edit") %></span>
|
||||
<% end %>
|
||||
|
||||
<%= link_to new_import_path,
|
||||
data: { turbo_frame: :modal },
|
||||
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %>
|
||||
<%= lucide_icon "download", class: "w-5 h-5 text-gray-500" %>
|
||||
|
||||
<span><%= t(".import") %></span>
|
||||
<% end %>
|
||||
|
||||
<%= button_to account_path(account),
|
||||
method: :delete,
|
||||
class: "block w-full py-2 px-3 space-x-2 text-red-600 hover:bg-red-50 flex items-center rounded-lg",
|
||||
data: {
|
||||
turbo_frame: :_top,
|
||||
turbo_confirm: {
|
||||
title: t(".confirm_title"),
|
||||
body: t(".confirm_body_html"),
|
||||
accept: t(".confirm_accept", name: account.name)
|
||||
}
|
||||
} do %>
|
||||
<%= lucide_icon("trash-2", class: "w-5 h-5 mr-2") %> Delete account
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
8
app/views/accounts/show/_tab.html.erb
Normal file
8
app/views/accounts/show/_tab.html.erb
Normal file
|
@ -0,0 +1,8 @@
|
|||
<%# locals: (account:, key:, is_selected:) %>
|
||||
|
||||
<%= link_to key.titleize,
|
||||
account_path(account, tab: key),
|
||||
class: [
|
||||
"px-2 py-1.5 rounded-md border border-transparent",
|
||||
"bg-white shadow-xs border-alpha-black-50": is_selected
|
||||
] %>
|
11
app/views/accounts/show/_tabs.html.erb
Normal file
11
app/views/accounts/show/_tabs.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%# locals: (account:, tabs:) %>
|
||||
|
||||
<% selected_tab = tabs.find { |tab| tab[:key] == params[:tab] } || tabs.first %>
|
||||
|
||||
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
|
||||
<% tabs.each do |tab| %>
|
||||
<%= render "accounts/show/tab", account: account, key: tab[:key], is_selected: selected_tab[:key] == tab[:key] %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= selected_tab[:contents] %>
|
27
app/views/accounts/show/_template.html.erb
Normal file
27
app/views/accounts/show/_template.html.erb
Normal file
|
@ -0,0 +1,27 @@
|
|||
<%# locals: (account:, header: nil, chart: nil, tabs: nil) %>
|
||||
|
||||
<%= turbo_stream_from account %>
|
||||
|
||||
<%= turbo_frame_tag dom_id(account) do %>
|
||||
<%= tag.div class: "space-y-4" do %>
|
||||
<% if header.present? %>
|
||||
<%= header %>
|
||||
<% else %>
|
||||
<%= render "accounts/show/header", account: account %>
|
||||
<% end %>
|
||||
|
||||
<% if chart.present? %>
|
||||
<%= chart %>
|
||||
<% else %>
|
||||
<%= render "accounts/show/chart", account: account %>
|
||||
<% end %>
|
||||
|
||||
<div class="min-h-[800px]">
|
||||
<% if tabs.present? %>
|
||||
<%= tabs %>
|
||||
<% else %>
|
||||
<%= render "accounts/show/activity", account: account %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
Loading…
Add table
Add a link
Reference in a new issue