mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 05:09:38 +02:00
Add transaction sidebar (#534)
* Create sidebar element and working with turbo * Add overview fields * Add columns to transations and tidy modal * permit new transaction params * Add autosubmit form controller * remove unused show code
This commit is contained in:
parent
9c9459211f
commit
7f2633f9da
9 changed files with 134 additions and 15 deletions
|
@ -56,6 +56,6 @@ class TransactionsController < ApplicationController
|
|||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def transaction_params
|
||||
params.require(:transaction).permit(:name, :date, :amount, :currency)
|
||||
params.require(:transaction).permit(:name, :date, :amount, :currency, :notes, :excluded)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,12 @@ module ApplicationHelper
|
|||
render partial: "shared/currency_dropdown", locals: { f: f, options: options }
|
||||
end
|
||||
|
||||
def sidebar_modal(&block)
|
||||
content = capture &block
|
||||
render partial: "shared/sidebar_modal", locals: { content: content }
|
||||
end
|
||||
|
||||
|
||||
def sidebar_link_to(name, path, options = {})
|
||||
base_class_names = [ "block", "border", "border-transparent", "rounded-xl", "-ml-2", "p-2", "text-sm", "font-medium", "text-gray-500", "flex", "items-center" ]
|
||||
hover_class_names = [ "hover:bg-white", "hover:border-alpha-black-50", "hover:text-gray-900", "hover:shadow-xs" ]
|
||||
|
|
33
app/javascript/controllers/auto_submit_form_controller.js
Normal file
33
app/javascript/controllers/auto_submit_form_controller.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
get cssInputSelector() {
|
||||
return 'input:not(.no-auto-submit), textarea:not(.no-auto-submit)';
|
||||
}
|
||||
|
||||
get inputElements() {
|
||||
return this.element.querySelectorAll(this.cssInputSelector);
|
||||
}
|
||||
|
||||
get selectElements() {
|
||||
return this.element.querySelectorAll('select:not(.no-auto-submit)');
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.inputElements.forEach(el => el.addEventListener('change', this.handler.bind(this)));
|
||||
this.selectElements.forEach(el => el.addEventListener('change', this.handler.bind(this)));
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.inputElements.forEach(el => el.removeEventListener('change', this.handler.bind(this)));
|
||||
this.selectElements.forEach(el => el.removeEventListener('change', this.handler.bind(this)));
|
||||
}
|
||||
|
||||
handler(e) {
|
||||
console.log(e);
|
||||
this.element.requestSubmit();
|
||||
}
|
||||
|
||||
}
|
||||
|
14
app/views/shared/_sidebar_modal.html.erb
Normal file
14
app/views/shared/_sidebar_modal.html.erb
Normal file
|
@ -0,0 +1,14 @@
|
|||
<%= turbo_frame_tag "modal" do %>
|
||||
<dialog class="bg-white border border-alpha-black-25 rounded-2xl max-h-[calc(100vh-32px)] max-w-[480px] w-full shadow-xs h-full mt-4 mr-4" data-controller="modal" data-action="click->modal#click_outside">
|
||||
<div class="flex flex-col h-full p-4">
|
||||
<div class="flex justify-end items-center h-9">
|
||||
<div data-action="click->modal#close" class="cursor-pointer">
|
||||
<%= lucide_icon("x", class: "w-5 h-5 shrink-0") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col overflow-scroll">
|
||||
<%= content %>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<% end %>
|
|
@ -1,4 +1,4 @@
|
|||
<div id="<%= dom_id transaction %>" class="flex items-center gap-6 py-4 text-sm font-medium">
|
||||
<%= link_to transaction_path(transaction), data: { turbo_frame: "modal" }, class: "text-gray-900 flex items-center gap-6 py-4 text-sm font-medium hover:bg-gray-50 px-4", id: dom_id(transaction) do %>
|
||||
<div class="w-96 flex items-center gap-2">
|
||||
<div class="w-8 h-8 flex items-center justify-center rounded-full bg-gray-600/5 text-gray-600"><%= transaction.name[0].upcase %></div>
|
||||
<p class="text-gray-900"><%= transaction.name %></p>
|
||||
|
@ -9,4 +9,4 @@
|
|||
<div class="ml-auto">
|
||||
<p class="<%= transaction.amount < 0 ? "text-green-600" : "" %>"><%= number_to_currency(-transaction.amount, { precision: 2 }) %></p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<h4><%= date.strftime('%b %d, %Y') %> · <%= transactions.size %></h4>
|
||||
<span><%= number_to_currency(-transactions.sum(&:amount)) %></span>
|
||||
</div>
|
||||
<div class="bg-white shadow-xs rounded-md border border-alpha-black-25 divide-y divide-alpha-black-50 px-4">
|
||||
<div class="bg-white shadow-xs rounded-md border border-alpha-black-25 divide-y divide-alpha-black-50">
|
||||
<%= render partial: "transactions/transaction", collection: transactions %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,68 @@
|
|||
<div class="mx-auto md:w-2/3 w-full flex">
|
||||
<div class="mx-auto">
|
||||
<%= render @transaction %>
|
||||
<%= link_to "Edit this transaction", edit_transaction_path(@transaction), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||
<div class="inline-block ml-2">
|
||||
<%= button_to "Destroy this transaction", transaction_path(@transaction), method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %>
|
||||
</div>
|
||||
<%= link_to "Back to transactions", transactions_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||
</div>
|
||||
</div>
|
||||
<%= sidebar_modal do %>
|
||||
<h3 class="font-medium mb-1">
|
||||
<span class="text-2xl"><%=format_currency @transaction.amount %></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>
|
||||
|
||||
<%= form_with model: @transaction, html: {data: {controller: "auto-submit-form"}} do |f| %>
|
||||
<details class="group" open>
|
||||
<summary class="list-none bg-gray-25 rounded-xl py-1 mt-4 group-open:mb-2">
|
||||
<div class="py-2 px-[11px] flex items-center justify-between font-medium text-xs text-gray-500">
|
||||
Overview
|
||||
<%= lucide_icon("chevron-down", class: "hidden group-open:block text-gray-500 w-5 h-5") %>
|
||||
<%= lucide_icon("chevron-right", class: "group-open:hidden text-gray-500 w-5 h-5") %>
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<%= f.date_field :date, label: "Date" %>
|
||||
<div class="h-2"></div>
|
||||
<%= f.collection_select :account_id, Current.family.accounts, :id, :name, { prompt: "Select an Account", label: "Account", class: "text-gray-400" }, {class: "form-field__input cursor-not-allowed text-gray-400", disabled: "disabled"} %>
|
||||
</details>
|
||||
|
||||
<details class="group" open>
|
||||
<summary class="list-none bg-gray-25 rounded-xl py-1 mt-6 group-open:mb-2">
|
||||
<div class="py-2 px-[11px] flex items-center justify-between font-medium text-xs text-gray-500">
|
||||
Description
|
||||
<%= lucide_icon("chevron-down", class: "hidden group-open:block text-gray-500 w-5 h-5") %>
|
||||
<%= lucide_icon("chevron-right", class: "group-open:hidden text-gray-500 w-5 h-5") %>
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<%= f.text_field :name, label: "Name" %>
|
||||
</details>
|
||||
|
||||
<details class="group" open>
|
||||
<summary class="list-none bg-gray-25 rounded-xl py-1 mt-6 group-open:mb-2">
|
||||
<div class="py-2 px-[11px] flex items-center justify-between font-medium text-xs text-gray-500">
|
||||
<span>Settings</span>
|
||||
<%= lucide_icon("chevron-down", class: "hidden group-open:block text-gray-500 w-5 h-5") %>
|
||||
<%= lucide_icon("chevron-right", class: "group-open:hidden text-gray-500 w-5 h-5") %>
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<label class="flex items-center cursor-pointer justify-between mx-3">
|
||||
<%= f.check_box :excluded, class: "sr-only peer" %>
|
||||
<div class="flex flex-col justify-center text-sm w-[340px] py-3">
|
||||
<span class="text-gray-900 mb-1">Exclude from analytics</span>
|
||||
<span class="text-gray-500">This excludes the transaction from any in-app features or analytics.</span>
|
||||
</div>
|
||||
<div class="relative w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-100 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
|
||||
</label>
|
||||
</details>
|
||||
|
||||
<details class="group" open>
|
||||
<summary class="list-none bg-gray-25 rounded-xl py-1 mt-6 mb-2">
|
||||
<div class="py-2 px-[11px] flex items-center justify-between font-medium text-xs text-gray-500">
|
||||
<span>Additional</span>
|
||||
<%= lucide_icon("chevron-down", class: "hidden group-open:block text-gray-500 w-5 h-5") %>
|
||||
<%= lucide_icon("chevron-right", class: "group-open:hidden text-gray-500 w-5 h-5") %>
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<%= f.text_area :notes, label: "Notes", placeholder: "Enter a note" %>
|
||||
</details>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
class AddNotesAndExcludedToTransaction < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_column :transactions, :excluded, :boolean, default: false
|
||||
add_column :transactions, :notes, :text
|
||||
end
|
||||
end
|
4
db/schema.rb
generated
4
db/schema.rb
generated
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_03_07_082827) do
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_03_08_214956) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
enable_extension "plpgsql"
|
||||
|
@ -217,6 +217,8 @@ ActiveRecord::Schema[7.2].define(version: 2024_03_07_082827) do
|
|||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.uuid "category_id"
|
||||
t.boolean "excluded", default: false
|
||||
t.text "notes"
|
||||
t.index ["account_id"], name: "index_transactions_on_account_id"
|
||||
t.index ["category_id"], name: "index_transactions_on_category_id"
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue