diff --git a/frontend/src/components/TimeLogsPage/InstructorTimeLogsPage.jsx b/frontend/src/components/TimeLogsPage/InstructorTimeLogsPage.jsx index 9d425b8..633afbf 100644 --- a/frontend/src/components/TimeLogsPage/InstructorTimeLogsPage.jsx +++ b/frontend/src/components/TimeLogsPage/InstructorTimeLogsPage.jsx @@ -1,17 +1,30 @@ import React, { useEffect, useState } from 'react' import { withRouter } from 'react-router-dom' - +import { connect } from 'react-redux' import { TimeLogsSelectForm } from './TimeLogsSelectForm' import { TimeLogRow } from './TimeLogRow' +import TimeLogChart from './TimeLogChart' import LoadingSpinner from '../common/LoadingSpinner' +import { SprintSelect } from './SprintSelect' + +import { Typography } from '@material-ui/core' import userService from '../../services/user' import configurationService from '../../services/configuration' import groupManagementService from '../../services/groupManagement' +import timeLogsService from '../../services/timeLogs' import instructorTimeLogsService from '../../services/instructorTimeLogs' + import * as notificationActions from '../../reducers/actions/notificationActions' +import timeLogsActions from '../../reducers/actions/timeLogsActions' + +const InstructorTimeLogsPage = (props) => { + const { + selectedSprintNumber, + setSelectedSprintNumber, + setGroupSprintSummary + } = props -const InstructorTimeLogsPage = () => { const [allConfigurations, setAllConfigurations] = useState([]) const [selectedConfiguration, setSelectedConfiguration] = useState(null) const [allGroups, setAllGroups] = useState([]) @@ -21,6 +34,7 @@ const InstructorTimeLogsPage = () => { const [allLogs, setAllLogs] = useState(null) const [isLoading, setIsLoading] = useState(true) + const possibleSprintNumbers = Array.from({length: 101}, (_, i) => i) useEffect(() => { const fetchAllConfigurations = async () => { @@ -94,43 +108,127 @@ const InstructorTimeLogsPage = () => { fetchData() }, []) + useEffect(() => { + const fetchGroupSprintSummary = async (group_id) => { + try { + const summaryData = await timeLogsService.getGroupSprintSummary(group_id) + setGroupSprintSummary(JSON.parse(summaryData)) + setSelectedSprintNumber(0) + } catch (error) { + console.error( + 'Error fetching group sprint summary:', + error.message, + ' / ', + error.response.data.error + ) + notificationActions.setError(error.response.data.error) + } + } + + const fetchChartData = async (selectedGroupId) => { + setIsLoading(true) + await fetchGroupSprintSummary(selectedGroupId) + setIsLoading(false) + } + selectedGroup?.id && fetchChartData(selectedGroup.id) + }, [selectedGroup]) + + const previousSprint = [...possibleSprintNumbers] + .reverse() + .find((sprint) => sprint < selectedSprintNumber) + + const nextSprint = possibleSprintNumbers.find( + (sprint) => sprint > selectedSprintNumber + ) + + const handleClickNextSprint = () => { + setSelectedSprintNumber( + nextSprint !== undefined ? nextSprint : selectedSprintNumber + ) + } + + const handleClickPreviousSprint = () => { + setSelectedSprintNumber( + previousSprint !== undefined ? previousSprint : selectedSprintNumber + ) + } + const isLogs = (logs) => logs && logs.length > 0 const logsByStudent = isLogs(allLogs) && allLogs.filter((log) => log.studentNumber === selectedStudentNumber) if (isLoading) return return ( -
-
- - {selectedGroup &&
{selectedGroup.name}
} -
-
- {isLogs(logsByStudent) && - logsByStudent.map((log) => ( - +
+
+ + {selectedGroup && ( +
+ Timelogs by {selectedGroup.name} + - ))} - {!isLogs(logsByStudent) && ( -

No logs by the selected user.

+
)} +
+
+ {isLogs(logsByStudent) && + logsByStudent.map((log) => ( + + ))} + {!isLogs(logsByStudent) && ( +

No logs by the selected user.

+ )} +
+
+
+ {selectedGroup && +
+
+ Sprint Chart + +
+
+ Project Chart + +
+
+ }
-
+
) } +const mapStateToProps = (state) => ({ + state: state, + selectedSprintNumber: state.timeLogs.selectedSprintNumber, +}) + +const mapDispatchToProps = { + setError: notificationActions.setError, + setSuccess: notificationActions.setSuccess, + setGroupSprintSummary: timeLogsActions.setGroupSprintSummary, + setSelectedSprintNumber: timeLogsActions.setSelectedSprintNumber, +} + export default withRouter( - (InstructorTimeLogsPage) + connect(mapStateToProps, mapDispatchToProps)(InstructorTimeLogsPage) ) diff --git a/frontend/src/components/TimeLogsPage/TimeLogChart.jsx b/frontend/src/components/TimeLogsPage/TimeLogChart.jsx index 7560097..5f01fe2 100644 --- a/frontend/src/components/TimeLogsPage/TimeLogChart.jsx +++ b/frontend/src/components/TimeLogsPage/TimeLogChart.jsx @@ -103,8 +103,10 @@ const TimeLogChart = (props) => { useEffect(() => { const mappedData = mapSprintSummaryData(groupSprintSummary) - setSprints([...new Set(mappedData.map((entry) => entry.sprint).filter((entry) => entry !== -1))]) - setChartData(mappedData) + if (mappedData) { + setSprints([...new Set(mappedData.map((entry) => entry.sprint).filter((entry) => entry !== -1))]) + setChartData(mappedData) + } }, [groupSprintSummary]) if (chartData && chartData.length > 0) {