Skip to content
This repository was archived by the owner on Jul 27, 2025. It is now read-only.

Commit 662f2c0

Browse files
authored
Multi-step account forms + clearer balance editing (#2427)
* Initial multi-step property form * Improve form structure, add optional tooltip help icons to form fields * Add basic inline alert component * Clean up and improve property form lifecycle * Implement Account status concept * Lint fixes * Remove whitespace * Balance editing, scope updates for account * Passing tests * Fix brakeman warning * Remove stale columns * data constraint tweaks * Redundant property
1 parent ba7e8d3 commit 662f2c0

File tree

66 files changed

+1034
-425
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1034
-425
lines changed

app/assets/tailwind/maybe-design-system.css

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,19 @@
334334
}
335335
}
336336

337+
/* New form field structure components */
338+
.form-field__header {
339+
@apply flex items-center justify-between gap-2;
340+
}
341+
342+
.form-field__body {
343+
@apply flex flex-col gap-1;
344+
}
345+
346+
.form-field__actions {
347+
@apply flex items-center gap-1;
348+
}
349+
337350
.form-field__label {
338351
@apply block text-xs text-secondary peer-disabled:text-subdued;
339352
}
@@ -347,17 +360,21 @@
347360
@apply transition-opacity duration-300;
348361
@apply placeholder:text-subdued;
349362

350-
&select {
351-
@apply pr-8;
352-
}
353-
354363
@variant theme-dark {
355364
&::-webkit-calendar-picker-indicator {
356365
filter: invert(1);
357366
cursor: pointer;
358367
}
359368
}
360369
}
370+
371+
select.form-field__input {
372+
@apply pr-10 appearance-none;
373+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
374+
background-position: right -0.15rem center;
375+
background-repeat: no-repeat;
376+
background-size: 1.25rem 1.25rem;
377+
}
361378

362379
.form-field__radio {
363380
@apply text-primary;
@@ -425,7 +442,5 @@
425442
@variant theme-dark {
426443
fill: var(--color-white);
427444
}
428-
429445
}
430-
}
431-
446+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div class="<%= container_classes %>">
2+
<%= helpers.icon icon_name, size: "sm", color: icon_color, class: "shrink-0" %>
3+
4+
<div class="flex-1 text-sm">
5+
<%= message %>
6+
</div>
7+
</div>

app/components/alert_component.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
class AlertComponent < ViewComponent::Base
2+
def initialize(message:, variant: :info)
3+
@message = message
4+
@variant = variant
5+
end
6+
7+
private
8+
attr_reader :message, :variant
9+
10+
def container_classes
11+
base_classes = "flex items-start gap-3 p-4 rounded-lg border"
12+
13+
variant_classes = case variant
14+
when :info
15+
"bg-blue-50 text-blue-700 border-blue-200 theme-dark:bg-blue-900/20 theme-dark:text-blue-400 theme-dark:border-blue-800"
16+
when :success
17+
"bg-green-50 text-green-700 border-green-200 theme-dark:bg-green-900/20 theme-dark:text-green-400 theme-dark:border-green-800"
18+
when :warning
19+
"bg-yellow-50 text-yellow-700 border-yellow-200 theme-dark:bg-yellow-900/20 theme-dark:text-yellow-400 theme-dark:border-yellow-800"
20+
when :error, :destructive
21+
"bg-red-50 text-red-700 border-red-200 theme-dark:bg-red-900/20 theme-dark:text-red-400 theme-dark:border-red-800"
22+
end
23+
24+
"#{base_classes} #{variant_classes}"
25+
end
26+
27+
def icon_name
28+
case variant
29+
when :info
30+
"info"
31+
when :success
32+
"check-circle"
33+
when :warning
34+
"alert-triangle"
35+
when :error, :destructive
36+
"x-circle"
37+
end
38+
end
39+
40+
def icon_color
41+
case variant
42+
when :success
43+
"success"
44+
when :warning
45+
"warning"
46+
when :error, :destructive
47+
"destructive"
48+
else
49+
"blue-600"
50+
end
51+
end
52+
end
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<%= link_to href, **merged_opts do %>
22
<% if icon && (icon_position != "right") %>
33
<%= helpers.icon(icon, size: size, color: icon_color) %>
4-
54
<% end %>
65

