|
1 | 1 | import React, { useEffect, useRef } from 'react'; |
2 | 2 |
|
3 | 3 | function CoursePagePopup({ |
4 | | - favouriteCourses, |
5 | | - handleFavouriteClick, |
6 | | - isOpen, |
7 | | - onClose, |
8 | | - course, |
9 | | - prerequisiteTree, |
10 | | - reviewPresenter, |
11 | | - }) { |
12 | | - const treeRef = useRef(null); |
13 | | - |
14 | | - useEffect(() => { |
15 | | - const handleKeyDown = (event) => { |
16 | | - if (event.key === 'Escape') { |
17 | | - onClose(); |
18 | | - } |
19 | | - }; |
20 | | - if (isOpen) { |
21 | | - window.addEventListener('keydown', handleKeyDown); |
22 | | - } |
23 | | - return () => { |
24 | | - window.removeEventListener('keydown', handleKeyDown); |
25 | | - }; |
26 | | - }, [isOpen, onClose]); |
27 | | - |
28 | | - const handleTreeClick = () => { |
29 | | - if (treeRef.current) { |
30 | | - treeRef.current.focus(); |
31 | | - } |
32 | | - }; |
33 | | - |
34 | | - if (!isOpen || !course) return null; |
35 | | - |
36 | | - return ( |
37 | | - <div |
38 | | - className="fixed backdrop-blur-sm inset-0 bg-transparent flex justify-end z-50" |
39 | | - onClick={onClose} |
40 | | - > |
41 | | - <div |
42 | | - className="bg-indigo-300/75 backdrop-blur-lg h-full w-3/4 flex flex-col overflow-auto" |
43 | | - onClick={(e) => e.stopPropagation()} |
44 | | - > |
45 | | - <div className="flex-1"> |
46 | | - <div className="px-10 py-10 md:px-20 md:py-16 text-slate-900 space-y-12 font-sans"> |
47 | | - {/* Course Title Section */} |
48 | | - <div> |
49 | | - <h2 className="text-5xl font-extrabold text-[#2e2e4f]"> |
50 | | - <span className="text-violet-700">{course.code}</span> - {course.name} |
51 | | - <span className="ml-4 text-lg text-violet-700 whitespace-nowrap"> |
52 | | - ({course.credits} Credits) |
53 | | - </span> |
54 | | - </h2> |
55 | | - <div className="my-6 h-1.5 w-full bg-violet-500"></div> |
56 | | - </div> |
57 | | - <div> |
58 | | - <button |
59 | | - className="text-yellow-100 bg-yellow-400 cursor-pointer" |
60 | | - onClick={(e) => { |
61 | | - e.stopPropagation(); |
62 | | - handleFavouriteClick(course); |
63 | | - }} |
64 | | - > |
65 | | - {favouriteCourses.some((fav) => fav.code === course.code) |
66 | | - ? 'Remove from Favourites' |
67 | | - : 'Add to Favourites'} |
68 | | - </button> |
69 | | - </div> |
70 | | - {/* Description Section */} |
71 | | - <div> |
72 | | - <h3 className="text-2xl font-bold text-[#2e2e4f] mb-0.5">Course Description</h3> |
73 | | - <div className="mb-3 h-0.5 w-full bg-violet-500"></div> |
74 | | - <div |
75 | | - className="text-lg leading-8 text-[#2e2e4f] font-semibold tracking-wide prose prose-slate max-w-full" |
76 | | - dangerouslySetInnerHTML={{ __html: course.description }} |
77 | | - /> |
78 | | - </div> |
79 | | - {/* Prerequisite Graph Tree Section */} |
80 | | - <div> |
81 | | - <h3 className="text-2xl font-semibold text-[#2e2e4f] mb-0.5">Prerequisite Graph Tree</h3> |
82 | | - <div className="mb-4 h-0.5 w-full bg-violet-500"></div> |
83 | | - <div |
84 | | - className="bg-indigo-300/50 outline-none focus:outline-none focus:ring-2 focus:ring-violet-600 rounded-lg transition-shadow" |
85 | | - ref={treeRef} |
86 | | - onClick={handleTreeClick} |
87 | | - tabIndex={0} |
88 | | - > |
89 | | - {prerequisiteTree} |
90 | | - </div> |
91 | | - </div> |
92 | | - {/* Reviews Section (optional) */} |
93 | | - {reviewPresenter && ( |
94 | | - <div> |
95 | | - <h3 className="text-2xl font-semibold text-[#2e2e4f] mb-0.5">Reviews</h3> |
96 | | - <div className="mb-4 h-0.5 w-full bg-violet-500"></div> |
97 | | - {reviewPresenter} |
98 | | - </div> |
99 | | - )} |
100 | | - </div> |
101 | | - </div> |
102 | | - <button onClick={onClose} className="px-4 py-2 bg-violet-500 text-white"> |
103 | | - Close |
104 | | - </button> |
105 | | - </div> |
106 | | - </div> |
107 | | - ); |
108 | | - favouriteCourses, |
109 | | - handleFavouriteClick, |
110 | | - isOpen, |
111 | | - onClose, |
112 | | - course, |
113 | | - prerequisiteTree, |
114 | | - reviewPresenter, |
115 | | -}) { |
| 4 | + favouriteCourses, |
| 5 | + handleFavouriteClick, |
| 6 | + isOpen, |
| 7 | + onClose, |
| 8 | + course, |
| 9 | + prerequisiteTree, |
| 10 | + reviewPresenter, |
| 11 | + }) { |
116 | 12 | const treeRef = useRef(null); |
117 | 13 |
|
118 | 14 | useEffect(() => { |
@@ -153,20 +49,20 @@ function CoursePagePopup({ |
153 | 49 | <h2 className="text-5xl font-extrabold text-[#2e2e4f]"> |
154 | 50 | <span className="text-violet-700">{course.code}</span> - {course.name} |
155 | 51 | <span className="ml-4 text-lg text-violet-700 whitespace-nowrap"> |
156 | | - ({course.credits} Credits) |
157 | | - </span> |
| 52 | + ({course.credits} Credits) |
| 53 | + </span> |
158 | 54 | </h2> |
159 | 55 | <div className="my-6 h-1.5 w-full bg-violet-500"></div> |
160 | 56 | </div> |
161 | 57 | <div> |
162 | 58 | <button |
163 | 59 | className={`inline-flex items-center px-4 py-2 gap-2 rounded-lg |
164 | | - transition-all duration-300 ease-in-out |
165 | | - font-semibold text-sm shadow-sm |
166 | | - ${favouriteCourses.some((fav) => fav.code === course.code) |
167 | | - ? 'bg-yellow-400 /90 hover:bg-yellow-500/90 border-2 border-yellow-600 hover:border-yellow-700 text-yellow-900' |
168 | | - : 'bg-yellow-200/90 hover:bg-yellow-300 border-2 border-yellow-400 hover:border-yellow-500 text-yellow-600 hover:text-yellow-700' |
169 | | - }`} |
| 60 | + transition-all duration-300 ease-in-out |
| 61 | + font-semibold text-sm shadow-sm |
| 62 | + ${favouriteCourses.some((fav) => fav.code === course.code) |
| 63 | + ? 'bg-yellow-400 /90 hover:bg-yellow-500/90 border-2 border-yellow-600 hover:border-yellow-700 text-yellow-900' |
| 64 | + : 'bg-yellow-200/90 hover:bg-yellow-300 border-2 border-yellow-400 hover:border-yellow-500 text-yellow-600 hover:text-yellow-700' |
| 65 | + }`} |
170 | 66 | onClick={(e) => { |
171 | 67 | e.stopPropagation(); |
172 | 68 | handleFavouriteClick(course); |
|
0 commit comments