Skip to content

Commit cb96d37

Browse files
committed
Student Stats: лучшее решение по задаче
1 parent 9f56644 commit cb96d37

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

hwproj.front/src/components/Courses/StudentStats.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import StudentStatsUtils from "../../services/StudentStatsUtils";
99
import ShowChartIcon from "@mui/icons-material/ShowChart";
1010
import {BonusTag, DefaultTags, TestTag} from "../Common/HomeworkTags";
1111
import Lodash from "lodash"
12+
import ApiSingleton from "@/api/ApiSingleton";
1213

1314
interface IStudentStatsProps {
1415
course: CourseViewModel;
@@ -35,6 +36,7 @@ const StudentStats: React.FC<IStudentStatsProps> = (props) => {
3536
}
3637

3738
const {searched} = state
39+
const isMentor = ApiSingleton.authService.isMentor()
3840

3941
useEffect(() => {
4042
const keyDownHandler = (event: KeyboardEvent) => {
@@ -98,6 +100,25 @@ const StudentStats: React.FC<IStudentStatsProps> = (props) => {
98100
const hasHomeworks = homeworksMaxSum > 0
99101
const hasTests = testsMaxSum > 0
100102

103+
const bestTaskSolutions = new Map<number, string>()
104+
if (solutions) {
105+
Lodash(homeworks)
106+
.flatMap(h => h.tasks!)
107+
.map(t => solutions
108+
.map(s => s.homeworks!
109+
.flatMap(h1 => h1.tasks!)
110+
.find(t1 => t1.id === t.id)?.solution || [])
111+
.map(s => StudentStatsUtils.calculateLastRatedSolution(s))
112+
.filter(x => x != undefined && x.rating! > 0))
113+
.filter(x => x.length > 0)
114+
.map(x => Lodash(x).orderBy([
115+
(x) => x.rating,
116+
(x) => new Date(x.publicationDate!).getTime()
117+
], ["desc", "asc"]).value()[0]
118+
)
119+
.forEach(x => bestTaskSolutions.set(x.taskId!, x.studentId!))
120+
}
121+
101122
return (
102123
<div>
103124
{props.solutions === undefined && <LinearProgress/>}
@@ -291,6 +312,7 @@ const StudentStats: React.FC<IStudentStatsProps> = (props) => {
291312
studentId={String(cm.id)}
292313
taskId={task.id!}
293314
taskMaxRating={task.maxRating!}
315+
isBestSolution={isMentor && bestTaskSolutions.get(task.id!) === cm.id}
294316
{...additionalStyles}/>;
295317
})
296318
)}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@keyframes golden-glow-strongest-inset {
2+
0% {
3+
box-shadow:
4+
inset 0 0 45px rgba(255, 215, 0, 1), /* супер яркое и большое внутреннее */
5+
0 0 10px rgba(255, 215, 0, 0.6); /* лёгкое внешнее */
6+
border-color: #ffd700;
7+
}
8+
70% {
9+
box-shadow:
10+
inset 0 0 12px rgba(255, 215, 0, 0.4), /* заметное затухание внутри */
11+
0 0 3px rgba(255, 215, 0, 0.2); /* почти исчезающее снаружи */
12+
border-color: #ffd700;
13+
}
14+
100% {
15+
box-shadow:
16+
inset 0 0 45px rgba(255, 215, 0, 1),
17+
0 0 10px rgba(255, 215, 0, 0.6);
18+
border-color: #ffd700;
19+
}
20+
}
21+
22+
.glow-cell {
23+
animation: golden-glow-strongest-inset 2.5s infinite ease-in-out;
24+
}

hwproj.front/src/components/Tasks/StudentStatsCell.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import * as React from "react";
2-
import {useState, FC, useEffect} from "react";
2+
import {FC} from "react";
33
import TableCell from "@material-ui/core/TableCell";
44
import {useNavigate} from "react-router-dom";
55
import {Solution} from "api";
66
import {Chip, Stack, Tooltip} from "@mui/material";
77
import StudentStatsUtils from "../../services/StudentStatsUtils";
88
import Utils from "../../services/Utils";
99
import {grey} from "@material-ui/core/colors";
10+
import "../Courses/Styles/StudentStatsCell.css";
1011

1112
interface ITaskStudentCellProps {
1213
studentId: string;
1314
taskId: number;
1415
forMentor: boolean;
1516
userId: string;
1617
taskMaxRating: number;
18+
isBestSolution: boolean;
1719
solutions?: Solution[];
1820
}
1921

@@ -27,7 +29,9 @@ const StudentStatsCell: FC<ITaskStudentCellProps & { borderLeftColor?: string }>
2729

2830
const tooltipTitle = ratedSolutionsCount === 0
2931
? solutionsDescription
30-
: solutionsDescription + `\n\n${Utils.pluralizeHelper(["Проверена", "Проверены", "Проверено"], ratedSolutionsCount)} ${ratedSolutionsCount} ${Utils.pluralizeHelper(["попытка", "попытки", "попыток"], ratedSolutionsCount)}`;
32+
: solutionsDescription
33+
+ (props.isBestSolution ? "\n Первое решение с лучшей оценкой" : "")
34+
+ `\n\n${Utils.pluralizeHelper(["Проверена", "Проверены", "Проверено"], ratedSolutionsCount)} ${ratedSolutionsCount} ${Utils.pluralizeHelper(["попытка", "попытки", "попыток"], ratedSolutionsCount)}`;
3135

3236
const result = cellState.lastRatedSolution === undefined
3337
? ""
@@ -58,6 +62,7 @@ const StudentStatsCell: FC<ITaskStudentCellProps & { borderLeftColor?: string }>
5862
title={<span style={{whiteSpace: 'pre-line'}}>{tooltipTitle}</span>}>
5963
<TableCell
6064
onClick={handleCellClick}
65+
className={props.isBestSolution ? "glow-cell" : ""}
6166
component="td"
6267
padding="none"
6368
variant={"body"}

0 commit comments

Comments
 (0)