@appcorp/fusion-storybook 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -32,7 +32,6 @@ import { teacherFormValidation } from "./validate";
|
|
|
32
32
|
import { getCachedTeachers, invalidateTeachersCache } from "./cache";
|
|
33
33
|
import { getCachedWorkspaceSync } from "../workspace/cache";
|
|
34
34
|
import { processAvatarFile } from "./avatar-upload";
|
|
35
|
-
import { v4 as uuidv4 } from "uuid";
|
|
36
35
|
// ============================================================================
|
|
37
36
|
// 1.1 DRAWER TYPES
|
|
38
37
|
// ============================================================================
|
|
@@ -107,6 +106,8 @@ export const useTeacherModule = () => {
|
|
|
107
106
|
const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
|
|
108
107
|
const listFetchNowRef = useRef(null);
|
|
109
108
|
const debouncedQuery = useDebounce(state.searchQuery, 800);
|
|
109
|
+
const uploadInProgressRef = useRef(false);
|
|
110
|
+
const lastUploadRef = useRef(null);
|
|
110
111
|
// ============================================================================
|
|
111
112
|
// 1.4.2 API PARAMETERS
|
|
112
113
|
// ============================================================================
|
|
@@ -355,30 +356,30 @@ export const useTeacherModule = () => {
|
|
|
355
356
|
}, [dispatch]);
|
|
356
357
|
const handleAvatarUpload = useCallback(async (file) => {
|
|
357
358
|
try {
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
//
|
|
362
|
-
|
|
359
|
+
// Prevent duplicate concurrent uploads
|
|
360
|
+
const sig = `${file.name}-${file.size}-${file.lastModified}`;
|
|
361
|
+
const now = Date.now();
|
|
362
|
+
// If same file uploaded within last 5s, ignore
|
|
363
|
+
if (lastUploadRef.current &&
|
|
364
|
+
lastUploadRef.current.sig === sig &&
|
|
365
|
+
now - lastUploadRef.current.ts < 5000)
|
|
366
|
+
return;
|
|
367
|
+
if (uploadInProgressRef.current)
|
|
368
|
+
return;
|
|
369
|
+
uploadInProgressRef.current = true;
|
|
370
|
+
lastUploadRef.current = { sig, ts: now };
|
|
363
371
|
// Process avatar file (validate, convert to WebP)
|
|
364
372
|
const result = await processAvatarFile(file);
|
|
365
373
|
if ("type" in result) {
|
|
366
374
|
// Error result
|
|
367
375
|
const error = result;
|
|
368
376
|
showToast(error.message, TOAST_VARIANT.ERROR);
|
|
369
|
-
// dispatch({
|
|
370
|
-
// type: TEACHER_ACTION_TYPES.SET_INPUT_FIELD,
|
|
371
|
-
// payload: { key: "avatarUploading", value: false },
|
|
372
|
-
// });
|
|
373
377
|
return;
|
|
374
378
|
}
|
|
375
|
-
const teacherId = state.
|
|
379
|
+
const teacherId = state.id;
|
|
376
380
|
if (!teacherId) {
|
|
377
381
|
showToast("Please save the teacher record first before uploading an avatar", TOAST_VARIANT.ERROR);
|
|
378
|
-
|
|
379
|
-
// type: TEACHER_ACTION_TYPES.SET_INPUT_FIELD,
|
|
380
|
-
// payload: { key: "avatarUploading", value: false },
|
|
381
|
-
// });
|
|
382
|
+
uploadInProgressRef.current = false;
|
|
382
383
|
return;
|
|
383
384
|
}
|
|
384
385
|
// Upload to S3 via teacher-avatar endpoint
|
|
@@ -392,21 +393,18 @@ export const useTeacherModule = () => {
|
|
|
392
393
|
teacherId,
|
|
393
394
|
fileBase64: result.fileBase64,
|
|
394
395
|
contentType: result.contentType,
|
|
396
|
+
workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id,
|
|
395
397
|
}),
|
|
396
398
|
});
|
|
397
399
|
if (!response.ok) {
|
|
398
400
|
const errorData = await response.json().catch(() => ({}));
|
|
399
401
|
const errorMessage = errorData.error || `Upload failed with status ${response.status}`;
|
|
400
402
|
showToast(errorMessage, TOAST_VARIANT.ERROR);
|
|
401
|
-
|
|
402
|
-
// type: TEACHER_ACTION_TYPES.SET_INPUT_FIELD,
|
|
403
|
-
// payload: { key: "avatarUploading", value: false },
|
|
404
|
-
// });
|
|
403
|
+
uploadInProgressRef.current = false;
|
|
405
404
|
return;
|
|
406
405
|
}
|
|
407
406
|
const data = await response.json();
|
|
408
407
|
const avatarUrl = data.url;
|
|
409
|
-
// Update avatar field with presigned URL
|
|
410
408
|
dispatch({
|
|
411
409
|
type: TEACHER_ACTION_TYPES.SET_INPUT_FIELD,
|
|
412
410
|
payload: { key: "avatar", value: avatarUrl },
|
|
@@ -420,12 +418,9 @@ export const useTeacherModule = () => {
|
|
|
420
418
|
showToast(errorMessage, TOAST_VARIANT.ERROR);
|
|
421
419
|
}
|
|
422
420
|
finally {
|
|
423
|
-
|
|
424
|
-
// type: TEACHER_ACTION_TYPES.SET_INPUT_FIELD,
|
|
425
|
-
// payload: { key: "avatarUploading", value: false },
|
|
426
|
-
// });
|
|
421
|
+
uploadInProgressRef.current = false;
|
|
427
422
|
}
|
|
428
|
-
}, [dispatch, showToast, state.
|
|
423
|
+
}, [dispatch, showToast, state.id, workspace === null || workspace === void 0 ? void 0 : workspace.id]);
|
|
429
424
|
const applyFilters = useCallback(() => {
|
|
430
425
|
dispatch({
|
|
431
426
|
type: TEACHER_ACTION_TYPES.SET_CURRENT_PAGE,
|