mirror of
https://github.com/we-promise/sure.git
synced 2026-04-12 08:37:22 +00:00
This can be updated to redirect/pull from third party sources in future, with the option of always falling back to the placeholder if there are any failures.
181 lines
8.4 KiB
Plaintext
181 lines
8.4 KiB
Plaintext
<div class="space-y-4">
|
|
<header class="flex items-center justify-between">
|
|
<div>
|
|
<h1 class="sr-only">Dashboard</h1>
|
|
<p class="text-xl font-medium text-gray-900 mb-1"><%= t(".greeting", name: Current.user.first_name ) %></p>
|
|
<p class="text-gray-500 text-sm"><%= t(".subtitle") %></p>
|
|
</div>
|
|
<%= link_to new_account_path, class: "flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2", data: { turbo_frame: "modal" } do %>
|
|
<%= lucide_icon("plus", class: "w-5 h-5") %>
|
|
<span><%= t(".new") %></span>
|
|
<% end %>
|
|
</header>
|
|
<section class="flex gap-4">
|
|
<div class="bg-white border border-alpha-black-25 shadow-xs rounded-xl w-3/4 min-h-48 flex flex-col">
|
|
<div class="flex justify-between p-4">
|
|
<div>
|
|
<%= render partial: "shared/value_heading", locals: {
|
|
label: t(".net_worth"),
|
|
period: @period,
|
|
value: Current.family.net_worth,
|
|
trend: @net_worth_series.trend
|
|
} %>
|
|
</div>
|
|
<%= form_with url: root_path, method: :get, class: "flex items-center gap-4", data: { controller: "auto-submit-form" } do %>
|
|
<%= render partial: "shared/period_select", locals: { value: @period.name } %>
|
|
<% end %>
|
|
</div>
|
|
<%= render partial: "pages/dashboard/net_worth_chart", locals: { series: @net_worth_series } %>
|
|
</div>
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl w-1/4">
|
|
<%= render partial: "pages/dashboard/allocation_chart", locals: { account_groups: @account_groups } %>
|
|
</div>
|
|
</section>
|
|
<section class="grid grid-cols-2 gap-4">
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
|
|
<div class="flex flex-col gap-4 h-full">
|
|
<div class="flex gap-4">
|
|
<div class="grow">
|
|
<%= render partial: "shared/value_heading", locals: {
|
|
label: t(".income"),
|
|
period: Period.last_30_days,
|
|
value: @income_series.last&.value,
|
|
trend: @income_series.trend
|
|
} %>
|
|
</div>
|
|
<div
|
|
id="incomeChart"
|
|
class="h-full w-2/5"
|
|
data-controller="time-series-chart"
|
|
data-time-series-chart-data-value="<%= @income_series.to_json %>"
|
|
data-time-series-chart-use-labels-value="false"
|
|
data-time-series-chart-use-tooltip-value="false"></div>
|
|
</div>
|
|
<div class="flex gap-1.5">
|
|
<% @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" %>
|
|
<span>+<%= Money.new(account.income, account.currency) %></span>
|
|
<% end %>
|
|
<% end %>
|
|
<% if @top_earners.count > 3 %>
|
|
<div class="bg-gray-25 rounded-full flex h-full aspect-1 items-center justify-center text-xs font-medium text-gray-500">+<%= @top_earners.count - 3 %></div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
|
|
<div class="flex flex-col gap-4 h-full">
|
|
<div class="flex gap-4">
|
|
<div class="grow">
|
|
<%= render partial: "shared/value_heading", locals: {
|
|
label: t(".spending"),
|
|
period: Period.last_30_days,
|
|
value: @spending_series.last&.value,
|
|
trend: @spending_series.trend
|
|
} %>
|
|
</div>
|
|
<div
|
|
id="spendingChart"
|
|
class="h-full w-2/5"
|
|
data-controller="time-series-chart"
|
|
data-time-series-chart-data-value="<%= @spending_series.to_json %>"
|
|
data-time-series-chart-use-labels-value="false"
|
|
data-time-series-chart-use-tooltip-value="false"></div>
|
|
</div>
|
|
<div class="flex gap-1.5">
|
|
<% @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 %>
|
|
<% if @top_spenders.count > 3 %>
|
|
<div class="bg-gray-25 rounded-full flex h-full aspect-1 items-center justify-center text-xs font-medium text-gray-500">+<%= @top_spenders.count - 3 %></div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
|
|
<div class="flex flex-col gap-4 h-full">
|
|
<div class="flex gap-4">
|
|
<div class="grow">
|
|
<%= 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
|
|
} %>
|
|
</div>
|
|
<div
|
|
id="savingsRateChart"
|
|
class="h-full w-2/5"
|
|
data-controller="time-series-chart"
|
|
data-time-series-chart-data-value="<%= @savings_rate_series.to_json %>"
|
|
data-time-series-chart-use-labels-value="false"
|
|
data-time-series-chart-use-tooltip-value="false"></div>
|
|
</div>
|
|
<div class="flex gap-1.5">
|
|
<% @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" %>
|
|
<span><%= account.savings_rate > 0 ? "+" : "-" %><%= number_to_percentage(account.savings_rate.abs * 100, precision: 2) %></span>
|
|
<% end %>
|
|
<% end %>
|
|
<% if @top_savers.count > 3 %>
|
|
<div class="bg-gray-25 rounded-full flex h-full aspect-1 items-center justify-center text-xs font-medium text-gray-500">+<%= @top_savers.count - 3 %></div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
|
|
<div class="flex gap-4 h-full">
|
|
<div class="grow">
|
|
<%= render partial: "shared/value_heading", locals: {
|
|
label: t(".investing"),
|
|
period: @period,
|
|
value: @investing_series.last.value,
|
|
trend: @investing_series.trend
|
|
} %>
|
|
</div>
|
|
<div
|
|
id="investingChart"
|
|
class="h-full w-2/5"
|
|
data-controller="time-series-chart"
|
|
data-time-series-chart-data-value="<%= @investing_series.to_json %>"
|
|
data-time-series-chart-use-labels-value="false"></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section class="grid grid-cols-2 gap-4 items-baseline">
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl space-y-4">
|
|
<h2 class="text-lg font-medium text-gray-900"><%= t(".transactions") %></h2>
|
|
<% if @transactions.empty? %>
|
|
<div class="text-gray-500 flex items-center justify-center py-12">
|
|
<p><%= t(".no_transactions") %></p>
|
|
</div>
|
|
<% else %>
|
|
<div class="text-gray-500 flex items-center justify-center flex-col bg-gray-25 rounded-md">
|
|
<%= render partial: "transactions/transaction_group", collection: @transactions.group_by(&:date), as: :transaction_group %>
|
|
<p class="py-2 text-sm"><%= link_to t(".view_all"), transactions_path %></p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<div class="space-y-4">
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl space-y-4">
|
|
<h2 class="text-lg font-medium text-gray-900"><%= t(".recurring") %></h2>
|
|
<div class="text-gray-500 flex items-center justify-center py-12">
|
|
<p>Coming soon...</p>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl space-y-4">
|
|
<h2 class="text-lg font-medium text-gray-900"><%= t(".categories") %></h2>
|
|
<div class="text-gray-500 flex items-center justify-center py-12">
|
|
<p>Coming soon...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|