mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 23:45:21 +02:00
WIP
This commit is contained in:
parent
9733794096
commit
e1296de458
5 changed files with 107 additions and 22 deletions
|
@ -6,6 +6,13 @@ class Import::UploadsController < ApplicationController
|
|||
def show
|
||||
end
|
||||
|
||||
def sample_csv
|
||||
send_data @import.csv_template.to_csv,
|
||||
filename: "#{@import.type.underscore.split('_').first}_sample.csv",
|
||||
type: "text/csv",
|
||||
disposition: "attachment"
|
||||
end
|
||||
|
||||
def update
|
||||
if csv_valid?(csv_str)
|
||||
@import.account = Current.family.accounts.find_by(id: params.dig(:import, :account_id))
|
||||
|
|
74
app/javascript/controllers/file_upload_controller.js
Normal file
74
app/javascript/controllers/file_upload_controller.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["input", "fileName", "uploadArea", "uploadText"]
|
||||
|
||||
connect() {
|
||||
if (this.hasInputTarget) {
|
||||
this.inputTarget.addEventListener("change", this.fileSelected.bind(this))
|
||||
}
|
||||
|
||||
// Find the form element
|
||||
this.form = this.element.closest("form")
|
||||
if (this.form) {
|
||||
this.form.addEventListener("turbo:submit-start", this.formSubmitting.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.hasInputTarget) {
|
||||
this.inputTarget.removeEventListener("change", this.fileSelected.bind(this))
|
||||
}
|
||||
|
||||
if (this.form) {
|
||||
this.form.removeEventListener("turbo:submit-start", this.formSubmitting.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
triggerFileInput() {
|
||||
if (this.hasInputTarget) {
|
||||
this.inputTarget.click()
|
||||
}
|
||||
}
|
||||
|
||||
fileSelected() {
|
||||
if (this.hasInputTarget && this.inputTarget.files.length > 0) {
|
||||
const fileName = this.inputTarget.files[0].name
|
||||
|
||||
if (this.hasFileNameTarget) {
|
||||
// Find the paragraph element inside the fileName target
|
||||
const fileNameText = this.fileNameTarget.querySelector('p')
|
||||
if (fileNameText) {
|
||||
fileNameText.textContent = fileName
|
||||
}
|
||||
|
||||
this.fileNameTarget.classList.remove("hidden")
|
||||
}
|
||||
|
||||
if (this.hasUploadTextTarget) {
|
||||
this.uploadTextTarget.classList.add("hidden")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
formSubmitting() {
|
||||
if (this.hasFileNameTarget && this.hasInputTarget && this.inputTarget.files.length > 0) {
|
||||
const fileNameText = this.fileNameTarget.querySelector('p')
|
||||
if (fileNameText) {
|
||||
fileNameText.textContent = `Uploading ${this.inputTarget.files[0].name}...`
|
||||
}
|
||||
|
||||
// Change the icon to a loader
|
||||
const iconContainer = this.fileNameTarget.querySelector('.lucide-file-text')
|
||||
if (iconContainer) {
|
||||
iconContainer.classList.add('animate-pulse')
|
||||
}
|
||||
}
|
||||
|
||||
if (this.hasUploadAreaTarget) {
|
||||
this.uploadAreaTarget.classList.add("opacity-70")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<%= content_for :previous_path, imports_path %>
|
||||
|
||||
<div class="space-y-12">
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-4 mx-auto max-w-md">
|
||||
<div class="text-center space-y-2">
|
||||
<h1 class="text-3xl text-primary font-medium"><%= t(".title") %></h1>
|
||||
|
@ -39,11 +39,23 @@
|
|||
placeholder: "Paste your CSV file contents here",
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
<% else %>
|
||||
<label for="import_csv_file" class="flex flex-col items-center justify-center w-full h-56 border-2 border-secondary border-dashed rounded-lg cursor-pointer bg-container-inset">
|
||||
<div class="flex flex-col items-center justify-center w-full h-64 border border-secondary border-dashed rounded-xl cursor-pointer" data-controller="file-upload" data-action="click->file-upload#triggerFileInput" data-file-upload-target="uploadArea">
|
||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||
<%= form.file_field :csv_file, class: "ml-32", "data-auto-submit-form-target": "auto" %>
|
||||
<div data-file-upload-target="uploadText" class="flex flex-col items-center">
|
||||
<%= lucide_icon("plus", class: "w-6 h-6 mb-4 text-secondary mx-auto") %>
|
||||
<p class="mb-2 text-md text-gray text-center">
|
||||
<span class="font-medium text-primary">Browse</span> to add your CSV file here
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center hidden" data-file-upload-target="fileName">
|
||||
<%= lucide_icon("file-text", class: "w-6 h-6 mb-4 text-primary") %>
|
||||
<p class="mb-2 text-md font-medium text-primary"></p>
|
||||
</div>
|
||||
|
||||
<%= form.file_field :csv_file, class: "hidden", "data-auto-submit-form-target": "auto", "data-file-upload-target": "input" %>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= form.submit "Upload CSV", disabled: @import.complete? %>
|
||||
|
@ -53,22 +65,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-alpha-black-25 rounded-xl p-1 mt-5 mx-auto max-w-7xl">
|
||||
<div class="text-secondary p-2 mb-2">
|
||||
<div class="flex gap-2 mb-2">
|
||||
<%= lucide_icon("info", class: "w-5 h-5 shrink-0") %>
|
||||
<p class="text-sm"><%= t(".instructions_1") %></p>
|
||||
<div class="flex justify-center">
|
||||
|
||||
<span class="text-secondary text-sm">
|
||||
<%= link_to "Download a sample CSV", "/imports/#{@import.id}/upload/sample_csv", class: "text-primary underline", data: { turbo: false } %> to see the required CSV format
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<ul class="list-disc list-inside text-sm pl-8">
|
||||
<li><%= t(".instructions_2") %></li>
|
||||
<li><%= t(".instructions_3") %></li>
|
||||
<li><%= t(".instructions_4") %></li>
|
||||
<li><%= t(".instructions_5") %></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<%= render partial: "imports/table", locals: { headers: @import.csv_template.headers, rows: @import.csv_template } %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%= render "layouts/shared/htmldoc" do %>
|
||||
<div class="flex flex-col h-dvh bg-surface pt-safe">
|
||||
<div class="flex flex-col h-dvh bg-white pt-safe">
|
||||
<header class="flex items-center justify-between p-8">
|
||||
<%= link_to content_for(:previous_path) || imports_path do %>
|
||||
<%= lucide_icon "arrow-left", class: "w-5 h-5 text-secondary" %>
|
||||
|
|
|
@ -203,6 +203,8 @@ Rails.application.routes.draw do
|
|||
get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
||||
get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
|
||||
|
||||
get "imports/:import_id/upload/sample_csv", to: "import/uploads#sample_csv", as: :import_upload_sample_csv
|
||||
|
||||
# Defines the root path route ("/")
|
||||
root "pages#dashboard"
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue