1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-19 05:09:38 +02:00

Added lints for ERB templates (#609)

* Added erblint and fixed offenses

* Added erblint bintstub. Included erblint into CI

* Merged GitHub Actions tasks for rubocop and erblint into one

* Added config for erblint.

* Reverted erblint call in the CI
This commit is contained in:
Igor Alexandrov 2024-04-09 16:08:58 +04:00 committed by GitHub
parent 21e2d05d0c
commit b5c56f7775
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 201 additions and 160 deletions

9
.erb-lint.yml Normal file
View file

@ -0,0 +1,9 @@
EnableDefaultLinters: true
linters:
Rubocop:
enabled: true
only: [Style/StringLiterals]
rubocop_config:
Style/StringLiterals:
Enabled: true
EnforcedStyle: double_quotes

View file

@ -54,6 +54,9 @@ jobs:
- name: Lint code for consistent style
run: bin/rubocop -f github
- name: Lint templates for consistent style
run: ./bin/erblint ./app/**/*.erb
test:
runs-on: ubuntu-latest
timeout-minutes: 10

View file

@ -48,6 +48,7 @@ group :development, :test do
gem "dotenv-rails"
gem "letter_opener"
gem "i18n-tasks"
gem "erb_lint"
end
group :development do

View file

@ -148,6 +148,13 @@ GEM
dotenv (= 3.1.0)
railties (>= 6.1)
drb (2.2.1)
erb_lint (0.5.0)
activesupport
better_html (>= 2.0.1)
parser (>= 2.7.1.4)
rainbow
rubocop
smart_properties
erubi (1.12.0)
et-orbi (1.2.11)
tzinfo
@ -418,6 +425,7 @@ DEPENDENCIES
capybara
debug
dotenv-rails
erb_lint
faraday
good_job
hotwire-livereload

View file

@ -20,4 +20,4 @@
<% end %>
</div>
</div>
<% end%>
<% end %>

View file

@ -21,7 +21,7 @@
<p class="ml-auto font-medium"><%= format_money account_value_node.original.balance_money %></p>
<% end %>
<% end %>
<%= link_to new_account_path(step: 'method', type: type.name.demodulize), class: "flex items-center gap-4 px-2 py-3 mb-1 text-gray-500 text-sm font-medium rounded-[10px] hover:bg-gray-100", data: { turbo_frame: "modal" } do %>
<%= link_to new_account_path(step: "method", type: type.name.demodulize), class: "flex items-center gap-4 px-2 py-3 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") %>
<p>New <%= type.model_name.human.downcase %></p>
<% end %>

View file

@ -1,4 +1,4 @@
<%= link_to new_account_path(step: 'method', type: type.class.name.demodulize), class: "flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-25 border border-transparent focus:border focus:border-gray-200 block px-2 hover:bg-gray-25 rounded-lg p-2" do %>
<%= link_to new_account_path(step: "method", type: type.class.name.demodulize), class: "flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-25 border border-transparent focus:border focus:border-gray-200 block px-2 hover:bg-gray-25 rounded-lg p-2" do %>
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg <%= bg_color %> border border-alpha-black-25">
<%= lucide_icon(icon, class: "#{text_color} w-5 h-5") %>
</span>

View file

@ -27,14 +27,12 @@
<div class="relative w-[72px]" data-controller="menu">
<button
data-menu-target="button"
class="ml-auto flex items-center justify-center hover:bg-gray-50 w-8 h-8 rounded-lg"
>
class="ml-auto flex items-center justify-center hover:bg-gray-50 w-8 h-8 rounded-lg">
<%= lucide_icon("more-horizontal", class: "w-5 h-5 text-gray-500") %>
</button>
<div
data-menu-target="content"
class="absolute min-w-[200px] z-10 top-10 right-0 bg-white p-1 rounded-sm shadow-xs border border-alpha-black-25 w-fit"
>
class="absolute min-w-[200px] z-10 top-10 right-0 bg-white p-1 rounded-sm shadow-xs border border-alpha-black-25 w-fit">
<%= link_to edit_valuation_path(valuation.original),
class: "flex gap-1 items-center hover:bg-gray-50 rounded-md p-2" do %>
<%= lucide_icon("pencil-line", class: "w-5 h-5 text-gray-500 shrink-0") %>
@ -42,9 +40,9 @@
<% end %>
<%= link_to valuation_path(valuation.original),
data: { turbo_method: :delete,
turbo_confirm: { title: t('custom_turbo_confirm.history.title'),
body: t('custom_turbo_confirm.history.body_html'),
accept: t('custom_turbo_confirm.history.accept') } },
turbo_confirm: { title: t("custom_turbo_confirm.history.title"),
body: t("custom_turbo_confirm.history.body_html"),
accept: t("custom_turbo_confirm.history.accept") } },
class: "text-red-600 flex gap-1 items-center hover:bg-gray-50 rounded-md p-2" do %>
<%= lucide_icon("trash-2", class: "w-5 h-5 shrink-0") %>
<span class="text-sm">Delete entry</span>

