diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 0e96acec..d78b8f31 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -96,7 +96,7 @@ } .btn { - @apply px-3 py-2 rounded-lg; + @apply px-3 py-2 rounded-lg text-sm font-medium; } .btn--primary { diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 33d9cfcb..c011224e 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -69,6 +69,11 @@ module AccountsHelper tab || available_tabs.first end + def account_groups(period: nil) + assets, liabilities = Current.family.accounts.by_group(currency: Current.family.currency, period: period || Period.last_30_days).values_at(:assets, :liabilities) + [ assets.children, liabilities.children ].flatten + end + private def class_mapping(accountable_type) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b834f54b..d2978dfd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -57,11 +57,6 @@ module ApplicationHelper render partial: "shared/drawer", locals: { content: content } end - def account_groups(period: nil) - assets, liabilities = Current.family.accounts.by_group(currency: Current.family.currency, period: period || Period.last_30_days).values_at(:assets, :liabilities) - [ assets.children, liabilities.children ].flatten - end - def sidebar_link_to(name, path, options = {}) is_current = current_page?(path) || (request.path.start_with?(path) && path != "/") diff --git a/app/views/accounts/_account_list.html.erb b/app/views/accounts/_account_list.html.erb index d5a15daf..6066c61a 100644 --- a/app/views/accounts/_account_list.html.erb +++ b/app/views/accounts/_account_list.html.erb @@ -1,6 +1,6 @@ <%# locals: (group:) -%> <% type = Accountable.from_type(group.name) %> -<% if group %> +<% if group && group.children.any? %>
<%= lucide_icon("chevron-down", class: "hidden group-open:block text-gray-500 w-5 h-5") %> @@ -8,8 +8,8 @@
<%= type.model_name.human %>

<%= format_money group.sum %>

-
- <%= +
+ <%= tag.div( id: "#{group.name}_sparkline", class: "h-3 w-8 ml-auto", @@ -21,10 +21,10 @@ "time-series-chart-use-tooltip-value": false } ) - %> - <% styles = trend_styles(group.series.trend) %> - <%= sprintf("%+.2f", group.series.trend.percent) %>% -
+ %> + <% styles = trend_styles(group.series.trend) %> + <%= sprintf("%+.2f", group.series.trend.percent) %>% +
<% group.children.sort_by(&:name).each do |account_value_node| %> diff --git a/app/views/layouts/_sidebar.html.erb b/app/views/layouts/_sidebar.html.erb index d1716c85..74cc5c64 100644 --- a/app/views/layouts/_sidebar.html.erb +++ b/app/views/layouts/_sidebar.html.erb @@ -91,8 +91,9 @@ <%= t(".portfolio") %> <% end %> - <%= form_with url: list_accounts_path, method: :get, data: { controller: "auto-submit-form", turbo_frame: "account-list" } do |form| %> - <%= period_select form: form, selected: "last_7_days", classes: "w-full border-none pl-2 pr-7 text-xs bg-transparent gap-1 cursor-pointer font-semibold tracking-wide focus:outline-none focus:ring-0" %> + + <%= form_with url: list_accounts_path, method: :get, data: { controller: Current.family.accounts.any? ? "auto-submit-form" : nil, turbo_frame: "account-list" } do |form| %> + <%= period_select form: form, selected: "last_30_days", classes: "w-full border-none pl-2 pr-7 text-xs bg-transparent gap-1 cursor-pointer font-semibold tracking-wide focus:outline-none focus:ring-0" %> <% end %> <%= link_to new_account_path, id: "sidebar-new-account", class: "block hover:bg-gray-100 font-semibold text-gray-900 flex items-center rounded", title: t(".new_account"), data: { turbo_frame: "modal" } do %> @@ -101,8 +102,15 @@ <%= turbo_frame_tag "account-list", target: "_top" do %> - <% account_groups.each do |group| %> - <%= render "accounts/account_list", group: group %> + <% if Current.family.accounts.any? %> + <% account_groups.each do |group| %> + <%= render "accounts/account_list", group: group %> + <% end %> + <% else %> + <%= link_to new_account_path, class: "flex items-center min-h-10 gap-4 px-3 py-2 mb-1 text-gray-500 text-sm font-medium rounded-[10px] hover:bg-gray-100", data: { turbo_frame: "modal" } do %> + <%= lucide_icon("plus", class: "w-5 h-5") %> + <%= tag.p t(".new_account") %> + <% end %> <% end %> <% end %> diff --git a/app/views/pages/dashboard.html.erb b/app/views/pages/dashboard.html.erb index 8a7a6b60..5bae643c 100644 --- a/app/views/pages/dashboard.html.erb +++ b/app/views/pages/dashboard.html.erb @@ -1,189 +1,177 @@
-

