mirror of
https://github.com/marcogll/TaxHacker_s23.git
synced 2026-01-13 13:25:18 +00:00
(squash) init
feat: filters, settings, backups fix: ts compile errors feat: new dashboard, webp previews and settings feat: use webp for pdfs feat: use webp fix: analyze resets old data fix: switch to corsproxy fix: switch to free cors fix: max upload limit fix: currency conversion feat: transaction export fix: currency conversion feat: refactor settings actions feat: new loader feat: README + LICENSE doc: update readme doc: update readme doc: update readme doc: update screenshots ci: bump prisma
This commit is contained in:
74
components/dashboard/drop-zone-widget.tsx
Normal file
74
components/dashboard/drop-zone-widget.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
"use client"
|
||||
|
||||
import { useNotification } from "@/app/context"
|
||||
import { uploadFilesAction } from "@/app/files/actions"
|
||||
import { FILE_ACCEPTED_MIMETYPES } from "@/lib/files"
|
||||
import { Camera, Loader2 } from "lucide-react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { startTransition, useState } from "react"
|
||||
|
||||
export default function DashboardDropZoneWidget() {
|
||||
const router = useRouter()
|
||||
const { showNotification } = useNotification()
|
||||
const [isUploading, setIsUploading] = useState(false)
|
||||
const [uploadError, setUploadError] = useState("")
|
||||
|
||||
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsUploading(true)
|
||||
setUploadError("")
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
const formData = new FormData()
|
||||
|
||||
// Append all selected files to the FormData
|
||||
for (let i = 0; i < e.target.files.length; i++) {
|
||||
formData.append("files", e.target.files[i])
|
||||
}
|
||||
|
||||
// Submit the files using the server action
|
||||
startTransition(async () => {
|
||||
const result = await uploadFilesAction(null, formData)
|
||||
if (result.success) {
|
||||
showNotification({ code: "sidebar.unsorted", message: "new" })
|
||||
setTimeout(() => showNotification({ code: "sidebar.unsorted", message: "" }), 3000)
|
||||
router.push("/unsorted")
|
||||
} else {
|
||||
setUploadError(result.error ? result.error : "Something went wrong...")
|
||||
}
|
||||
setIsUploading(false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex w-full h-full">
|
||||
<label className="relative w-full h-full border-2 border-dashed rounded-lg transition-colors hover:border-primary cursor-pointer">
|
||||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
className="hidden"
|
||||
multiple
|
||||
accept={FILE_ACCEPTED_MIMETYPES}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
<div className="flex flex-col items-center justify-center gap-4 p-8 text-center h-full">
|
||||
{isUploading ? (
|
||||
<Loader2 className="h-8 w-8 text-muted-foreground animate-spin" />
|
||||
) : (
|
||||
<Camera className="h-8 w-8 text-muted-foreground" />
|
||||
)}
|
||||
<div>
|
||||
<p className="text-lg font-medium">
|
||||
{isUploading ? "Uploading..." : "Take a photo or drop your files here"}
|
||||
</p>
|
||||
{!uploadError && (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
upload receipts, invoices and any other documents for me to scan
|
||||
</p>
|
||||
)}
|
||||
{uploadError && <p className="text-red-500">{uploadError}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user