View file

@ -3,7 +3,7 @@
<h1 class="text-xl font-medium text-gray-900">Accounts</h1>
<%= 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_account') %></span>
<span><%= t(".new_account") %></span>
<% end %>
</div>
<% if Current.family.accounts.empty? %>
@ -13,7 +13,7 @@
<p class="text-gray-500 mb-4">Add an account either via connection, importing or entering manually.</p>
<%= 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", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<span><%= t('.new_account') %></span>
<span><%= t(".new_account") %></span>
<% end %>
</div>
</div>
@ -40,7 +40,7 @@
<p><%= to_accountable_title(Accountable.from_type(group)) %></p>
<span class="text-gray-400 mx-2">&middot;</span>
<p><%= accounts.count %></p>
<p class="ml-auto"><%= format_money accounts.sum(&:balance_money) %></p>
<p class="ml-auto"><%= format_money accounts.sum(&:balance_money) %></p>
</div>
<div class="bg-white">
<% accounts.each do |account| %>

View file

@ -1,9 +1,9 @@
<h1 class="text-3xl font-semibold font-display"><%= t('.title')%></h1>
<h1 class="text-3xl font-semibold font-display"><%= t(".title") %></h1>
<%= modal do %>
<div class="flex flex-col min-h-[530px]" data-controller="list-keyboard-navigation">
<% if @account.accountable.blank? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400">
<%= t '.select_accountable_type' %>
<%= t ".select_accountable_type" %>
</div>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
@ -20,10 +20,10 @@
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("corner-down-left", class: "inline w-3 h-3") %></kbd>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("arrow-up", class: "inline w-3 h-3") %></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("arrow-down", class: "inline w-3 h-3") %></kbd>
</div>
</div>
<div class="flex items-center space-x-2">
@ -33,24 +33,24 @@
<% elsif params[:step] == 'method' && @account.accountable.present? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400 flex items-center space-x-3">
<%= link_to new_account_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 back focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<%= lucide_icon("arrow-left", class: "text-gray-500 w-5 h-5") %>
<% end %>
<span>How would you like to add it?</span>
</div>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
<button hidden data-controller="hotkey" data-hotkey="j,J,ArrowDown,ArrowRight" data-action="list-keyboard-navigation#focusNext">Next</button>
<%= render "entry_method", type: @account.accountable, text: 'Enter account balance manually', icon: "keyboard" %>
<%= render "entry_method", type: @account.accountable, text: 'Securely link bank account with data provider (coming soon)', icon: "link-2", disabled: true %>
<%= render "entry_method", type: @account.accountable, text: 'Upload spreadsheet (coming soon)', icon: "sheet", disabled: true %>
<%= render "entry_method", type: @account.accountable, text: "Enter account balance manually", icon: "keyboard" %>
<%= render "entry_method", type: @account.accountable, text: "Securely link bank account with data provider (coming soon)", icon: "link-2", disabled: true %>
<%= render "entry_method", type: @account.accountable, text: "Upload spreadsheet (coming soon)", icon: "sheet", disabled: true %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("corner-down-left", class: "inline w-3 h-3") %></kbd>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("arrow-up", class: "inline w-3 h-3") %></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon("arrow-down", class: "inline w-3 h-3") %></kbd>
</div>
</div>
<div class="flex items-center space-x-2">
@ -59,17 +59,17 @@
</div>
<% else %>
<div class="border-b border-alpha-black-25 p-4 text-gray-800 flex items-center space-x-3">
<%= link_to new_account_path(step: 'method', type: params[:type]), class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<%= link_to new_account_path(step: "method", type: params[:type]), class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon("arrow-left", class: "text-gray-500 w-5 h-5") %>
<% end %>
<span>Add <%= @account.accountable.model_name.human.downcase %></span>
</div>
<%= form_with model: @account, url: accounts_path, scope: :account, html: { class: "m-5 mt-1 flex flex-col justify-between grow", data: { turbo: false } } do |f| %>
<div class="space-y-4 grow">
<%= f.hidden_field :accountable_type %>
<%= f.text_field :name, placeholder: t('accounts.new.name.placeholder'), required: 'required', label: t('accounts.new.name.label'), autofocus: true %>
<%= f.text_field :name, placeholder: t("accounts.new.name.placeholder"), required: "required", label: t("accounts.new.name.label"), autofocus: true %>
<%= render "accounts/#{permitted_accountable_partial(@account.accountable_type)}", f: f %>
<%= f.money_field :balance_money, label: "Balance", required: 'required' %>
<%= f.money_field :balance_money, label: "Balance", required: "required" %>
</div>
<%= f.submit "Add #{@account.accountable.model_name.human.downcase}" %>
<% end %>

View file

@ -51,8 +51,7 @@
period: @period,
balance: @account.balance_money,
trend: @balance_series.trend
}
%>
} %>
</div>
<%= form_with url: account_path(@account), method: :get, class: "flex items-center gap-4", data: { controller: "auto-submit-form" } do %>
<%= render partial: "shared/period_select", locals: { value: @period.name } %>

View file

@ -29,7 +29,7 @@
<div class="flex-col p-5 min-w-80">
<div class="flex items-center justify-between">
<%= link_to root_path do %>
<%= image_tag 'logo.svg', alt: 'Maybe', class: "h-[22px]" %>
<%= image_tag "logo.svg", alt: "Maybe", class: "h-[22px]" %>
<% end %>
<div class="relative" data-controller="menu">
<button data-menu-target="button">
@ -37,8 +37,7 @@
</button>
<div
data-menu-target="content"
class="hidden absolute min-w-[200px] z-10 top-10 right-0 bg-white p-1 rounded-sm shadow-xs border border-alpha-black-25 w-fit"
>
class="hidden absolute min-w-[200px] z-10 top-10 right-0 bg-white p-1 rounded-sm shadow-xs border border-alpha-black-25 w-fit">
<%= link_to edit_settings_path, class: "flex gap-1 items-center hover:bg-gray-50 rounded-md p-2" do %>
<%= lucide_icon("pencil-line", class: "w-5 h-5 text-gray-500 shrink-0") %>
<span class="text-gray-900 text-sm">Settings</span>
@ -53,31 +52,31 @@
<nav>
<ul class="mt-6 space-y-1">
<li>
<%= sidebar_link_to t('.dashboard'), root_path, icon: 'layout-grid' %>
<%= sidebar_link_to t(".dashboard"), root_path, icon: "layout-grid" %>
</li>
<li>
<%= sidebar_link_to t('.accounts'), accounts_path, icon: 'layers' %>
<%= sidebar_link_to t(".accounts"), accounts_path, icon: "layers" %>
</li>
<li>
<%= sidebar_link_to t('.transactions'), transactions_path, icon: 'credit-card' %>
<%= sidebar_link_to t(".transactions"), transactions_path, icon: "credit-card" %>
</li>
</ul>
</nav>
<div class="flex flex-col mt-6">
<div class="flex items-center justify-between">
<%= link_to accounts_path, class: 'text-xs uppercase text-gray-500 font-bold tracking-wide' do%>
<%= t('.accounts') %>
<%= link_to accounts_path, class: "text-xs uppercase text-gray-500 font-bold tracking-wide" do %>
<%= t(".accounts") %>
<% end %>
<%= link_to new_account_path, class: 'block hover:bg-gray-100 p-2 text-sm font-semibold text-gray-900 flex items-center rounded', title: t('.new_account'), data: { turbo_frame: "modal" } do %>
<%= link_to new_account_path, class: "block hover:bg-gray-100 p-2 text-sm font-semibold text-gray-900 flex items-center rounded", title: t(".new_account"), data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-500") %>
<% end %>
</div>
<%= link_to new_account_path, class: "flex items-center gap-4 px-2 py-3 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") %>
<p><%= t('.new_account') %></p>
<p><%= t(".new_account") %></p>
<% end %>
<% account_groups.each do |group| %>
<%= render 'accounts/account_list', group: group %>
<%= render "accounts/account_list", group: group %>
<% end %>
</div>
</div>
@ -86,6 +85,6 @@
</main>
</div>
<%= turbo_frame_tag "modal" %>
<%= render 'shared/custom_confirm_modal' %>
<%= render "shared/custom_confirm_modal" %>
</body>
</html>