76
<% unless icon_only? %>
@@ -10,6 +9,5 @@
109

1110
<% if icon && icon_position == "right" %>
1211
<%= helpers.icon(icon, size: size, color: icon_color) %>
13-
1412
<% end %>
1513
<% end %>

app/controllers/accountable_sparklines_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def accountable
3232
end
3333

3434
def account_ids
35-
family.accounts.active.where(accountable_type: accountable.name).pluck(:id)
35+
family.accounts.visible.where(accountable_type: accountable.name).pluck(:id)
3636
end
3737

3838
def cache_key

app/controllers/accounts_controller.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class AccountsController < ApplicationController
2-
before_action :set_account, only: %i[sync chart sparkline]
2+
before_action :set_account, only: %i[sync chart sparkline toggle_active]
33
include Periodable
44

55
def index
@@ -33,6 +33,15 @@ def sparkline
3333
end
3434
end
3535

36+
def toggle_active
37+
if @account.active?
38+
@account.disable!
39+
elsif @account.disabled?
40+
@account.enable!
41+
end
42+
redirect_to accounts_path
43+
end
44+
3645
private
3746
def family
3847
Current.family

app/controllers/api/v1/accounts_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Api::V1::AccountsController < Api::V1::BaseController
99
def index
1010
# Test with Pagy pagination
1111
family = current_resource_owner.family
12-
accounts_query = family.accounts.active.alphabetically
12+
accounts_query = family.accounts.visible.alphabetically
1313

1414
# Handle pagination with Pagy
1515
@pagy, @accounts = pagy(

app/controllers/api/v1/transactions_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Api::V1::TransactionsController < Api::V1::BaseController
1010

1111
def index
1212
family = current_resource_owner.family
13-
transactions_query = family.transactions.active
13+
transactions_query = family.transactions.visible
1414

1515
# Apply filters
1616
transactions_query = apply_filters(transactions_query)

app/controllers/concerns/accountable_resource.rb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,25 @@ def create
4343
end
4444

4545
def update
46-
@account.update_with_sync!(account_params.except(:return_to))
47-
@account.lock_saved_attributes!
46+
# Handle balance update if provided
47+
if account_params[:balance].present?
48+
result = @account.update_balance(balance: account_params[:balance], currency: account_params[:currency])
49+
unless result.success?
50+
@error_message = result.error_message
51+
render :edit, status: :unprocessable_entity
52+
return
53+
end
54+
end
4855

56+
# Update remaining account attributes
57+
update_params = account_params.except(:return_to, :balance, :currency)
58+
unless @account.update(update_params)
59+
@error_message = @account.errors.full_messages.join(", ")
60+
render :edit, status: :unprocessable_entity
61+
return
62+
end
63+
64+
@account.lock_saved_attributes!
4965
redirect_back_or_to @account, notice: t("accounts.update.success", type: accountable_type.name.underscore.humanize)
5066
end
5167

@@ -74,7 +90,7 @@ def set_account
7490

7591
def account_params
7692
params.require(:account).permit(
77-
:name, :is_active, :balance, :subtype, :currency, :accountable_type, :return_to,
93+
:name, :balance, :subtype, :currency, :accountable_type, :return_to,
7894
accountable_attributes: self.class.permitted_accountable_attributes
7995
)
8096
end

app/controllers/pages_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class PagesController < ApplicationController
55

66
def dashboard
77
@balance_sheet = Current.family.balance_sheet
8-
@accounts = Current.family.accounts.active.with_attached_logo
8+
@accounts = Current.family.accounts.visible.with_attached_logo
99

1010
period_param = params[:cashflow_period]
1111
@cashflow_period = if period_param.present?

0 commit comments

Comments
 (0)