Spaces:
Sleeping
Sleeping
Update web/src/App.tsx
Browse files- web/src/App.tsx +18 -14
web/src/App.tsx
CHANGED
|
@@ -911,34 +911,38 @@ function App() {
|
|
| 911 |
// File Upload (FIXED)
|
| 912 |
// =========================
|
| 913 |
// 1) Upload: accept File[] OR FileList OR null
|
| 914 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
const files = Array.isArray(input) ? input : input ? Array.from(input) : [];
|
| 918 |
if (!files.length) return;
|
| 919 |
|
| 920 |
-
// 1) UI 先加进去(默认 other)
|
| 921 |
const newFiles: UploadedFile[] = files.map((file) => ({ file, type: "other" as FileType }));
|
|
|
|
|
|
|
| 922 |
setUploadedFiles((prev) => [...prev, ...newFiles]);
|
| 923 |
|
| 924 |
-
//
|
| 925 |
-
|
| 926 |
-
|
| 927 |
-
|
|
|
|
|
|
|
|
|
|
| 928 |
uploadedFingerprintsRef.current.add(fp);
|
| 929 |
|
| 930 |
try {
|
| 931 |
await apiUpload({
|
| 932 |
user_id: user.email,
|
| 933 |
-
doc_type: DOC_TYPE_MAP
|
| 934 |
-
file,
|
| 935 |
});
|
| 936 |
-
toast.success(`
|
| 937 |
} catch (e: any) {
|
| 938 |
-
toast.error(e?.message || `Upload failed: ${
|
| 939 |
-
|
|
|
|
| 940 |
}
|
| 941 |
-
}
|
| 942 |
};
|
| 943 |
|
| 944 |
// 2) Remove: accept index OR File OR UploadedFile (use any to avoid prop signature mismatch crash)
|
|
|
|
| 911 |
// File Upload (FIXED)
|
| 912 |
// =========================
|
| 913 |
// 1) Upload: accept File[] OR FileList OR null
|
| 914 |
+
|
| 915 |
+
const handleFileUpload = async (input: File[] | FileList | null | undefined) => {
|
|
|
|
| 916 |
const files = Array.isArray(input) ? input : input ? Array.from(input) : [];
|
| 917 |
if (!files.length) return;
|
| 918 |
|
|
|
|
| 919 |
const newFiles: UploadedFile[] = files.map((file) => ({ file, type: "other" as FileType }));
|
| 920 |
+
|
| 921 |
+
// update UI immediately
|
| 922 |
setUploadedFiles((prev) => [...prev, ...newFiles]);
|
| 923 |
|
| 924 |
+
// if not logged in (shouldn't happen), skip backend upload
|
| 925 |
+
if (!user) return;
|
| 926 |
+
|
| 927 |
+
// upload to backend right away (default as "Other Course Document")
|
| 928 |
+
for (const f of files) {
|
| 929 |
+
const fp = `${f.name}::${f.size}::${f.lastModified}`;
|
| 930 |
+
if (uploadedFingerprintsRef.current.has(fp)) continue;
|
| 931 |
uploadedFingerprintsRef.current.add(fp);
|
| 932 |
|
| 933 |
try {
|
| 934 |
await apiUpload({
|
| 935 |
user_id: user.email,
|
| 936 |
+
doc_type: DOC_TYPE_MAP["other"] || "Other Course Document",
|
| 937 |
+
file: f,
|
| 938 |
});
|
| 939 |
+
toast.success(`File uploaded: ${f.name}`);
|
| 940 |
} catch (e: any) {
|
| 941 |
+
toast.error(e?.message || `Upload failed: ${f.name}`);
|
| 942 |
+
// allow retry if failed
|
| 943 |
+
uploadedFingerprintsRef.current.delete(fp);
|
| 944 |
}
|
| 945 |
+
}
|
| 946 |
};
|
| 947 |
|
| 948 |
// 2) Remove: accept index OR File OR UploadedFile (use any to avoid prop signature mismatch crash)
|