Linux websever 5.15.0-153-generic #163-Ubuntu SMP Thu Aug 7 16:37:18 UTC 2025 x86_64
Apache/2.4.52 (Ubuntu)
: 192.168.3.70 | : 192.168.1.99
Cant Read [ /etc/named.conf ]
8.1.2-1ubuntu2.23
urlab
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
var /
www /
html /
coursewise /
assets /
[ HOME SHELL ]
Name
Size
Permission
Action
AcademicTools-tj30wEj0.js
7.55
KB
-rwxr-xr-x
AcademicTools-tj30wEj0.js.map
14.63
KB
-rwxr-xr-x
AddCourse-BTNu-pnI.js
10.08
KB
-rwxr-xr-x
AddCourse-BTNu-pnI.js.map
35.84
KB
-rwxr-xr-x
AdminFeedbackManagement-DsTd1C...
13.52
KB
-rwxr-xr-x
AdminFeedbackManagement-DsTd1C...
45.25
KB
-rwxr-xr-x
CourseReviews-CLlzbLuT.js
27.45
KB
-rwxr-xr-x
CourseReviews-CLlzbLuT.js.map
112.09
KB
-rwxr-xr-x
Dewan-B5d13VSK.png
819.07
KB
-rwxr-xr-x
Dewan-Bniqtmij.js
102
B
-rwxr-xr-x
Dewan-Bniqtmij.js.map
197
B
-rwxr-xr-x
EditCourse-DeWQqcol.js
9.65
KB
-rwxr-xr-x
EditCourse-DeWQqcol.js.map
34.87
KB
-rwxr-xr-x
MyCourses-BA9wctPB.js
8.48
KB
-rwxr-xr-x
MyCourses-BA9wctPB.js.map
31.95
KB
-rwxr-xr-x
Rajput-BnxWGXCy.js
104
B
-rwxr-xr-x
Rajput-BnxWGXCy.js.map
200
B
-rwxr-xr-x
Rajput-CE3gMniE.png
908.11
KB
-rwxr-xr-x
Settings-BGf6-NRc.js
2.09
KB
-rwxr-xr-x
Settings-BGf6-NRc.js.map
5.35
KB
-rwxr-xr-x
TimetableClashChecker-gskbNvYE...
32.74
KB
-rwxr-xr-x
TimetableClashChecker-gskbNvYE...
137.78
KB
-rwxr-xr-x
UserManagement-pl4YxOXe.js
2.17
KB
-rwxr-xr-x
UserManagement-pl4YxOXe.js.map
5.49
KB
-rwxr-xr-x
academic-components-DF0R8Z3x.j...
670.84
KB
-rwxr-xr-x
academic-components-DF0R8Z3x.j...
1.87
MB
-rwxr-xr-x
admin-components-DUStTukf.js
1.36
MB
-rwxr-xr-x
admin-components-DUStTukf.js.m...
5.5
MB
-rwxr-xr-x
apple-touch-icon-CvbJoadU.png
20.94
KB
-rwxr-xr-x
browser-DyVnc2OH.js
392
B
-rwxr-xr-x
browser-DyVnc2OH.js.map
404
B
-rwxr-xr-x
favicon-16x16-CXk8OJVQ.png
734
B
-rwxr-xr-x
favicon-32x32-BMg2Kocu.png
1.78
KB
-rwxr-xr-x
favicon-hhFM0i7Z.ico
15.04
KB
-rwxr-xr-x
geminiService-khxcBfs7.js
2.36
KB
-rwxr-xr-x
geminiService-khxcBfs7.js.map
6.73
KB
-rwxr-xr-x
index-BbxTXAhJ.css
45.32
KB
-rwxr-xr-x
index-DN1SJQ1D.js
73.27
KB
-rwxr-xr-x
index-DN1SJQ1D.js.map
215.58
KB
-rwxr-xr-x
index.es-B3idowhG.js
155.35
KB
-rwxr-xr-x
index.es-B3idowhG.js.map
624.87
KB
-rwxr-xr-x
kunal-UYflGF6w.jpg
9.22
MB
-rwxr-xr-x
kunal-ozIpZZVI.js
102
B
-rwxr-xr-x
kunal-ozIpZZVI.js.map
197
B
-rwxr-xr-x
pdf-vendor-Bz5wMm03.js
317.87
KB
-rwxr-xr-x
pdf-vendor-Bz5wMm03.js.map
976.2
KB
-rwxr-xr-x
purify.es-CQJ0hv7W.js
21.35
KB
-rwxr-xr-x
purify.es-CQJ0hv7W.js.map
88.01
KB
-rwxr-xr-x
react-vendor-BFYHlx6n.js
160.29
KB
-rwxr-xr-x
react-vendor-BFYHlx6n.js.map
687.16
KB
-rwxr-xr-x
sarthak-CfXTejkX.png
764.15
KB
-rwxr-xr-x
sarthak-Cq6ZcrGb.js
106
B
-rwxr-xr-x
sarthak-Cq6ZcrGb.js.map
203
B
-rwxr-xr-x
site-BwHFeIBa.webmanifest
263
B
-rwxr-xr-x
supabase-vendor-DtZyL83W.js
105.45
KB
-rwxr-xr-x
supabase-vendor-DtZyL83W.js.ma...
449.41
KB
-rwxr-xr-x
ui-vendor-DSJ4jbeb.js
44.26
KB
-rwxr-xr-x
ui-vendor-DSJ4jbeb.js.map
190.96
KB
-rwxr-xr-x
useToast-Bg1woyD1.js
414
B
-rwxr-xr-x
useToast-Bg1woyD1.js.map
1.83
KB
-rwxr-xr-x
xlsx-vendor-D_ykzFJ-.js
276.48
KB
-rwxr-xr-x
xlsx-vendor-D_ykzFJ-.js.map
1.37
MB
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : TimetableClashChecker-gskbNvYE.js.map
{"version":3,"file":"TimetableClashChecker-gskbNvYE.js","sources":["../../src_new/features/academic/TimetableClashChecker.tsx"],"sourcesContent":["import React, { useState, useEffect, useMemo } from \"react\";\r\nimport {\r\n Box,\r\n Heading,\r\n Text,\r\n Grid,\r\n Input,\r\n Select,\r\n Button,\r\n Flex,\r\n Badge,\r\n Spinner,\r\n useToast,\r\n IconButton,\r\n Tooltip,\r\n Tag,\r\n TagLabel,\r\n TagLeftIcon,\r\n SimpleGrid,\r\n Divider,\r\n VStack,\r\n HStack,\r\n Tabs,\r\n TabList,\r\n TabPanels,\r\n Tab,\r\n TabPanel,\r\n Table,\r\n Thead,\r\n Tbody,\r\n Tr,\r\n Th,\r\n Td,\r\n Alert,\r\n AlertIcon,\r\n AlertTitle,\r\n AlertDescription,\r\n useDisclosure,\r\n Modal,\r\n ModalOverlay,\r\n ModalContent,\r\n ModalHeader,\r\n ModalFooter,\r\n ModalBody,\r\n ModalCloseButton,\r\n} from \"@chakra-ui/react\";\r\nimport {\r\n Search,\r\n Calendar,\r\n Clock,\r\n AlertCircle,\r\n CheckCircle,\r\n Filter,\r\n Book,\r\n X,\r\n Clock8,\r\n BookmarkCheck,\r\n Minus as MinusIcon,\r\n} from \"lucide-react\";\r\nimport { useNavigate } from \"react-router-dom\";\r\nimport { supabase } from \"../../lib/supabase\";\r\nimport { useAuth } from \"../../lib/contexts/AuthContext\";\r\nimport NavBar from \"../shared/NavBar\";\r\n\r\n// Type definitions\r\ninterface Course {\r\n uuid: string;\r\n course_code: string;\r\n course_name: string;\r\n credits: number;\r\n semester: number | null;\r\n description: string | null;\r\n professor_allocated: string | null;\r\n dept_acronym: string;\r\n prerequisites: string[];\r\n antirequisites: string[];\r\n schedule: Schedule[];\r\n department: {\r\n uuid: string;\r\n dept_name: string;\r\n dept_acronym: string;\r\n } | null;\r\n isSelected?: boolean;\r\n course_acronym?: string;\r\n semester_type?: string | null;\r\n}\r\n\r\ninterface Schedule {\r\n day: string;\r\n start_time: string;\r\n end_time: string;\r\n room?: string;\r\n type?: string;\r\n}\r\n\r\ninterface FilterOptions {\r\n search: string;\r\n semester: string;\r\n department: string;\r\n credits: string;\r\n sortBy: string;\r\n sortOrder: \"asc\" | \"desc\";\r\n}\r\n\r\ninterface ClashResult {\r\n courseId: string;\r\n hasClash: boolean;\r\n clashingWith: string[]; // Course IDs that clash\r\n}\r\n\r\ninterface CourseBlock {\r\n course: Course;\r\n startSlotIndex: number;\r\n endSlotIndex: number;\r\n duration: number; // number of 30-minute slots\r\n}\r\n\r\n// Helper function to convert time string to minutes for comparison\r\nconst timeToMinutes = (timeStr: string): number => {\r\n if (!timeStr) return 0;\r\n const [hours, minutes] = timeStr.split(\":\").map(Number);\r\n return hours * 60 + minutes;\r\n};\r\n\r\n// Function to detect clashes between courses\r\nconst detectClashes = (courses: Course[]): ClashResult[] => {\r\n const results: ClashResult[] = [];\r\n\r\n for (let i = 0; i < courses.length; i++) {\r\n const course = courses[i];\r\n const clashingWith: string[] = [];\r\n\r\n // Skip courses with no schedule\r\n if (!course.schedule || course.schedule.length === 0) {\r\n results.push({\r\n courseId: course.uuid,\r\n hasClash: false,\r\n clashingWith: [],\r\n });\r\n continue;\r\n }\r\n\r\n // Check against all other courses\r\n for (let j = 0; j < courses.length; j++) {\r\n if (i === j) continue; // Skip comparing with itself\r\n\r\n const otherCourse = courses[j];\r\n\r\n // Skip courses with no schedule\r\n if (!otherCourse.schedule || otherCourse.schedule.length === 0) {\r\n continue;\r\n }\r\n\r\n // Compare all schedule slots\r\n for (const slot1 of course.schedule) {\r\n for (const slot2 of otherCourse.schedule) {\r\n // Check if same day and time overlap\r\n if (slot1.day === slot2.day) {\r\n const slot1Start = timeToMinutes(slot1.start_time);\r\n const slot1End = timeToMinutes(slot1.end_time);\r\n const slot2Start = timeToMinutes(slot2.start_time);\r\n const slot2End = timeToMinutes(slot2.end_time);\r\n\r\n // Check for overlap - standard interval overlap check\r\n if (slot1Start < slot2End && slot1End > slot2Start) {\r\n if (!clashingWith.includes(otherCourse.uuid)) {\r\n clashingWith.push(otherCourse.uuid);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n results.push({\r\n courseId: course.uuid,\r\n hasClash: clashingWith.length > 0,\r\n clashingWith,\r\n });\r\n }\r\n\r\n return results;\r\n};\r\n\r\n// Add an array of colors for courses\r\nconst COURSE_COLORS = [\r\n \"blue.400\",\r\n \"green.400\",\r\n \"purple.400\",\r\n \"pink.400\",\r\n \"orange.400\",\r\n \"teal.400\",\r\n \"cyan.400\",\r\n \"yellow.400\",\r\n \"red.400\",\r\n \"indigo.400\",\r\n];\r\n\r\n// Main component\r\nconst TimetableClashChecker: React.FC = () => {\r\n const [courses, setCourses] = useState<Course[]>([]);\r\n const [filteredCourses, setFilteredCourses] = useState<Course[]>([]);\r\n const [selectedCourses, setSelectedCourses] = useState<Course[]>([]);\r\n const [clashResults, setClashResults] = useState<ClashResult[]>([]);\r\n const [departments, setDepartments] = useState<string[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [noCoursesFound, setNoCoursesFound] = useState(false);\r\n const [courseColors, setCourseColors] = useState<{\r\n [courseId: string]: string;\r\n }>({});\r\n const [filters, setFilters] = useState<FilterOptions>({\r\n search: \"\",\r\n semester: \"\",\r\n department: \"\",\r\n credits: \"\",\r\n sortBy: \"name\",\r\n sortOrder: \"asc\",\r\n });\r\n const [viewMode, setViewMode] = useState<\"list\" | \"streams\" | \"semesters\">(\r\n \"streams\",\r\n );\r\n const {\r\n isOpen: isDetailsOpen,\r\n onOpen: onDetailsOpen,\r\n onClose: onDetailsClose,\r\n } = useDisclosure();\r\n const {\r\n isOpen: isTimetableOpen,\r\n onOpen: onTimetableOpen,\r\n onClose: onTimetableClose,\r\n } = useDisclosure();\r\n const [selectedCourseDetails, setSelectedCourseDetails] =\r\n useState<Course | null>(null);\r\n\r\n // Add state variables to track credit count and max limits\r\n const [totalCredits, setTotalCredits] = useState<number>(0);\r\n const [totalCourses, setTotalCourses] = useState<number>(0);\r\n const [creditLimit, setCreditLimit] = useState<number>(20);\r\n const [saving, setSaving] = useState(false);\r\n const [isSavedToCurrentSemester, setIsSavedToCurrentSemester] = useState(false);\r\n const MAX_COURSES = 8;\r\n const MIN_CREDITS = 12;\r\n const MAX_CREDITS = 24;\r\n const CREDIT_LIMITS = [20, 22, 24];\r\n\r\n const navigate = useNavigate();\r\n const toast = useToast();\r\n const { session } = useAuth();\r\n\r\n // Fetch courses on component mount\r\n useEffect(() => {\r\n fetchCourses();\r\n loadCurrentSemesterSelections();\r\n }, []);\r\n\r\n // Define filterCourses before using it in useEffect\r\n const filterCourses = () => {\r\n if (!courses) {\r\n setFilteredCourses([]);\r\n return;\r\n }\r\n\r\n let filtered = [...courses];\r\n\r\n // Apply search filter\r\n if (filters.search) {\r\n const searchLower = filters.search.toLowerCase();\r\n filtered = filtered.filter(\r\n (course) =>\r\n course.course_name.toLowerCase().includes(searchLower) ||\r\n course.course_code.toLowerCase().includes(searchLower) ||\r\n (course.course_acronym && \r\n course.course_acronym.toLowerCase().includes(searchLower)) ||\r\n (course.professor_allocated &&\r\n course.professor_allocated.toLowerCase().includes(searchLower)),\r\n );\r\n }\r\n\r\n // Apply semester filter\r\n if (filters.semester) {\r\n filtered = filtered.filter(\r\n (course) => course.semester === parseInt(filters.semester),\r\n );\r\n }\r\n\r\n // Apply department filter - match on dept_name\r\n if (filters.department) {\r\n filtered = filtered.filter(\r\n (course) =>\r\n course.department &&\r\n course.department.dept_name === filters.department,\r\n );\r\n }\r\n\r\n // Apply credits filter\r\n if (filters.credits) {\r\n filtered = filtered.filter(\r\n (course) => course.credits === parseInt(filters.credits),\r\n );\r\n }\r\n\r\n // Sort results\r\n filtered = filtered.sort((a, b) => {\r\n // Sort logic\r\n if (filters.sortBy === \"name\") {\r\n return filters.sortOrder === \"asc\"\r\n ? a.course_name.localeCompare(b.course_name)\r\n : b.course_name.localeCompare(a.course_name);\r\n } else if (filters.sortBy === \"code\") {\r\n return filters.sortOrder === \"asc\"\r\n ? a.course_code.localeCompare(b.course_code)\r\n : b.course_code.localeCompare(a.course_code);\r\n } else if (filters.sortBy === \"credits\") {\r\n return filters.sortOrder === \"asc\"\r\n ? a.credits - b.credits\r\n : b.credits - a.credits;\r\n }\r\n return 0;\r\n });\r\n\r\n setFilteredCourses(filtered);\r\n };\r\n\r\n // Update filtered courses whenever courses or filters change\r\n useEffect(() => {\r\n filterCourses();\r\n }, [courses, filters]);\r\n\r\n // Update clash results whenever selected courses change\r\n useEffect(() => {\r\n if (selectedCourses.length > 0) {\r\n // Calculate total credits\r\n const credits = selectedCourses.reduce(\r\n (total, course) => total + course.credits,\r\n 0,\r\n );\r\n setTotalCredits(credits);\r\n setTotalCourses(selectedCourses.length);\r\n\r\n // Check for clashes\r\n const results = detectClashes(selectedCourses);\r\n setClashResults(results);\r\n } else {\r\n setTotalCredits(0);\r\n setTotalCourses(0);\r\n setClashResults([]);\r\n }\r\n }, [selectedCourses]);\r\n\r\n const fetchCourses = async () => {\r\n try {\r\n setLoading(true);\r\n console.log('Fetching courses...');\r\n \r\n // Debug Supabase connection\r\n console.log('Attempting to connect to Supabase...');\r\n \r\n // Use the correct table name from the screenshot\r\n const tableName = \"courses_iiitd\";\r\n console.log(`Attempting to fetch data from table: ${tableName}`);\r\n \r\n // Now try to fetch the courses\r\n const { data: coursesData, error: coursesError } = await supabase\r\n .from(tableName)\r\n .select(\"*\");\r\n \r\n console.log('Query result:', coursesData ? 'Data received' : 'No data', 'Error:', coursesError);\r\n \r\n if (coursesError) {\r\n console.error(`Error accessing ${tableName}:`, coursesError);\r\n console.error(`Error details: ${JSON.stringify(coursesError)}`);\r\n setNoCoursesFound(true);\r\n throw new Error(`Error accessing ${tableName}: ${coursesError.message}`);\r\n }\r\n \r\n console.log(`Data from ${tableName}:`, coursesData?.length || 0, 'courses');\r\n \r\n // If no courses data is available, show a toast message\r\n if (!coursesData || coursesData.length === 0) {\r\n console.log(`No data found in ${tableName} table`);\r\n setNoCoursesFound(true);\r\n toast({\r\n title: \"No courses found in database\",\r\n description: \"Please upload courses using the Admin Dashboard or contact the system administrator.\",\r\n status: \"warning\",\r\n duration: 10000,\r\n isClosable: true,\r\n });\r\n setLoading(false);\r\n return;\r\n }\r\n\r\n // Fetch departments separately\r\n const { data: departmentsData, error: departmentsError } = await supabase\r\n .from(\"departments_iiitd\")\r\n .select(\"uuid, dept_name, dept_acronym\");\r\n \r\n console.log('Departments data received:', departmentsData?.length || 0, 'departments');\r\n\r\n if (departmentsError) {\r\n console.error(\"Error fetching departments:\", departmentsError);\r\n }\r\n\r\n // Process courses data with proper field names and join with departments\r\n const processedCourses =\r\n coursesData.map((course) => {\r\n // Find matching department\r\n const dept = departmentsData?.find(\r\n (d) => d.dept_acronym === course.dept_acronym,\r\n );\r\n\r\n // Parse schedule from JSON string if needed\r\n let schedule = [];\r\n if (course.schedule) {\r\n try {\r\n schedule =\r\n typeof course.schedule === \"string\"\r\n ? JSON.parse(course.schedule)\r\n : course.schedule;\r\n } catch (e) {\r\n console.error(\r\n \"Error parsing schedule for course\",\r\n course.course_code,\r\n e,\r\n );\r\n }\r\n }\r\n\r\n return {\r\n ...course,\r\n prerequisites: course.prerequisites\r\n ? course.prerequisites.split(\"/\").filter(Boolean)\r\n : [],\r\n antirequisites: course.antirequisites\r\n ? course.antirequisites.split(\"/\").filter(Boolean)\r\n : [],\r\n schedule: schedule,\r\n department: dept\r\n ? {\r\n uuid: dept.uuid,\r\n dept_name: dept.dept_name,\r\n dept_acronym: dept.dept_acronym,\r\n }\r\n : null,\r\n };\r\n }) || [];\r\n \r\n console.log('Processed courses:', processedCourses.length);\r\n setCourses(processedCourses);\r\n console.log('Courses state updated');\r\n\r\n // Extract unique departments for filter\r\n if (departmentsData) {\r\n const depts = departmentsData.map((d) => d.dept_name).filter(Boolean);\r\n console.log('Setting departments:', depts);\r\n setDepartments(depts);\r\n }\r\n } catch (error: any) {\r\n console.error(\"Error fetching courses:\", error);\r\n toast({\r\n title: \"Error fetching courses\",\r\n description: error.message,\r\n status: \"error\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n setNoCoursesFound(true);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const loadCurrentSemesterSelections = async () => {\r\n if (!session?.user?.id) return;\r\n\r\n try {\r\n // Fetch user's current semester courses\r\n const { data: userData, error } = await supabase\r\n .from(\"users\")\r\n .select(\"current_semester_courses\")\r\n .eq(\"id\", session.user.id)\r\n .single();\r\n\r\n if (error) throw error;\r\n\r\n const currentSemesterData = userData?.current_semester_courses;\r\n if (\r\n currentSemesterData &&\r\n currentSemesterData.courses &&\r\n currentSemesterData.courses.length > 0\r\n ) {\r\n // Create array to hold full course details\r\n const coursesWithDetails: Course[] = [];\r\n\r\n // Use the same table name as in fetchCourses\r\n const tableName = \"courses_iiitd\";\r\n console.log(`Using ${tableName} for current semester selections`);\r\n\r\n // Process each course individually\r\n for (const semesterCourse of currentSemesterData.courses) {\r\n const courseId = semesterCourse.course_uuid || semesterCourse.course_acronym;\r\n\r\n try {\r\n // First, try to fetch the course by course_code/acronym\r\n let { data: courseData } = await supabase\r\n .from(tableName)\r\n .select(\"*\")\r\n .eq(\"course_code\", semesterCourse.course_acronym)\r\n .maybeSingle();\r\n\r\n // If not found by course_code, try by UUID\r\n if (!courseData && semesterCourse.course_uuid) {\r\n try {\r\n const { data: courseByUuid } = await supabase\r\n .from(tableName)\r\n .select(\"*\")\r\n .eq(\"uuid\", semesterCourse.course_uuid)\r\n .maybeSingle();\r\n\r\n if (courseByUuid) {\r\n courseData = courseByUuid;\r\n }\r\n } catch (uuidError) {\r\n console.log(`UUID format error for ${semesterCourse.course_uuid}, skipping course`);\r\n }\r\n }\r\n\r\n // If we found the course, fetch the department separately\r\n if (courseData) {\r\n // Get department data\r\n if (courseData.dept_acronym) {\r\n const { data: deptData } = await supabase\r\n .from(\"departments_iiitd\")\r\n .select(\"uuid, dept_name, dept_acronym\")\r\n .eq(\"dept_acronym\", courseData.dept_acronym)\r\n .maybeSingle();\r\n \r\n // Add department to course data\r\n if (deptData) {\r\n courseData.department = {\r\n uuid: deptData.uuid,\r\n dept_name: deptData.dept_name,\r\n dept_acronym: deptData.dept_acronym\r\n };\r\n }\r\n }\r\n\r\n // Process course data\r\n const courseWithDetails = processCourseFetchResult(courseData);\r\n if (courseWithDetails) {\r\n coursesWithDetails.push(courseWithDetails);\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`Error fetching course ${courseId}:`, error);\r\n }\r\n }\r\n\r\n if (coursesWithDetails.length > 0) {\r\n // Set the selected courses and update state\r\n setSelectedCourses(coursesWithDetails);\r\n setCreditLimit(currentSemesterData.credit_limit || 20);\r\n setIsSavedToCurrentSemester(true);\r\n\r\n // Assign colors to pre-selected courses\r\n const colors: { [courseId: string]: string } = {};\r\n coursesWithDetails.forEach((course, index) => {\r\n colors[course.uuid] = COURSE_COLORS[index % COURSE_COLORS.length];\r\n });\r\n setCourseColors(colors);\r\n\r\n toast({\r\n title: \"Current semester courses loaded\",\r\n description: `Loaded ${coursesWithDetails.length} courses from your current semester`,\r\n status: \"info\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n }\r\n }\r\n } catch (error: any) {\r\n console.error(\"Error loading current semester selections:\", error);\r\n // Don't show error toast for this as it's not critical\r\n }\r\n };\r\n\r\n // Helper function to process course data\r\n const processCourseFetchResult = (course: any): Course | null => {\r\n if (!course) return null;\r\n\r\n try {\r\n // Parse schedule from string to array if needed\r\n let schedule = [];\r\n if (course.schedule) {\r\n try {\r\n schedule =\r\n typeof course.schedule === \"string\"\r\n ? JSON.parse(course.schedule)\r\n : course.schedule;\r\n } catch (e) {\r\n console.error(\"Error parsing schedule:\", e);\r\n schedule = [];\r\n }\r\n }\r\n\r\n // Parse prerequisites and antirequisites if they exist\r\n const prerequisites = course.prerequisites\r\n ? course.prerequisites.split(\"/\").filter(Boolean)\r\n : [];\r\n\r\n const antirequisites = course.antirequisites\r\n ? course.antirequisites.split(\"/\").filter(Boolean)\r\n : [];\r\n\r\n // Process department info - handle nested join\r\n let department: { uuid: string; dept_name: string; dept_acronym: string; } | null = null;\r\n if (course.departments_iiitd) {\r\n department = {\r\n uuid: course.departments_iiitd.uuid,\r\n dept_name: course.departments_iiitd.dept_name,\r\n dept_acronym: course.departments_iiitd.dept_acronym,\r\n };\r\n } else if (course.dept_acronym) {\r\n // Fallback to just using the acronym if we don't have the full department info\r\n department = {\r\n uuid: \"\",\r\n dept_name: course.dept_acronym,\r\n dept_acronym: course.dept_acronym,\r\n };\r\n }\r\n\r\n return {\r\n uuid: course.uuid,\r\n course_code: course.course_code,\r\n course_name: course.course_name,\r\n credits: course.credits,\r\n semester: course.semester,\r\n semester_type: course.semester_type,\r\n description: course.description,\r\n professor_allocated: course.professor_allocated,\r\n dept_acronym: course.dept_acronym,\r\n prerequisites: prerequisites,\r\n antirequisites: antirequisites,\r\n schedule: schedule,\r\n department: department,\r\n course_acronym: course.course_acronym,\r\n };\r\n } catch (e) {\r\n console.error(\"Error processing course data:\", e);\r\n return null;\r\n }\r\n };\r\n\r\n const handleFilterChange = (name: keyof FilterOptions, value: string) => {\r\n setFilters((prev) => ({\r\n ...prev,\r\n [name]: value,\r\n }));\r\n };\r\n\r\n const toggleSort = (field: string) => {\r\n if (filters.sortBy === field) {\r\n setFilters((prev) => ({\r\n ...prev,\r\n sortOrder: prev.sortOrder === \"asc\" ? \"desc\" : \"asc\",\r\n }));\r\n } else {\r\n setFilters((prev) => ({\r\n ...prev,\r\n sortBy: field,\r\n sortOrder: \"asc\",\r\n }));\r\n }\r\n };\r\n\r\n const selectCourse = (course: Course) => {\r\n // Check if course is already selected\r\n const isAlreadySelected = selectedCourses.some(\r\n (c) => c.uuid === course.uuid,\r\n );\r\n\r\n if (isAlreadySelected) {\r\n // Remove from selected courses\r\n setSelectedCourses((prev) => prev.filter((c) => c.uuid !== course.uuid));\r\n\r\n // Remove the color assignment\r\n setCourseColors((prev) => {\r\n const updated = { ...prev };\r\n delete updated[course.uuid];\r\n return updated;\r\n });\r\n\r\n // Mark as not saved since we modified the selection\r\n setIsSavedToCurrentSemester(false);\r\n\r\n toast({\r\n title: \"Course removed\",\r\n description: `${course.course_code} has been removed from your selection`,\r\n status: \"info\",\r\n duration: 2000,\r\n isClosable: true,\r\n });\r\n } else {\r\n // Check course and credit limits\r\n const newTotalCourses = selectedCourses.length + 1;\r\n const newTotalCredits = totalCredits + course.credits;\r\n\r\n if (newTotalCourses > MAX_COURSES) {\r\n toast({\r\n title: \"Course limit exceeded\",\r\n description: `You can select a maximum of ${MAX_COURSES} courses per semester.`,\r\n status: \"warning\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n if (newTotalCredits > creditLimit) {\r\n toast({\r\n title: \"Credit limit exceeded\",\r\n description: `You can select a maximum of ${creditLimit} credits per semester.`,\r\n status: \"warning\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n // Check if adding this course would create a clash\r\n const tempSelected = [...selectedCourses, course];\r\n const tempResults = detectClashes(tempSelected);\r\n\r\n // Find if this course would clash with any existing course\r\n const courseResult = tempResults.find((r) => r.courseId === course.uuid);\r\n const wouldClash = courseResult?.hasClash || false;\r\n\r\n if (wouldClash) {\r\n // Don't add the course, show warning toast instead\r\n const clashingCourses = courseResult?.clashingWith\r\n .map((id) => {\r\n const c = selectedCourses.find((sc) => sc.uuid === id);\r\n return c?.course_code;\r\n })\r\n .filter(Boolean)\r\n .join(\", \");\r\n\r\n toast({\r\n title: \"Schedule Conflict Detected\",\r\n description: `${course.course_code} clashes with ${clashingCourses}. Please select a different course.`,\r\n status: \"warning\",\r\n duration: 4000,\r\n isClosable: true,\r\n });\r\n } else {\r\n // Add to selected courses - keep existing courses\r\n setSelectedCourses((prev) => [...prev, course]);\r\n\r\n // Assign a color to this course\r\n setCourseColors((prev) => {\r\n const nextColorIndex =\r\n Object.keys(prev).length % COURSE_COLORS.length;\r\n return {\r\n ...prev,\r\n [course.uuid]: COURSE_COLORS[nextColorIndex],\r\n };\r\n });\r\n\r\n // Mark as not saved since we modified the selection\r\n setIsSavedToCurrentSemester(false);\r\n\r\n toast({\r\n title: \"Course selected\",\r\n description: `${course.course_code} has been added to your selection`,\r\n status: \"success\",\r\n duration: 2000,\r\n isClosable: true,\r\n });\r\n }\r\n }\r\n };\r\n\r\n const viewCourseDetails = (course: Course) => {\r\n setSelectedCourseDetails(course);\r\n onDetailsOpen();\r\n };\r\n\r\n const getCourseById = (courseId: string): Course | undefined => {\r\n return selectedCourses.find((course) => course.uuid === courseId);\r\n };\r\n\r\n const getClashResultForCourse = (\r\n courseId: string,\r\n ): ClashResult | undefined => {\r\n return clashResults.find((result) => result.courseId === courseId);\r\n };\r\n\r\n const saveToCurrentSemester = async () => {\r\n if (!session?.user?.id) {\r\n toast({\r\n title: \"Authentication required\",\r\n description: \"Please log in to save courses\",\r\n status: \"error\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n if (selectedCourses.length === 0) {\r\n toast({\r\n title: \"No courses selected\",\r\n description: \"Please select courses before saving\",\r\n status: \"warning\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n if (hasAnyClashes) {\r\n toast({\r\n title: \"Cannot save courses with clashes\",\r\n description: \"Please resolve all timetable conflicts before saving\",\r\n status: \"error\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n if (totalCredits < MIN_CREDITS) {\r\n toast({\r\n title: \"Minimum credit requirement not met\",\r\n description: `You need at least ${MIN_CREDITS} credits. Currently selected: ${totalCredits} credits`,\r\n status: \"warning\",\r\n duration: 4000,\r\n isClosable: true,\r\n });\r\n return;\r\n }\r\n\r\n setSaving(true);\r\n try {\r\n // Prepare course data in minimal format\r\n const coursesToSave = selectedCourses.map((course) => ({\r\n course_id: course.uuid,\r\n course_code: course.course_code,\r\n course_name: course.course_name,\r\n credits: course.credits,\r\n schedule: course.schedule,\r\n enrollment_date: new Date().toISOString(),\r\n }));\r\n\r\n const currentSemesterData = {\r\n courses: coursesToSave,\r\n total_credits: totalCredits,\r\n total_courses: totalCourses,\r\n credit_limit: creditLimit,\r\n last_updated: new Date().toISOString(),\r\n clash_checked: true,\r\n };\r\n\r\n // Update user's current semester courses\r\n const { error } = await supabase\r\n .from(\"users\")\r\n .update({ current_semester_courses: currentSemesterData })\r\n .eq(\"id\", session.user.id);\r\n\r\n if (error) throw error;\r\n\r\n toast({\r\n title: \"Courses saved successfully!\",\r\n description: `${totalCourses} courses (${totalCredits} credits) saved to current semester`,\r\n status: \"success\",\r\n duration: 4000,\r\n isClosable: true,\r\n });\r\n\r\n setIsSavedToCurrentSemester(true);\r\n\r\n // Optionally navigate to dashboard\r\n // navigate('/dashboard');\r\n } catch (error: any) {\r\n console.error(\"Error saving courses:\", error);\r\n toast({\r\n title: \"Error saving courses\",\r\n description: error.message,\r\n status: \"error\",\r\n duration: 3000,\r\n isClosable: true,\r\n });\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const hasAnyClashes = useMemo(() => {\r\n return clashResults.some((result) => result.hasClash);\r\n }, [clashResults]);\r\n\r\n // Get color for a course by index\r\n const getCourseColor = (index: number): string => {\r\n const course = selectedCourses[index];\r\n return (\r\n courseColors[course.uuid] || COURSE_COLORS[index % COURSE_COLORS.length]\r\n );\r\n };\r\n\r\n // Use website's theme color for all course cards\r\n const getThemeColor = (): string => {\r\n return \"purple\"; // Matches website's indigo/purple theme\r\n };\r\n\r\n // Group courses by stream\r\n const coursesByStream = useMemo(() => {\r\n const grouped: { [key: string]: Course[] } = {};\r\n\r\n filteredCourses.forEach((course) => {\r\n const streamName = course.department?.dept_name || \"Uncategorized\";\r\n if (!grouped[streamName]) {\r\n grouped[streamName] = [];\r\n }\r\n grouped[streamName].push(course);\r\n });\r\n\r\n return grouped;\r\n }, [filteredCourses]);\r\n\r\n // Group courses by semester\r\n const coursesBySemester = useMemo(() => {\r\n const grouped: { [key: string]: Course[] } = {};\r\n\r\n filteredCourses.forEach((course) => {\r\n // Convert null/undefined to string key \"0\"\r\n const semesterKey = String(course.semester || 0);\r\n if (!grouped[semesterKey]) {\r\n grouped[semesterKey] = [];\r\n }\r\n grouped[semesterKey].push(course);\r\n });\r\n\r\n return Object.entries(grouped)\r\n .sort(([semA], [semB]) => parseInt(semA) - parseInt(semB))\r\n .map(([semester, courses]) => ({\r\n semester: parseInt(semester),\r\n courses,\r\n }));\r\n }, [filteredCourses]);\r\n\r\n // Generate timetable data structure for the weekly view\r\n const weeklyTimetable = useMemo(() => {\r\n const days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"];\r\n const timeSlots: string[] = [];\r\n\r\n // Generate time slots from 8AM to 8PM\r\n for (let hour = 8; hour <= 20; hour++) {\r\n timeSlots.push(`${hour}:00`);\r\n if (hour < 20) timeSlots.push(`${hour}:30`);\r\n }\r\n\r\n // Create course blocks for spanning visualization\r\n const courseBlocks: { [day: string]: CourseBlock[] } = {};\r\n const grid: { [day: string]: { [time: string]: Course[] } } = {};\r\n const occupied: { [day: string]: { [timeIndex: number]: boolean } } = {};\r\n\r\n // Initialize structures\r\n days.forEach((day) => {\r\n courseBlocks[day] = [];\r\n grid[day] = {};\r\n occupied[day] = {};\r\n timeSlots.forEach((time, index) => {\r\n grid[day][time] = [];\r\n occupied[day][index] = false;\r\n });\r\n });\r\n\r\n // Process courses and create blocks\r\n selectedCourses.forEach((course) => {\r\n if (!course.schedule) return;\r\n\r\n course.schedule.forEach((slot) => {\r\n const day = slot.day;\r\n if (!days.includes(day)) return;\r\n\r\n const startMinutes = timeToMinutes(slot.start_time);\r\n const endMinutes = timeToMinutes(slot.end_time);\r\n\r\n // Find all slots the course should occupy\r\n const occupiedSlots: number[] = [];\r\n\r\n // Go through each time slot and check if course runs during that period\r\n for (let i = 0; i < timeSlots.length; i++) {\r\n const [hour, minute] = timeSlots[i].split(\":\").map(Number);\r\n const slotStartMinutes = hour * 60 + minute;\r\n const slotEndMinutes = slotStartMinutes + 30;\r\n\r\n // Proper overlap detection to prevent false clashes at endpoints\r\n // Course includes slot if it starts before slot ends AND ends after slot starts\r\n // BUT: if course ends exactly at slot start, don't include that slot\r\n const courseStartsBeforeSlotEnds = startMinutes < slotEndMinutes;\r\n const courseEndsAfterSlotStarts = endMinutes > slotStartMinutes;\r\n const shouldIncludeSlot =\r\n courseStartsBeforeSlotEnds && courseEndsAfterSlotStarts;\r\n\r\n if (shouldIncludeSlot) {\r\n occupiedSlots.push(i);\r\n }\r\n }\r\n\r\n if (occupiedSlots.length > 0) {\r\n const courseStartSlotIndex = occupiedSlots[0];\r\n const courseEndSlotIndex = occupiedSlots[occupiedSlots.length - 1];\r\n const duration = occupiedSlots.length;\r\n\r\n courseBlocks[day].push({\r\n course,\r\n startSlotIndex: courseStartSlotIndex,\r\n endSlotIndex: courseEndSlotIndex,\r\n duration,\r\n });\r\n\r\n // Mark slots as occupied and populate grid\r\n occupiedSlots.forEach((slotIndex) => {\r\n occupied[day][slotIndex] = true;\r\n grid[day][timeSlots[slotIndex]].push(course);\r\n });\r\n }\r\n });\r\n });\r\n\r\n return { days, timeSlots, grid, courseBlocks, occupied };\r\n }, [selectedCourses]);\r\n\r\n // Check if a course is from current semester (pre-loaded)\r\n const isCourseFromCurrentSemester = (courseId: string): boolean => {\r\n // This will be true for courses that were loaded from current semester\r\n return (\r\n selectedCourses.some((c) => c.uuid === courseId) &&\r\n courseColors[courseId] !== undefined\r\n );\r\n };\r\n\r\n // Course card component\r\n const CourseCard = ({ course }: { course: Course }) => {\r\n const isSelected = selectedCourses.some((c) => c.uuid === course.uuid);\r\n const isFromCurrentSemester = isCourseFromCurrentSemester(course.uuid);\r\n const clashResult = isSelected\r\n ? getClashResultForCourse(course.uuid)\r\n : undefined;\r\n const hasClash = clashResult?.hasClash || false;\r\n const courseColor = isSelected\r\n ? hasClash\r\n ? \"red\"\r\n : courseColors[course.uuid]?.split(\".\")[0] || \"green\"\r\n : null;\r\n const themeColor = getThemeColor();\r\n\r\n return (\r\n <Box\r\n className=\"bg-white rounded-xl shadow-md hover:shadow-lg transition-all duration-300 overflow-hidden border border-gray-100 relative\"\r\n borderColor={\r\n isSelected\r\n ? hasClash\r\n ? \"red.300\"\r\n : courseColors[course.uuid] || \"green.300\"\r\n : `${themeColor}.200`\r\n }\r\n borderLeftWidth={isSelected ? \"4px\" : \"1px\"}\r\n borderWidth={isSelected ? \"2px\" : \"1px\"}\r\n transition=\"all 0.2s\"\r\n _hover={{\r\n transform: \"translateY(-2px)\",\r\n boxShadow: \"md\",\r\n }}\r\n >\r\n {/* Color strip at the top based on stream or selection status */}\r\n <Box\r\n h=\"6px\"\r\n w=\"100%\"\r\n bg={\r\n isSelected\r\n ? hasClash\r\n ? \"red.400\"\r\n : courseColors[course.uuid] || \"green.400\"\r\n : `linear-gradient(to right, var(--chakra-colors-${themeColor}-400), var(--chakra-colors-${themeColor}-500))`\r\n }\r\n />\r\n\r\n <Box p={5}>\r\n <Flex justifyContent=\"space-between\" alignItems=\"flex-start\" mb={3}>\r\n <Box>\r\n <Badge\r\n colorScheme={\r\n isSelected\r\n ? hasClash\r\n ? \"red\"\r\n : courseColor || \"green\"\r\n : themeColor\r\n }\r\n rounded=\"full\"\r\n px={2}\r\n py={0.5}\r\n fontSize=\"xs\"\r\n >\r\n Semester {course.semester}\r\n </Badge>\r\n <Badge\r\n ml={2}\r\n colorScheme={\r\n isSelected\r\n ? hasClash\r\n ? \"red\"\r\n : courseColor || \"green\"\r\n : themeColor\r\n }\r\n variant=\"subtle\"\r\n rounded=\"full\"\r\n px={2}\r\n py={0.5}\r\n fontSize=\"xs\"\r\n >\r\n {course.credits} credit{course.credits !== 1 ? \"s\" : \"\"}\r\n </Badge>\r\n {isFromCurrentSemester && (\r\n <Badge\r\n ml={2}\r\n colorScheme=\"purple\"\r\n variant=\"solid\"\r\n rounded=\"full\"\r\n px={2}\r\n py={0.5}\r\n fontSize=\"xs\"\r\n >\r\n Current\r\n </Badge>\r\n )}\r\n </Box>\r\n\r\n <IconButton\r\n aria-label={\r\n isSelected ? \"Remove from selection\" : \"Add to selection\"\r\n }\r\n icon={\r\n isSelected ? (\r\n hasClash ? (\r\n <AlertCircle size={18} />\r\n ) : (\r\n <CheckCircle size={18} />\r\n )\r\n ) : (\r\n <Calendar size={18} />\r\n )\r\n }\r\n size=\"sm\"\r\n colorScheme={\r\n isSelected\r\n ? hasClash\r\n ? \"red\"\r\n : courseColor || \"green\"\r\n : themeColor\r\n }\r\n variant={isSelected ? \"solid\" : \"outline\"}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n selectCourse(course);\r\n }}\r\n />\r\n </Flex>\r\n\r\n <Heading\r\n size=\"md\"\r\n mb={1}\r\n noOfLines={1}\r\n title={course.course_name}\r\n color={\r\n isSelected\r\n ? hasClash\r\n ? \"red.700\"\r\n : `${courseColor}.700` || \"green.700\"\r\n : `${themeColor}.700`\r\n }\r\n >\r\n {course.course_name}\r\n </Heading>\r\n\r\n <Text\r\n fontSize=\"sm\"\r\n color={\r\n isSelected\r\n ? hasClash\r\n ? \"red.500\"\r\n : `${courseColor}.500` || \"green.500\"\r\n : `${themeColor}.500`\r\n }\r\n fontFamily=\"mono\"\r\n mb={4}\r\n >\r\n {course.course_code}\r\n </Text>\r\n\r\n <Text\r\n fontSize=\"sm\"\r\n color=\"gray.600\"\r\n noOfLines={2}\r\n mb={4}\r\n title={course.description || \"No description available\"}\r\n >\r\n {course.description || \"No description available\"}\r\n </Text>\r\n\r\n <HStack spacing={4} mb={4}>\r\n {course.professor_allocated && (\r\n <Flex align=\"center\" gap={1.5}>\r\n <Clock\r\n size={14}\r\n className={\r\n isSelected\r\n ? hasClash\r\n ? \"text-red-400\"\r\n : `text-${courseColor}-400` || \"text-green-400\"\r\n : `text-${themeColor}-400`\r\n }\r\n />\r\n <Text fontSize=\"xs\" color=\"gray.600\">\r\n {course.schedule && course.schedule.length > 0\r\n ? `${course.schedule.length} schedule slot${course.schedule.length !== 1 ? \"s\" : \"\"}`\r\n : \"No schedule\"}\r\n </Text>\r\n </Flex>\r\n )}\r\n\r\n {course.department?.dept_name && (\r\n <Flex align=\"center\" gap={1.5}>\r\n <Book\r\n size={14}\r\n className={\r\n isSelected\r\n ? hasClash\r\n ? \"text-red-400\"\r\n : `text-${courseColor}-400` || \"text-green-400\"\r\n : `text-${themeColor}-400`\r\n }\r\n />\r\n <Text fontSize=\"xs\" color=\"gray.600\">\r\n {course.professor_allocated || \"No professor assigned\"}\r\n </Text>\r\n </Flex>\r\n )}\r\n </HStack>\r\n\r\n {isSelected && hasClash && (\r\n <Alert\r\n status=\"error\"\r\n variant=\"left-accent\"\r\n mb={4}\r\n py={2}\r\n fontSize=\"xs\"\r\n >\r\n <AlertIcon boxSize={4} />\r\n <AlertTitle fontSize=\"xs\" mr={1}>\r\n Timetable clash detected!\r\n </AlertTitle>\r\n </Alert>\r\n )}\r\n\r\n <Divider mb={4} />\r\n\r\n <Button\r\n size=\"sm\"\r\n width=\"full\"\r\n colorScheme={\r\n isSelected\r\n ? hasClash\r\n ? \"red\"\r\n : courseColor || \"purple\"\r\n : themeColor\r\n }\r\n variant=\"outline\"\r\n onClick={() => viewCourseDetails(course)}\r\n >\r\n View Details\r\n </Button>\r\n </Box>\r\n </Box>\r\n );\r\n };\r\n\r\n // Render the appropriate content based on loading and data state\r\n const renderContent = () => {\r\n if (loading) {\r\n return (\r\n <Flex justifyContent=\"center\" py={10}>\r\n <Spinner size=\"xl\" color=\"purple.500\" />\r\n </Flex>\r\n );\r\n }\r\n\r\n if (noCoursesFound) {\r\n return (\r\n <Flex\r\n direction=\"column\"\r\n align=\"center\"\r\n justify=\"center\"\r\n bg=\"white\"\r\n rounded=\"xl\"\r\n shadow=\"md\"\r\n p={8}\r\n mt={4}\r\n >\r\n <Box p={4} bg=\"purple.50\" rounded=\"full\" mb={4}>\r\n <Search size={40} className=\"text-purple-400\" />\r\n </Box>\r\n <Heading size=\"md\" mb={4} color=\"gray.700\">\r\n No Courses Found in Database\r\n </Heading>\r\n <Text color=\"gray.500\" textAlign=\"center\" mb={4}>\r\n It appears there are no courses in the database yet. \r\n </Text>\r\n \r\n <Box bg=\"blue.50\" p={4} borderRadius=\"md\" mb={6} maxW=\"600px\" textAlign=\"left\">\r\n <Heading size=\"sm\" mb={2} color=\"blue.700\">\r\n Administrator Instructions:\r\n </Heading>\r\n <Text fontSize=\"sm\" color=\"gray.700\" mb={2}>\r\n 1. There is a CSV file named \"iiitd_final_courses.csv\" in the project root directory.\r\n </Text>\r\n <Text fontSize=\"sm\" color=\"gray.700\" mb={2}>\r\n 2. Go to Admin Dashboard {`>`} Bulk Course Upload.\r\n </Text>\r\n <Text fontSize=\"sm\" color=\"gray.700\">\r\n 3. Upload the CSV file to populate the course database.\r\n </Text>\r\n </Box>\r\n \r\n {/* Check if user is admin and show button */}\r\n <Button\r\n colorScheme=\"purple\"\r\n leftIcon={<AlertCircle size={16} />}\r\n onClick={() => navigate('/admin/bulk-upload')}\r\n size=\"md\"\r\n >\r\n Go to Admin Dashboard\r\n </Button>\r\n </Flex>\r\n );\r\n }\r\n\r\n if (filteredCourses.length === 0) {\r\n return (\r\n <Flex\r\n direction=\"column\"\r\n align=\"center\"\r\n justify=\"center\"\r\n bg=\"white\"\r\n rounded=\"xl\"\r\n shadow=\"md\"\r\n p={8}\r\n mt={4}\r\n >\r\n <Box p={4} bg=\"purple.50\" rounded=\"full\" mb={4}>\r\n <Search size={40} className=\"text-purple-400\" />\r\n </Box>\r\n <Heading size=\"md\" mb={2} color=\"gray.700\">\r\n No courses found\r\n </Heading>\r\n <Text color=\"gray.500\" textAlign=\"center\">\r\n Try adjusting your search filters to find more courses\r\n </Text>\r\n </Flex>\r\n );\r\n }\r\n\r\n return (\r\n <Box>\r\n {viewMode === \"list\" && (\r\n <Grid\r\n templateColumns={{\r\n base: \"repeat(1, 1fr)\",\r\n md: \"repeat(2, 1fr)\",\r\n lg: \"repeat(3, 1fr)\",\r\n }}\r\n gap={6}\r\n >\r\n {filteredCourses.map((course) => (\r\n <CourseCard key={course.uuid} course={course} />\r\n ))}\r\n </Grid>\r\n )}\r\n\r\n {viewMode === \"streams\" && (\r\n <Tabs variant=\"soft-rounded\" colorScheme=\"purple\" isLazy>\r\n <TabList\r\n overflowX=\"auto\"\r\n py={2}\r\n className=\"flex-nowrap whitespace-nowrap\"\r\n >\r\n {Object.keys(coursesByStream).map((streamName) => (\r\n <Tab key={streamName} px={4}>\r\n {streamName} ({coursesByStream[streamName].length})\r\n </Tab>\r\n ))}\r\n </TabList>\r\n <TabPanels>\r\n {Object.entries(coursesByStream).map(([streamName, courses]) => (\r\n <TabPanel key={streamName} px={0}>\r\n <Grid\r\n templateColumns={{\r\n base: \"repeat(1, 1fr)\",\r\n md: \"repeat(2, 1fr)\",\r\n lg: \"repeat(3, 1fr)\",\r\n }}\r\n gap={6}\r\n >\r\n {courses.map((course) => (\r\n <CourseCard key={course.uuid} course={course} />\r\n ))}\r\n </Grid>\r\n </TabPanel>\r\n ))}\r\n </TabPanels>\r\n </Tabs>\r\n )}\r\n\r\n {viewMode === \"semesters\" && (\r\n <Tabs variant=\"soft-rounded\" colorScheme=\"purple\" isLazy>\r\n <TabList\r\n overflowX=\"auto\"\r\n py={2}\r\n className=\"flex-nowrap whitespace-nowrap\"\r\n >\r\n {coursesBySemester.map(({ semester, courses }) => (\r\n <Tab key={semester} px={4}>\r\n Semester {semester} ({courses.length})\r\n </Tab>\r\n ))}\r\n </TabList>\r\n <TabPanels>\r\n {coursesBySemester.map(({ semester, courses }) => (\r\n <TabPanel key={semester} px={0}>\r\n <Grid\r\n templateColumns={{\r\n base: \"repeat(1, 1fr)\",\r\n md: \"repeat(2, 1fr)\",\r\n lg: \"repeat(3, 1fr)\",\r\n }}\r\n gap={6}\r\n >\r\n {courses.map((course) => (\r\n <CourseCard key={course.uuid} course={course} />\r\n ))}\r\n </Grid>\r\n </TabPanel>\r\n ))}\r\n </TabPanels>\r\n </Tabs>\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n return (\r\n <>\r\n <NavBar />\r\n <Box className=\"min-h-screen bg-gradient-to-br from-indigo-50 to-purple-50 pb-16\">\r\n <Box maxW=\"1200px\" margin=\"0 auto\" p={[4, 6, 8]}>\r\n <Flex direction=\"column\" gap={6}>\r\n {/* Header section */}\r\n <Box className=\"bg-gradient-to-r from-indigo-600 to-purple-600 rounded-xl shadow-xl p-8 text-white\">\r\n <Flex\r\n direction={[\"column\", \"row\"]}\r\n alignItems=\"center\"\r\n gap={4}\r\n position=\"relative\"\r\n >\r\n <Box className=\"bg-white/20 p-4 rounded-full backdrop-blur-sm\">\r\n <Calendar size={40} />\r\n </Box>\r\n <Box>\r\n <Heading size=\"xl\">Timetable Clash Checker</Heading>\r\n <Text fontSize=\"lg\" mt={2} opacity={0.9}>\r\n Select multiple courses to check for scheduling conflicts\r\n </Text>\r\n </Box>\r\n <HStack\r\n spacing={2}\r\n position={[\"static\", \"absolute\"]}\r\n right={4}\r\n top={4}\r\n mt={[4, 0]}\r\n ml={[\"auto\", 0]}\r\n >\r\n {selectedCourses.length > 0 && (\r\n <Button\r\n leftIcon={<Calendar size={16} />}\r\n colorScheme=\"white\"\r\n variant=\"outline\"\r\n onClick={onTimetableOpen}\r\n size=\"sm\"\r\n >\r\n View Timetable\r\n </Button>\r\n )}\r\n <Button\r\n leftIcon={\r\n <Box as=\"span\" className=\"rotate-180 inline-block\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n className=\"h-5 w-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M10 19l-7-7m0 0l7-7m-7 7h18\"\r\n />\r\n </svg>\r\n </Box>\r\n }\r\n colorScheme=\"white\"\r\n variant=\"outline\"\r\n onClick={() => navigate(\"/academic-tools\")}\r\n size=\"sm\"\r\n >\r\n Back to Academic Tools\r\n </Button>\r\n </HStack>\r\n </Flex>\r\n </Box>\r\n\r\n {/* Selected courses and clash detection results */}\r\n {selectedCourses.length > 0 && (\r\n <Box className=\"bg-white rounded-xl shadow-lg p-6\">\r\n <Flex justifyContent=\"space-between\" alignItems=\"center\" mb={4}>\r\n <Heading size=\"md\">Selected Courses</Heading>\r\n <HStack spacing={3}>\r\n <Tag\r\n size=\"md\"\r\n colorScheme={\r\n totalCourses >= MAX_COURSES ? \"orange\" : \"purple\"\r\n }\r\n variant=\"subtle\"\r\n >\r\n <TagLeftIcon as={Calendar} />\r\n <TagLabel fontWeight=\"bold\">\r\n {totalCourses}/{MAX_COURSES} Courses\r\n </TagLabel>\r\n </Tag>\r\n <Tag\r\n size=\"md\"\r\n colorScheme={\r\n totalCredits < MIN_CREDITS\r\n ? \"red\"\r\n : totalCredits >= creditLimit\r\n ? \"orange\"\r\n : \"blue\"\r\n }\r\n variant=\"subtle\"\r\n >\r\n <TagLeftIcon boxSize={3} as={Book} />\r\n <TagLabel fontWeight=\"bold\">\r\n {totalCredits}/{creditLimit} Credits\r\n {totalCredits < MIN_CREDITS && ` (Min: ${MIN_CREDITS})`}\r\n </TagLabel>\r\n </Tag>\r\n <Select\r\n size=\"sm\"\r\n value={creditLimit}\r\n onChange={(e) => setCreditLimit(Number(e.target.value))}\r\n width=\"100px\"\r\n >\r\n {CREDIT_LIMITS.map((limit) => (\r\n <option key={limit} value={limit}>\r\n {limit} Credits\r\n </option>\r\n ))}\r\n </Select>\r\n </HStack>\r\n </Flex>\r\n\r\n {hasAnyClashes ? (\r\n <Alert status=\"error\" mb={4}>\r\n <AlertIcon />\r\n <AlertTitle>Schedule conflicts detected!</AlertTitle>\r\n <AlertDescription>\r\n Some of your selected courses have time clashes. Check the\r\n details below.\r\n </AlertDescription>\r\n </Alert>\r\n ) : (\r\n <Alert status=\"success\" mb={4}>\r\n <AlertIcon />\r\n <AlertTitle>No conflicts detected!</AlertTitle>\r\n <AlertDescription>\r\n Your selected courses don't have any schedule conflicts.\r\n </AlertDescription>\r\n </Alert>\r\n )}\r\n\r\n {/* Save to Current Semester Button */}\r\n {selectedCourses.length > 0 && !hasAnyClashes && (\r\n <Flex justifyContent=\"center\" mb={4}>\r\n <Button\r\n colorScheme={\r\n totalCredits >= MIN_CREDITS ? \"green\" : \"gray\"\r\n }\r\n size=\"lg\"\r\n leftIcon={<CheckCircle size={20} />}\r\n onClick={saveToCurrentSemester}\r\n isLoading={saving}\r\n loadingText=\"Saving courses...\"\r\n disabled={hasAnyClashes || totalCredits < MIN_CREDITS}\r\n >\r\n {isSavedToCurrentSemester ? \"Update Current Semester\" : \"Save to Current Semester\"}\r\n {totalCredits < MIN_CREDITS &&\r\n ` (Need ${MIN_CREDITS - totalCredits} more credits)`}\r\n </Button>\r\n </Flex>\r\n )}\r\n\r\n {/* Selected courses list with clash information */}\r\n <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4} mb={6}>\r\n {selectedCourses.map((course) => {\r\n const clashResult = getClashResultForCourse(course.uuid);\r\n const hasClash = clashResult?.hasClash || false;\r\n const courseColor =\r\n courseColors[course.uuid] || \"green.400\";\r\n const colorBase = hasClash\r\n ? \"red\"\r\n : courseColor.split(\".\")[0];\r\n\r\n return (\r\n <Box\r\n key={course.uuid}\r\n p={4}\r\n borderWidth=\"1px\"\r\n borderColor={hasClash ? \"red.300\" : `${courseColor}`}\r\n bg={hasClash ? \"red.50\" : `${colorBase}.50`}\r\n borderLeft={`4px solid ${hasClash ? \"red.400\" : courseColor}`}\r\n rounded=\"md\"\r\n position=\"relative\"\r\n transition=\"all 0.2s\"\r\n boxShadow=\"sm\"\r\n _hover={{\r\n boxShadow: \"md\",\r\n bg: hasClash ? \"red.100\" : `${colorBase}.100`,\r\n }}\r\n >\r\n <Flex justify=\"space-between\" align=\"flex-start\">\r\n <Box>\r\n <Heading\r\n size=\"sm\"\r\n mb={1}\r\n color={hasClash ? \"red.700\" : `${colorBase}.700`}\r\n >\r\n {course.course_code}: {course.course_name}\r\n </Heading>\r\n\r\n {course.schedule && course.schedule.length > 0 ? (\r\n <VStack align=\"start\" spacing={1} mt={2}>\r\n {course.schedule.map((slot, index) => (\r\n <Text key={index} fontSize=\"xs\">\r\n {slot.day}, {slot.start_time} -{\" \"}\r\n {slot.end_time}\r\n </Text>\r\n ))}\r\n </VStack>\r\n ) : (\r\n <Text fontSize=\"xs\" color=\"gray.500\">\r\n No schedule information available\r\n </Text>\r\n )}\r\n\r\n {hasClash && (\r\n <Box mt={3}>\r\n <Text\r\n fontSize=\"sm\"\r\n color=\"red.600\"\r\n fontWeight=\"bold\"\r\n >\r\n Clashes with:\r\n </Text>\r\n <VStack align=\"start\" spacing={1} mt={1}>\r\n {clashResult?.clashingWith.map((clashId) => {\r\n const clashCourse = getCourseById(clashId);\r\n return clashCourse ? (\r\n <Text key={clashId} fontSize=\"xs\">\r\n {clashCourse.course_code}:{\" \"}\r\n {clashCourse.course_name}\r\n </Text>\r\n ) : null;\r\n })}\r\n </VStack>\r\n </Box>\r\n )}\r\n </Box>\r\n\r\n <IconButton\r\n aria-label=\"Remove course\"\r\n icon={<X size={14} />}\r\n size=\"sm\"\r\n colorScheme={hasClash ? \"red\" : colorBase}\r\n variant=\"ghost\"\r\n onClick={() => selectCourse(course)}\r\n />\r\n </Flex>\r\n </Box>\r\n );\r\n })}\r\n </SimpleGrid>\r\n\r\n {/* Course cards for quick view */}\r\n <VStack spacing={2} align=\"stretch\" mb={4}>\r\n {selectedCourses.map((course, index) => {\r\n const courseColor = getCourseColor(index);\r\n const colorBase = courseColor.split(\".\")[0];\r\n\r\n return (\r\n <Flex\r\n key={`course-card-${course.course_code}`}\r\n p={2}\r\n justify=\"space-between\"\r\n align=\"center\"\r\n borderRadius=\"md\"\r\n borderLeft={`4px solid ${courseColor}`}\r\n bg={`${colorBase}.50`}\r\n boxShadow=\"sm\"\r\n transition=\"all 0.2s\"\r\n _hover={{\r\n boxShadow: \"md\",\r\n bg: `${colorBase}.100`,\r\n }}\r\n >\r\n <Box>\r\n <Flex align=\"center\">\r\n <Text\r\n fontWeight=\"bold\"\r\n fontSize=\"sm\"\r\n color={`${colorBase}.700`}\r\n >\r\n {course.course_code}\r\n </Text>\r\n <Badge ml={2} colorScheme={colorBase} size=\"sm\">\r\n {course.credits} Credits\r\n </Badge>\r\n </Flex>\r\n <Text fontSize=\"xs\" noOfLines={1}>\r\n {course.course_name}\r\n </Text>\r\n </Box>\r\n <IconButton\r\n aria-label=\"Remove course\"\r\n icon={<MinusIcon />}\r\n colorScheme={colorBase}\r\n size=\"xs\"\r\n onClick={() => selectCourse(course)}\r\n />\r\n </Flex>\r\n );\r\n })}\r\n </VStack>\r\n\r\n {/* Weekly timetable visualization */}\r\n <Box mb={6}>\r\n <Flex\r\n justifyContent=\"space-between\"\r\n alignItems=\"center\"\r\n mb={4}\r\n >\r\n <Heading size=\"md\">Timetable Visualization</Heading>\r\n <HStack>\r\n <Button\r\n size=\"sm\"\r\n leftIcon={<Calendar size={14} />}\r\n colorScheme=\"purple\"\r\n onClick={onTimetableOpen}\r\n variant=\"outline\"\r\n >\r\n View Full Timetable\r\n </Button>\r\n </HStack>\r\n </Flex>\r\n\r\n <Box\r\n maxHeight=\"400px\"\r\n overflowY=\"auto\"\r\n overflowX=\"auto\"\r\n borderWidth=\"1px\"\r\n borderColor=\"gray.200\"\r\n borderRadius=\"md\"\r\n >\r\n {/* Grid-based timetable - Days vertical, Time horizontal */}\r\n <Box\r\n display=\"grid\"\r\n gridTemplateColumns={`100px repeat(${weeklyTimetable.timeSlots.length}, 80px)`}\r\n gridTemplateRows={`40px repeat(${weeklyTimetable.days.length}, 60px)`}\r\n minW=\"1400px\"\r\n bg=\"white\"\r\n gap=\"1px\"\r\n >\r\n {/* Top-left corner */}\r\n <Box\r\n bg=\"gray.50\"\r\n border=\"1px solid\"\r\n borderColor=\"gray.200\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"sm\"\r\n >\r\n Day / Time\r\n </Box>\r\n\r\n {/* Time header row */}\r\n {weeklyTimetable.timeSlots.map((timeSlot) => (\r\n <Box\r\n key={timeSlot}\r\n bg=\"gray.50\"\r\n border=\"1px solid\"\r\n borderColor=\"gray.200\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"medium\"\r\n fontSize=\"xs\"\r\n textAlign=\"center\"\r\n >\r\n {timeSlot}\r\n </Box>\r\n ))}\r\n\r\n {/* Day rows and course blocks */}\r\n {weeklyTimetable.days.map((day, dayIndex) => (\r\n <React.Fragment key={day}>\r\n {/* Day label */}\r\n <Box\r\n bg=\"gray.50\"\r\n border=\"1px solid\"\r\n borderColor=\"gray.200\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"sm\"\r\n >\r\n {day}\r\n </Box>\r\n\r\n {/* Time slots for this day */}\r\n {weeklyTimetable.timeSlots.map(\r\n (timeSlot, timeIndex) => {\r\n // Check if this slot should be rendered or is part of a spanning block\r\n const courseBlock = weeklyTimetable.courseBlocks[\r\n day\r\n ].find(\r\n (block) => block.startSlotIndex === timeIndex,\r\n );\r\n\r\n if (courseBlock) {\r\n // Render spanning block\r\n const courseColor =\r\n courseColors[courseBlock.course.uuid] ||\r\n \"green.400\";\r\n const colorBase = courseColor.split(\".\")[0];\r\n const hasClash =\r\n weeklyTimetable.grid[day][timeSlot].length >\r\n 1;\r\n\r\n return (\r\n <Box\r\n key={`${day}-${timeSlot}-block`}\r\n gridColumnStart={timeIndex + 2}\r\n gridColumnEnd={\r\n timeIndex + 2 + courseBlock.duration\r\n }\r\n gridRow={dayIndex + 2}\r\n bg={\r\n hasClash ? \"red.100\" : `${colorBase}.100`\r\n }\r\n border=\"2px solid\"\r\n borderColor={\r\n hasClash ? \"red.400\" : courseColor\r\n }\r\n borderRadius=\"md\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"sm\"\r\n color={\r\n hasClash ? \"red.700\" : `${colorBase}.700`\r\n }\r\n position=\"relative\"\r\n boxShadow=\"sm\"\r\n transition=\"all 0.2s\"\r\n _hover={{\r\n bg: hasClash\r\n ? \"red.200\"\r\n : `${colorBase}.200`,\r\n boxShadow: \"md\",\r\n transform: \"scale(1.02)\",\r\n }}\r\n cursor=\"pointer\"\r\n onClick={() =>\r\n viewCourseDetails(courseBlock.course)\r\n }\r\n p={1}\r\n >\r\n <VStack spacing={0}>\r\n <Text\r\n fontWeight=\"bold\"\r\n fontSize=\"xs\"\r\n textAlign=\"center\"\r\n >\r\n {courseBlock.course.course_code}\r\n </Text>\r\n {courseBlock.duration > 2 && (\r\n <Text\r\n fontSize=\"10px\"\r\n opacity={0.8}\r\n textAlign=\"center\"\r\n >\r\n {courseBlock.course.course_name\r\n .length > 15\r\n ? courseBlock.course.course_name.substring(\r\n 0,\r\n 15,\r\n ) + \"...\"\r\n : courseBlock.course.course_name}\r\n </Text>\r\n )}\r\n {hasClash && (\r\n <Text\r\n fontSize=\"9px\"\r\n bg=\"red.200\"\r\n color=\"red.700\"\r\n px={1}\r\n borderRadius=\"sm\"\r\n >\r\n CLASH\r\n </Text>\r\n )}\r\n </VStack>\r\n </Box>\r\n );\r\n } else if (\r\n !weeklyTimetable.occupied[day][timeIndex]\r\n ) {\r\n // Render empty cell only if not occupied by a spanning block\r\n return (\r\n <Box\r\n key={`${day}-${timeSlot}-empty`}\r\n border=\"1px solid\"\r\n borderColor=\"gray.200\"\r\n bg=\"white\"\r\n />\r\n );\r\n }\r\n return null;\r\n },\r\n )}\r\n </React.Fragment>\r\n ))}\r\n </Box>\r\n </Box>\r\n\r\n {/* Add color legend */}\r\n {selectedCourses.length > 0 && (\r\n <Flex mt={3} flexWrap=\"wrap\" gap={2}>\r\n <Text\r\n fontSize=\"sm\"\r\n fontWeight=\"medium\"\r\n color=\"gray.600\"\r\n mr={2}\r\n >\r\n Color Legend:\r\n </Text>\r\n {selectedCourses.map((course) => {\r\n const courseColor =\r\n courseColors[course.uuid] || \"green.400\";\r\n const colorBase = courseColor.split(\".\")[0];\r\n\r\n return (\r\n <Box\r\n key={`legend-${course.uuid}`}\r\n display=\"inline-flex\"\r\n alignItems=\"center\"\r\n bg={`${colorBase}.50`}\r\n color={`${colorBase}.700`}\r\n borderLeft={`4px solid ${courseColor}`}\r\n px={2}\r\n py={1}\r\n borderRadius=\"md\"\r\n fontSize=\"xs\"\r\n fontWeight=\"bold\"\r\n boxShadow=\"sm\"\r\n >\r\n {course.course_code}\r\n </Box>\r\n );\r\n })}\r\n <Box\r\n display=\"inline-flex\"\r\n alignItems=\"center\"\r\n bg=\"red.100\"\r\n color=\"red.700\"\r\n borderLeft=\"4px solid red.400\"\r\n px={2}\r\n py={1}\r\n borderRadius=\"md\"\r\n fontSize=\"xs\"\r\n fontWeight=\"bold\"\r\n boxShadow=\"sm\"\r\n >\r\n Clash\r\n </Box>\r\n </Flex>\r\n )}\r\n </Box>\r\n </Box>\r\n )}\r\n\r\n {/* Filters and search */}\r\n <Box className=\"bg-white rounded-xl shadow-lg p-6\">\r\n {!noCoursesFound && (\r\n <>\r\n <Flex direction={[\"column\", \"row\"]} gap={4} mb={6} wrap=\"wrap\">\r\n <Flex flex={1} position=\"relative\">\r\n <Input\r\n placeholder=\"Search courses...\"\r\n value={filters.search}\r\n onChange={(e) =>\r\n handleFilterChange(\"search\", e.target.value)\r\n }\r\n pl={10}\r\n bg=\"gray.50\"\r\n borderColor=\"gray.200\"\r\n _focus={{\r\n borderColor: \"purple.400\",\r\n boxShadow: \"0 0 0 1px var(--chakra-colors-purple-400)\",\r\n }}\r\n />\r\n <Box\r\n position=\"absolute\"\r\n left={3}\r\n top=\"50%\"\r\n transform=\"translateY(-50%)\"\r\n >\r\n <Search size={18} opacity={0.5} />\r\n </Box>\r\n </Flex>\r\n\r\n <Select\r\n placeholder=\"Semester\"\r\n value={filters.semester}\r\n onChange={(e) =>\r\n handleFilterChange(\"semester\", e.target.value)\r\n }\r\n maxW={[\"100%\", \"150px\"]}\r\n bg=\"gray.50\"\r\n borderColor=\"gray.200\"\r\n _focus={{\r\n borderColor: \"purple.400\",\r\n boxShadow: \"0 0 0 1px var(--chakra-colors-purple-400)\",\r\n }}\r\n >\r\n {[1, 2, 3, 4, 5, 6, 7, 8].map((sem) => (\r\n <option key={sem} value={sem}>\r\n Semester {sem}\r\n </option>\r\n ))}\r\n </Select>\r\n\r\n <Select\r\n placeholder=\"Department\"\r\n value={filters.department}\r\n onChange={(e) =>\r\n handleFilterChange(\"department\", e.target.value)\r\n }\r\n maxW={[\"100%\", \"180px\"]}\r\n bg=\"gray.50\"\r\n borderColor=\"gray.200\"\r\n _focus={{\r\n borderColor: \"purple.400\",\r\n boxShadow: \"0 0 0 1px var(--chakra-colors-purple-400)\",\r\n }}\r\n >\r\n {departments.map((dept) => (\r\n <option key={dept} value={dept}>\r\n {dept}\r\n </option>\r\n ))}\r\n </Select>\r\n\r\n <Button\r\n leftIcon={<Filter size={16} />}\r\n onClick={() =>\r\n setFilters({\r\n search: \"\",\r\n semester: \"\",\r\n department: \"\",\r\n credits: \"\",\r\n sortBy: \"name\",\r\n sortOrder: \"asc\",\r\n })\r\n }\r\n variant=\"outline\"\r\n colorScheme=\"purple\"\r\n size=\"md\"\r\n >\r\n Reset Filters\r\n </Button>\r\n </Flex>\r\n </>\r\n )}\r\n\r\n {renderContent()}\r\n </Box>\r\n </Flex>\r\n </Box>\r\n </Box>\r\n\r\n {/* Course details modal */}\r\n <Modal\r\n isOpen={isDetailsOpen}\r\n onClose={onDetailsClose}\r\n size=\"xl\"\r\n scrollBehavior=\"inside\"\r\n >\r\n <ModalOverlay backdropFilter=\"blur(2px)\" />\r\n <ModalContent rounded=\"xl\" overflow=\"hidden\">\r\n {selectedCourseDetails && (\r\n <>\r\n <Box\r\n h=\"8px\"\r\n w=\"100%\"\r\n className={`bg-gradient-to-r ${\r\n (!selectedCourseDetails?.semester || selectedCourseDetails.semester <= 2)\r\n ? \"from-green-400 to-green-500\"\r\n : selectedCourseDetails.semester <= 4\r\n ? \"from-blue-400 to-blue-500\"\r\n : selectedCourseDetails.semester <= 6\r\n ? \"from-purple-400 to-purple-500\"\r\n : \"from-red-400 to-red-500\"\r\n }`}\r\n />\r\n\r\n <ModalHeader pb={2}>\r\n <Flex justify=\"space-between\" align=\"center\" w=\"full\">\r\n <Text\r\n fontSize=\"2xl\"\r\n fontWeight=\"bold\"\r\n className=\"text-gray-800\"\r\n >\r\n {selectedCourseDetails.course_name}\r\n </Text>\r\n <ModalCloseButton position=\"static\" />\r\n </Flex>\r\n <Text fontSize=\"md\" color=\"gray.500\" fontFamily=\"mono\">\r\n {selectedCourseDetails.course_code}\r\n </Text>\r\n </ModalHeader>\r\n\r\n <Divider />\r\n\r\n <ModalBody pt={4}>\r\n <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4} mb={6}>\r\n <Box>\r\n <Text fontSize=\"sm\" color=\"gray.500\" fontWeight=\"medium\">\r\n Department\r\n </Text>\r\n <Text>\r\n {selectedCourseDetails.department?.dept_name ||\r\n \"Not specified\"}\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text fontSize=\"sm\" color=\"gray.500\" fontWeight=\"medium\">\r\n Stream\r\n </Text>\r\n <Text>\r\n {selectedCourseDetails.department?.dept_name ||\r\n \"Not specified\"}\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text fontSize=\"sm\" color=\"gray.500\" fontWeight=\"medium\">\r\n Semester\r\n </Text>\r\n <Text>Semester {selectedCourseDetails.semester}</Text>\r\n </Box>\r\n <Box>\r\n <Text fontSize=\"sm\" color=\"gray.500\" fontWeight=\"medium\">\r\n Credits\r\n </Text>\r\n <Text>\r\n {selectedCourseDetails.credits} credit\r\n {selectedCourseDetails.credits !== 1 ? \"s\" : \"\"}\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text fontSize=\"sm\" color=\"gray.500\" fontWeight=\"medium\">\r\n Instructor\r\n </Text>\r\n <Text>\r\n {selectedCourseDetails.professor_allocated ||\r\n \"Not specified\"}\r\n </Text>\r\n </Box>\r\n </SimpleGrid>\r\n\r\n <Box mb={6}>\r\n <Text\r\n fontSize=\"sm\"\r\n color=\"gray.500\"\r\n fontWeight=\"medium\"\r\n mb={1}\r\n >\r\n Description\r\n </Text>\r\n <Text fontSize=\"md\" whiteSpace=\"pre-wrap\">\r\n {selectedCourseDetails.description ||\r\n \"No description available for this course.\"}\r\n </Text>\r\n </Box>\r\n\r\n {selectedCourseDetails.prerequisites &&\r\n selectedCourseDetails.prerequisites.length > 0 && (\r\n <Box mb={6}>\r\n <Text\r\n fontSize=\"sm\"\r\n color=\"gray.500\"\r\n fontWeight=\"medium\"\r\n mb={2}\r\n >\r\n Prerequisites\r\n </Text>\r\n <Flex gap={2} flexWrap=\"wrap\">\r\n {selectedCourseDetails.prerequisites.map((prereq) => (\r\n <Tag\r\n key={prereq}\r\n size=\"md\"\r\n colorScheme=\"blue\"\r\n variant=\"subtle\"\r\n >\r\n {prereq}\r\n </Tag>\r\n ))}\r\n </Flex>\r\n </Box>\r\n )}\r\n\r\n {selectedCourseDetails.schedule &&\r\n selectedCourseDetails.schedule.length > 0 && (\r\n <Box mb={6}>\r\n <Text\r\n fontSize=\"sm\"\r\n color=\"gray.500\"\r\n fontWeight=\"medium\"\r\n mb={2}\r\n >\r\n Schedule\r\n </Text>\r\n <VStack align=\"stretch\" spacing={2}>\r\n {selectedCourseDetails.schedule.map((slot, index) => (\r\n <Flex\r\n key={index}\r\n bg=\"gray.50\"\r\n p={3}\r\n rounded=\"md\"\r\n align=\"center\"\r\n justifyContent=\"space-between\"\r\n >\r\n <HStack spacing={4}>\r\n <Tag\r\n size=\"sm\"\r\n colorScheme=\"purple\"\r\n variant=\"subtle\"\r\n width=\"90px\"\r\n justifyContent=\"center\"\r\n >\r\n {slot.day}\r\n </Tag>\r\n <Flex alignItems=\"center\" gap={1}>\r\n <Clock size={14} className=\"text-gray-400\" />\r\n <Text fontSize=\"sm\">\r\n {slot.start_time} - {slot.end_time}\r\n </Text>\r\n </Flex>\r\n </HStack>\r\n {slot.room && (\r\n <Text fontSize=\"xs\" color=\"gray.500\">\r\n Room: {slot.room}\r\n </Text>\r\n )}\r\n </Flex>\r\n ))}\r\n </VStack>\r\n </Box>\r\n )}\r\n </ModalBody>\r\n\r\n <ModalFooter borderTop=\"1px\" borderColor=\"gray.100\" pt={4}>\r\n <Button colorScheme=\"gray\" mr={3} onClick={onDetailsClose}>\r\n Close\r\n </Button>\r\n <Button\r\n colorScheme=\"purple\"\r\n leftIcon={\r\n selectedCourses.some(\r\n (c) => c.uuid === selectedCourseDetails.uuid,\r\n ) ? (\r\n <BookmarkCheck size={18} />\r\n ) : (\r\n <Calendar size={18} />\r\n )\r\n }\r\n onClick={() => selectCourse(selectedCourseDetails)}\r\n >\r\n {selectedCourses.some(\r\n (c) => c.uuid === selectedCourseDetails.uuid,\r\n )\r\n ? \"Remove from Selection\"\r\n : \"Add to Selection\"}\r\n </Button>\r\n </ModalFooter>\r\n </>\r\n )}\r\n </ModalContent>\r\n </Modal>\r\n\r\n {/* Full timetable visualization modal */}\r\n <Modal\r\n isOpen={isTimetableOpen}\r\n onClose={onTimetableClose}\r\n size=\"6xl\"\r\n scrollBehavior=\"inside\"\r\n >\r\n <ModalOverlay backdropFilter=\"blur(2px)\" />\r\n <ModalContent rounded=\"xl\">\r\n <ModalHeader>Weekly Timetable View</ModalHeader>\r\n <ModalCloseButton />\r\n <ModalBody>\r\n <Box overflowX=\"auto\">\r\n {/* Grid-based timetable for modal */}\r\n <Box\r\n display=\"grid\"\r\n gridTemplateColumns={`100px repeat(${weeklyTimetable.days.length}, 1fr)`}\r\n gridTemplateRows={`50px repeat(${weeklyTimetable.timeSlots.length}, 50px)`}\r\n minW=\"900px\"\r\n bg=\"white\"\r\n gap=\"1px\"\r\n border=\"1px solid\"\r\n borderColor=\"gray.200\"\r\n borderRadius=\"md\"\r\n >\r\n {/* Header row */}\r\n <Box\r\n bg=\"gray.50\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"md\"\r\n borderRadius=\"md\"\r\n >\r\n Time\r\n </Box>\r\n {weeklyTimetable.days.map((day) => (\r\n <Box\r\n key={day}\r\n bg=\"gray.50\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"md\"\r\n borderRadius=\"md\"\r\n >\r\n {day}\r\n </Box>\r\n ))}\r\n\r\n {/* Time slots and course blocks */}\r\n {weeklyTimetable.timeSlots.map((timeSlot, timeIndex) => (\r\n <React.Fragment key={timeSlot}>\r\n {/* Time label */}\r\n <Box\r\n bg=\"gray.50\"\r\n display=\"flex\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"medium\"\r\n fontSize=\"sm\"\r\n borderRadius=\"md\"\r\n >\r\n {timeSlot}\r\n </Box>\r\n\r\n {/* Day columns */}\r\n {weeklyTimetable.days.map((day, dayIndex) => {\r\n // Check if this slot should be rendered or is part of a spanning block\r\n const courseBlock = weeklyTimetable.courseBlocks[\r\n day\r\n ].find((block) => block.startSlotIndex === timeIndex);\r\n\r\n if (courseBlock) {\r\n // Render spanning block\r\n const courseColor =\r\n courseColors[courseBlock.course.uuid] || \"green.400\";\r\n const colorBase = courseColor.split(\".\")[0];\r\n const hasClash =\r\n weeklyTimetable.grid[day][timeSlot].length > 1;\r\n\r\n return (\r\n <Box\r\n key={`${day}-${timeSlot}-modal-block`}\r\n gridRowStart={timeIndex + 2}\r\n gridRowEnd={timeIndex + 2 + courseBlock.duration}\r\n gridColumn={dayIndex + 2}\r\n bg={hasClash ? \"red.100\" : `${colorBase}.100`}\r\n border=\"3px solid\"\r\n borderColor={hasClash ? \"red.400\" : courseColor}\r\n borderRadius=\"lg\"\r\n display=\"flex\"\r\n flexDirection=\"column\"\r\n alignItems=\"center\"\r\n justifyContent=\"center\"\r\n fontWeight=\"bold\"\r\n fontSize=\"md\"\r\n color={hasClash ? \"red.700\" : `${colorBase}.700`}\r\n position=\"relative\"\r\n boxShadow=\"lg\"\r\n transition=\"all 0.2s\"\r\n _hover={{\r\n bg: hasClash ? \"red.200\" : `${colorBase}.200`,\r\n boxShadow: \"xl\",\r\n transform: \"scale(1.02)\",\r\n }}\r\n cursor=\"pointer\"\r\n onClick={() =>\r\n viewCourseDetails(courseBlock.course)\r\n }\r\n p={2}\r\n >\r\n <Text\r\n fontWeight=\"bold\"\r\n fontSize=\"lg\"\r\n textAlign=\"center\"\r\n >\r\n {courseBlock.course.course_code}\r\n </Text>\r\n {courseBlock.duration > 1 && (\r\n <Text\r\n fontSize=\"sm\"\r\n opacity={0.9}\r\n textAlign=\"center\"\r\n mt={1}\r\n >\r\n {courseBlock.course.course_name.length > 25\r\n ? courseBlock.course.course_name.substring(\r\n 0,\r\n 25,\r\n ) + \"...\"\r\n : courseBlock.course.course_name}\r\n </Text>\r\n )}\r\n <Text fontSize=\"xs\" opacity={0.7} mt={1}>\r\n {\r\n courseBlock.course.schedule.find(\r\n (s) => s.day === day,\r\n )?.start_time\r\n }{\" \"}\r\n -{\" \"}\r\n {\r\n courseBlock.course.schedule.find(\r\n (s) => s.day === day,\r\n )?.end_time\r\n }\r\n </Text>\r\n {hasClash && (\r\n <Text\r\n fontSize=\"sm\"\r\n bg=\"red.200\"\r\n color=\"red.700\"\r\n px={2}\r\n py={1}\r\n borderRadius=\"md\"\r\n mt={1}\r\n >\r\n CLASH DETECTED\r\n </Text>\r\n )}\r\n </Box>\r\n );\r\n } else if (!weeklyTimetable.occupied[day][timeIndex]) {\r\n // Render empty cell only if not occupied by a spanning block\r\n return (\r\n <Box\r\n key={`${day}-${timeSlot}-modal-empty`}\r\n bg=\"white\"\r\n borderRadius=\"md\"\r\n />\r\n );\r\n }\r\n return null;\r\n })}\r\n </React.Fragment>\r\n ))}\r\n </Box>\r\n </Box>\r\n\r\n {/* Color legend for modal */}\r\n {selectedCourses.length > 0 && (\r\n <Flex\r\n mt={4}\r\n flexWrap=\"wrap\"\r\n gap={2}\r\n borderTop=\"1px solid\"\r\n borderColor=\"gray.100\"\r\n pt={4}\r\n >\r\n <Text fontSize=\"sm\" fontWeight=\"medium\" color=\"gray.700\" mr={2}>\r\n Color Legend:\r\n </Text>\r\n {selectedCourses.map((course) => {\r\n const courseColor = courseColors[course.uuid] || \"green.400\";\r\n const colorBase = courseColor.split(\".\")[0];\r\n\r\n return (\r\n <Box\r\n key={`legend-modal-${course.uuid}`}\r\n display=\"inline-flex\"\r\n alignItems=\"center\"\r\n bg={`${colorBase}.50`}\r\n color={`${colorBase}.700`}\r\n borderLeft={`4px solid ${courseColor}`}\r\n px={3}\r\n py={1}\r\n borderRadius=\"md\"\r\n fontSize=\"sm\"\r\n fontWeight=\"bold\"\r\n boxShadow=\"sm\"\r\n >\r\n {course.course_code}\r\n </Box>\r\n );\r\n })}\r\n <Box\r\n display=\"inline-flex\"\r\n alignItems=\"center\"\r\n bg=\"red.100\"\r\n color=\"red.700\"\r\n borderLeft=\"4px solid red.400\"\r\n px={3}\r\n py={1}\r\n borderRadius=\"md\"\r\n fontSize=\"sm\"\r\n fontWeight=\"bold\"\r\n boxShadow=\"sm\"\r\n >\r\n Clash\r\n </Box>\r\n </Flex>\r\n )}\r\n </ModalBody>\r\n <ModalFooter>\r\n <HStack spacing={3}>\r\n <Tag\r\n size=\"md\"\r\n colorScheme={totalCourses >= MAX_COURSES ? \"orange\" : \"purple\"}\r\n variant=\"subtle\"\r\n >\r\n <TagLeftIcon as={Calendar} />\r\n <TagLabel fontWeight=\"bold\">\r\n {totalCourses}/{MAX_COURSES} Courses\r\n </TagLabel>\r\n </Tag>\r\n <Tag\r\n size=\"md\"\r\n colorScheme={\r\n totalCredits < MIN_CREDITS\r\n ? \"red\"\r\n : totalCredits >= creditLimit\r\n ? \"orange\"\r\n : \"blue\"\r\n }\r\n variant=\"subtle\"\r\n >\r\n <TagLeftIcon boxSize={3} as={Book} />\r\n <TagLabel fontWeight=\"bold\">\r\n {totalCredits}/{creditLimit} Credits\r\n {totalCredits < MIN_CREDITS && ` (Min: ${MIN_CREDITS})`}\r\n </TagLabel>\r\n </Tag>\r\n <Select\r\n size=\"sm\"\r\n value={creditLimit}\r\n onChange={(e) => setCreditLimit(Number(e.target.value))}\r\n width=\"120px\"\r\n >\r\n {CREDIT_LIMITS.map((limit) => (\r\n <option key={limit} value={limit}>\r\n {limit} Credits\r\n </option>\r\n ))}\r\n </Select>\r\n {!hasAnyClashes && selectedCourses.length > 0 && (\r\n <Button\r\n colorScheme={totalCredits >= MIN_CREDITS ? \"green\" : \"gray\"}\r\n leftIcon={<CheckCircle size={16} />}\r\n onClick={saveToCurrentSemester}\r\n isLoading={saving}\r\n loadingText=\"Saving...\"\r\n size=\"sm\"\r\n disabled={totalCredits < MIN_CREDITS}\r\n >\r\n Save to Current Semester\r\n </Button>\r\n )}\r\n <Button colorScheme=\"purple\" onClick={onTimetableClose}>\r\n Close\r\n </Button>\r\n </HStack>\r\n </ModalFooter>\r\n </ModalContent>\r\n </Modal>\r\n </>\r\n );\r\n};\r\n\r\nexport default TimetableClashChecker;\r\n\r\n"],"names":["timeToMinutes","timeStr","hours","minutes","detectClashes","courses","results","i","course","clashingWith","j","otherCourse","slot1","slot2","slot1Start","slot1End","slot2Start","slot2End","COURSE_COLORS","TimetableClashChecker","setCourses","useState","filteredCourses","setFilteredCourses","selectedCourses","setSelectedCourses","clashResults","setClashResults","departments","setDepartments","loading","setLoading","noCoursesFound","setNoCoursesFound","courseColors","setCourseColors","filters","setFilters","viewMode","setViewMode","isDetailsOpen","onDetailsOpen","onDetailsClose","useDisclosure","isTimetableOpen","onTimetableOpen","onTimetableClose","selectedCourseDetails","setSelectedCourseDetails","totalCredits","setTotalCredits","totalCourses","setTotalCourses","creditLimit","setCreditLimit","saving","setSaving","isSavedToCurrentSemester","setIsSavedToCurrentSemester","MAX_COURSES","MIN_CREDITS","CREDIT_LIMITS","navigate","useNavigate","toast","useToast","session","useAuth","useEffect","fetchCourses","loadCurrentSemesterSelections","filterCourses","filtered","searchLower","a","b","credits","total","tableName","coursesData","coursesError","supabase","departmentsData","departmentsError","processedCourses","dept","d","schedule","e","depts","error","userData","currentSemesterData","coursesWithDetails","semesterCourse","courseId","courseData","courseByUuid","deptData","courseWithDetails","processCourseFetchResult","colors","index","prerequisites","antirequisites","department","handleFilterChange","name","value","prev","selectCourse","c","updated","newTotalCourses","newTotalCredits","tempSelected","courseResult","r","clashingCourses","id","sc","nextColorIndex","viewCourseDetails","getCourseById","getClashResultForCourse","result","saveToCurrentSemester","hasAnyClashes","useMemo","getCourseColor","getThemeColor","coursesByStream","grouped","streamName","coursesBySemester","semesterKey","semA","semB","semester","weeklyTimetable","days","timeSlots","hour","courseBlocks","grid","occupied","day","time","slot","startMinutes","endMinutes","occupiedSlots","minute","slotStartMinutes","slotEndMinutes","courseStartsBeforeSlotEnds","courseEndsAfterSlotStarts","courseStartSlotIndex","courseEndSlotIndex","duration","slotIndex","isCourseFromCurrentSemester","CourseCard","isSelected","isFromCurrentSemester","hasClash","courseColor","themeColor","jsxs","Box","jsx","Flex","Badge","IconButton","AlertCircle","CheckCircle","Calendar","Heading","Text","HStack","Clock","Book","Alert","AlertIcon","AlertTitle","Divider","Button","renderContent","Spinner","Search","Grid","Tabs","TabList","Tab","TabPanels","TabPanel","Fragment","NavBar","Tag","TagLeftIcon","TagLabel","Select","limit","AlertDescription","SimpleGrid","clashResult","colorBase","VStack","clashId","clashCourse","X","MinusIcon","timeSlot","dayIndex","React","timeIndex","courseBlock","block","Input","sem","Filter","Modal","ModalOverlay","ModalContent","ModalHeader","ModalCloseButton","ModalBody","prereq","ModalFooter","BookmarkCheck","s"],"mappings":"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"}
Close