Skip to content

Commit f60a4a4

Browse files
authored
Merge pull request #131 from Coding-Club-IITG/aditya
Aditya
2 parents d508484 + 76f7d6f commit f60a4a4

File tree

15 files changed

+869
-397
lines changed

15 files changed

+869
-397
lines changed

admin/src/apis/courses.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,97 @@ export const updateCourseName = async (code, newName) => {
3535
throw error;
3636
}
3737
};
38+
39+
// Create a new course
40+
export const createCourse = async (code, name) => {
41+
try {
42+
const response = await fetch(`${API_BASE_URL}api/course/create/${code}`, {
43+
method: "POST",
44+
headers: {
45+
"Content-Type": "application/json",
46+
Authorization: "Bearer admin-coursehub-cc23-golang",
47+
},
48+
body: JSON.stringify({ name }),
49+
credentials: "include",
50+
});
51+
return await response.json();
52+
} catch (error) {
53+
console.error("Error creating course:", error);
54+
throw error;
55+
}
56+
};
57+
58+
// Bulk sync courses from CSV data
59+
export const bulkSyncCourses = async (courses, analysis, onProgress = null) => {
60+
const results = {
61+
created: [],
62+
updated: [],
63+
skipped: [],
64+
errors: [],
65+
};
66+
67+
// Only process courses that need changes
68+
const coursesToProcess = [];
69+
70+
// Add missing courses (need to be created)
71+
if (analysis.missingCourses && analysis.missingCourses.length > 0) {
72+
coursesToProcess.push(...analysis.missingCourses);
73+
}
74+
75+
// Add courses with name mismatches (need to be updated)
76+
if (analysis.nameConflicts && analysis.nameConflicts.length > 0) {
77+
coursesToProcess.push(
78+
...analysis.nameConflicts.map((conflict) => ({
79+
code: conflict.code,
80+
name: conflict.csvName,
81+
}))
82+
);
83+
}
84+
85+
const total = coursesToProcess.length;
86+
let processed = 0;
87+
88+
if (total === 0) {
89+
// No courses need processing
90+
if (onProgress) {
91+
onProgress(0, 0);
92+
}
93+
return results;
94+
}
95+
96+
for (const course of coursesToProcess) {
97+
try {
98+
// Check if this is a missing course (needs creation) or existing course (needs update)
99+
const isMissingCourse =
100+
analysis.missingCourses &&
101+
analysis.missingCourses.some((c) => c.code === course.code);
102+
103+
if (isMissingCourse) {
104+
// Create new course
105+
const createResponse = await createCourse(course.code, course.name);
106+
if (createResponse.message === "Course created successfully") {
107+
results.created.push(course);
108+
} else {
109+
results.errors.push({ course, error: "Failed to create course" });
110+
}
111+
} else {
112+
// Update existing course name
113+
const updateResponse = await updateCourseName(course.code, course.name);
114+
if (updateResponse && updateResponse.code) {
115+
results.updated.push(course);
116+
} else {
117+
results.errors.push({ course, error: "Failed to update course name" });
118+
}
119+
}
120+
} catch (error) {
121+
results.errors.push({ course, error: error.message });
122+
}
123+
124+
processed++;
125+
if (onProgress) {
126+
onProgress(processed, total);
127+
}
128+
}
129+
130+
return results;
131+
};

admin/src/components/ui/alert.jsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as React from "react";
2+
import { cn } from "@/lib/utils";
3+
4+
const Alert = React.forwardRef(({ className, variant, ...props }, ref) => (
5+
<div
6+
ref={ref}
7+
role="alert"
8+
className={cn(
9+
"relative w-full rounded-lg border p-4 max-h-64 overflow-y-auto",
10+
{
11+
"border-gray-200 text-gray-950": variant === "default",
12+
"border-red-200 text-red-800 bg-red-50": variant === "destructive",
13+
"border-yellow-200 text-yellow-800 bg-yellow-50": variant === "warning",
14+
"border-green-200 text-green-800 bg-green-50": variant === "success",
15+
"border-blue-200 text-blue-800 bg-blue-50": variant === "info",
16+
},
17+
className
18+
)}
19+
{...props}
20+
/>
21+
));
22+
Alert.displayName = "Alert";
23+
24+
const AlertDescription = React.forwardRef(({ className, ...props }, ref) => (
25+
<div ref={ref} className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} />
26+
));
27+
AlertDescription.displayName = "AlertDescription";
28+
29+
const AlertTitle = React.forwardRef(({ className, ...props }, ref) => (
30+
<h5
31+
ref={ref}
32+
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
33+
{...props}
34+
/>
35+
));
36+
AlertTitle.displayName = "AlertTitle";
37+
38+
export { Alert, AlertDescription, AlertTitle };

0 commit comments

Comments
 (0)