feat(UI Fix) - upload zone fixed

This commit is contained in:
2025-09-16 19:55:05 +05:30
parent 5834ec2b0e
commit cb7123afc5
5 changed files with 470 additions and 409 deletions

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react";
import React, { useCallback, useRef, useState } from "react";
import {
Card,
CardContent,
@@ -9,7 +9,10 @@ import {
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";
import {
MultipleFileUploadZone,
MultipleFileUploadZoneHandle,
} from "../file-upload/multiple-file-upload-zone";
export default function ClaimDocumentsUploadMultiple() {
const { toast } = useToast();
@@ -22,14 +25,15 @@ export default function ClaimDocumentsUploadMultiple() {
const DESCRIPTION =
"You can upload up to 10 files. Allowed types: PDF, JPG, PNG, WEBP.";
// Internal state
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
// Zone ref + minimal UI state (parent does not own files)
const uploadZoneRef = useRef<MultipleFileUploadZoneHandle | null>(null);
const [filesForUI, setFilesForUI] = useState<File[]>([]);
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);
// Called by MultipleFileUploadZone when its internal list changes (UI-only)
const handleZoneFilesChange = useCallback((files: File[]) => {
setFilesForUI(files);
}, []);
// Dummy save (simulate async). Replace with real API call when needed.
@@ -42,9 +46,11 @@ export default function ClaimDocumentsUploadMultiple() {
);
}, []);
// Extract handler — calls handleSave (dummy) and shows toasts.
// Extract handler — reads files from the zone via ref and calls handleSave
const handleExtract = useCallback(async () => {
if (uploadedFiles.length === 0) {
const files = uploadZoneRef.current?.getFiles() ?? [];
if (files.length === 0) {
toast({
title: "No files",
description: "Please upload at least one file before extracting.",
@@ -57,17 +63,15 @@ export default function ClaimDocumentsUploadMultiple() {
setIsExtracting(true);
try {
await handleSave(uploadedFiles);
await handleSave(files);
toast({
title: "Extraction started",
description: `Processing ${uploadedFiles.length} file(s).`,
description: `Processing ${files.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.
// we intentionally leave files intact in the zone after extraction
} catch (err) {
toast({
title: "Extraction failed",
@@ -80,7 +84,7 @@ export default function ClaimDocumentsUploadMultiple() {
} finally {
setIsExtracting(false);
}
}, [uploadedFiles, handleSave, isExtracting, toast]);
}, [handleSave, isExtracting, toast]);
return (
<div className="space-y-8 py-8">
@@ -93,20 +97,21 @@ export default function ClaimDocumentsUploadMultiple() {
{/* File Upload Section */}
<div className="bg-gray-100 p-4 rounded-md space-y-4">
<MultipleFileUploadZone
onFileUpload={handleFileUpload}
ref={uploadZoneRef}
onFilesChange={handleZoneFilesChange}
isUploading={isUploading}
acceptedFileTypes={ACCEPTED_FILE_TYPES}
maxFiles={MAX_FILES}
/>
{/* Show list of files received from the upload zone */}
{uploadedFiles.length > 0 && (
{filesForUI.length > 0 && (
<div>
<p className="text-sm text-gray-600 mb-2">
Uploaded ({uploadedFiles.length}/{MAX_FILES})
Uploaded ({filesForUI.length}/{MAX_FILES})
</p>
<ul className="text-sm text-gray-700 list-disc ml-6 max-h-40 overflow-auto">
{uploadedFiles.map((file, index) => (
{filesForUI.map((file, index) => (
<li key={index} className="truncate" title={file.name}>
{file.name}
</li>
@@ -120,7 +125,7 @@ export default function ClaimDocumentsUploadMultiple() {
<div className="mt-4">
<Button
className="w-full h-12 gap-2"
disabled={uploadedFiles.length === 0 || isExtracting}
disabled={filesForUI.length === 0 || isExtracting}
onClick={handleExtract}
>
{isExtracting ? (

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from "react";
import { useState, useEffect, useRef, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
@@ -20,7 +20,10 @@ import {
} from "@/components/ui/popover";
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@/lib/queryClient";
import { MultipleFileUploadZone } from "../file-upload/multiple-file-upload-zone";
import {
MultipleFileUploadZone,
MultipleFileUploadZoneHandle,
} from "../file-upload/multiple-file-upload-zone";
import { useAuth } from "@/hooks/use-auth";
import {
Tooltip,
@@ -281,53 +284,13 @@ export function ClaimForm({
};
// FILE UPLOAD ZONE
const uploadZoneRef = useRef<MultipleFileUploadZoneHandle | null>(null);
const [isUploading, setIsUploading] = useState(false);
const handleFileUpload = (files: File[]) => {
setIsUploading(true);
const allowedTypes = [
"application/pdf",
"image/jpeg",
"image/jpg",
"image/png",
"image/webp",
];
const validFiles = files.filter((file) => allowedTypes.includes(file.type));
if (validFiles.length > 10) {
toast({
title: "Too Many Files",
description: "You can only upload up to 10 files (PDFs or images).",
variant: "destructive",
});
setIsUploading(false);
return;
}
if (validFiles.length === 0) {
toast({
title: "Invalid File Type",
description: "Only PDF and image files are allowed.",
variant: "destructive",
});
setIsUploading(false);
return;
}
setForm((prev) => ({
...prev,
uploadedFiles: validFiles,
}));
toast({
title: "Files Selected",
description: `${validFiles.length} file(s) ready for processing.`,
});
setIsUploading(false);
};
// NO validation here — the upload zone handles validation, toasts, max files, sizes, etc.
const handleFilesChange = useCallback((files: File[]) => {
setForm((prev) => ({ ...prev, uploadedFiles: files }));
}, []);
// 1st Button workflow - Mass Health Button Handler
const handleMHSubmit = async () => {
@@ -865,7 +828,8 @@ export function ClaimForm({
</p>
<MultipleFileUploadZone
onFileUpload={handleFileUpload}
ref={uploadZoneRef}
onFilesChange={handleFilesChange}
isUploading={isUploading}
acceptedFileTypes="application/pdf,image/jpeg,image/jpg,image/png,image/webp"
maxFiles={10}
@@ -893,10 +857,7 @@ export function ClaimForm({
>
MH
</Button>
<Button
className="w-32"
variant="warning"
>
<Button className="w-32" variant="warning">
MH PreAuth
</Button>
<Button