github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/components/Courses.tsx (about) 1 import React from "react" 2 import { useAppState } from "../overmind" 3 import { Enrollment, Enrollment_UserStatus } from "../../proto/qf/types_pb" 4 import CourseCard from "./CourseCard" 5 import Button, { ButtonType } from "./admin/Button" 6 import { useHistory } from "react-router" 7 import { Color, isVisible } from "../Helpers" 8 9 // If home is set to true, display only favorite courses. Otherwise, display all courses. 10 // Can be used on dashboard to let the user choose which courses to display based on favorites. 11 interface overview { 12 home: boolean 13 } 14 15 /** This component lists the user's courses and courses available for enrollment. */ 16 const Courses = (overview: overview): JSX.Element => { 17 const state = useAppState() 18 const history = useHistory() 19 20 // Notify user if there are no courses (should only ever happen with a fresh database on backend) 21 // Display shortcut buttons for admins to create new course or managing (promoting) users 22 if (state.courses.length === 0) { 23 return ( 24 <div className="container centered"> 25 <h3>There are currently no available courses.</h3> 26 {state.self.IsAdmin ? 27 <div> 28 <Button 29 text="Go to course creation" 30 color={Color.GREEN} 31 type={ButtonType.BUTTON} 32 className="mr-3" 33 onClick={() => history.push("/admin/create")} 34 /> 35 <Button 36 text="Manage users" 37 color={Color.BLUE} 38 type={ButtonType.BUTTON} 39 onClick={() => history.push("/admin/manage")} 40 /> 41 </div> 42 : null} 43 </div> 44 ) 45 } 46 47 // Push to separate arrays for layout purposes. Favorite - Student - Teacher - Pending 48 const courses = () => { 49 const favorite: JSX.Element[] = [] 50 const student: JSX.Element[] = [] 51 const teacher: JSX.Element[] = [] 52 const pending: JSX.Element[] = [] 53 const availableCourses: JSX.Element[] = [] 54 state.courses.map(course => { 55 const enrol = state.enrollmentsByCourseID[course.ID.toString()] 56 if (enrol) { 57 const courseCard = <CourseCard key={course.ID.toString()} course={course} enrollment={enrol} /> 58 if (isVisible(enrol)) { 59 favorite.push(courseCard) 60 } else { 61 switch (enrol.status) { 62 case Enrollment_UserStatus.PENDING: 63 pending.push(courseCard) 64 break 65 case Enrollment_UserStatus.STUDENT: 66 student.push(courseCard) 67 break 68 case Enrollment_UserStatus.TEACHER: 69 teacher.push(courseCard) 70 break 71 } 72 } 73 } else { 74 availableCourses.push( 75 <CourseCard key={course.ID.toString()} course={course} enrollment={new Enrollment} /> 76 ) 77 } 78 }) 79 80 if (overview.home) { 81 // Render only favorite courses. 82 return ( 83 <> 84 {favorite.length > 0 && 85 <div className="container-fluid"> 86 <div className="card-deck course-card-row favorite-row"> 87 {favorite} 88 </div> 89 </div> 90 } 91 </> 92 ) 93 } 94 95 return ( 96 <div className="box container-fluid"> 97 {favorite.length > 0 && 98 <div className="container-fluid"> 99 <h2>Favorites</h2> 100 <div className="card-deck course-card-row favorite-row"> 101 {favorite} 102 </div> 103 </div> 104 } 105 106 {(student.length > 0 || teacher.length > 0) && 107 <div className="container-fluid myCourses"> 108 <h2>My Courses</h2> 109 <div className="card-deck course-card-row"> 110 {teacher} 111 {student} 112 </div> 113 </div> 114 } 115 {pending.length > 0 && 116 <div className="container-fluid"> 117 {(student.length === 0 && teacher.length === 0) && 118 <h2>My Courses</h2> 119 } 120 <div className="card-deck"> 121 {pending} 122 </div> 123 </div> 124 } 125 126 {availableCourses.length > 0 && 127 <> 128 <h2>Available Courses</h2> 129 <div className="card-deck course-card-row"> 130 {availableCourses} 131 </div> 132 </> 133 } 134 </div> 135 ) 136 } 137 return courses() 138 139 } 140 141 export default Courses