github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/components/navbar/Breadcrumbs.tsx (about)

     1  import React, { useEffect, useState } from 'react'
     2  import { useLocation, Link } from 'react-router-dom'
     3  import { useActions, useAppState } from '../../overmind'
     4  
     5  
     6  const Breadcrumbs = () => {
     7      const state = useAppState()
     8      const actions = useActions()
     9      const location = useLocation()
    10      const [courseName, setCourseName] = useState<string | null>(null)
    11      const [assignmentName, setAssignmentName] = useState<string | null>(null)
    12      const pathnames = location.pathname.split('/').filter(x => x)
    13  
    14      const getCourseNameById = (id: string): string | null => {
    15          const course = state.courses.find(course => course.ID.toString() === id)
    16          return course ? course.name : null
    17      }
    18  
    19      const getAssignmentNameById = (id: string): string | null => {
    20          if (pathnames[0] === 'course' && pathnames[1]) {
    21              const assignment = state.assignments[pathnames[1]].find(assignment => assignment.ID.toString() === id)
    22              return assignment ? assignment.name : null
    23          }
    24          return null
    25      }
    26  
    27      const handleDashboard = () => {
    28          actions.setActiveCourse(0n)
    29      }
    30  
    31      useEffect(() => {
    32          if (pathnames[0] === 'course' && pathnames[1]) {
    33              setCourseName(getCourseNameById(pathnames[1]))
    34          }
    35          if (pathnames[2] === 'lab' && pathnames[3]) {
    36              setAssignmentName(getAssignmentNameById(pathnames[3]))
    37          }
    38      }, [pathnames])
    39  
    40      return (
    41          <nav aria-label="breadcrumb">
    42              <ol className="breadcrumb m-0 bg-transparent">
    43                  <li className="breadcrumb-item">
    44                      <Link to="/" onClick={handleDashboard}>Dashboard</Link>
    45                  </li>
    46                  {pathnames.map((value, index) => {
    47                      const last = index === pathnames.length - 1
    48                      const to = `/${pathnames.slice(0, index + 1).join('/')}`
    49                      // title case the path segment.
    50                      let breadcrumbName = decodeURIComponent(value.charAt(0).toUpperCase() + value.slice(1))
    51  
    52                      // skip the first path segment (e.g., 'course/ID').
    53                      if (index === 0 && value === 'course') {
    54                          return null
    55                      }
    56  
    57                      // skip the second path segment (e.g., 'course/ID/lab/ID').
    58                      if (index === 2 && value === 'lab') {
    59                          return null
    60                      }
    61  
    62                      // Replace 'course/ID' with 'course/Course Name' in the breadcrumb.
    63                      if (index === 1 && courseName && pathnames[0] === 'course') {
    64                          breadcrumbName = courseName
    65                      }
    66  
    67                      // Replace 'lab/ID' with 'lab/Assignment Name' in the breadcrumb.
    68                      if (index === 3 && assignmentName && pathnames[2] === 'lab') {
    69                          breadcrumbName = assignmentName
    70                      }
    71  
    72                      return last ? (
    73                          <li key={to} className="breadcrumb-item active" aria-current="page">
    74                              {breadcrumbName}
    75                          </li>
    76                      ) : (
    77                          <li key={to} className="breadcrumb-item">
    78                              <Link to={to}>{breadcrumbName}</Link>
    79                          </li>
    80                      )
    81                  })}
    82              </ol>
    83          </nav>
    84      )
    85  }
    86  
    87  export default Breadcrumbs