mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 07:39:39 +02:00
New Add Account UI
* Add Lucide gem (#364) * feat: add cursor pointer in the log-in and create account pages, also make full with (it's cutted right now) the fileds in the settings edit page * feat: skip system test with an explanation instead of comment them * fix typo in the skip * feat: add lucide gem * Add reusable modal (#362) * Remove unused form * Add reusable modal * Prelim styling * Add instructions --------- Co-authored-by: Josh Pigford <josh@joshpigford.com> * Add keyboard navigation to new account selector (#375) * New account menu (#372) * New account menu * Styling tweaks --------- Signed-off-by: Josh Pigford <josh@joshpigford.com> * Entry method links (#376) * Initial add account form (#378) * Initial add account form * Unused --------- Signed-off-by: Josh Pigford <josh@joshpigford.com> Co-authored-by: Pedro López Mareque <Pedro.lopez.mareque@gmail.com> Co-authored-by: Rob Zolkos <rob@zolkos.com> Co-authored-by: Josh Brown <josh@joossh.com>
This commit is contained in:
parent
e79636f372
commit
4761619870
18 changed files with 208 additions and 57 deletions
1
Gemfile
1
Gemfile
|
@ -17,6 +17,7 @@ gem "bootsnap", require: false
|
||||||
gem "importmap-rails"
|
gem "importmap-rails"
|
||||||
gem "propshaft"
|
gem "propshaft"
|
||||||
gem "tailwindcss-rails"
|
gem "tailwindcss-rails"
|
||||||
|
gem "lucide-rails", github: "maybe-finance/lucide-rails"
|
||||||
|
|
||||||
# Hotwire
|
# Hotwire
|
||||||
gem "stimulus-rails"
|
gem "stimulus-rails"
|
||||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -1,3 +1,10 @@
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/maybe-finance/lucide-rails.git
|
||||||
|
revision: 6170b3a0eceb43a8af6552638e9526673c356d0d
|
||||||
|
specs:
|
||||||
|
lucide-rails (0.2.0)
|
||||||
|
railties (>= 4.1.0)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/rails/rails.git
|
remote: https://github.com/rails/rails.git
|
||||||
revision: bab4aa7cb25112846e04cea907361a1de0f126ef
|
revision: bab4aa7cb25112846e04cea907361a1de0f126ef
|
||||||
|
@ -325,7 +332,7 @@ GEM
|
||||||
rubyzip (>= 1.2.2, < 3.0)
|
rubyzip (>= 1.2.2, < 3.0)
|
||||||
websocket (~> 1.0)
|
websocket (~> 1.0)
|
||||||
smart_properties (1.17.0)
|
smart_properties (1.17.0)
|
||||||
sorbet-runtime (0.5.11226)
|
sorbet-runtime (0.5.11234)
|
||||||
stimulus-rails (1.3.3)
|
stimulus-rails (1.3.3)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
stringio (3.1.0)
|
stringio (3.1.0)
|
||||||
|
@ -388,6 +395,7 @@ DEPENDENCIES
|
||||||
inline_svg
|
inline_svg
|
||||||
jbuilder
|
jbuilder
|
||||||
letter_opener
|
letter_opener
|
||||||
|
lucide-rails!
|
||||||
money-rails (~> 1.12)
|
money-rails (~> 1.12)
|
||||||
pg (~> 1.1)
|
pg (~> 1.1)
|
||||||
propshaft
|
propshaft
|
||||||
|
|
|
@ -10,4 +10,10 @@ module ApplicationHelper
|
||||||
def permitted_accountable_partial(name)
|
def permitted_accountable_partial(name)
|
||||||
name.underscore
|
name.underscore
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Wrap view with <%= modal do %> ... <% end %> to have it open in a modal
|
||||||
|
# Make sure to add data-turbo-frame="modal" to the link/button that opens the modal
|
||||||
|
def modal(&block)
|
||||||
|
render "shared/modal", &block
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
13
app/javascript/controllers/hotkey_controller.js
Normal file
13
app/javascript/controllers/hotkey_controller.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
import { install, uninstall } from "@github/hotkey"
|
||||||
|
|
||||||
|
// Connects to data-controller="hotkey"
|
||||||
|
export default class extends Controller {
|
||||||
|
connect() {
|
||||||
|
install(this.element)
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
uninstall(this.element)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
// Connects to data-controller="list-keyboard-navigation"
|
||||||
|
export default class extends Controller {
|
||||||
|
focusPrevious() {
|
||||||
|
this.focusLinkTargetInDirection(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
focusNext() {
|
||||||
|
this.focusLinkTargetInDirection(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
focusLinkTargetInDirection(direction) {
|
||||||
|
const element = this.getLinkTargetInDirection(direction)
|
||||||
|
element?.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
getLinkTargetInDirection(direction) {
|
||||||
|
const indexOfLastFocus = this.indexOfLastFocus()
|
||||||
|
return this.focusableLinks[indexOfLastFocus + direction]
|
||||||
|
}
|
||||||
|
|
||||||
|
indexOfLastFocus(targets = this.focusableLinks) {
|
||||||
|
const indexOfActiveElement = targets.indexOf(document.activeElement)
|
||||||
|
|
||||||
|
if (indexOfActiveElement !== -1) {
|
||||||
|
return indexOfActiveElement
|
||||||
|
} else {
|
||||||
|
return targets.findIndex(target => target.getAttribute("tabindex") === "0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get focusableLinks() {
|
||||||
|
return Array.from(this.element.querySelectorAll("a[href]"))
|
||||||
|
}
|
||||||
|
}
|
15
app/javascript/controllers/modal_controller.js
Normal file
15
app/javascript/controllers/modal_controller.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
// Connects to data-controller="modal"
|
||||||
|
export default class extends Controller {
|
||||||
|
connect() {
|
||||||
|
this.element.showModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the dialog when the user clicks outside of it
|
||||||
|
click_outside(e) {
|
||||||
|
if (e.target === this.element) {
|
||||||
|
this.element.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
<div class="relative flex-col items-center px-5 py-4 space-x-3 text-center bg-white border border-gray-100 shadow-sm rounded-xl hover:border-gray-200">
|
<%= 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-50 border border-transparent focus:border focus:border-gray-200 block px-2 hover:bg-gray-50 rounded-lg p-2" do %>
|
||||||
<%= link_to new_account_path(type: type.class.name.demodulize), class: "flex flex-col items-center justify-center w-full text-center focus:outline-none" do %>
|
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg <%= bg_color %> shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
|
||||||
<span class="absolute inset-0" aria-hidden="true"></span>
|
<%= lucide_icon(icon, class: "#{text_color} w-5 h-5") %>
|
||||||
<span class="flex w-10 h-10 shrink-0 grow-0 items-center justify-center rounded-xl <%= bg_color %> mb-2">
|
</span>
|
||||||
<%= inline_svg_tag(icon, class: "#{text_color} stroke-current") %>
|
<%= type.model_name.human %>
|
||||||
</span>
|
<% end %>
|
||||||
<%= type.model_name.human %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
15
app/views/accounts/_entry_method.html.erb
Normal file
15
app/views/accounts/_entry_method.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<% if local_assigns[:disabled] && disabled %>
|
||||||
|
<span class="flex items-center w-full gap-4 p-2 px-2 text-center border border-transparent rounded-lg cursor-not-allowed focus:outline-none focus:bg-gray-50 focus:border focus:border-gray-200 hover:bg-gray-50">
|
||||||
|
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-[#141414]/5 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
|
||||||
|
<%= lucide_icon(icon, class: "text-gray-500 w-5 h-5") %>
|
||||||
|
</span>
|
||||||
|
<%= text %>
|
||||||
|
</span>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to new_account_path(type: type.class.name.demodulize), class: "flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2" do %>
|
||||||
|
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-[#141414]/5 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
|
||||||
|
<%= lucide_icon(icon, class: "text-gray-500 w-5 h-5") %>
|
||||||
|
</span>
|
||||||
|
<%= text %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="relative p-4 border border-gray-100 bg-offwhite rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
|
<div class="relative p-3 border border-[#141414]/8 bg-white rounded-xl focus-within:bg-white focus-within:shadow-none focus-within:border-gray-900 focus-within:ring-4 focus-within:ring-gray-100 focus-within:opacity-100 shadow-sm">
|
||||||
<label for="account_name" class="block text-sm font-medium opacity-50 focus-within:opacity-100">Type</label>
|
<label for="account_name" class="block text-sm font-medium opacity-50 focus-within:opacity-100">Type</label>
|
||||||
<%= f.select :subtype, options_for_select([["Checking", "checking"], ["Savings", "savings"]], selected: ""), {}, class: "block w-full p-0 mt-1 bg-transparent border-none focus:outline-none focus:ring-0" %>
|
<%= f.select :subtype, options_for_select([["Checking", "checking"], ["Savings", "savings"]], selected: ""), {}, class: "block w-full p-0 mt-1 bg-transparent border-none focus:outline-none focus:ring-0" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="relative p-4 border border-gray-100 bg-offwhite rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
|
<div class="relative p-3 border border-[#141414]/8 bg-white rounded-xl focus-within:bg-white focus-within:shadow-none focus-within:border-gray-900 focus-within:ring-4 focus-within:ring-gray-100 focus-within:opacity-100 shadow-sm">
|
||||||
<label for="account_name" class="block text-sm font-medium opacity-50 focus-within:opacity-100">Type</label>
|
<label for="account_name" class="block text-sm font-medium opacity-50 focus-within:opacity-100">Type</label>
|
||||||
<%= f.select :subtype, options_for_select(Account::Investment::SUBTYPES, selected: ""), {}, class: "block w-full p-0 mt-1 bg-transparent border-none focus:outline-none focus:ring-0" %>
|
<%= f.select :subtype, options_for_select(Account::Investment::SUBTYPES, selected: ""), {}, class: "block w-full p-0 mt-1 bg-transparent border-none focus:outline-none focus:ring-0" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,47 +1,94 @@
|
||||||
<h1 class="text-3xl font-semibold font-display"><%= t('.title')%></h1>
|
<h1 class="text-3xl font-semibold font-display"><%= t('.title')%></h1>
|
||||||
|
|
||||||
<% if params[:type].blank? || Account.accountable_types.include?("Account::#{params[:type]}") == false %>
|
<%= modal do %>
|
||||||
<div class="grid grid-cols-2 gap-4 mt-8 text-sm sm:grid-cols-3 md:grid-cols-4">
|
<% if params[:type].blank? || Account.accountable_types.include?("Account::#{params[:type]}") == false %>
|
||||||
<%= render "account_type", type: Account::Credit.new, bg_color: "bg-[#E6F6FA]", text_color: "text-[#189FC7]", icon: "icon-credit-card.svg" %>
|
<div class="border-b border-[#141414]/2 p-4 text-gray-400">
|
||||||
<%= render "account_type", type: Account::Depository.new, bg_color: "bg-[#EAF4FF]", text_color: "text-[#3492FB]", icon: "icon-bank-accounts.svg" %>
|
What would you like to add?
|
||||||
<%= render "account_type", type: Account::Investment.new, bg_color: "bg-[#EDF7F4]", text_color: "text-[#1BD5A1]", icon: "icon-bank-accounts.svg" %>
|
|
||||||
<%= render "account_type", type: Account::Loan.new, bg_color: "bg-[#EDF7F4]", text_color: "text-[#1BD5A1]", icon: "icon-bank-accounts.svg" %>
|
|
||||||
<%= render "account_type", type: Account::OtherAsset.new, bg_color: "bg-[#EDF7F4]", text_color: "text-[#1BD5A1]", icon: "icon-bank-accounts.svg" %>
|
|
||||||
<%= render "account_type", type: Account::OtherLiability.new, bg_color: "bg-[#EDF7F4]", text_color: "text-[#1BD5A1]", icon: "icon-bank-accounts.svg" %>
|
|
||||||
<%= render "account_type", type: Account::Property.new, bg_color: "bg-[#FEF0F7]", text_color: "text-[#F03695]", icon: "icon-real-estate.svg" %>
|
|
||||||
<%= render "account_type", type: Account::Vehicle.new, bg_color: "bg-[#EDF7F4]", text_color: "text-[#1BD5A1]", icon: "icon-bank-accounts.svg" %>
|
|
||||||
</div>
|
|
||||||
<% else %>
|
|
||||||
<div class="relative flex items-center mb-5 space-x-2">
|
|
||||||
<%= link_to new_account_path, class: "" do %>
|
|
||||||
<%= inline_svg_tag('icon-arrow-left.svg', class: 'text-gray-500 fill-current') %>
|
|
||||||
<% end %>
|
|
||||||
<h2 class="text-2xl font-semibold font-display"><%= t('.enter_type_account', type: @account.accountable_class.model_name.human.downcase ) %></h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%= form_with model: @account, url: accounts_path, scope: :account, html: { class: "space-y-4" } do |f| %>
|
|
||||||
<%= f.hidden_field :accountable_type %>
|
|
||||||
|
|
||||||
<div class="relative p-4 border border-gray-100 bg-offwhite rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
|
|
||||||
<%# <span class="absolute px-2 py-1 text-xs font-medium text-gray-400 uppercase bg-gray-200 rounded-full opacity-50 right-3">Optional</span> %>
|
|
||||||
<%= f.label :name, class: 'block text-sm font-medium opacity-50 focus-within:opacity-100' %>
|
|
||||||
<%= f.text_field :name, placeholder: t('.account_name_placeholder'), required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100" %>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col p-2 text-sm" data-controller="list-keyboard-navigation">
|
||||||
|
<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 "accounts/#{permitted_accountable_partial(@account.accountable_type)}", f: f %>
|
<%= render "account_type", type: Account::Depository.new, bg_color: "bg-[#EFF8FF]", text_color: "text-[#2E90FA]", icon: "landmark" %>
|
||||||
|
<%= render "account_type", type: Account::Investment.new, bg_color: "bg-[#ECFDF3]", text_color: "text-[#32D583]", icon: "line-chart" %>
|
||||||
<div class="relative p-4 border border-gray-100 bg-offwhite rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
|
<%= render "account_type", type: Account::Property.new, bg_color: "bg-[#FCF5F9]", text_color: "text-[#F23E94]", icon: "home" %>
|
||||||
|
<%= render "account_type", type: Account::Vehicle.new, bg_color: "bg-[#EEF4FF]", text_color: "text-[#6172F3]", icon: "car-front" %>
|
||||||
<%= f.label :balance, class: 'block text-sm font-medium opacity-50 focus-within:opacity-100' %>
|
<%= render "account_type", type: Account::Credit.new, bg_color: "bg-[#F0F9FF]", text_color: "text-[#36BFFA]", icon: "credit-card" %>
|
||||||
<div class="flex">
|
<%= render "account_type", type: Account::Loan.new, bg_color: "bg-[#FEF6EE]", text_color: "text-[#F38744]", icon: "hand-coins" %>
|
||||||
<%= f.number_field :balance, placeholder: number_to_currency(0), in: 0.00..100000000.00, required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100" %>
|
<%= render "account_type", type: Account::OtherAsset.new, bg_color: "bg-[#ECFDF3]", text_color: "text-[#12B76A]", icon: "plus" %>
|
||||||
|
<%= render "account_type", type: Account::OtherLiability.new, bg_color: "bg-[#FEF3F2]", text_color: "text-[#F04438]", icon: "minus" %>
|
||||||
|
</div>
|
||||||
|
<div class="border-t border-[#141414]/2 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-[#141414]/5 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-[#141414]/5 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-[#141414]/5 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">
|
||||||
|
<span>Close</span> <kbd class="bg-[#141414]/5 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<% elsif params[:step] == 'method' && params[:type].present? %>
|
||||||
<div class="absolute right-5 bottom-5">
|
<div class="border-b border-[#141414]/2 p-4 text-gray-400 flex items-center space-x-3">
|
||||||
<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" title="Submit">
|
<%= link_to new_account_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-[#141414]/5" do %>
|
||||||
<%= inline_svg_tag('icn-check.svg', class: 'text-white fill-current') %>
|
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
|
||||||
</button>
|
<% end %>
|
||||||
|
<span>How would you like to add it?</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col p-2 text-sm" data-controller="list-keyboard-navigation">
|
||||||
|
<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::Depository.new, text: 'Enter account balance manually', icon: "keyboard" %>
|
||||||
|
<%= render "entry_method", type: Account::Depository.new, text: 'Securely link bank account with data provider (coming soon)', icon: "link-2", disabled: true %>
|
||||||
|
<%= render "entry_method", type: Account::Depository.new, text: 'Upload spreadsheet (coming soon)', icon: "sheet", disabled: true %>
|
||||||
|
</div>
|
||||||
|
<div class="border-t border-[#141414]/2 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-[#141414]/5 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-[#141414]/5 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-[#141414]/5 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">
|
||||||
|
<span>Close</span> <kbd class="bg-[#141414]/5 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="border-b border-[#141414]/2 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-[#141414]/5" do %>
|
||||||
|
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
|
||||||
|
<% end %>
|
||||||
|
<span>Add account</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form_with model: @account, url: accounts_path, scope: :account, html: { class: "space-y-4 m-5 mt-1", data: { turbo: false } } do |f| %>
|
||||||
|
<%= f.hidden_field :accountable_type %>
|
||||||
|
|
||||||
|
<div class="relative p-3 border border-[#141414]/8 bg-white rounded-xl focus-within:bg-white focus-within:shadow-none focus-within:border-gray-900 focus-within:ring-4 focus-within:ring-gray-100 focus-within:opacity-100 shadow-sm">
|
||||||
|
<%= f.label :name, 'Account name', class: 'block text-sm font-medium opacity-50 focus-within:opacity-100' %>
|
||||||
|
<%= f.text_field :name, placeholder: 'Example account name', required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= render "accounts/#{permitted_accountable_partial(@account.accountable_type)}", f: f %>
|
||||||
|
|
||||||
|
<div class="relative p-3 border border-[#141414]/8 bg-white rounded-xl focus-within:bg-white focus-within:shadow-none focus-within:border-gray-900 focus-within:ring-4 focus-within:ring-gray-100 focus-within:opacity-100 shadow-sm">
|
||||||
|
<%= f.label :balance, class: 'block text-sm font-medium opacity-50 focus-within:opacity-100' %>
|
||||||
|
<div class="flex">
|
||||||
|
<%= f.number_field :balance, placeholder: number_to_currency(0), in: 0.00..100000000.00, required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100 w-full" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
<button type="submit" class="w-full p-3 text-center text-white bg-black rounded-lg hover:bg-gray-700" title="Submit">
|
||||||
|
Add account
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -59,10 +59,11 @@
|
||||||
<%= link_to accounts_path, class: 'text-xs' do%>
|
<%= link_to accounts_path, class: 'text-xs' do%>
|
||||||
<%= t('.accounts') %>
|
<%= t('.accounts') %>
|
||||||
<% end %>
|
<% 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') 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 %>
|
||||||
<%= inline_svg_tag('icon-add.svg', class: 'text-gray-500 fill-current') %>
|
<%= inline_svg_tag('icon-add.svg', class: 'text-gray-500 fill-current') %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-sm font-semibold font-display"><%= t('.cash') %></h2>
|
<h2 class="text-sm font-semibold font-display"><%= t('.cash') %></h2>
|
||||||
|
|
||||||
|
@ -83,5 +84,6 @@
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
<%= turbo_frame_tag "modal" %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
7
app/views/shared/_modal.html.erb
Normal file
7
app/views/shared/_modal.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<%= turbo_frame_tag "modal" do %>
|
||||||
|
<dialog class="bg-white border border-[#141414]/25 rounded-2xl max-h-[556px] max-w-[580px] w-full shadow-xs" data-controller="modal" data-action="click->modal#click_outside">
|
||||||
|
<div class="flex flex-col h-full">
|
||||||
|
<%= yield %>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
<% end %>
|
|
@ -5,3 +5,4 @@ pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
|
||||||
pin "@hotwired/stimulus", to: "stimulus.min.js"
|
pin "@hotwired/stimulus", to: "stimulus.min.js"
|
||||||
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
|
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
|
||||||
pin_all_from "app/javascript/controllers", under: "controllers"
|
pin_all_from "app/javascript/controllers", under: "controllers"
|
||||||
|
pin "@github/hotkey", to: "@github--hotkey.js" # @3.1.0
|
||||||
|
|
|
@ -13,7 +13,7 @@ en:
|
||||||
account: Account
|
account: Account
|
||||||
account/credit: Credit Card
|
account/credit: Credit Card
|
||||||
account/depository: Bank Accounts
|
account/depository: Bank Accounts
|
||||||
account/investiment: Investments
|
account/investment: Investments
|
||||||
account/loan: Loan
|
account/loan: Loan
|
||||||
account/other_asset: Other Asset
|
account/other_asset: Other Asset
|
||||||
account/other_liability: Other Liability
|
account/other_liability: Other Liability
|
||||||
|
|
|
@ -6,6 +6,4 @@ en:
|
||||||
index:
|
index:
|
||||||
title: Cash
|
title: Cash
|
||||||
new:
|
new:
|
||||||
account_name_placeholder: Account name
|
|
||||||
enter_type_account: Enter %{type} account
|
|
||||||
title: Add an account
|
title: Add an account
|
||||||
|
|
|
@ -22,6 +22,9 @@ module.exports = {
|
||||||
},
|
},
|
||||||
dropShadow: {
|
dropShadow: {
|
||||||
'form': '0px 4px 10px rgba(52, 54, 60, 0.08)',
|
'form': '0px 4px 10px rgba(52, 54, 60, 0.08)',
|
||||||
|
},
|
||||||
|
boxShadow: {
|
||||||
|
'xs': '0px 1px 2px 0px #1018280D'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
2
vendor/javascript/@github--hotkey.js
vendored
Normal file
2
vendor/javascript/@github--hotkey.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue