diff --git a/compose.yaml b/compose.yaml index 951ac7e..a67e059 100644 --- a/compose.yaml +++ b/compose.yaml @@ -2,7 +2,7 @@ db: image: postgres:16-alpine ports: - - 5432:5432 + - 127.0.0.1:5432:5432 volumes: - pg-data:/var/lib/postgresql/data environment: diff --git a/frontend/src/components/AdminSprintsPage/AdminSprintsPage.jsx b/frontend/src/components/AdminSprintsPage/AdminSprintsPage.jsx index 13638ca..33575d1 100644 --- a/frontend/src/components/AdminSprintsPage/AdminSprintsPage.jsx +++ b/frontend/src/components/AdminSprintsPage/AdminSprintsPage.jsx @@ -6,7 +6,14 @@ import LoadingSpinner from '../common/LoadingSpinner' import { SprintsSelectForm } from "./SprintsSelectForm" import { SprintListItem } from "./SprintListItem" -import { Typography } from '@material-ui/core' +import { + Typography, + Table, + TableRow, + TableBody, + TableHead, + TableCell +} from '@material-ui/core' import sprintService from '../../services/sprints' import configurationService from '../../services/configuration' @@ -112,21 +119,21 @@ const AdminSprintsPage = (props) => { Sprints by {selectedGroup.name} {allSprints.length > 0 && (
- - - - - - - - - - +
Sprint NumberStart DateEnd DateActions
+ + + Sprint Number + Start Date + End Date + Actions + + + {allSprints.sort((a, b) => b.sprint - a.sprint).map((sprint) => { return })} - -
+ +
)} diff --git a/frontend/src/components/AdminSprintsPage/SprintListItem.jsx b/frontend/src/components/AdminSprintsPage/SprintListItem.jsx index b8673ef..475cf22 100644 --- a/frontend/src/components/AdminSprintsPage/SprintListItem.jsx +++ b/frontend/src/components/AdminSprintsPage/SprintListItem.jsx @@ -1,5 +1,6 @@ -import React, { useState, useEffect, useImperativeHandle } from 'react' +import React, { useState, useEffect } from 'react' import Button from '@material-ui/core/Button' +import { TableRow, TableCell } from '@material-ui/core' import TextField from '@material-ui/core/TextField' import sprintService from '../../services/sprints' @@ -71,9 +72,9 @@ export const SprintListItem = (props) => { setEndDateErrorMessage("") try { - const res = await sprintService.updateSprint({ + const res = await sprintService.updateSprint({ id: sprint.id, - start_date: newStartDate, + start_date: newStartDate, end_date: newEndDate, sprint: sprint.sprint }) @@ -91,43 +92,47 @@ export const SprintListItem = (props) => { return ( - - {sprint.sprint} - {!isEditing ? formatDate(startDate) : - setNewStartDate(e.target.value)} - InputLabelProps={{ - shrink: true, - }} - variant="outlined" - /> - } - {!isEditing ? formatDate(endDate) : - setNewEndDate(e.target.value)} - InputLabelProps={{ - shrink: true, - }} - variant="outlined" - /> - } - + + {sprint.sprint} + + {!isEditing ? formatDate(startDate) : + setNewStartDate(e.target.value)} + InputLabelProps={{ + shrink: true, + }} + variant="outlined" + /> + } + + + {!isEditing ? formatDate(endDate) : + setNewEndDate(e.target.value)} + InputLabelProps={{ + shrink: true, + }} + variant="outlined" + /> + } + + {isEditing && } - - + + ) } diff --git a/frontend/src/components/GroupManagementPage/GroupManagementForm.jsx b/frontend/src/components/GroupManagementPage/GroupManagementForm.jsx index 0338996..00726d4 100644 --- a/frontend/src/components/GroupManagementPage/GroupManagementForm.jsx +++ b/frontend/src/components/GroupManagementPage/GroupManagementForm.jsx @@ -2,6 +2,7 @@ import React from 'react' import { connect } from 'react-redux' import Paper from '@material-ui/core/Paper' +import { Table, TableBody, TableRow, TableCell } from '@material-ui/core' import * as notificationActions from '../../reducers/actions/notificationActions' import groupManagementActions from '../../reducers/actions/groupManagementActions' @@ -31,10 +32,10 @@ const GroupManagementForm = ({ style={{ clear: 'both', display: 'table', padding: '15px' }} > - - - -
+ + + + - - - -
+ + + +
) diff --git a/frontend/src/components/InstructorPage/InstructorPage.jsx b/frontend/src/components/InstructorPage/InstructorPage.jsx index 726d36c..1e05df5 100644 --- a/frontend/src/components/InstructorPage/InstructorPage.jsx +++ b/frontend/src/components/InstructorPage/InstructorPage.jsx @@ -8,6 +8,7 @@ import MenuItem from '@material-ui/core/MenuItem' import Typography from '@material-ui/core/Typography' import Select from '@material-ui/core/Select' import Error from '@material-ui/icons/Error' +import { Table, TableRow, TableCell, TableHead, TableBody } from '@material-ui/core' import * as notificationActions from '../../reducers/actions/notificationActions' import './InstructorPage.css' @@ -259,46 +260,46 @@ const RadioAnswer = ({ answers, questionNumber, students }) => { return (
- - - -
+ + + + {peers.map((peer, index) => ( - + ))} - - - - - - + + + + {peers.map((member, index) => { return ( - - + - + ) })} - -
Reviewer - -
+ + + + - + Average

(without self-review)

-
+ +

{member}

-
+ +
) } @@ -306,9 +307,9 @@ const RadioAnswer = ({ answers, questionNumber, students }) => { const PeerHeaders = ({ peers }) => { return peers.map((option, optionId) => { return ( - + {option} - + ) }) } @@ -343,13 +344,15 @@ const PeerRows = ({ member, answers, questionNumber, numberOfPeers }) => { return ( {allPeersRatings.map((ratingInfo, index) => ( - + {typeof ratingInfo.rating === 'number' ? ratingInfo.rating.toFixed(2) : ratingInfo.rating} - + ))} - {averageRating} + + {averageRating} + ) } diff --git a/frontend/src/components/SprintsPage/SprintsDashboard.jsx b/frontend/src/components/SprintsPage/SprintsDashboard.jsx index 7f2d97d..cad81d1 100644 --- a/frontend/src/components/SprintsPage/SprintsDashboard.jsx +++ b/frontend/src/components/SprintsPage/SprintsDashboard.jsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react' import Typography from '@material-ui/core/Typography' import TextField from '@material-ui/core/TextField' import Button from '@material-ui/core/Button' +import { Table, TableRow, TableHead, TableBody, TableCell } from '@material-ui/core' import sprintService from '../../services/sprints' import { NotInGroupPlaceholder } from '../common/Placeholders' import './SprintsDashboard.css' @@ -130,16 +131,16 @@ const SprintsPage = (props) => { {allSprints.length > 0 && (
- - - - - - - - - - +
Sprint NumberStart DateEnd DateActions
+ + + Sprint Number + Start Date + End Date + Actions + + + {allSprints .sort((a, b) => b.sprint - a.sprint) .map((sprint) => { @@ -163,13 +164,13 @@ const SprintsPage = (props) => { .replace(/\./g, '/') return ( - - - - - - + + ) })} - -
+ + {sprint.sprint} - {formattedStartDate}{formattedEndDate} + + {formattedStartDate} + {formattedEndDate} + -
+ +
)} diff --git a/frontend/src/components/TagPage/TagUsageBarChart.jsx b/frontend/src/components/TagPage/TagUsageBarChart.jsx index d2d689b..ea855fc 100644 --- a/frontend/src/components/TagPage/TagUsageBarChart.jsx +++ b/frontend/src/components/TagPage/TagUsageBarChart.jsx @@ -9,8 +9,11 @@ import { ResponsiveContainer, Cell, } from 'recharts' +import { useTheme } from '@material-ui/core/styles'; const TagUsageBarChart = ({ allTags, selectedTags, tagData, tagColors }) => { + const theme = useTheme() + const data = allTags .filter((tag) => selectedTags.includes(tag)) .map((tag) => { @@ -33,6 +36,9 @@ const TagUsageBarChart = ({ allTags, selectedTags, tagData, tagColors }) => { textAnchor="end" interval={0} height={80} + tick={{ fill: theme.palette.text.primary }} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} tickFormatter={(value) => value.length > 10 ? `${value.substring(0, 10)}...` : value } @@ -42,9 +48,18 @@ const TagUsageBarChart = ({ allTags, selectedTags, tagData, tagColors }) => { value: 'Hours', angle: -90, position: 'insideLeft', + fill: theme.palette.text.primary, }} + tick={{ fill: theme.custom.chartAxis.stroke }} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} + /> + `${Math.round(value * 100) / 100} h`} + cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }} + contentStyle={{ backgroundColor: theme.custom.chartTooltip.background }} + itemStyle={{ color: theme.palette.text }} /> - `${Math.round(value * 100) / 100} h`} /> {data.map((entry) => ( { + const theme = useTheme() + const data = allSprints.map((sprint) => { const sprintTagHours = {} @@ -40,15 +43,28 @@ const TagUsageLineChart = ({ - + + `${Math.round(value * 100) / 100} h`} + cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }} + contentStyle={{ backgroundColor: theme.custom.chartTooltip.background }} /> - `${Math.round(value * 100) / 100} h`} /> {allTags diff --git a/frontend/src/components/TimeLogsPage/TimeLogChart.jsx b/frontend/src/components/TimeLogsPage/TimeLogChart.jsx index d6d9f74..14056c7 100644 --- a/frontend/src/components/TimeLogsPage/TimeLogChart.jsx +++ b/frontend/src/components/TimeLogsPage/TimeLogChart.jsx @@ -1,9 +1,9 @@ - import React, { useState, useEffect } from 'react' import { connect } from 'react-redux' import { ResponsiveContainer, BarChart, XAxis, YAxis, Tooltip, ReferenceLine, Label, LabelList, Bar, Cell } from 'recharts' import { NoTimeLogsPlaceholderSprint, NoTimeLogsPlaceholderProject } from '../common/Placeholders' import Error from '@material-ui/icons/Error' +import { useTheme } from '@material-ui/core/styles'; import './TimeLogsPage.css' @@ -175,6 +175,7 @@ const TimeLogChart = (props) => { const [sprintDates, setSprintDates] = useState({}) const [projectDuration, setProjectDuration] = useState(0) const [selectedSprintDuration, setSelectedSprintDuration] = useState(0) + const theme = useTheme() const mapSprintSummaryData = (summaryData) => { let mappedData = [] @@ -281,11 +282,11 @@ const TimeLogChart = (props) => {

{`${label} : ${payload[0].value}h`}

@@ -311,11 +312,11 @@ const TimeLogChart = (props) => {

{`${label} : ${payload[0].value}h`}

@@ -342,14 +343,30 @@ const TimeLogChart = (props) => { className='timelogs-chart' data={chartData.filter((entry) => entry.sprint === -1)} > - } angle={270} tickLine={false} /> - Math.max(dataMax, idealHours(projectDuration))]}/> + } + angle={270} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} + /> + Math.max(dataMax, idealHours(projectDuration))]} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + tick={{ fill: theme.custom.chartAxis.stroke }} + /> - + { className='timelogs-chart' data={chartData.filter((entry) => entry.sprint === selectedSprintNumber)} > - } angle={270} tickLine={false} /> - Math.max(dataMax, idealHours(selectedSprintDuration))]}/> + } + angle={270} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} + /> + Math.max(dataMax, idealHours(projectDuration))]} + axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }} + tickLine={{ stroke: theme.custom.chartAxis.stroke }} + tick={{ fill: theme.custom.chartAxis.stroke }} + /> - + { const [agreement, setAgreement] = useState(false) const timing = props.content.summerDates + const theme = useTheme() + + const bgColor = theme.palette.type === 'dark' + ? '#202020' + : '#ffffff' const boxStyle = { - backgroundColor: agreement ? '' :'#f0f0f0', + backgroundColor: agreement ? '' : bgColor, border: '2px solid #333', borderRadius: '5px', padding: '20px', boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', fontSize: '16px', - color: '#333', + color: theme.palette.text.primary, margin: '20px auto', } diff --git a/frontend/src/index.jsx b/frontend/src/index.jsx index 4d5738e..846a3a5 100644 --- a/frontend/src/index.jsx +++ b/frontend/src/index.jsx @@ -9,6 +9,7 @@ import amber from '@material-ui/core/colors/amber' import CssBaseline from '@material-ui/core/CssBaseline' import useMediaQuery from '@material-ui/core/useMediaQuery' import { ColorModeContext } from './context/ColorModeContext' +import CustomerReviewPage from './components/CustomerReviewPage' const getInitialMode = () => { const stored = localStorage.getItem('theme') @@ -57,6 +58,18 @@ const Root = () => { marginBottom: '1.67em', }, }, + custom: { + chartTooltip: { + background: effectiveDark ? '#202020' : '#ffffff', + border: effectiveDark ? '#73292c' : '#d88488', + shadow: effectiveDark + ? '1px 1px 2px #73292c' + : '1px 1px 2px #d88488', + }, + chartAxis: { + stroke: effectiveDark ? '#ffffff' : '#4d4d4d', + }, + }, overrides: { MuiTableCell: { head: {