1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-24 23:59:40 +02:00

Basic account onboarding (#1328)

* Basic account onboarding

* Cleanup
This commit is contained in:
Zach Gollwitzer 2024-10-18 17:18:54 -04:00 committed by GitHub
parent e8e100e1d8
commit 263d65ea7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 146 additions and 73 deletions

View file

@ -79,6 +79,6 @@ class AccountsController < ApplicationController
end
def account_params
params.require(:account).permit(:name, :accountable_type, :balance, :start_date, :start_balance, :currency, :subtype, :is_active, :institution_id)
params.require(:account).permit(:name, :accountable_type, :mode, :balance, :start_date, :start_balance, :currency, :subtype, :is_active, :institution_id)
end
end

View file

@ -27,7 +27,7 @@ class CreditCardsController < ApplicationController
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :start_balance, :currency, :accountable_type,
:name, :balance, :institution_id, :mode, :start_date, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:available_credit,

View file

@ -27,7 +27,7 @@ class LoansController < ApplicationController
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :start_balance, :currency, :accountable_type,
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:rate_type,

View file

@ -27,7 +27,7 @@ class PropertiesController < ApplicationController
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :start_balance, :currency, :accountable_type,
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:year_built,

View file

@ -27,7 +27,7 @@ class VehiclesController < ApplicationController
def account_params
params.require(:account)
.permit(
:name, :balance, :institution_id, :start_date, :start_balance, :currency, :accountable_type,
:name, :balance, :institution_id, :start_date, :mode, :start_balance, :currency, :accountable_type,
accountable_attributes: [
:id,
:make,

View file

@ -1,7 +1,10 @@
class Account < ApplicationRecord
VALUE_MODES = %w[balance transactions]
include Syncable, Monetizable, Issuable
validates :name, :balance, :currency, presence: true
validates :mode, inclusion: { in: VALUE_MODES }, allow_nil: true
belongs_to :family
belongs_to :institution, optional: true

View file

@ -23,11 +23,11 @@ class Account::Balance::Calculator
attr_reader :account, :sync_start_date
def find_start_balance_for_partial_sync
account.balances.find_by(currency: account.currency, date: sync_start_date - 1.day).balance
account.balances.find_by(currency: account.currency, date: sync_start_date - 1.day)&.balance
end
def find_start_balance_for_full_sync(cached_entries)
account.balance + net_entry_flows(cached_entries)
account.balance + net_entry_flows(cached_entries.select { |e| e.account_transaction? })
end
def calculate_balance_for_date(date, entries:, prior_balance:)

View file

@ -2,6 +2,10 @@
<%= styled_form_with model: account, url: url, scope: :account, class: "flex flex-col gap-4 justify-between grow", data: { turbo: false } do |f| %>
<div class="grow space-y-2">
<% unless account.new_record? %>
<%= f.select :mode, Account::VALUE_MODES.map { |mode| [mode.titleize, mode] }, { label: t(".mode"), prompt: t(".mode_prompt") } %>
<% end %>
<%= f.select :accountable_type, Accountable::TYPES.map { |type| [type.titleize, type] }, { label: t(".accountable_type"), prompt: t(".type_prompt") }, required: true, autofocus: true %>
<%= f.text_field :name, placeholder: t(".name_placeholder"), required: "required", label: t(".name_label") %>

View file

@ -1,8 +0,0 @@
<div class="flex items-center gap-2 rounded-xl justify-between shadow-xs bg-white p-4 border border-alpha-black-25">
<p class="text-lg font-medium text-gray-900">Setup your new account</p>
<div class="flex items-center gap-2">
<%= link_to "Track balances only", new_account_valuation_path(@account), class: "btn btn--ghost", data: { turbo_frame: dom_id(@account.entries.account_valuations.new) } %>
<%= link_to "Add your first transaction", new_transaction_path(account_id: @account.id), class: "btn btn--primary", data: { turbo_frame: :modal } %>
</div>
</div>

View file

@ -1,7 +1,13 @@
<%# locals: (account:) %>
<%# locals: (account:, selected_tab:) %>
<% if account.transactions.any? %>
<%= render "accounts/accountables/transactions", account: account %>
<% if account.mode.nil? %>
<%= render "accounts/accountables/value_onboarding", account: account %>
<% else %>
<%= render "accounts/accountables/valuations", account: account %>
<div class="min-h-[800px]">
<% if account.mode == "transactions" %>
<%= render "accounts/accountables/transactions", account: account %>
<% else %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>
</div>
<% end %>

View file

@ -0,0 +1,16 @@
<%# locals: (account:) %>
<div data-test-id="value-onboarding" class="py-12 flex flex-col justify-center items-center bg-white rounded-lg border border-alpha-black-25 shadow-xs">
<h3 class="font-medium text-lg mb-2">How would you like to track value for this account?</h3>
<p class="text-sm text-gray-500 mb-8">We will use this to determine what data to show for this account.</p>
<div class="flex items-center gap-4">
<%= button_to account_path(account, { account: { mode: "balance" } }), method: :put, class: "btn btn--outline", data: { controller: "tooltip", turbo: false } do %>
<%= render partial: "shared/text_tooltip", locals: { tooltip_text: "Choose this if you only need to track the historical value of this account over time and do not plan on importing any transactions." } %>
<span>Balance only</span>
<% end %>
<%= button_to account_path(account, { account: { mode: "transactions" } }), method: :put, class: "btn btn--primary", data: { controller: "tooltip", turbo: false } do %>
<%= render partial: "shared/text_tooltip", locals: { tooltip_text: "Choose this if you plan on importing transactions into this account for budgeting and other analytics." } %>
<span>Transactions</span>
<% end %>
</div>
</div>

View file

@ -1,15 +1,26 @@
<%# locals: (account:, selected_tab:) %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
<%= render "accounts/accountables/tab", account: account, key: "overview", is_selected: selected_tab.in?([nil, "overview"]) %>
<%= render "accounts/accountables/tab", account: account, key: "transactions", is_selected: selected_tab == "transactions" %>
</div>
<% if account.mode.nil? %>
<%= render "accounts/accountables/value_onboarding", account: account %>
<% else %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
<%= render "accounts/accountables/tab", account: account, key: "overview", is_selected: selected_tab.in?([nil, "overview"]) %>
<div class="min-h-[800px]">
<% case selected_tab %>
<% when nil, "overview" %>
<%= render "accounts/accountables/credit_card/overview", account: account %>
<% when "transactions" %>
<%= render "accounts/accountables/transactions", account: account %>
<% end %>
</div>
<% if account.mode == "transactions" %>
<%= render "accounts/accountables/tab", account: account, key: "transactions", is_selected: selected_tab == "transactions" %>
<% else %>
<%= render "accounts/accountables/tab", account: account, key: "value", is_selected: selected_tab == "value" %>
<% end %>
</div>
<div class="min-h-[800px]">
<% case selected_tab %>
<% when nil, "overview" %>
<%= render "accounts/accountables/credit_card/overview", account: account %>
<% when "transactions" %>
<%= render "accounts/accountables/transactions", account: account %>
<% when "value" %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>
</div>
<% end %>

View file

@ -1 +1 @@
<%= render "accounts/accountables/default_tabs", account: account %>
<%= render "accounts/accountables/default_tabs", account: account, selected_tab: selected_tab %>

View file

@ -1 +1 @@
<%= render "accounts/accountables/default_tabs", account: account %>
<%= render "accounts/accountables/default_tabs", account: account, selected_tab: selected_tab %>

View file

@ -1,28 +1,34 @@
<%# locals: (account:, selected_tab:) %>
<% if account.entries.account_trades.any? || account.entries.account_transactions.any? %>
<% if account.mode.nil? %>
<%= render "accounts/accountables/value_onboarding", account: account %>
<% else %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
<%= render "accounts/accountables/tab", account: account, key: "holdings", is_selected: selected_tab.in?([nil, "holdings"]) %>
<%= render "accounts/accountables/tab", account: account, key: "cash", is_selected: selected_tab == "cash" %>
<%= render "accounts/accountables/tab", account: account, key: "transactions", is_selected: selected_tab == "transactions" %>
<% if account.mode == "transactions" %>
<%= render "accounts/accountables/tab", account: account, key: "holdings", is_selected: selected_tab.in?([nil, "holdings"]) %>
<%= render "accounts/accountables/tab", account: account, key: "cash", is_selected: selected_tab == "cash" %>
<%= render "accounts/accountables/tab", account: account, key: "transactions", is_selected: selected_tab == "transactions" %>
<% end %>
</div>
<div class="min-h-[800px]">
<% case selected_tab %>
<% when nil, "holdings" %>
<%= turbo_frame_tag dom_id(account, :holdings), src: account_holdings_path(account) do %>
<%= render "account/entries/loading" %>
<% end %>
<% when "cash" %>
<%= turbo_frame_tag dom_id(account, :cash), src: account_cashes_path(account) do %>
<%= render "account/entries/loading" %>
<% end %>
<% when "transactions" %>
<%= turbo_frame_tag dom_id(account, :trades), src: account_trades_path(account) do %>
<%= render "account/entries/loading" %>
<% if account.mode == "transactions" %>
<% case selected_tab %>
<% when nil, "holdings" %>
<%= turbo_frame_tag dom_id(account, :holdings), src: account_holdings_path(account) do %>
<%= render "account/entries/loading" %>
<% end %>
<% when "cash" %>
<%= turbo_frame_tag dom_id(account, :cash), src: account_cashes_path(account) do %>
<%= render "account/entries/loading" %>
<% end %>
<% when "transactions" %>
<%= turbo_frame_tag dom_id(account, :trades), src: account_trades_path(account) do %>
<%= render "account/entries/loading" %>
<% end %>
<% end %>
<% else %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>
</div>
<% else %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>

View file

@ -1,15 +1,25 @@
<%# locals: (account:, selected_tab:) %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
<%= render "accounts/accountables/tab", account: account, key: "overview", is_selected: selected_tab.in?([nil, "overview"]) %>
<%= render "accounts/accountables/tab", account: account, key: "value", is_selected: selected_tab == "value" %>
</div>
<% if account.mode.nil? %>
<%= render "accounts/accountables/value_onboarding", account: account %>
<% else %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4">
<%= render "accounts/accountables/tab", account: account, key: "overview", is_selected: selected_tab.in?([nil, "overview"]) %>
<% if account.mode == "transactions" %>
<%= render "accounts/accountables/tab", account: account, key: "transactions", is_selected: selected_tab == "transactions" %>
<% else %>
<%= render "accounts/accountables/tab", account: account, key: "value", is_selected: selected_tab == "value" %>
<% end %>
</div>
<div class="min-h-[800px]">
<% case selected_tab %>
<% when nil, "overview" %>
<%= render "accounts/accountables/loan/overview", account: account %>
<% when "value" %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>
</div>
<div class="min-h-[800px]">
<% case selected_tab %>
<% when nil, "overview" %>
<%= render "accounts/accountables/loan/overview", account: account %>
<% when "transactions" %>
<%= render "accounts/accountables/transactions", account: account %>
<% when "value" %>
<%= render "accounts/accountables/valuations", account: account %>
<% end %>
</div>
<% end %>

View file

@ -16,10 +16,6 @@
</div>
</header>
<% if @account.entries.empty? && @account.depository? %>
<%= render "accounts/new_account_setup_bar", account: @account %>
<% end %>
<% if @account.highest_priority_issue %>
<%= render partial: "issues/issue", locals: { issue: @account.highest_priority_issue } %>
<% end %>

View file

@ -1,5 +1,5 @@
<div role="tooltip" data-tooltip-target="tooltip" class="tooltip bg-gray-700 text-sm px-1.5 py-1 rounded-md">
<div class="text-white font-normal">
<div class="text-white font-normal max-w-[200px]">
<%= tooltip_text %>
</div>
</div>