Fix SimpleFin new account setup flow and UI dark mode issues

- Fix accounts showing as 'unknown' by displaying proper account type from Account model
- Fix new accounts in existing connections not triggering setup flow with correct query
- Fix dark mode colors throughout SimpleFin views using design system tokens
- Improve UI logic to show existing accounts alongside new account setup prompt
- Remove balance attribute error when creating CreditCard accounts
- Simplify CreditCard subtype selection (auto-default to credit_card)
This commit is contained in:
Sholom Ber
2025-08-07 22:12:10 -04:00
parent e8b54bc2ca
commit 6681537b1e
8 changed files with 43 additions and 31 deletions

View File

@@ -52,7 +52,7 @@ class SimplefinItemsController < ApplicationController
end
def setup_accounts
@simplefin_accounts = @simplefin_item.simplefin_accounts
@simplefin_accounts = @simplefin_item.simplefin_accounts.includes(:account).where(accounts: { id: nil })
@account_type_options = [
[ "Checking or Savings Account", "Depository" ],
[ "Credit Card", "CreditCard" ],
@@ -69,8 +69,9 @@ class SimplefinItemsController < ApplicationController
options: Depository::SUBTYPES.map { |k, v| [ v[:long], k ] }
},
"CreditCard" => {
label: "Credit Card Type:",
options: CreditCard::SUBTYPES.map { |k, v| [ v[:long], k ] }
label: "",
options: [],
message: "Credit cards will be automatically set up as credit card accounts."
},
"Investment" => {
label: "Investment Type:",
@@ -98,6 +99,9 @@ class SimplefinItemsController < ApplicationController
simplefin_account = @simplefin_item.simplefin_accounts.find(simplefin_account_id)
selected_subtype = account_subtypes[simplefin_account_id]
# Default subtype for CreditCard since it only has one option
selected_subtype = "credit_card" if selected_type == "CreditCard" && selected_subtype.blank?
# Create account with user-selected type and subtype
account = Account.create_from_simplefin_account(

View File

@@ -93,7 +93,6 @@ class Account < ApplicationRecord
def build_simplefin_accountable_attributes(simplefin_account, account_type, subtype)
attributes = {}
attributes[:balance] = simplefin_account.current_balance if %w[CreditCard Loan].include?(account_type)
attributes[:subtype] = subtype if subtype.present?
attributes
end

View File

@@ -15,8 +15,8 @@ class SimplefinAccount < ApplicationRecord
current_balance: parse_balance(snapshot[:balance]),
available_balance: parse_balance(snapshot[:"available-balance"]),
currency: parse_currency(snapshot[:currency]),
account_type: snapshot[:type] || "unknown",
account_subtype: snapshot[:subtype],
account_type: snapshot["type"] || "unknown",
account_subtype: snapshot["subtype"],
name: snapshot[:name],
account_id: snapshot[:id],
raw_payload: account_snapshot

View File

@@ -9,8 +9,9 @@ class SimplefinItem::Syncer
# Loads item metadata, accounts, transactions from SimpleFin API
simplefin_item.import_latest_simplefin_data
# Check if this is the first sync and we have new accounts to set up
if simplefin_item.accounts.empty? && simplefin_item.simplefin_accounts.any?
# Check if we have new SimpleFin accounts that need setup
unlinked_accounts = simplefin_item.simplefin_accounts.includes(:account).where(accounts: { id: nil })
if unlinked_accounts.any?
# Mark as pending account setup so user can choose account types
simplefin_item.update!(pending_account_setup: true)
return

View File

@@ -72,18 +72,20 @@
<div class="space-y-4 mt-4">
<% if simplefin_item.accounts.any? %>
<%= render "accounts/index/account_groups", accounts: simplefin_item.accounts %>
<% elsif simplefin_item.pending_account_setup? %>
<% end %>
<% if simplefin_item.pending_account_setup? %>
<div class="p-4 flex flex-col gap-3 items-center justify-center">
<p class="text-primary font-medium text-sm">Accounts ready to set up</p>
<p class="text-secondary text-sm">Choose account types for your imported SimpleFin accounts.</p>
<p class="text-primary font-medium text-sm">New accounts ready to set up</p>
<p class="text-secondary text-sm">Choose account types for your newly imported SimpleFin accounts.</p>
<%= render DS::Link.new(
text: "Set Up Accounts",
text: "Set Up New Accounts",
icon: "settings",
variant: "primary",
href: setup_accounts_simplefin_item_path(simplefin_item)
) %>
</div>
<% else %>
<% elsif simplefin_item.accounts.empty? %>
<div class="p-4 flex flex-col gap-3 items-center justify-center">
<p class="text-primary font-medium text-sm">No accounts found</p>
<p class="text-secondary text-sm">This connection doesn't have any synchronized accounts yet.</p>

View File

@@ -7,7 +7,7 @@
simplefin_account.name.downcase.include?("savings") ? "savings" : "") : "" %>
<%= select_tag "account_subtypes[#{simplefin_account.id}]",
options_for_select([["Select #{account_type == 'Depository' ? 'subtype' : 'type'}", ""]] + subtype_config[:options], selected_value),
{ class: "w-full px-3 py-2 border border-primary rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600" } %>
{ class: "w-full px-3 py-2 border border-primary rounded-lg focus:ring-2 focus:ring-primary focus:border-primary" } %>
<% else %>
<p class="text-sm text-secondary"><%= subtype_config[:message] %></p>
<% end %>

View File

@@ -4,7 +4,7 @@
<% dialog.with_header(title: "Set Up Your SimpleFin Accounts") do %>
<div class="flex items-center gap-2">
<%= icon "building-2", class: "text-primary" %>
<span>Choose the correct account types for your imported accounts</span>
<span class="text-primary">Choose the correct account types for your imported accounts</span>
</div>
<% end %>
@@ -52,7 +52,7 @@
class: "block text-sm font-medium text-primary mb-2" %>
<%= select_tag "account_types[#{simplefin_account.id}]",
options_for_select(@account_type_options),
{ class: "w-full px-3 py-2 border border-primary rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600",
{ class: "w-full px-3 py-2 border border-primary rounded-lg focus:ring-2 focus:ring-primary focus:border-primary",
data: {
action: "change->account-type-selector#updateSubtype"
} } %>
@@ -71,7 +71,7 @@
<div class="flex gap-3">
<%= form.submit "Create Accounts",
class: "flex-1 bg-blue-600 text-white px-4 py-2 rounded-lg font-medium hover:bg-blue-700 focus:ring-2 focus:ring-blue-600 focus:ring-offset-2" %>
class: "flex-1 bg-primary text-white px-4 py-2 rounded-lg font-medium hover:bg-primary-hover focus:ring-2 focus:ring-primary focus:ring-offset-2" %>
<%= link_to "Cancel",
simplefin_items_path,
class: "px-4 py-2 text-secondary hover:text-primary" %>

View File

@@ -1,7 +1,7 @@
<% content_for :title, @simplefin_item.name %>
<div class="mb-8">
<%= link_to simplefin_items_path, class: "text-gray-700 hover:text-gray-900" do %>
<%= link_to simplefin_items_path, class: "text-secondary hover:text-primary" do %>
← Back to SimpleFin Connections
<% end %>
<h1 class="text-2xl font-bold mt-2"><%= @simplefin_item.name %></h1>
@@ -18,26 +18,32 @@
<div class="space-y-6">
<% if @simplefin_item.syncing? %>
<div class="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<div class="p-4 bg-surface border border-primary rounded-lg">
<div class="flex items-center">
<%= icon "loader-2", class: "w-5 h-5 text-blue-600 animate-spin mr-2" %>
<p class="text-blue-700">Syncing accounts...</p>
<%= icon "loader-2", class: "w-5 h-5 text-primary animate-spin mr-2" %>
<p class="text-primary">Syncing accounts...</p>
</div>
</div>
<% end %>
<% if @simplefin_item.simplefin_accounts.any? %>
<div class="bg-white shadow rounded-lg">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-medium">Connected Accounts</h3>
<div class="bg-container shadow-border-xs rounded-lg">
<div class="px-6 py-4 border-b border-primary">
<h3 class="text-lg font-medium text-primary">Connected Accounts</h3>
</div>
<ul class="divide-y divide-gray-200">
<ul class="divide-y divide-secondary">
<% @simplefin_item.simplefin_accounts.each do |simplefin_account| %>
<li class="p-6 flex justify-between items-center">
<div>
<h4 class="font-medium text-gray-900"><%= simplefin_account.name %></h4>
<p class="text-sm text-gray-500"><%= simplefin_account.account_type.humanize %></p>
<p class="text-sm text-gray-500">
<h4 class="font-medium text-primary"><%= simplefin_account.name %></h4>
<p class="text-sm text-secondary">
<% if simplefin_account.account %>
<%= simplefin_account.account.accountable_type.humanize %>
<% else %>
<%= simplefin_account.account_type.humanize %>
<% end %>
</p>
<p class="text-sm text-secondary">
Balance: <%= number_to_currency(simplefin_account.current_balance || 0) %>
<% if simplefin_account.currency != "USD" %>
<%= simplefin_account.currency %>
@@ -47,9 +53,9 @@
<div class="text-right">
<% if simplefin_account.account %>
<%= link_to "View Account", account_path(simplefin_account.account),
class: "text-blue-600 hover:text-blue-800" %>
class: "text-primary hover:text-primary-hover" %>
<% else %>
<span class="text-gray-400">Setting up...</span>
<span class="text-secondary">Setting up...</span>
<% end %>
</div>
</li>
@@ -58,7 +64,7 @@
</div>
<% else %>
<div class="text-center py-12">
<p class="text-gray-500">No accounts found. Try syncing again.</p>
<p class="text-secondary">No accounts found. Try syncing again.</p>
<%= button_to "Sync Now", sync_simplefin_item_path(@simplefin_item),
method: :post,
class: "mt-4 btn btn--secondary" %>