From 5834ec2b0e3708e3046ac36760e4dd80da86dd0f Mon Sep 17 00:00:00 2001 From: Potenz Date: Tue, 16 Sep 2025 18:44:27 +0530 Subject: [PATCH] feat(upload-modal) - claim document upload modal added --- .../claims/claim-document-upload-modal.tsx | 143 ++++++++++++++++++ apps/Frontend/src/pages/claims-page.tsx | 4 + 2 files changed, 147 insertions(+) create mode 100644 apps/Frontend/src/components/claims/claim-document-upload-modal.tsx diff --git a/apps/Frontend/src/components/claims/claim-document-upload-modal.tsx b/apps/Frontend/src/components/claims/claim-document-upload-modal.tsx new file mode 100644 index 0000000..2bb10d8 --- /dev/null +++ b/apps/Frontend/src/components/claims/claim-document-upload-modal.tsx @@ -0,0 +1,143 @@ +import React, { useCallback, useState } from "react"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { RefreshCw, FilePlus } from "lucide-react"; +import { useToast } from "@/hooks/use-toast"; +import { MultipleFileUploadZone } from "../file-upload/multiple-file-upload-zone"; + +export default function ClaimDocumentsUploadMultiple() { + const { toast } = useToast(); + + // Internal configuration + const MAX_FILES = 10; + const ACCEPTED_FILE_TYPES = + "application/pdf,image/jpeg,image/jpg,image/png,image/webp"; + const TITLE = "Upload Claim Document(s)"; + const DESCRIPTION = + "You can upload up to 10 files. Allowed types: PDF, JPG, PNG, WEBP."; + + // Internal state + const [uploadedFiles, setUploadedFiles] = useState([]); + const [isUploading, setIsUploading] = useState(false); // forwarded to upload zone + const [isExtracting, setIsExtracting] = useState(false); + + // Called by MultipleFileUploadZone whenever its internal list changes. + const handleFileUpload = useCallback((files: File[]) => { + setUploadedFiles(files); + }, []); + + // Dummy save (simulate async). Replace with real API call when needed. + const handleSave = useCallback(async (files: File[]) => { + // simulate network / processing time + await new Promise((res) => setTimeout(res, 800)); + console.log( + "handleSave called for files:", + files.map((f) => f.name) + ); + }, []); + + // Extract handler — calls handleSave (dummy) and shows toasts. + const handleExtract = useCallback(async () => { + if (uploadedFiles.length === 0) { + toast({ + title: "No files", + description: "Please upload at least one file before extracting.", + variant: "destructive", + }); + return; + } + + if (isExtracting) return; + setIsExtracting(true); + + try { + await handleSave(uploadedFiles); + + toast({ + title: "Extraction started", + description: `Processing ${uploadedFiles.length} file(s).`, + variant: "default", + }); + + // If you want to clear the upload zone after extraction, you'll need a small + // change in MultipleFileUploadZone to accept a reset signal from parent. + // We intentionally leave files intact here. + } catch (err) { + toast({ + title: "Extraction failed", + description: + "There was an error starting extraction. Please try again.", + variant: "destructive", + }); + // eslint-disable-next-line no-console + console.error("extract error", err); + } finally { + setIsExtracting(false); + } + }, [uploadedFiles, handleSave, isExtracting, toast]); + + return ( +
+ + + {TITLE} + {DESCRIPTION} + + + {/* File Upload Section */} +
+ + + {/* Show list of files received from the upload zone */} + {uploadedFiles.length > 0 && ( +
+

+ Uploaded ({uploadedFiles.length}/{MAX_FILES}) +

+
    + {uploadedFiles.map((file, index) => ( +
  • + {file.name} +
  • + ))} +
+
+ )} +
+ + {/* Action Button */} +
+ +
+
+
+
+ ); +} diff --git a/apps/Frontend/src/pages/claims-page.tsx b/apps/Frontend/src/pages/claims-page.tsx index d45bfd3..5bc0e3a 100644 --- a/apps/Frontend/src/pages/claims-page.tsx +++ b/apps/Frontend/src/pages/claims-page.tsx @@ -31,6 +31,7 @@ import { UpdateAppointment, UpdatePatient, } from "@repo/db/types"; +import ClaimDocumentsUploadMultiple from "@/components/claims/claim-document-upload-modal"; export default function ClaimsPage() { const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); @@ -459,6 +460,9 @@ export default function ClaimsPage() { + {/* File Upload Zone */} + + {/* Claim Form Modal */} {isClaimFormOpen && selectedPatientId !== null && (