1
1
import RootPage from "../root" ;
2
2
import Container from "@mui/material/Container" ;
3
3
import "./courses.css" ; // Import CSS file for additional styling
4
- import List from "@mui/material/List" ;
5
- import ListItem from "@mui/material/ListItem" ;
6
- import ListItemButton from "@mui/material/ListItemButton" ;
7
- import ListItemText from "@mui/material/ListItemText" ;
8
- import { useEffect } from "react" ;
9
- import { useAxiosRequest } from "../../utils" ;
4
+ import { useEffect , useState } from "react" ;
5
+ import { useNavigate } from "react-router-dom" ;
6
+ import { backend_post , useAxiosRequest } from "../../utils" ;
10
7
import { Course , Empty } from "../../types/common" ;
8
+ import { IsAdmin } from "../../utils" ;
9
+ import { User } from "../../types/common" ;
10
+ import {
11
+ Button ,
12
+ Checkbox ,
13
+ IconButton ,
14
+ Typography ,
15
+ styled
16
+ } from "@mui/material" ;
17
+ import MoreVertIcon from "@mui/icons-material/MoreVert" ;
18
+ import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline" ;
19
+ import Avatar from "@mui/material/Avatar" ;
11
20
12
21
type ResponseData = Course [ ] ;
13
22
14
23
const Courses = ( ) => {
24
+ const navigate = useNavigate ( ) ;
15
25
const { response, error, loading, sendRequest } = useAxiosRequest <
16
26
Empty ,
17
27
ResponseData
18
28
> ( ) ;
29
+ const [ course_data , setCourseData ] = useState < Course [ ] > ( ) ;
30
+
31
+ const alternatingColor = [
32
+ "#424242" ,
33
+ "#595959"
34
+ ] ;
35
+
19
36
20
37
useEffect ( ( ) => {
21
38
sendRequest ( {
@@ -25,47 +42,150 @@ const Courses = () => {
25
42
} ) ;
26
43
} , [ sendRequest ] ) ;
27
44
45
+ useEffect ( ( ) => {
46
+ if ( response ) setCourseData ( response )
47
+ } , [ response ] ) ;
48
+
28
49
if ( error ) {
29
50
console . error ( "Error fetching courses:" , error ) ;
30
51
// Optionally, render an error message in the UI
31
52
}
53
+
54
+ const StyledTable = styled ( "table" ) ( {
55
+ borderCollapse : "collapse" ,
56
+ width : "100%" ,
57
+ "& th, & tr" : {
58
+ padding : "8px" ,
59
+ borderBottom : "1px solid #ddd" ,
60
+ textAlign : "left"
61
+ } ,
62
+ "& td" :{
63
+ padding : "8px" ,
64
+ textAlign : "left"
65
+ } ,
66
+ "& th" : {
67
+ fontWeight : "bold" // Add bold font weight to header cells if needed
68
+ } ,
69
+ "& .type-column" : {
70
+ width : "10%" , // Adjust the width of the actions column
71
+ textAlign : "left" // Align content to the left
72
+ } ,
73
+ "& .actions-column" : {
74
+ width : "5%" , // Adjust the width of the actions column
75
+ textAlign : "left" // Align content to the left
76
+ } ,
77
+ "& .enroll-column" : {
78
+ width : "5%"
79
+ } ,
80
+ "& .avatar-column" : {
81
+ width : "5%" , // Adjust the width of the avatar column
82
+ textAlign : "left" // Align content to the left
83
+ } ,
84
+ "& .actions-icon" : {
85
+ display : "flex" ,
86
+ justifyContent : "center" ,
87
+ alignItems : "center"
88
+ }
89
+ } ) ;
90
+
91
+ const handleNewCourseClick = ( ) => {
92
+ navigate ( `/create_course` ) ;
93
+ } ;
94
+
95
+ const handleCourseClick = ( course_id : number ) => {
96
+ navigate ( `/course/${ course_id } /create_lecture` ) ;
97
+ } ;
98
+
99
+ const handleEnrollment =
100
+ ( courseId : number , enroll : boolean ) =>
101
+ ( event : React . ChangeEvent < HTMLInputElement > ) => {
102
+ if ( enroll ) {
103
+ backend_post ( "course/enroll/" + courseId , "" , true ) ;
104
+ if ( response == null ) return
105
+ const new_data = course_data ?. map ( ( course : Course ) => ( course . id == courseId ? { ...course , enrolled : true } : course ) )
106
+ setCourseData ( new_data )
107
+ }
108
+ } ;
109
+
32
110
return (
33
111
< RootPage >
34
- < Container component = "main" maxWidth = "xs" >
35
- { loading ? (
36
- < div > Loading...</ div > // Added loading state feedback
37
- ) : (
38
- < List
39
- sx = { {
40
- width : "100%" ,
41
- maxWidth : 1000
42
- } }
43
- aria-label = "Courses"
44
- >
45
- < ListItem disablePadding >
46
- < ListItemButton
47
- sx = { {
48
- border : 1 ,
49
- bgcolor : "rgba(255, 255, 255, 0.12)"
112
+ < Container component = "main" className = "mainComponent" >
113
+ < Typography variant = "h4" gutterBottom >
114
+ Courses
115
+ { IsAdmin ( ) ? (
116
+ < IconButton
117
+ onClick = { ( ) => handleNewCourseClick ( ) }
118
+ style = { {
119
+ marginLeft : "2%" ,
120
+ color : "white" ,
121
+ backgroundColor : "rgba(255, 255, 255, 0.5)"
122
+ } }
123
+ >
124
+ < AddCircleOutlineIcon style = { { fontSize : "1em" } } />
125
+ </ IconButton >
126
+ ) : null }
127
+ </ Typography >
128
+
129
+ < StyledTable >
130
+ < thead >
131
+ < tr >
132
+ < th > Course Name</ th >
133
+ < th className = "type-column" > Students</ th >
134
+ { IsAdmin ( ) ? (
135
+ < th className = "actions-column" > Actions</ th >
136
+ ) : (
137
+ < th className = "enroll-column" > Enroll</ th >
138
+ ) }
139
+ </ tr >
140
+ </ thead >
141
+ < tbody >
142
+ { course_data ?. map ( ( course : Course , index : number ) => (
143
+ < tr
144
+ key = { course . id }
145
+ style = { {
146
+ backgroundColor :
147
+ alternatingColor [ index % 2 ]
50
148
} }
51
149
>
52
- < ListItemText primary = "Courses" />
53
- </ ListItemButton >
54
- </ ListItem >
55
-
56
- { response ?. map ( ( course : Course ) => (
57
- < ListItem disablePadding key = { course . course_name } >
58
- { " " }
59
- { /* Assuming course_name is unique */ }
60
- < ListItemButton sx = { { border : 1 } } >
61
- < ListItemText
62
- primary = { course . course_name }
150
+ < td >
151
+ < Button
152
+ style = { {
153
+ color : "white" ,
154
+ textTransform : "none" ,
155
+ fontSize : "1em"
156
+ } }
157
+ onClick = { ( ) =>
158
+ handleCourseClick ( course . id )
159
+ }
160
+ >
161
+ { `${ course . course_name } ` }
162
+ </ Button >
163
+ </ td >
164
+ < td > </ td >
165
+ { IsAdmin ( ) ? (
166
+ < td className = "actions-icon" >
167
+ < IconButton >
168
+ < MoreVertIcon />
169
+ </ IconButton >
170
+ </ td >
171
+ ) : (
172
+ < Checkbox className = "actions-icon"
173
+ checked = { course . enrolled }
174
+ onChange = { handleEnrollment (
175
+ course . id ,
176
+ ! course . enrolled
177
+ ) }
178
+ sx = { {
179
+ "& .MuiSvgIcon-root" : {
180
+ color : "white"
181
+ }
182
+ } }
63
183
/>
64
- </ ListItemButton >
65
- </ ListItem >
184
+ ) }
185
+ </ tr >
66
186
) ) }
67
- </ List >
68
- ) }
187
+ </ tbody >
188
+ </ StyledTable >
69
189
</ Container >
70
190
</ RootPage >
71
191
) ;
0 commit comments