updated more components to support dark mode

This commit is contained in:
eeritvan
2026-04-20 21:34:02 +03:00
parent 7272d7eee4
commit 99ec989009
12 changed files with 236 additions and 137 deletions
+1 -1
View File
@@ -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:
@@ -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) => {
<Typography variant='h5'>Sprints by {selectedGroup.name}</Typography>
{allSprints.length > 0 && (
<div className="sprint-list-container">
<table>
<thead>
<tr>
<th>Sprint Number</th>
<th>Start Date</th>
<th>End Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="sprint-list-rows">
<Table>
<TableHead>
<TableRow hover>
<TableCell>Sprint Number</TableCell>
<TableCell>Start Date</TableCell>
<TableCell>End Date</TableCell>
<TableCell>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody id="sprint-list-rows">
{allSprints.sort((a, b) => b.sprint - a.sprint).map((sprint) => {
return <SprintListItem sprint={sprint} setError={setError} setSuccess={setSuccess} key={sprint.id}/>
})}
</tbody>
</table>
</TableBody>
</Table>
</div>
)}
</div>
@@ -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'
@@ -91,9 +92,10 @@ export const SprintListItem = (props) => {
return (
<tr>
<td className="sprint-list-sprint-number">{sprint.sprint}</td>
<td>{!isEditing ? formatDate(startDate) :
<TableRow hover>
<TableCell className="sprint-list-sprint-number">{sprint.sprint}</TableCell>
<TableCell>
{!isEditing ? formatDate(startDate) :
<TextField
errors={(!!startDateErrorMessage).toString()}
helperText={startDateErrorMessage}
@@ -109,8 +111,10 @@ export const SprintListItem = (props) => {
}}
variant="outlined"
/>
}</td>
<td>{!isEditing ? formatDate(endDate) :
}
</TableCell>
<TableCell>
{!isEditing ? formatDate(endDate) :
<TextField
errors={(!!endDateErrorMessage).toString()}
helperText={endDateErrorMessage}
@@ -126,8 +130,9 @@ export const SprintListItem = (props) => {
}}
variant="outlined"
/>
}</td>
<td>
}
</TableCell>
<TableCell>
{isEditing &&
<Button
id={`sprint-edit-save-button-${sprint.id}`}
@@ -148,7 +153,7 @@ export const SprintListItem = (props) => {
>
{isEditing ? "Cancel" : "Edit" }
</Button>
</td>
</tr>
</TableCell>
</TableRow>
)
}
@@ -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' }}
>
<Paper>
<table>
<tbody>
<tr>
<td style={{ verticalAlign: 'top', padding: '25px' }}>
<Table>
<TableBody>
<TableRow hover>
<TableCell style={{ verticalAlign: 'top', padding: '25px' }}>
<GroupViewer
group={group}
topics={topics}
@@ -44,10 +45,10 @@ const GroupManagementForm = ({
setSuccess={setSuccess}
setError={setError}
/>
</td>
</tr>
</tbody>
</table>
</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
</div>
)
@@ -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 (
<div className="padding-left-18">
<table className="radio-button-table">
<thead>
<tr className="radio-inforow">
<th />
<Table className="radio-button-table">
<TableHead>
<TableRow hover className="radio-inforow">
<TableCell />
{peers.map((peer, index) => (
<th
<TableCell
key={`radio-infoheader-${index}`}
className="radio-infoheader text-overflow-ellipsis"
>
Reviewer
</th>
</TableCell>
))}
<th />
</tr>
<tr className="radio-row">
<th />
<TableCell />
</TableRow>
<TableRow hover className="radio-row">
<TableCell />
<PeerHeaders peers={peers} />
<th className="radio-header text-overflow-ellipsis">
<TableCell className="radio-header text-overflow-ellipsis">
Average <p>(without self-review)</p>
</th>
</tr>
</thead>
<tbody>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{peers.map((member, index) => {
return (
<tr key={index}>
<th className="peer-header text-overflow-ellipsis">
<TableRow hover key={index}>
<TableCell className="peer-header text-overflow-ellipsis">
<p>{member}</p>
</th>
</TableCell>
<PeerRows
member={member}
answers={answers}
questionNumber={questionNumber}
numberOfPeers={peers.length}
/>
</tr>
</TableRow>
)
})}
</tbody>
</table>
</TableBody>
</Table>
</div>
)
}
@@ -306,9 +307,9 @@ const RadioAnswer = ({ answers, questionNumber, students }) => {
const PeerHeaders = ({ peers }) => {
return peers.map((option, optionId) => {
return (
<th className="radio-header text-overflow-ellipsis" key={optionId}>
<TableCell className="radio-header text-overflow-ellipsis" key={optionId}>
{option}
</th>
</TableCell>
)
})
}
@@ -343,13 +344,15 @@ const PeerRows = ({ member, answers, questionNumber, numberOfPeers }) => {
return (
<React.Fragment>
{allPeersRatings.map((ratingInfo, index) => (
<td className="radio-button" key={`peer-row-${index}`}>
<TableCell className="radio-button" key={`peer-row-${index}`}>
{typeof ratingInfo.rating === 'number'
? ratingInfo.rating.toFixed(2)
: ratingInfo.rating}
</td>
</TableCell>
))}
<td className="radio-button">{averageRating}</td>
<TableCell className="radio-button">
{averageRating}
</TableCell>
</React.Fragment>
)
}
@@ -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) => {
</Button>
{allSprints.length > 0 && (
<div className="sprint-list-container">
<table>
<thead>
<tr>
<th>Sprint Number</th>
<th>Start Date</th>
<th>End Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="sprint-list-rows">
<Table>
<TableHead>
<TableRow hover>
<TableCell>Sprint Number</TableCell>
<TableCell>Start Date</TableCell>
<TableCell>End Date</TableCell>
<TableCell>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody id="sprint-list-rows">
{allSprints
.sort((a, b) => b.sprint - a.sprint)
.map((sprint) => {
@@ -163,13 +164,13 @@ const SprintsPage = (props) => {
.replace(/\./g, '/')
return (
<tr key={sprint.id} data-cy={`sprint-${sprint.sprint}`}>
<td className="sprint-list-sprint-number">
<TableRow hover key={sprint.id} data-cy={`sprint-${sprint.sprint}`}>
<TableCell className="sprint-list-sprint-number">
{sprint.sprint}
</td>
<td>{formattedStartDate}</td>
<td>{formattedEndDate}</td>
<td>
</TableCell>
<TableCell>{formattedStartDate}</TableCell>
<TableCell>{formattedEndDate}</TableCell>
<TableCell>
<Button
id={`sprint-remove-button-${sprint.id}`}
onClick={() => handleDeleteSprint(sprint.id)}
@@ -179,12 +180,12 @@ const SprintsPage = (props) => {
>
Delete
</Button>
</td>
</tr>
</TableCell>
</TableRow>
)
})}
</tbody>
</table>
</TableBody>
</Table>
</div>
)}
</div>
@@ -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 }}
/>
<Tooltip
formatter={(value) => `${Math.round(value * 100) / 100} h`}
cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }}
contentStyle={{ backgroundColor: theme.custom.chartTooltip.background }}
itemStyle={{ color: theme.palette.text }}
/>
<Tooltip formatter={(value) => `${Math.round(value * 100) / 100} h`} />
<Bar dataKey="value">
{data.map((entry) => (
<Cell
@@ -9,6 +9,7 @@ import {
XAxis,
YAxis,
} from 'recharts'
import { useTheme } from '@material-ui/core/styles';
const TagUsageLineChart = ({
allSprints,
@@ -17,6 +18,8 @@ const TagUsageLineChart = ({
tagData,
tagColors,
}) => {
const theme = useTheme()
const data = allSprints.map((sprint) => {
const sprintTagHours = {}
@@ -40,15 +43,28 @@ const TagUsageLineChart = ({
<ResponsiveContainer width="100%" aspect={2} style={{ maxWidth: 800 }}>
<LineChart responsive data={data} id="tag-usage-line-chart">
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<XAxis
dataKey="name"
tick={{ fill: theme.palette.text.primary }}
tickLine={{ stroke: theme.custom.chartAxis.stroke }}
axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }}
/>
<YAxis
label={{
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 }}
/>
<Tooltip
formatter={(value) => `${Math.round(value * 100) / 100} h`}
cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }}
contentStyle={{ backgroundColor: theme.custom.chartTooltip.background }}
/>
<Tooltip formatter={(value) => `${Math.round(value * 100) / 100} h`} />
<Legend />
{allTags
@@ -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) => {
<div
className="custom-tooltip"
style={{
border: '1px solid #d88488',
backgroundColor: '#fff',
border: `1px solid ${theme.custom.chartTooltip.border}`,
backgroundColor: theme.custom.chartTooltip.background,
padding: '10px',
borderRadius: '5px',
boxShadow: '1px 1px 2px #d88488',
boxShadow: theme.custom.chartTooltip.shadow,
}}
>
<h3>{`${label} : ${payload[0].value}h`}</h3>
@@ -311,11 +312,11 @@ const TimeLogChart = (props) => {
<div
className="custom-tooltip"
style={{
border: '1px solid #d88488',
backgroundColor: '#fff',
border: `1px solid ${theme.custom.chartTooltip.border}`,
backgroundColor: theme.custom.chartTooltip.background,
padding: '10px',
borderRadius: '5px',
boxShadow: '1px 1px 2px #d88488',
boxShadow: theme.custom.chartTooltip.shadow,
}}
>
<h3>{`${label} : ${payload[0].value}h`}</h3>
@@ -342,14 +343,30 @@ const TimeLogChart = (props) => {
className='timelogs-chart'
data={chartData.filter((entry) => entry.sprint === -1)}
>
<XAxis dataKey='name' minTickGap={0} height={70} tick={<CustomizedTick variant={chartVariant} />} angle={270} tickLine={false} />
<YAxis domain={[0, (dataMax) => Math.max(dataMax, idealHours(projectDuration))]}/>
<XAxis
dataKey='name'
minTickGap={0}
height={70}
tick={<CustomizedTick variant={chartVariant} />}
angle={270}
tickLine={{ stroke: theme.custom.chartAxis.stroke }}
axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }}
/>
<YAxis
domain={[0, (dataMax) => 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 }}
/>
<ReferenceLine
y={idealHours(projectDuration)}
stroke="red"
strokeDasharray="3 3"
/>
<Tooltip content={showTotalTooltip} />
<Tooltip
content={showTotalTooltip}
cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }}
/>
<Bar
dataKey='altHours'
background={false}
@@ -374,14 +391,30 @@ const TimeLogChart = (props) => {
className='timelogs-chart'
data={chartData.filter((entry) => entry.sprint === selectedSprintNumber)}
>
<XAxis dataKey='name' minTickGap={0} height={70} tick={<CustomizedTick variant={chartVariant} />} angle={270} tickLine={false} />
<YAxis domain={[0, (dataMax) => Math.max(dataMax, idealHours(selectedSprintDuration))]}/>
<XAxis
dataKey='name'
minTickGap={0}
height={70}
tick={<CustomizedTick variant={chartVariant} />}
angle={270}
tickLine={{ stroke: theme.custom.chartAxis.stroke }}
axisLine={{ stroke: theme.custom.chartAxis.stroke, strokeWidth: 1 }}
/>
<YAxis
domain={[0, (dataMax) => 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 }}
/>
<ReferenceLine
y={idealHours(selectedSprintDuration)}
stroke="red"
strokeDasharray="3 3"
/>
<Tooltip content={showSprintTooltip} />
<Tooltip
content={showSprintTooltip}
cursor={{ fill: '#4d4d4d', fillOpacity: 0.2 }}
/>
<Bar
dataKey='altHours'
background={false}
@@ -55,7 +55,7 @@
margin-top: 8px;
.button {
padding: 0px 12px
padding: 0px 12px;
}
.button:hover {
@@ -90,7 +90,7 @@
}
.timelogs-form .submit-button:hover {
background-color: rgb(231, 231, 231)
background-color: rgb(231, 231, 231);
}
.timelogs-table-row {
@@ -105,7 +105,6 @@
padding-bottom: 16px;
}
.timelogs-description {
flex: 2;
padding: 0 8px;
@@ -127,7 +126,7 @@
}
.timelogs-remove-button:hover {
background-color: transparent
background-color: transparent;
}
.timelogs-remove-button {
@@ -144,7 +143,7 @@
display: flex;
gap: 16px;
align-items: center;
color: #4d4d4d;
/*color: #4d4d4d;*/
}
.timelogs-tags-row {
+8 -2
View File
@@ -4,20 +4,26 @@ import topicFormPageActions from '../reducers/actions/topicFormPageActions'
import TextField from '@material-ui/core/TextField'
import { Radio, RadioGroup, Checkbox } from '@material-ui/core'
import Button from '@material-ui/core/Button'
import { useTheme } from '@material-ui/core'
import './TopicForm.css'
const TopicForm = (props) => {
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',
}
+13
View File
@@ -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: {