Dashboard

+

<%= t(".title") %>

<%= t(".greeting", name: Current.user.first_name ) %>

<% unless @accounts.blank? %>

<%= t(".subtitle") %>

<% end %>
- <%= link_to new_account_path, class: "flex text-white text-sm font-medium items-center gap-1 bg-gray-900 hover:bg-gray-700 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %> + + <%= link_to new_account_path, class: "flex items-center gap-1 btn btn--primary", data: { turbo_frame: "modal" } do %> <%= lucide_icon("plus", class: "w-5 h-5") %> <%= t(".new") %> <% end %>
+ <% if @accounts.empty? %> <%= render "shared/no_account_empty_state" %> <% else %> -
-
-
-
- <%= render partial: "shared/value_heading", locals: { +
+
+
+
+ <%= render partial: "shared/value_heading", locals: { label: t(".net_worth"), period: @period, value: Current.family.net_worth, trend: @net_worth_series.trend } %> +
+ <%= form_with url: root_path, method: :get, class: "flex items-center gap-4", data: { controller: "auto-submit-form" } do |form| %> + <%= period_select form: form, selected: @period.name %> + <% end %>
- <%= form_with url: root_path, method: :get, class: "flex items-center gap-4", data: { controller: "auto-submit-form" } do |form| %> - <%= period_select form: form, selected: @period.name %> - <% end %> + <%= render partial: "pages/dashboard/net_worth_chart", locals: { series: @net_worth_series } %>
- <%= render partial: "pages/dashboard/net_worth_chart", locals: { series: @net_worth_series } %> -
-
- <%= render partial: "pages/dashboard/allocation_chart", locals: { account_groups: @account_groups } %> -
-
-
-
-
-
-
- <%= render partial: "shared/value_heading", locals: { +
+ <%= render partial: "pages/dashboard/allocation_chart", locals: { account_groups: @account_groups } %> +
+
+
+
+
+
+
+ <%= render partial: "shared/value_heading", locals: { label: t(".income"), period: Period.last_30_days, value: @income_series.last&.value, trend: @income_series.trend } %> -
-
+
-
-
- <% @top_earners.first(3).each do |account| %> - <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> - <%= image_tag account_logo_url(account), class: "w-5 h-5" %> - +<%= Money.new(account.income, account.currency) %> +
+
+ <% @top_earners.first(3).each do |account| %> + <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> + <%= image_tag account_logo_url(account), class: "w-5 h-5" %> + +<%= Money.new(account.income, account.currency) %> + <% end %> <% end %> - <% end %> - <% if @top_earners.count > 3 %> -
+<%= @top_earners.count - 3 %>
- <% end %> + <% if @top_earners.count > 3 %> +
+<%= @top_earners.count - 3 %>
+ <% end %> +
-
-
-
-
-
- <%= render partial: "shared/value_heading", locals: { +
+
+
+
+ <%= render partial: "shared/value_heading", locals: { label: t(".spending"), period: Period.last_30_days, value: @spending_series.last&.value, trend: @spending_series.trend } %> -
-
+
-
-
- <% @top_spenders.first(3).each do |account| %> - <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> - <%= image_tag account_logo_url(account), class: "w-5 h-5" %> - -<%= Money.new(account.spending, account.currency) %> +
+
+ <% @top_spenders.first(3).each do |account| %> + <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> + <%= image_tag account_logo_url(account), class: "w-5 h-5" %> + -<%= Money.new(account.spending, account.currency) %> + <% end %> <% end %> - <% end %> - <% if @top_spenders.count > 3 %> -
+<%= @top_spenders.count - 3 %>
- <% end %> + <% if @top_spenders.count > 3 %> +
+<%= @top_spenders.count - 3 %>
+ <% end %> +
-
-
-
-
-
- <%= render partial: "shared/value_heading", locals: { +
+
+
+
+ <%= render partial: "shared/value_heading", locals: { label: t(".savings_rate"), period: Period.last_30_days, value: @savings_rate_series.last&.value, trend: @savings_rate_series.trend, is_percentage: true } %> -
-
+
-
-
- <% @top_savers.first(3).each do |account| %> - <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> - <%= image_tag account_logo_url(account), class: "w-5 h-5" %> - <%= account.savings_rate > 0 ? "+" : "-" %><%= number_to_percentage(account.savings_rate.abs * 100, precision: 2) %> +
+
+ <% @top_savers.first(3).each do |account| %> + <%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-gray-900 font-medium hover:bg-gray-25" do %> + <%= image_tag account_logo_url(account), class: "w-5 h-5" %> + <%= account.savings_rate > 0 ? "+" : "-" %><%= number_to_percentage(account.savings_rate.abs * 100, precision: 2) %> + <% end %> <% end %> - <% end %> - <% if @top_savers.count > 3 %> -
+<%= @top_savers.count - 3 %>
- <% end %> + <% if @top_savers.count > 3 %> +
+<%= @top_savers.count - 3 %>
+ <% end %> +
-
-
-
-
- <%= render partial: "shared/value_heading", locals: { +
+
+
+ <%= render partial: "shared/value_heading", locals: { label: t(".investing"), period: @period, value: @investing_series.last.value, trend: @investing_series.trend } %> -
-
+
-
-
-
-
-
-

<%= t(".transactions") %>

- <% if @transaction_entries.empty? %> -
-

<%= t(".no_transactions") %>

- <% else %> -
- <%= entries_by_date(@transaction_entries, selectable: false) do |entries| %> - <%= render entries, selectable: false, editable: false, short: true %> - <% end %> +
+
+
+
+

<%= t(".transactions") %>

+ <% if @transaction_entries.empty? %> +
+

<%= t(".no_transactions") %>

+
+ <% else %> +
+ <%= entries_by_date(@transaction_entries, selectable: false) do |entries| %> + <%= render entries, selectable: false, editable: false %> + <% end %> -

<%= link_to t(".view_all"), transactions_path %>

-
- <% end %> -
-
-
-

<%= t(".recurring") %>

-
-

Coming soon...

-
+

<%= link_to t(".view_all"), transactions_path %>

+
+ <% end %>
-
-

<%= t(".categories") %>

-
-

Coming soon...

-
-
-
- + <% end %> diff --git a/app/views/shared/_no_account_empty_state.html.erb b/app/views/shared/_no_account_empty_state.html.erb index 061e6af8..cfb79003 100644 --- a/app/views/shared/_no_account_empty_state.html.erb +++ b/app/views/shared/_no_account_empty_state.html.erb @@ -1,8 +1,13 @@ -
-
-

<%= t(".no_account_title") %>

-

<%= t(".no_account_subtitle") %>

- <%= link_to new_account_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %> +
+
+ <%= lucide_icon "layers", class: "w-6 h-6 text-gray-500" %> + +
+

<%= t(".no_account_title") %>

+

<%= t(".no_account_subtitle") %>

+
+ + <%= 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") %> <%= t(".new_account") %> <% end %> diff --git a/config/locales/views/pages/en.yml b/config/locales/views/pages/en.yml index c6777dc3..8bbccbc0 100644 --- a/config/locales/views/pages/en.yml +++ b/config/locales/views/pages/en.yml @@ -7,16 +7,15 @@ en: allocation_chart: assets: Assets debts: Debts - categories: Categories greeting: Welcome back, %{name} income: Income investing: Investing (coming soon...) net_worth: Net Worth new: New account no_transactions: You have no recent transactions - recurring: Recurring savings_rate: Savings Rate spending: Spending subtitle: Here's what's happening today - transactions: Transactions + title: Dashboard + transactions: Recent transactions view_all: View all