github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/components/ProgressBar.tsx (about) 1 import React from "react" 2 import { useAppState } from "../overmind" 3 import { Submission, Submission_Status } from "../../proto/qf/types_pb" 4 5 export enum Progress { 6 NAV, 7 LAB, 8 OVERVIEW 9 } 10 11 type ProgressBarProps = { 12 courseID: string, 13 assignmentIndex: number, 14 submission?: Submission, 15 type: Progress 16 } 17 18 const ProgressBar = ({ courseID, assignmentIndex, submission, type }: ProgressBarProps): JSX.Element => { 19 const state = useAppState() 20 21 const sub = submission 22 ? submission 23 : state.submissions[courseID][assignmentIndex] 24 25 const assignment = state.assignments[courseID][assignmentIndex] 26 27 const score = sub?.score ?? 0 28 const scorelimit = assignment?.scoreLimit ?? 0 29 const status = sub?.status ?? Submission_Status.NONE 30 const secondaryProgress = scorelimit - score 31 // Returns a thin line to be used for labs in the NavBar 32 if (type === Progress.NAV) { 33 const percentage = 100 - score 34 const color = score >= scorelimit ? "green" : "yellow" 35 return ( 36 <div style={{ 37 position: "absolute", 38 borderBottom: `2px solid ${color}`, 39 bottom: 0, 40 left: 0, 41 right: `${percentage}%`, 42 opacity: 0.3 43 }} /> 44 ) 45 } 46 47 let text = "" 48 let secondaryText = "" 49 if (type === Progress.LAB) { 50 text = `${score} %` 51 secondaryText = `${secondaryProgress} %` 52 } 53 54 // Returns a regular size progress bar to be used for labs 55 let color = "" 56 if (type > Progress.NAV) { 57 switch (status) { 58 case Submission_Status.NONE: 59 color = "bg-primary" 60 break 61 case Submission_Status.APPROVED: 62 color = "bg-success" 63 break 64 case Submission_Status.REJECTED: 65 color = "bg-danger" 66 break 67 case Submission_Status.REVISION: 68 color = "bg-warning text-dark" 69 break 70 } 71 } 72 73 return ( 74 <div className="progress"> 75 <div 76 className={`progress-bar ${color}`} 77 role="progressbar" 78 style={{ width: `${score}%`, transitionDelay: "0.5s" }} 79 aria-valuenow={score} 80 aria-valuemin={0} 81 aria-valuemax={100} 82 > 83 {text} 84 </div> 85 {secondaryProgress > 0 && 86 <div 87 className={"progress-bar progressbar-secondary bg-secondary"} 88 role="progressbar" 89 style={{ width: `${secondaryProgress}%` }} 90 aria-valuemax={100} 91 > 92 {secondaryText} 93 </div> 94 } 95 </div> 96 ) 97 } 98 99 export default ProgressBar