diff --git a/src/components/ui/progress.tsx b/src/components/ui/progress.tsx index 93349bb..6451efe 100644 --- a/src/components/ui/progress.tsx +++ b/src/components/ui/progress.tsx @@ -6,8 +6,11 @@ import { cn } from "@/lib/utils"; function Progress({ className, value, + indicatorClassName, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + indicatorClassName?: string; +}) { return ( diff --git a/src/features/home/components/MangaManualImportDialog.tsx b/src/features/home/components/MangaManualImportDialog.tsx index 65e8e7f..9660ceb 100644 --- a/src/features/home/components/MangaManualImportDialog.tsx +++ b/src/features/home/components/MangaManualImportDialog.tsx @@ -1,5 +1,5 @@ import axios from "axios"; -import { FileUp } from "lucide-react"; +import { FileUp, XCircle } from "lucide-react"; import type React from "react"; import { useState } from "react"; import { toast } from "sonner"; @@ -33,6 +33,7 @@ export const MangaManualImportDialog = ({ const [uploadProgress, setUploadProgress] = useState>( {}, ); + const [uploadErrors, setUploadErrors] = useState>({}); const { mutateAsync: requestPresignedUrl } = useRequestPresignedImport(); @@ -49,6 +50,7 @@ export const MangaManualImportDialog = ({ setIsUploading(true); setUploadProgress({}); + setUploadErrors({}); let hasError = false; for (const file of files) { @@ -85,6 +87,7 @@ export const MangaManualImportDialog = ({ } catch (error) { console.error(`Error uploading ${file.name}:`, error); hasError = true; + setUploadErrors((prev) => ({ ...prev, [file.name]: true })); toast.error(`Failed to import ${file.name}`); } } @@ -96,6 +99,7 @@ export const MangaManualImportDialog = ({ setMalId(""); setAniListId(""); setUploadProgress({}); + setUploadErrors({}); onFileImportDialogOpenChange(false); toast.success("Manga imported successfully! Backend will process it."); } @@ -223,23 +227,52 @@ export const MangaManualImportDialog = ({ 0, ) / files.length } + indicatorClassName={ + Math.round( + files.reduce( + (acc, file) => acc + (uploadProgress[file.name] || 0), + 0, + ) / files.length, + ) === 100 + ? "bg-green-500" + : "" + } /> -
- {files.map((file) => ( -
-
- - {file.name} - - {uploadProgress[file.name] || 0}% +
+ {files.map((file) => { + const isError = uploadErrors[file.name]; + const progress = uploadProgress[file.name] || 0; + return ( +
+
+ + {file.name} + + {isError ? ( + + Failed + + ) : ( + {progress}% + )} +
+
- -
- ))} + ); + })}
)} @@ -251,6 +284,7 @@ export const MangaManualImportDialog = ({ onClick={() => { setFiles(null); setUploadProgress({}); + setUploadErrors({}); onFileImportDialogOpenChange(false); }} >