View file

@ -33,16 +33,16 @@
<%= render "shared/logo" %>
<h2 class="mt-6 text-3xl font-semibold tracking-tight text-center font-display">
<%= content_for?(:header_title) ? yield(:header_title).html_safe : t('.your_account') %>
<%= content_for?(:header_title) ? yield(:header_title).html_safe : t(".your_account") %>
</h2>
<% if controller_name == "sessions" %>
<p class="mt-2 text-sm text-center text-gray-600">
<%= t('.or') %> <%= link_to t('.sign_up'), new_registration_path, class: 'font-medium text-gray-600 hover:text-gray-400 transition' %>
<%= t(".or") %> <%= link_to t(".sign_up"), new_registration_path, class: "font-medium text-gray-600 hover:text-gray-400 transition" %>
</p>
<% elsif controller_name == "registrations" %>
<p class="mt-2 text-sm text-center text-gray-600">
<%= t('.or') %> <%= link_to t('.sign_in'), new_session_path, class: 'font-medium text-gray-600 hover:text-gray-400 transition' %>
<%= t(".or") %> <%= link_to t(".sign_in"), new_session_path, class: "font-medium text-gray-600 hover:text-gray-400 transition" %>
</p>
<% end %>
@ -53,7 +53,7 @@
</div>
<div class="p-8 mt-2 text-center">
<p class="mt-6 text-sm text-black"><%= link_to t('.privacy_policy'), "/privacy", class: "font-medium text-gray-600 hover:text-gray-400 transition" %> &bull; <%= link_to t('.terms_of_service'), "/terms", class: "font-medium text-gray-600 hover:text-gray-400 transition" %></p>
<p class="mt-6 text-sm text-black"><%= link_to t(".privacy_policy"), "/privacy", class: "font-medium text-gray-600 hover:text-gray-400 transition" %> &bull; <%= link_to t(".terms_of_service"), "/terms", class: "font-medium text-gray-600 hover:text-gray-400 transition" %></p>
</div>
</div>

View file

@ -7,7 +7,7 @@
<div class="ml-4 h-2.5 w-2.5 rounded-full <%= accountable_bg_class(accountable_group.name) %>"></div>
<p class="text-gray-900 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><%= accountable_group.children.count %></div>
<div class="ml-auto text-right flex items-center gap-10 text-sm font-medium text-gray-900">
<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 } %>

View file

@ -1,8 +1,8 @@
<div class="space-y-4">
<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 font-medium"><%= Date.current.strftime('%A, %b %d') %></p>
<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 font-medium"><%= Date.current.strftime("%A, %b %d") %></p>
</div>
<section class="bg-white rounded-xl shadow-xs border border-alpha-black-25">
<div class="flex justify-between p-4">
@ -12,8 +12,7 @@
period: @period,
balance: 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 } %>
@ -37,8 +36,7 @@
id="assetsTrendline"
class="h-full w-2/5"
data-trendline-series-value="<%= @asset_series.to_json %>"
data-trendline-classification-value="asset"
></div>
data-trendline-classification-value="asset"></div>
</div>
<div class="w-1/2 p-4 flex items-stretch justify-between">
<div class="space-y-2 grow">
@ -55,8 +53,7 @@
id="liabilitiesTrendline"
class="h-full w-2/5"
data-trendline-series-value="<%= @liability_series.to_json %>"
data-trendline-classification-value="liability"
></div>
data-trendline-classification-value="liability"></div>
</div>
</div>
</section>
@ -70,7 +67,7 @@
<div class="flex items-center gap-2">
<%= link_to new_account_path, class: "flex items-center gap-1 p-2 text-gray-900 text-sm font-medium bg-gray-50 rounded-lg hover:bg-gray-100", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-500") %>
<p><%= t('.new') %></p>
<p><%= t(".new") %></p>
<% end %>
<%= 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 } %>

View file

