(undefined);
const [editConfirmOpen, setEditConfirmOpen] = useState(false);
@@ -81,10 +80,9 @@ const Students = () => {
return normalized || null;
}
if (["id_proof", "disability_cert", "photo", "bank_details"].includes(field)) {
- if (value === "Yes") return 1;
- if (value === "No") return 0;
- // Number or null is passed through
- return value ?? null;
+ if (value === "Yes" || value === 1 || value === "1") return "Yes";
+ if (value === "No" || value === 0 || value === "0") return "No";
+ return value === "" ? null : (value ?? null);
}
return value === "" ? null : value;
};
@@ -140,8 +138,7 @@ const Students = () => {
const data = await r.json();
if (data.success !== false) {
setRowData((prev) => prev.map((row) => (row.id === payload.student_id ? { ...row, ...payload } : row)));
- setMessage("Saved!");
- setAlertOpen(true);
+ notify("Saved!", "success");
const focused = lastFocusedCell.current;
if (focused && gridRef.current?.api) {
const { rowIndex, colKey } = focused;
@@ -160,8 +157,7 @@ const Students = () => {
}
} catch (e) {
console.error("Error saving student:", e);
- setMessage(`Save failed: ${e.message || "Unknown error"}`);
- setAlertOpen(true);
+ notify(`Save failed: ${e.message || "Unknown error"}`, "error");
} finally {
setSaving(false);
}
@@ -243,17 +239,14 @@ const Students = () => {
});
if (response.ok) {
- setMessage("Telecaller remarks updated successfully!");
- setAlertOpen(true);
+ notify("Telecaller remarks updated successfully!", "success");
onGridReady();
} else {
- setMessage("Error updating remarks. Please try again.");
- setAlertOpen(true);
+ notify("Error updating remarks. Please try again.", "error");
}
} catch (error) {
console.error("Error updating telecaller remarks:", error);
- setMessage("Error updating remarks. Please try again.");
- setAlertOpen(true);
+ notify("Error updating remarks. Please try again.", "error");
}
return;
}
@@ -262,8 +255,7 @@ const Students = () => {
if (field === "enrollment_status") {
const code = ENROLLMENT_STATUS.find((o) => o.value === rawNew || o.label === rawNew)?.value ?? null;
if (rawNew && !code) {
- setMessage("Invalid enrollment status");
- setAlertOpen(true);
+ notify("Invalid enrollment status", "error");
return;
}
value = code; // Send only code to server
@@ -329,19 +321,16 @@ const Students = () => {
body: JSON.stringify({ student_id, remark: rawNew }),
});
if (response.ok) {
- setMessage("Telecaller remarks updated successfully!");
- setAlertOpen(true);
+ notify("Telecaller remarks updated successfully!", "success");
onGridReady();
} else {
- setMessage("Error updating remarks. Please try again.");
- setAlertOpen(true);
+ notify("Error updating remarks. Please try again.", "error");
isRevertingCellRef.current = true;
node.setDataValue(field, rawOld);
}
} catch (error) {
console.error("Error updating telecaller remarks:", error);
- setMessage("Error updating remarks. Please try again.");
- setAlertOpen(true);
+ notify("Error updating remarks. Please try again.", "error");
isRevertingCellRef.current = true;
node.setDataValue(field, rawOld);
}
@@ -419,9 +408,8 @@ const Students = () => {
body: JSON.stringify({ id: deleteStudentData.id }),
}).then(() => {
const id = deleteStudentData.id;
- setMessage(`${deleteStudentData.name} was deleted!`);
+ notify(`${deleteStudentData.name} was deleted!`, "success");
setDeleteStudentData(null);
- setAlertOpen(true);
setRowData(rowData.filter((student) => student.id !== id));
setLoading(false);
});
@@ -513,7 +501,6 @@ const Students = () => {
}
`}
-
(() => []);
const [courseOptions1, setCourseOptions1] = useState(() => []);
@@ -160,8 +159,7 @@ export default function Page() {
if (response.ok) {
await getPageData();
- setMessage(`User: ${editedUser.name} updated!`);
- setAlertOpen(true);
+ notify(`User: ${editedUser.name} updated!`, "success");
setEditingId(null);
} else {
console.error("Error updating the user");
@@ -170,7 +168,7 @@ export default function Page() {
setContentLoading(false);
}
},
- [getPageData]
+ [getPageData, notify]
);
const onCellValueChanged = async (params) => {
@@ -270,8 +268,7 @@ export default function Page() {
if (response.ok) {
await getPageData();
- setMessage("Staff member created successfully!");
- setAlertOpen(true);
+ notify("Staff member created successfully!", "success");
// Reset controlled form states so the next open starts clean
setShowForm(false);
@@ -288,17 +285,15 @@ export default function Page() {
// ignore JSON parse errors
}
- setMessage("Error creating staff: " + errMessage);
- setAlertOpen(true);
+ notify("Error creating staff: " + errMessage, "error");
}
} catch (error) {
console.error("Error creating staff:", error);
- setMessage("Error creating staff: " + (error?.error || error?.message || "Unknown error"));
- setAlertOpen(true);
+ notify("Error creating staff: " + (error?.error || error?.message || "Unknown error"), "error");
} finally {
setContentLoading(false);
}
- }, [pendingUserCreate, getPageData]);
+ }, [pendingUserCreate, getPageData, notify]);
const onGridReady = useCallback((params) => {
// Store grid API reference if needed
@@ -391,9 +386,8 @@ export default function Page() {
setLoading(true);
setConfirmOpen(false);
handleDeleteUser(deleteUsersData.id).then(() => {
- setMessage(`${deleteUsersData.name} was deleted!`);
+ notify(`${deleteUsersData.name} was deleted!`, "success");
setDeleteUsersData(null);
- setAlertOpen(true);
setLoading(false);
});
};
@@ -571,7 +565,6 @@ export default function Page() {
-
=6.9.0'}
+ '@babel/runtime@7.29.7':
+ resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
+ engines: {node: '>=6.9.0'}
+
'@babel/template@7.27.2':
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'}
@@ -263,6 +270,33 @@ packages:
resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
engines: {node: '>=6.9.0'}
+ '@base-ui/react@1.8.0':
+ resolution: {integrity: sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@date-fns/tz': ^1.2.0
+ '@types/react': ^17 || ^18 || ^19
+ date-fns: ^4.0.0
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ '@date-fns/tz':
+ optional: true
+ '@types/react':
+ optional: true
+ date-fns:
+ optional: true
+
+ '@base-ui/utils@0.4.0':
+ resolution: {integrity: sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==}
+ peerDependencies:
+ '@types/react': ^17 || ^18 || ^19
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@bcoe/v8-coverage@1.0.2':
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
@@ -691,6 +725,21 @@ packages:
'@noble/hashes':
optional: true
+ '@floating-ui/core@1.8.0':
+ resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==}
+
+ '@floating-ui/dom@1.8.0':
+ resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==}
+
+ '@floating-ui/react-dom@2.1.9':
+ resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.12':
+ resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
+
'@hexagon/base64@1.1.28':
resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==}
@@ -4253,6 +4302,9 @@ packages:
reselect@5.1.1:
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
+ reselect@5.2.0:
+ resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==}
+
resend@6.20.0:
resolution: {integrity: sha512-fXDFt7jVMuka6ruS79DzaQFKPyxOAUtoYUGSl3dTUyOnFK9klmUULxADQRzFFtHfHRipYyy62jYcm4cMKqvtjw==}
engines: {node: '>=20'}
@@ -5124,6 +5176,8 @@ snapshots:
'@babel/runtime@7.28.4': {}
+ '@babel/runtime@7.29.7': {}
+
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
@@ -5147,6 +5201,30 @@ snapshots:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
+ '@base-ui/react@1.8.0(@types/react@19.3.0)(date-fns@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
+ dependencies:
+ '@babel/runtime': 7.29.7
+ '@base-ui/utils': 0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
+ '@floating-ui/react-dom': 2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
+ '@floating-ui/utils': 0.2.12
+ react: 19.3.0
+ react-dom: 19.3.0(react@19.3.0)
+ use-sync-external-store: 1.6.0(react@19.3.0)
+ optionalDependencies:
+ '@types/react': 19.3.0
+ date-fns: 4.1.0
+
+ '@base-ui/utils@0.4.0(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
+ dependencies:
+ '@babel/runtime': 7.29.7
+ '@floating-ui/utils': 0.2.12
+ react: 19.3.0
+ react-dom: 19.3.0(react@19.3.0)
+ reselect: 5.2.0
+ use-sync-external-store: 1.6.0(react@19.3.0)
+ optionalDependencies:
+ '@types/react': 19.3.0
+
'@bcoe/v8-coverage@1.0.2': {}
'@better-auth/core@1.7.5(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.1)':
@@ -5497,6 +5575,23 @@ snapshots:
optionalDependencies:
'@noble/hashes': 2.3.0
+ '@floating-ui/core@1.8.0':
+ dependencies:
+ '@floating-ui/utils': 0.2.12
+
+ '@floating-ui/dom@1.8.0':
+ dependencies:
+ '@floating-ui/core': 1.8.0
+ '@floating-ui/utils': 0.2.12
+
+ '@floating-ui/react-dom@2.1.9(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
+ dependencies:
+ '@floating-ui/dom': 1.8.0
+ react: 19.3.0
+ react-dom: 19.3.0(react@19.3.0)
+
+ '@floating-ui/utils@0.2.12': {}
+
'@hexagon/base64@1.1.28': {}
'@humanfs/core@0.19.2':
@@ -9103,6 +9198,8 @@ snapshots:
reselect@5.1.1: {}
+ reselect@5.2.0: {}
+
resend@6.20.0:
dependencies:
postal-mime: 2.7.5
diff --git a/utils/generate-batch-status-report.ts b/utils/generate-batch-status-report.ts
index 47a1801..a98554f 100644
--- a/utils/generate-batch-status-report.ts
+++ b/utils/generate-batch-status-report.ts
@@ -15,13 +15,11 @@ import {
* @param {string} batchName - The batch name (optional, will be fetched if not provided)
* @param {string} courseName - The course name (optional, will be fetched if not provided)
* @returns {Promise}
+ * @throws {Error} when report data is unavailable or report generation fails
*/
export const generateBatchStatusReport = async (batchId, batchName, courseName) => {
if (!batchId) {
- if (typeof window !== "undefined") {
- window.alert("Batch ID is missing");
- }
- return;
+ throw new Error("Batch ID is missing.");
}
try {
@@ -36,10 +34,7 @@ export const generateBatchStatusReport = async (batchId, batchName, courseName)
const batchData = await response.json();
if (!batchData.students || batchData.students.length === 0) {
- if (typeof window !== "undefined") {
- window.alert("No students found for this batch");
- }
- return;
+ throw new Error("No students found for this batch.");
}
// Use fetched batch name and course name if not provided
@@ -198,8 +193,9 @@ export const generateBatchStatusReport = async (batchId, batchName, courseName)
exportToCsv(fileName, rows, summaryRows);
} catch (error) {
console.error("Error generating batch status report:", error);
- if (typeof window !== "undefined") {
- window.alert("Failed to download report. Please try again.");
+ if (error instanceof Error && error.message === "No students found for this batch.") {
+ throw error;
}
+ throw new Error("Failed to download report. Please try again.");
}
};