Skip to content

Commit 8664e35

Browse files
PrincekumarofficialPranay-GottimukulametamyteeeSakshya2504AnandVivek-iiti
authored
bulk cg update (#457)
Co-authored-by: Pranay-Gottimukula <97828875+Pranay-Gottimukula@users.noreply.github.com> Co-authored-by: metamyte <89248467+metamyteee@users.noreply.github.com> Co-authored-by: Sakshya2504 <singhkaserasakshya2504@gmail.com> Co-authored-by: Anand Vivek <anand1234.vivek@gmail.com>
1 parent 7a46cd5 commit 8664e35

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

src/app/(routes)/admin/students/page.tsx

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import type { DTO } from "@/dto/StudentDto";
66
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
77
import { jsondto } from "@/dto/StudentDto";
88
import { CSVImportModal } from "@/components/common/CSVImportModal";
9-
import { addStudents, promoteToManagers, deleteStudents } from "@/helpers/admin/api";
9+
import {
10+
addStudents,
11+
promoteToManagers,
12+
deleteStudents,
13+
updateStudents,
14+
} from "@/helpers/admin/api";
1015
import { fetchPrograms, fetchAllSeasons } from "@/helpers/api";
1116
import { Program } from "@/dto/SalaryDto";
1217
import { toast } from "react-hot-toast";
@@ -36,6 +41,7 @@ const StudentPage = () => {
3641
const [selectedRows, setSelectedRows] = useState<DTO[]>([]);
3742
const [seasons, setSeasons] = useState<{ id: string; name: string }[]>([]);
3843
const [bulkLoading, setBulkLoading] = useState(false);
44+
const [cpiImportOpen, setCpiImportOpen] = useState(false);
3945

4046
const visibleColumns = columns.filter(
4147
(column: any) => !hiddenColumns.includes(column?.accessorKey),
@@ -97,7 +103,38 @@ const StudentPage = () => {
97103
}
98104
setImportLoading(false);
99105
};
106+
const handleCpiImport = async (data: any[]) => {
107+
try {
108+
const payload = data
109+
.map((row) => {
110+
const student = students.find(
111+
(s) => String(s.rollNo) === String(row.rollNo),
112+
);
113+
114+
if (!student) return null;
115+
116+
return {
117+
id: student.id,
118+
cpi: Number(row.cpi),
119+
};
120+
})
121+
.filter(Boolean);
122+
if (payload.length === 0) {
123+
toast.error("No matching roll numbers found");
124+
return;
125+
}
126+
await updateStudents(payload);
127+
128+
toast.success(`Updated CPI for ${payload.length} students`);
100129

130+
const updatedData = await fetchStudentData();
131+
setStudents(updatedData);
132+
133+
setCpiImportOpen(false);
134+
} catch (e) {
135+
toast.error("Failed to update CPI");
136+
}
137+
};
101138
const parseStudentRow = (row: any) => {
102139
if (!row.rollNo || !row.name || !row.email) return null;
103140

@@ -203,6 +240,9 @@ const StudentPage = () => {
203240
toast.error("Failed to delete students");
204241
}
205242
setBulkLoading(false);
243+
} else if (action === "update-cpi") {
244+
setBulkModalOpen(false);
245+
setCpiImportOpen(true);
206246
}
207247
// Add more actions here later
208248
};
@@ -243,6 +283,16 @@ const StudentPage = () => {
243283
entityName="students"
244284
cleanData={true}
245285
/>
286+
<CSVImportModal
287+
open={cpiImportOpen}
288+
onClose={() => setCpiImportOpen(false)}
289+
onSubmit={handleCpiImport}
290+
templateHeaders={["rollNo", "cpi"]}
291+
templateFileName="cpi_update_template.csv"
292+
entityName="cpi updates"
293+
parseRow={(row) => row}
294+
cleanData={true}
295+
/>
246296
<div>
247297
{students.length > 0 && (
248298
<Table
@@ -260,7 +310,11 @@ const StudentPage = () => {
260310
actions={[
261311
{ label: "Create registration for season", value: "register-season" },
262312
{ label: "Promote to CAMC Member", value: "promote-tpc" },
263-
{ label: "🗑️ Delete Students (Admin Only)", value: "delete-students" },
313+
{
314+
label: "🗑️ Delete Students (Admin Only)",
315+
value: "delete-students",
316+
},
317+
{ label: "Bulk CPI Update (Admin Only)", value: "update-cpi" },
264318
]}
265319
onSubmit={handleBulkModalSubmit}
266320
seasons={seasons}

src/helpers/admin/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,9 @@ export async function deleteRegistrations(ids: string[]): Promise<any> {
7979
queryParam: { id: ids },
8080
});
8181
}
82+
export async function updateStudents(payload: any[]): Promise<any> {
83+
return apiCall("/students", {
84+
method: "PATCH",
85+
body: payload,
86+
});
87+
}

0 commit comments

Comments
 (0)