@ -1 +1 @@
<%= link_to t('.cta'), edit_password_reset_url(token: params[:token]) %>
<%= link_to t(".cta"), edit_password_reset_url(token: params[:token]) %>

View file

@ -1,21 +1,21 @@
<%
header_title t('.title')
header_title t(".title")
%>
<%= form_with url: password_reset_path(token: params[:token]), html: {class: 'space-y-6'} do |form| %>
<%= form_with url: password_reset_path(token: params[:token]), html: {class: "space-y-6"} do |form| %>
<%= auth_messages form %>
<div class="relative border border-gray-100 bg-gray-25 rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
<%= form.label :password, class: 'p-4 pb-0 block text-sm font-medium text-gray-700' %>
<%= form.password_field :password, required: 'required', class: 'p-4 pt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100 w-full' %>
<%= form.label :password, class: "p-4 pb-0 block text-sm font-medium text-gray-700" %>
<%= form.password_field :password, required: "required", class: "p-4 pt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100 w-full" %>
</div>
<div class="relative border border-gray-100 bg-gray-25 rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
<%= form.label :password_confirmation, class: 'p-4 pb-0 block text-sm font-medium text-gray-700' %>
<%= form.password_field :password_confirmation, required: 'required', class: 'p-4 pt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100 w-full' %>
<%= form.label :password_confirmation, class: "p-4 pb-0 block text-sm font-medium text-gray-700" %>
<%= form.password_field :password_confirmation, required: "required", class: "p-4 pt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100 w-full" %>
</div>
<div>
<%= form.submit t('.submit'), class: 'flex justify-center w-full px-4 py-3 text-sm font-medium text-white bg-black rounded-xl hover:bg-black focus:outline-none focus:ring-2 focus:ring-gray-200 shadow' %>
<%= form.submit t(".submit"), class: "flex justify-center w-full px-4 py-3 text-sm font-medium text-white bg-black rounded-xl hover:bg-black focus:outline-none focus:ring-2 focus:ring-gray-200 shadow" %>
</div>
<% end %>

View file

@ -1,11 +1,11 @@
<%
header_title t('.title')
header_title t(".title")
%>
<%= form_with url: password_reset_path do |form| %>
<%= auth_messages form %>
<%= form.email_field :email, label: true, autofocus: false, autocomplete: "email", required: 'required', placeholder: 'you@example.com' %>
<%= form.email_field :email, label: true, autofocus: false, autocomplete: "email", required: "required", placeholder: "you@example.com" %>
<%= form.submit t('.submit') %>
<%= form.submit t(".submit") %>
<% end %>

View file

@ -1,15 +1,15 @@
<h1><% t('.title')%></h1>
<h1><% t(".title") %></h1>
<%= form_with model: Current.user, url: password_path do |form| %>
<%= auth_messages form %>
<div>
<%= form.label :password_challenge, t('.password_challenge') %>
<%= form.label :password_challenge, t(".password_challenge") %>
<%= form.password_field :password_challenge %>
</div>
<div>
<%= form.label :password, t('.password') %>
<%= form.label :password, t(".password") %>
<%= form.password_field :password %>
</div>
@ -19,6 +19,6 @@
</div>
<div>
<%= form.submit t('.submit') %>
<%= form.submit t(".submit") %>
</div>
<% end %>

View file

@ -1,18 +1,18 @@
<%
header_title t('.title')
header_title t(".title")
%>
<%= form_with model: @user, url: registration_path do |form| %>
<%= auth_messages form %>
<%= form.email_field :email, autofocus: false, autocomplete: "email", required: 'required', placeholder: 'you@example.com', label: true %>
<%= form.email_field :email, autofocus: false, autocomplete: "email", required: "required", placeholder: "you@example.com", label: true %>
<%= form.password_field :password, autocomplete: "new-password", required: 'required', label: true %>
<%= form.password_field :password, autocomplete: "new-password", required: "required", label: true %>
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: 'required', label: true %>
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: "required", label: true %>
<% if hosted_app? %>
<%= form.password_field :invite_code, required: 'required', label: true %>
<%= form.password_field :invite_code, required: "required", label: true %>
<% end %>
<%= form.submit %>

View file

@ -1,17 +1,17 @@
<%
header_title t('.title')
header_title t(".title")
%>
<%= form_with url: session_path do |form| %>
<%= auth_messages form %>
<%= form.email_field :email, label: t('.email'), autofocus: false, autocomplete: "email", required: 'required', placeholder: t('.email_placeholder') %>
<%= form.email_field :email, label: t(".email"), autofocus: false, autocomplete: "email", required: "required", placeholder: t(".email_placeholder") %>
<%= form.password_field :password, label: true, required: 'required' %>
<%= form.password_field :password, label: true, required: "required" %>
<%= form.submit t('.submit') %>
<%= form.submit t(".submit") %>
<% end %>
<div class="mt-6 text-center">
<p class="text-sm text-gray-600"><%= t('.forgot_password') %> <%= link_to t('.reset_password'), new_password_reset_path, class: 'font-medium text-gray-600 hover:text-gray-400 transition' %></p>
<p class="text-sm text-gray-600"><%= t(".forgot_password") %> <%= link_to t(".reset_password"), new_password_reset_path, class: "font-medium text-gray-600 hover:text-gray-400 transition" %></p>
</div>

View file

@ -11,7 +11,7 @@
<%= form.password_field :password_confirmation, label: true %>
<div class="fixed right-5 bottom-5">
<button type="submit" class="flex items-center justify-center w-12 h-12 mb-2 bg-black rounded-full shrink-0 grow-0 hover:bg-gray-600">
<%= inline_svg_tag('icn-check.svg', class: 'text-white fill-current') %>
<%= inline_svg_tag("icn-check.svg", class: "text-white fill-current") %>
</button>
</div>
<% end %>

View file

@ -1,5 +1,5 @@
<% flash.each do |type, msg| %>
<div class="p-4 <%= type == 'notice' ? 'bg-blue-200' : 'bg-red-200' %> rounded-lg"><%= msg %></div>
<div class="p-4 <%= type == "notice" ? "bg-blue-200" : "bg-red-200" %> rounded-lg"><%= msg %></div>
<% end %>
<% errors.each do |message| %>

View file

@ -2,15 +2,15 @@
<form method="dialog" class="p-4">
<div class="flex flex-col mb-4">
<div class="flex justify-between mb-2 gap-4">
<h3 id="turbo-confirm-title" class="font-medium text-md"><%= t('custom_turbo_confirm.default.title') %></h3>
<h3 id="turbo-confirm-title" class="font-medium text-md"><%= t("custom_turbo_confirm.default.title") %></h3>
<button value="cancel">
<%= lucide_icon("x", class: "w-5 h-5 shrink-0 text-gray-500") %>
</button>
</div>
<div id="turbo-confirm-body" class="text-gray-500 text-sm">
<%= t('custom_turbo_confirm.default.body_html') %>
<%= t("custom_turbo_confirm.default.body_html") %>
</div>
</div>
<button id="turbo-confirm-accept" class="w-full text-red-600 rounded-xl text-center p-[10px] border" value="confirm"><%= t('custom_turbo_confirm.default.accept') %></button>
<button id="turbo-confirm-accept" class="w-full text-red-600 rounded-xl text-center p-[10px] border" value="confirm"><%= t("custom_turbo_confirm.default.accept") %></button>
</form>
</dialog>

View file

@ -1 +1 @@
<%= link_to image_tag("logomark.svg", class: 'w-auto h-12 mx-auto'), root_path, data: { turbo: false} %>
<%= link_to image_tag("logomark.svg", class: "w-auto h-12 mx-auto"), root_path, data: { turbo: false} %>

View file

@ -1,5 +1,5 @@
<%# locals: (value: 'last_30_days') -%>
<% options = [['7D', 'last_7_days'], ['1M', 'last_30_days'], ["1Y", "last_365_days"], ['All', 'all']] %>
<% options = [["7D", "last_7_days"], ["1M", "last_30_days"], ["1Y", "last_365_days"], ["All", "all"]] %>
<div data-controller="select" data-select-active-class="bg-alpha-black-50" class="relative" data-select-selected-value="<%= value %>">
<button type="button" data-select-target="button" class="flex items-center gap-1 w-full border border-alpha-black-100 shadow-xs rounded-lg text-sm p-2 cursor-pointer">
<span data-select-target="buttonText" class="text-gray-900 text-sm"><%= options.find { |option| option[1] == value }[0] %></span>

View file

