11import React , { useEffect , useRef } from 'react' ;
22
33function CoursePagePopup ( {
4- favouriteCourses,
5- handleFavouriteClick,
6- isOpen,
7- onClose,
8- course,
9- prerequisiteTree,
10- reviewPresenter,
4+ favouriteCourses,
5+ handleFavouriteClick,
6+ isOpen,
7+ onClose,
8+ course,
9+ prerequisiteTree,
10+ reviewPresenter,
1111} ) {
12- const treeRef = useRef ( null ) ;
12+ const treeRef = useRef ( null ) ;
1313
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 ] ) ;
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 ] ) ;
2727
28- const handleTreeClick = ( ) => {
29- if ( treeRef . current ) {
30- treeRef . current . focus ( ) ;
31- }
32- } ;
28+ const handleTreeClick = ( ) => {
29+ if ( treeRef . current ) {
30+ treeRef . current . focus ( ) ;
31+ }
32+ } ;
3333
34- if ( ! isOpen || ! course ) return null ;
34+ if ( ! isOpen || ! course ) return null ;
3535
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- ) ;
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 = { `inline-flex items-center px-4 py-2 gap-2 rounded-lg
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+ } `}
66+ onClick = { ( e ) => {
67+ e . stopPropagation ( ) ;
68+ handleFavouriteClick ( course ) ;
69+ } }
70+ >
71+ { favouriteCourses . some ( ( fav ) => fav . code === course . code ) ? (
72+ < >
73+ < svg xmlns = "http://www.w3.org/2000/svg" className = "h-5 w-5 fill-yellow-900" viewBox = "0 0 20 20" >
74+ < path d = "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
75+ </ svg >
76+ Remove from Favourites
77+ </ >
78+ ) : (
79+ < >
80+ < svg xmlns = "http://www.w3.org/2000/svg" className = "h-5 w-5 stroke-yellow-500" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
81+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />
82+ </ svg >
83+ Add to Favourites
84+ </ >
85+ ) }
86+ </ button >
87+ </ div >
88+ { /* Description Section */ }
89+ < div >
90+ < h3 className = "text-2xl font-bold text-[#2e2e4f] mb-0.5" > Course Description</ h3 >
91+ < div className = "mb-3 h-0.5 w-full bg-violet-500" > </ div >
92+ < div
93+ className = "text-lg leading-8 text-[#2e2e4f] font-semibold tracking-wide prose prose-slate max-w-full"
94+ dangerouslySetInnerHTML = { { __html : course . description } }
95+ />
96+ </ div >
97+ { /* Prerequisite Graph Tree Section */ }
98+ < div >
99+ < h3 className = "text-2xl font-semibold text-[#2e2e4f] mb-0.5" > Prerequisite Graph Tree</ h3 >
100+ < div className = "mb-4 h-0.5 w-full bg-violet-500" > </ div >
101+ < div
102+ className = "bg-indigo-300/50 outline-none focus:outline-none focus:ring-2 focus:ring-violet-600 rounded-lg transition-shadow"
103+ ref = { treeRef }
104+ onClick = { handleTreeClick }
105+ tabIndex = { 0 }
106+ >
107+ { prerequisiteTree }
108+ </ div >
109+ </ div >
110+ { /* Reviews Section (optional) */ }
111+ { reviewPresenter && (
112+ < div >
113+ < h3 className = "text-2xl font-semibold text-[#2e2e4f] mb-0.5" > Reviews</ h3 >
114+ < div className = "mb-4 h-0.5 w-full bg-violet-500" > </ div >
115+ { reviewPresenter }
116+ </ div >
117+ ) }
118+ </ div >
119+ </ div >
120+ < button onClick = { onClose } className = "px-4 py-2 bg-violet-500 text-white" >
121+ Close
122+ </ button >
123+ </ div >
124+ </ div >
125+ ) ;
108126}
109127
110128export default CoursePagePopup ;
0 commit comments