1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-07 14:35:23 +02:00

New Design System + Codebase Refresh (#1823)

Since the very first 0.1.0-alpha.1 release, we've been moving quickly to add new features to the Maybe app. In doing so, some parts of the codebase have become outdated, unnecessary, or overly-complex as a natural result of this feature prioritization.

Now that "core" Maybe is complete, we're moving into a second phase of development where we'll be working hard to improve the accuracy of existing features and build additional features on top of "core". This PR is a quick overhaul of the existing codebase aimed to:

- Establish the brand new and simplified dashboard view (pictured above)
- Establish and move towards the conventions introduced in Cursor rules and project design overview #1788
- Consolidate layouts and improve the performance of layout queries
- Organize the core models of the Maybe domain (i.e. Account::Entry, Account::Transaction, etc.) and break out specific traits of each model into dedicated concerns for better readability
- Remove stale / dead code from codebase
- Remove overly complex code paths in favor of simpler ones
This commit is contained in:
Zach Gollwitzer 2025-02-21 11:57:59 -05:00 committed by GitHub
parent 8539ac7dec
commit d75be2282b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
278 changed files with 3428 additions and 4354 deletions

View file

@ -1,48 +0,0 @@
<%# locals: (accountable_group:) %>
<% text_class = accountable_text_class(accountable_group.name) %>
<details class="open:bg-gray-25 group">
<summary class="flex p-4 items-center w-full rounded-lg font-medium hover:bg-gray-50 text-secondary text-sm font-medium cursor-pointer">
<%= lucide_icon("chevron-down", class: "hidden group-open:block w-5 h-5") %>
<%= lucide_icon("chevron-right", class: "group-open:hidden w-5 h-5") %>
<div class="ml-4 h-2.5 w-2.5 rounded-full <%= accountable_bg_class(accountable_group.name) %>"></div>
<p class="text-primary ml-2"><%= to_accountable_title(Accountable.from_type(accountable_group.name)) %></p>
<span class="mx-1">&middot;</span>
<div><%= accountable_group.children.count %></div>
<div class="ml-auto text-right flex items-center gap-10 text-sm font-medium text-primary">
<div class="flex items-center justify-end gap-2 w-24">
<%= render partial: "shared/progress_circle", locals: { progress: accountable_group.percent_of_total, text_class: text_class } %>
<p><%= accountable_group.percent_of_total.round(1) %>%</p>
</div>
<div class="w-24">
<p><%= format_money accountable_group.sum %></p>
</div>
<div class="w-40">
<%= render partial: "shared/trend_change", locals: { trend: accountable_group.series.trend } %>
</div>
</div>
</summary>
<div class="px-4 py-3 space-y-4">
<% accountable_group.children.map do |account_value_node| %>
<div class="flex items-center justify-between text-sm font-medium text-primary">
<div class="flex items-center gap-4 overflow-hidden">
<%= render "accounts/logo", account: account_value_node.original, size: "sm" %>
<div class="truncate">
<p><%= account_value_node.name %></p>
</div>
</div>
<div class="flex gap-10 items-center text-right">
<div class="flex items-center justify-end gap-2 w-24">
<%= render partial: "shared/progress_circle", locals: { progress: account_value_node.percent_of_total, text_class: text_class } %>
<p><%= account_value_node.percent_of_total %>%</p>
</div>
<div class="w-24">
<p><%= format_money account_value_node.original.balance_money %></p>
</div>
<div class="w-40">
<%= render partial: "shared/trend_change", locals: { trend: account_value_node.original.series.trend } %>
</div>
</div>
</div>
<% end %>
</div>
</details>

View file

@ -1,17 +0,0 @@
<%# locals: (account_groups:) %>
<div class="space-y-4">
<div class="flex gap-1">
<% account_groups.sort_by(&:percent_of_total).reverse.each do |group| %>
<div class="h-1.5 rounded-sm w-12 <%= accountable_bg_class(group.name) %>" style="width: <%= group.percent_of_total %>%;"></div>
<% end %>
</div>
<div class="flex gap-4">
<% account_groups.sort_by(&:percent_of_total).reverse.each do |group| %>
<div class="flex items-center gap-2 text-sm">
<div class="h-2.5 w-2.5 rounded-full <%= accountable_bg_class(group.name) %>"></div>
<p class="text-secondary"><%= to_accountable_title(Accountable.from_type(group.name)) %></p>
<p class="text-black"><%= group.percent_of_total.round(1) %>%</p>
</div>
<% end %>
</div>
</div>

View file

@ -1,20 +0,0 @@
<%# locals: (account_groups:) %>
<div class="bg-gray-25 p-1 rounded-xl">
<div class="px-4 py-2 flex items-center uppercase text-xs font-medium text-secondary">
<div>Name</div>
<div class="ml-auto text-right flex items-center gap-10">
<div class="w-24">
<p>% of total</p>
</div>
<div class="w-24">
<p>Value</p>
</div>
<div class="w-40">
<p>Change</p>
</div>
</div>
</div>
<div class="bg-white border border-alpha-black-25 shadow-xs rounded-lg divide-y divide-alpha-black-50">
<%= render partial: "pages/account_group_disclosure", collection: account_groups.sort_by(&:name), as: :accountable_group %>
</div>
</div>

View file

@ -1,30 +1,21 @@
<% content_for :sidebar do %>
<%= render "settings/nav" %>
<% end %>
<%= content_for :page_title, t(".title") %>
<div class="space-y-4 flex flex-col h-full">
<h1 class="text-primary text-xl font-medium mb-4"><%= t(".title") %></h1>
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4 grow overflow-y-auto">
<div class="flex justify-between gap-4 mb-12 last:mb-0">
<div class="w-1/3">
<div class="px-3 flex items-center gap-3">
<div class="text-white shrink-0 w-9 h-9">
<%= image_tag @release_notes[:avatar], class: "rounded-full w-full h-full object-cover" %>
</div>
<div>
<a class="text-primary font-medium text-sm" href="https://github.com/<%= @release_notes[:username] %>"><%= "@#{@release_notes[:username]}" %></a>
<div class="text-secondary text-sm"><%= @release_notes[:published_at].strftime("%B %d, %Y") %></div>
</div>
<div class="bg-white shadow-border-xs rounded-xl p-4 grow overflow-y-auto">
<div class="flex justify-between gap-4 mb-12 last:mb-0">
<div class="w-1/3">
<div class="px-3 flex items-center gap-3">
<div class="text-white shrink-0 w-9 h-9">
<%= image_tag @release_notes[:avatar], class: "rounded-full w-full h-full object-cover" %>
</div>
<div>
<a class="text-primary font-medium text-sm" href="https://github.com/<%= @release_notes[:username] %>"><%= "@#{@release_notes[:username]}" %></a>
<div class="text-secondary text-sm"><%= @release_notes[:published_at].strftime("%B %d, %Y") %></div>
</div>
</div>
<div class="w-2/3 text-secondary text-sm prose prose--github-release-notes">
<h2 class="mb-5 text-xl text-primary"><%= @release_notes[:name] %></h2>
<%= @release_notes[:body].html_safe %>
</div>
</div>
<div class="w-2/3 text-secondary text-sm prose prose--github-release-notes">
<h2 class="mb-5 text-xl text-primary"><%= @release_notes[:name] %></h2>
<%= @release_notes[:body].html_safe %>
</div>
</div>
<div class="mt-auto">
<%= settings_nav_footer %>
</div>
</div>

View file

@ -1,203 +1,28 @@
<div class="space-y-4">
<% if self_hosted? %>
<% if Current.family&.synth_overage? %>
<div class="bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-3 rounded relative" role="alert">
Your Synth API credit limit has been exceeded. Please visit your <a href="https://dashboard.synthfinance.com/settings" class="font-medium underline hover:text-yellow-900">Synth billing settings</a> to upgrade your plan or wait for your credits to reset.
</div>
<% elsif !Current.family&.synth_valid? %>
<div class="bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-3 rounded relative" role="alert">
Your Synth API Key is invalid. Please visit your <a href="https://dashboard.synthfinance.com/dashboard" class="font-medium underline hover:text-yellow-900">Synth dashboard</a> and verify that your API key is correct.
</div>
<% end %>
<% end %>
<header class="flex items-center justify-between">
<div>
<h1 class="sr-only"><%= t(".title") %></h1>
<p class="text-xl font-medium text-primary mb-1">
<%= Current.user.first_name.present? ? t(".greeting", name: Current.user.first_name ) : t(".fallback_greeting") %>
</p>
<% unless @accounts.blank? %>
<p class="text-secondary text-sm"><%= t(".subtitle") %></p>
<% end %>
</div>
<div class="w-full space-y-6 pb-24">
<header class="space-y-6">
<nav class="flex items-center gap-2">
<button data-action="sidebar#toggle" class="w-9 h-9 inline-flex rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer">
<%= icon("panel-left", color: "gray") %>
</button>
<div class="flex items-center gap-2">
<%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= contextual_menu_modal_action_item t(".import"), new_import_path, icon: "hard-drive-upload" %>
</div>
<% end %>
<span class="text-sm text-gray-500 font-medium">Home</span>
<%= 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") %>
<span><%= t(".new") %></span>
<% end %>
<%= icon("chevron-right", color: "gray", size: "sm") %>
<span class="text-gray-900 font-medium text-sm">Dashboard</span>
</nav>
<div class="space-y-1">
<h1 class="text-3xl font-medium text-gray-900">Welcome back, <%= Current.user.first_name %></h1>
<p class="text-gray-500">Here's what's happening with your money this week</p>
</div>
</header>
<% if @accounts.empty? %>
<%= render "shared/no_account_empty_state" %>
<% else %>
<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 |form| %>
<%= period_select form: form, selected: @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 mt-auto">
<% @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-primary font-medium hover:bg-gray-25", data: { controller: "tooltip" } do %>
<%= render "accounts/logo", account: account, size: "sm" %>
<span>+<%= Money.new(account.income, account.currency) %></span>
<%= render partial: "shared/text_tooltip", locals: { tooltip_text: account.name } %>
<% 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-secondary">+<%= @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="mt-auto 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-primary font-medium hover:bg-gray-25", data: { controller: "tooltip" } do %>
<%= render "accounts/logo", account: account, size: "sm" %>
-<%= Money.new(account.spending, account.currency) %>
<%= render partial: "shared/text_tooltip", locals: { tooltip_text: account.name } %>
<% 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-secondary">+<%= @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)*100,
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| %>
<% unless account.savings_rate.infinite? %>
<%= link_to account, class: "border border-alpha-black-25 rounded-full p-1 pr-2 flex items-center gap-1 text-xs text-primary font-medium hover:bg-gray-25", data: { controller: "tooltip" } do %>
<%= render "accounts/logo", account: account, size: "sm" %>
<span><%= account.savings_rate > 0 ? "+" : "-" %><%= number_to_percentage(account.savings_rate.abs * 100, precision: 2) %></span>
<%= render partial: "shared/text_tooltip", locals: { tooltip_text: account.name } %>
<% end %>
<% 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-secondary">+<%= @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="w-full">
<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-primary"><%= t(".transactions") %></h2>
<% if @transaction_entries.empty? %>
<div class="text-secondary flex items-center justify-center py-12">
<p><%= t(".no_transactions") %></p>
</div>
<% else %>
<div class="text-secondary p-1 space-y-1 bg-gray-25 rounded-xl">
<%= entries_by_date(@transaction_entries, selectable: false) do |entries, _transfers| %>
<%= render entries, selectable: false %>
<% end %>
<section class="bg-white py-4 rounded-xl shadow-border-xs">
<%= render partial: "pages/dashboard/net_worth_chart", locals: { series: @balance_sheet.net_worth_series(period: @period), period: @period } %>
</section>
<p class="py-2 text-sm text-center"><%= link_to t(".view_all"), transactions_path %></p>
</div>
<% end %>
</div>
</section>
<% end %>
<section>
<%= render "pages/dashboard/balance_sheet", balance_sheet: @balance_sheet %>
</section>
</div>

View file

@ -1,29 +0,0 @@
<%# locals: (account_groups:) -%>
<div data-controller="tabs" data-tabs-active-class="bg-white border-alpha-black-25 shadow-xs text-primary" data-tabs-default-tab-value="asset-tab">
<div class="bg-gray-25 rounded-lg p-1 flex gap-1 text-sm text-secondary font-medium">
<button data-id="asset-tab" class="w-1/2 px-2 py-1 rounded-md border border-transparent" data-tabs-target="btn" data-action="tabs#select"><%= t(".assets") %></button>
<button data-id="liability-tab" class="w-1/2 px-2 py-1 rounded-md border border-transparent" data-tabs-target="btn" data-action="tabs#select"><%= t(".debts") %></button>
</div>
<div>
<div data-tabs-target="tab" id="asset-tab" class="space-y-6">
<div class="text-secondary flex items-center justify-center py-6">
<div
data-controller="pie-chart"
class="w-full aspect-1"
data-pie-chart-data-value="<%= value_group_pie_data(account_groups[:assets]) %>"
data-pie-chart-total-value="<%= format_money(account_groups[:assets].sum, precision: 0) %>">
</div>
</div>
</div>
<div data-tabs-target="tab" id="liability-tab" class="space-y-6 hidden">
<div class="text-secondary flex items-center justify-center py-6">
<div
data-controller="pie-chart"
class="w-full aspect-1"
data-pie-chart-data-value="<%= value_group_pie_data(account_groups[:liabilities]) %>"
data-pie-chart-total-value="<%= format_money(account_groups[:liabilities].sum, precision: 0) %>">
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,103 @@
<%# locals: (balance_sheet:) %>
<div class="space-y-4">
<% balance_sheet.classification_groups.each do |classification_group| %>
<div class="bg-white shadow-border-xs rounded-xl space-y-4 p-4">
<h2 class="text-lg font-medium"><%= classification_group.display_name %></h2>
<% if classification_group.account_groups.any? %>
<div class="space-y-4">
<div class="flex gap-1">
<% classification_group.account_groups.each do |account_group| %>
<div class="h-1.5 rounded-sm" style="width: <%= account_group.weight %>%; background-color: <%= account_group.color %>;"></div>
<% end %>
</div>
<div class="flex gap-4">
<% classification_group.account_groups.each do |account_group| %>
<div class="flex items-center gap-2 text-sm">
<div class="h-2.5 w-2.5 rounded-full" style="background-color: <%= account_group.color %>;"></div>
<p class="text-secondary"><%= account_group.name %></p>
<p class="text-black"><%= number_to_percentage(account_group.weight, precision: 0) %></p>
</div>
<% end %>
</div>
</div>
<div class="bg-surface rounded-xl p-1 space-y-1">
<div class="px-4 py-2 flex items-center uppercase text-xs font-medium text-secondary">
<div>Name</div>
<div class="ml-auto text-right flex items-center gap-6">
<div class="w-24">
<p>Weight</p>
</div>
<div class="w-40">
<p>Value</p>
</div>
</div>
</div>
<div class="shadow-border-xs rounded-lg bg-white">
<% classification_group.account_groups.each do |account_group| %>
<details class="group rounded-lg open:bg-surface font-medium text-sm">
<summary class="cursor-pointer p-4 group-open:bg-surface bg-white rounded-lg flex items-center justify-between">
<div class="flex items-center gap-4">
<%= lucide_icon("chevron-right", class: "group-open:rotate-90 text-secondary w-5 h-5") %>
<p><%= account_group.name %></p>
</div>
<div class="ml-auto flex items-center text-right gap-6">
<div class="w-24 flex items-center justify-end gap-2">
<%= render partial: "shared/progress_circle", locals: { progress: account_group.weight, color: account_group.color } %>
<p><%= number_to_percentage(account_group.weight, precision: 0) %></p>
</div>
<div class="w-40">
<p><%= format_money(account_group.total_money) %></p>
</div>
</div>
</summary>
<div>
<% account_group.accounts.each_with_index do |account, idx| %>
<div class="pl-12 pr-4 py-3 flex items-center justify-between text-sm font-medium">
<div class="flex items-center gap-3">
<%= render "accounts/logo", account: account, size: "sm", color: account_group.color %>
<%= link_to account.name, account_path(account) %>
</div>
<div class="ml-auto flex items-center text-right gap-6">
<div class="w-24 flex items-center justify-end gap-2">
<%= render partial: "shared/progress_circle", locals: { progress: account.weight, color: account_group.color } %>
<p><%= number_to_percentage(account.weight, precision: 0) %></p>
</div>
<div class="w-40">
<p><%= format_money(account.balance_money) %></p>
</div>
</div>
</div>
<% if idx < account_group.accounts.size - 1 %>
<div class="pl-[84px] pr-40">
<div class="w-full border-subdued border-b"></div>
</div>
<% end %>
<% end %>
</div>
</details>
<% end %>
</div>
</div>
<% else %>
<div class="py-20 flex flex-col items-center">
<%= lucide_icon classification_group.icon, class: "w-6 h-6 shrink-0 text-secondary" %>
<p class="text-primary text-sm font-medium mb-1 mt-4">No <%= classification_group.display_name %></p>
<p class="text-secondary text-sm max-w-xs text-center"><%= "You have no #{classification_group.display_name}" %></p>
</div>
<% end %>
</div>
<% end %>
</div>

View file

@ -1,16 +1,37 @@
<%# locals: (series:) %>
<% if series.has_current_day_value? %>
<%# locals: (series:, period:) %>
<div class="flex justify-between p-4">
<div class="space-y-2">
<div class="space-y-2">
<p class="text-sm text-secondary font-medium">Net Worth</p>
<p class="text-primary -space-x-0.5 text-xl font-medium">
<%= series.current.format %>
</p>
<% if series.trend.nil? %>
<p class="text-sm text-secondary">Data not available for the selected period</p>
<% elsif series.trend.direction.flat? %>
<p class="text-sm text-secondary">No change vs. prior period</p>
<% else %>
<div class="flex items-center gap-2">
<%= render partial: "shared/trend_change", locals: { trend: series.trend } %>
<span class="text-sm text-secondary"><%= period.comparison_label %></span>
</div>
<% end %>
</div>
</div>
<%= 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 %>
<% end %>
</div>
<% if series.any? %>
<div
id="netWorthChart"
class="w-full flex-1 min-h-52"
data-controller="time-series-chart"
data-time-series-chart-data-value="<%= series.to_json %>"></div>
<% elsif series.empty? %>
<% else %>
<div class="w-full h-full flex items-center justify-center">
<p class="text-secondary text-sm">No data available for the selected period.</p>
</div>
<% else %>
<div class="w-full h-full flex items-center justify-center">
<p class="text-secondary text-sm animate-pulse">Calculating latest balance data...</p>
</div>
<% end %>

View file

@ -0,0 +1,15 @@
<div class="flex justify-center items-center h-[800px]">
<div class="text-center flex flex-col gap-4 items-center max-w-[300px]">
<%= lucide_icon "layers", class: "w-6 h-6 text-secondary" %>
<div class="space-y-1 text-sm">
<p class="text-primary font-medium"><%= t(".no_account_title") %></p>
<p class="text-secondary"><%= t(".no_account_subtitle") %></p>
</div>
<%= 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") %>
<span><%= t(".new_account") %></span>
<% end %>
</div>
</div>

View file

@ -1,35 +1,28 @@
<% content_for :sidebar do %>
<%= render "settings/nav" %>
<% end %>
<%= content_for :page_title, "Feedback" %>
<div class="space-y-4">
<h1 class="text-primary text-xl font-medium mb-4">Feedback</h1>
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4">
<h2 class="text-lg font-medium text-primary mb-1">Leave feedback</h2>
<p class="text-sm text-secondary mb-4">Let us know if you have any specific feedback. Feel free to include links to videos or screenshots.</p>
<div class="flex gap-2">
<%= link_to "https://github.com/maybe-finance/maybe/discussions/categories/feature-requests", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<div class="bg-white shadow-border-xs rounded-xl p-4">
<h2 class="text-lg font-medium text-primary mb-1">Leave feedback</h2>
<p class="text-sm text-secondary mb-4">Let us know if you have any specific feedback. Feel free to include links to videos or screenshots.</p>
<div class="flex gap-2">
<%= link_to "https://github.com/maybe-finance/maybe/discussions/categories/feature-requests", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Write a feature request</span>
<% end %>
<% if self_hosted? %>
<%= link_to "https://github.com/maybe-finance/maybe/issues/new?assignees=&labels=bug&template=bug_report.md&title=", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Write a feature request</span>
<span class="text-sm font-medium text-primary">File a bug report</span>
<% end %>
<% if self_hosted? %>
<%= link_to "https://github.com/maybe-finance/maybe/issues/new?assignees=&labels=bug&template=bug_report.md&title=", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">File a bug report</span>
<% end %>
<% else %>
<%= link_to "mailto:hello@maybefinance.com", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50", onclick: "Intercom('showNewMessage'); return false;" do %>
<%= lucide_icon "bug", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">File a bug report</span>
<% end %>
<% else %>
<%= link_to "mailto:hello@maybefinance.com", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50", onclick: "Intercom('showNewMessage'); return false;" do %>
<%= lucide_icon "bug", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">File a bug report</span>
<% end %>
<% end %>
<%= link_to "https://link.maybe.co/discord", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "discord-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Discuss Maybe with others</span>
<% end %>
</div>
<%= link_to "https://link.maybe.co/discord", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "discord-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Discuss Maybe with others</span>
<% end %>
</div>
<%= settings_nav_footer %>
</div>