@ -8,7 +8,7 @@
</div>
<% when "category" %>
<div class="flex items-center gap-2">
<div class="w-2 h-4 text-xs flex items-center justify-center rounded-full" style="background-color: <%= filter[:value].color %>"></div>
<div class="w-2 h-4 text-xs flex items-center justify-center rounded-full" style="background-color: <%= filter[:value].color %>"></div>
<p><%= filter[:value].name %></p>
</div>
<% when "search" %>

View file

@ -1,15 +1,15 @@
<!-- start mobile pagination -->
<div class="flex flex-1 justify-center md:hidden">
<% if pagy.prev %>
<%= link_to 'Previous', pagy_url_for(pagy, pagy.prev), class: "relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-500 hover:bg-gray-50" %>
<%= link_to "Previous", pagy_url_for(pagy, pagy.prev), class: "relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-500 hover:bg-gray-50" %>
<% else %>
<div class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-200" >Previous</div>
<div class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-200">Previous</div>
<% end %>
<% if pagy.next %>
<%= link_to 'Next', pagy_url_for(pagy, pagy.next), class: "relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-500 hover:bg-gray-50" %>
<%= link_to "Next", pagy_url_for(pagy, pagy.next), class: "relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-500 hover:bg-gray-50" %>
<% else %>
<div class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-200" >Next</div>
<div class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-200">Next</div>
<% end %>
</div>
<!-- end mobile pagination -->
@ -22,7 +22,7 @@
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-500") %>
<% end %>
<% else %>
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300" >
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300">
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-200") %>
</div>
<% end %>
@ -48,7 +48,7 @@
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-500") %>
<% end %>
<% else %>
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300" >
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300">
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-200") %>
</div>
<% end %>

View file

@ -1,7 +1,7 @@
<%# locals: (date:, transactions:) %>
<div class="bg-gray-25 rounded-xl p-1">
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-gray-500">
<h4><%= date.strftime('%b %d, %Y') %> &middot; <%= transactions.size %></h4>
<h4><%= date.strftime("%b %d, %Y") %> &middot; <%= transactions.size %></h4>
<span><%= format_money -transactions.sum(&:amount_money) %></span>
</div>
<div class="bg-white shadow-xs rounded-md border border-alpha-black-25 divide-y divide-alpha-black-50">

View file

@ -8,7 +8,7 @@
<div class="flex flex-col relative" data-controller="list-filter">
<div class="grow p-1.5">
<div class="relative flex items-center bg-white border border-gray-200 rounded-lg">
<input placeholder="Search" type="search" class="placeholder:text-sm placeholder:text-gray-500 font-normal h-10 relative pl-10 w-full border-none rounded-lg" data-list-filter-target="input" data-action="list-filter#filter" />
<input placeholder="Search" autocomplete="nope" type="search" class="placeholder:text-sm placeholder:text-gray-500 font-normal h-10 relative pl-10 w-full border-none rounded-lg" data-list-filter-target="input" data-action="list-filter#filter">
<%= lucide_icon("search", class: "w-5 h-5 text-gray-500 ml-2 absolute inset-0 transform top-1/2 -translate-y-1/2") %>
</div>
</div>
@ -21,7 +21,7 @@
<%= render partial: "transactions/categories/dropdown/row", locals: { category:, transaction: } %>
<% end %>
</div>
<hr/>
<hr>
<div data-controller="menu" class="relative p-1.5 w-full">
<button data-menu-target="button" class="flex text-sm font-medium items-center gap-2 text-gray-500 w-full rounded-lg p-2 hover:bg-gray-100">
<%= lucide_icon("plus", class: "w-5 h-5") %>

View file

@ -2,7 +2,7 @@
<div class="w-96 text-sm font-semibold leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<div class="flex flex-col">
<%= render partial: "transactions/categories/dropdown/form", locals: { category: } %>
<hr/>
<hr>
<div class="p-1.5 w-full">
<%= button_to transactions_category_path(category),
method: :delete,

View file

@ -18,7 +18,7 @@
</div>
</div>
</div>
<hr/>
<hr>
<div class="p-1.5 w-full">
<%= form.button "Create category", class: "flex text-sm font-medium items-center gap-2 text-gray-900 w-full rounded-lg p-2 hover:bg-gray-100" do %>
<%= lucide_icon("plus", class: "w-5 h-5") %> <%= category.nil? ? "Create" : "Update" %> category

View file

@ -1,7 +1,7 @@
<%# locals: (form:) %>
<div data-controller="list-filter">
<div class="relative">
<input type="search" placeholder="Filter accounts" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full border border-gray-200 rounded-md py-2 pl-10 pr-3 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm">
<input type="search" autocomplete="off" placeholder="Filter accounts" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full border border-gray-200 rounded-md py-2 pl-10 pr-3 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-gray-500 absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">

View file

@ -1,7 +1,7 @@
<%# locals: (form:) %>
<div data-controller="list-filter">
<div class="relative">
<input type="search" placeholder="Filter category" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full border border-gray-200 rounded-md py-2 pl-10 pr-3 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm">
<input type="search" autocomplete="off" placeholder="Filter category" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full border border-gray-200 rounded-md py-2 pl-10 pr-3 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-gray-500 absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">
@ -10,7 +10,7 @@
<%= form.check_box :category_id_in, { "data-auto-submit-form-target": "auto", multiple: true, class: "rounded-sm border-gray-300 text-indigo-600 shadow-xs focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" }, transaction_category.id, nil %>
<%= form.label :category_id_in, transaction_category.name, value: transaction_category.id, class: "text-sm text-gray-900" do %>
<%= render partial: "transactions/categories/badge", locals: { name: transaction_category.name, color: transaction_category.color } %>
<%end%>
<% end %>
</div>
<% end %>
</div>

View file

@ -1,6 +1,6 @@
<%= sidebar_modal do %>
<h3 class="font-medium mb-1">
<span class="text-2xl"><%=format_money @transaction.amount_money %></span>
<span class="text-2xl"><%= format_money @transaction.amount_money %></span>
<span class="text-lg text-gray-500"><%= @transaction.currency %></span>
</h3>
<span class="text-sm text-gray-500"><%= @transaction.date.strftime("%A %d %B") %></span>

View file

@ -6,8 +6,8 @@
</div>
</div>
<div class="flex items-center justify-between grow">
<%= f.date_field :date, required: 'required', class: "border border-alpha-black-200 bg-white rounded-lg shadow-xs min-w-[200px] px-3 py-1.5 text-gray-900 text-sm" %>
<%= f.number_field :value, required: 'required', placeholder: "0.00", class: "bg-white border border-alpha-black-200 rounded-lg shadow-xs text-gray-900 text-sm px-3 py-1.5 text-right" %>
<%= f.date_field :date, required: "required", class: "border border-alpha-black-200 bg-white rounded-lg shadow-xs min-w-[200px] px-3 py-1.5 text-gray-900 text-sm" %>
<%= f.number_field :value, required: "required", placeholder: "0.00", class: "bg-white border border-alpha-black-200 rounded-lg shadow-xs text-gray-900 text-sm px-3 py-1.5 text-right" %>
</div>
<div class="w-[296px] flex gap-2 justify-end items-center">
<%= link_to "Cancel", account_path(@valuation.account), class: "text-sm text-gray-900 hover:text-gray-800 font-medium px-3 py-1.5" %>

View file

@ -2,7 +2,7 @@
<h1 class="font-bold text-4xl">Edit Valuation</h1>
<%= turbo_frame_tag dom_id(@valuation) do %>
<%= form_with model: @valuation, url: valuation_path(@valuation), html: { class: "" } do |f| %>
<%= render 'form_row', f: f, form_icon: "pencil-line", submit_button_text: "Update" %>
<%= render "form_row", f: f, form_icon: "pencil-line", submit_button_text: "Update" %>
<% end %>
<% end %>
</div>

View file

@ -2,7 +2,7 @@
<h1 class="font-bold text-4xl">Add Valuation: <%= @account.name %></h1>
<%= turbo_frame_tag dom_id(Valuation.new) do %>
<%= form_with model: [@account, @valuation], url: account_valuations_path(@account), html: { class: "" } do |f| %>
<%= render 'form_row', f: f, form_icon: "plus", submit_button_text: "Add" %>
<%= render "form_row", f: f, form_icon: "plus", submit_button_text: "Add" %>
<% end %>
<div class="h-px bg-alpha-black-50 ml-20 mr-4"></div>
<% end %>

27
bin/erblint Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'erblint' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("erb_lint", "erblint")