55 HomeworkTaskViewModel ,
66 Solution ,
77 TaskSolutionsStats ,
8- SolutionState , StudentDataDto
8+ SolutionState , StudentDataDto , AccountDataDto
99} from "@/api" ;
1010import Typography from "@material-ui/core/Typography" ;
1111import Task from "../Tasks/Task" ;
@@ -26,7 +26,10 @@ import {
2626 SelectChangeEvent ,
2727 Stack ,
2828 Tooltip ,
29- Checkbox
29+ Checkbox ,
30+ Autocomplete ,
31+ AutocompleteRenderInputParams ,
32+ TextField
3033} from "@mui/material" ;
3134import StudentStatsUtils from "../../services/StudentStatsUtils" ;
3235
@@ -37,16 +40,19 @@ import {getTip} from "../Common/HomeworkTags";
3740import { appBarStateManager } from "../AppBar" ;
3841import { DotLottieReact } from "@lottiefiles/dotlottie-react" ;
3942import { RemovedFromCourseTag } from "@/components/Common/StudentTags" ;
43+ import AuthService from "@/services/AuthService" ;
4044
4145interface IStudentSolutionsPageState {
4246 currentTaskId : string
4347 task : HomeworkTaskViewModel
4448 isLoaded : boolean
4549 courseId : number ,
50+ courseMentors : AccountDataDto [ ] ,
4651 homeworkSolutionsStats : HomeworksGroupSolutionStats [ ] ,
4752 taskStudentsSolutionsPreview : {
4853 taskId : number ,
4954 studentSolutionsPreview : {
55+ hasDifferentReviewer : boolean ,
5056 student : StudentDataDto ,
5157 solutions : GetSolutionModel [ ]
5258 lastSolution : GetSolutionModel ,
@@ -79,14 +85,18 @@ const StudentSolutionsPage: FC = () => {
7985 const [ studentSolutionsState , setStudentSolutionsState ] = useState < IStudentSolutionsPageState > ( {
8086 currentTaskId : "" ,
8187 task : { } ,
88+ courseMentors : [ ] ,
8289 isLoaded : false ,
8390 courseId : - 1 ,
8491 homeworkSolutionsStats : [ ] ,
8592 taskStudentsSolutionsPreview : [ ] ,
8693 } )
87- const [ filterState , setFilterState ] = React . useState < Filter [ ] > (
94+ const [ filterState , setFilterState ] = useState < Filter [ ] > (
8895 localStorage . getItem ( FilterStorageKey ) ?. split ( ", " ) . filter ( x => x !== "" ) . map ( x => x as Filter ) || [ ]
8996 )
97+
98+ const [ secondMentorId , setSecondMentorId ] = useState < string | undefined > ( undefined )
99+
90100 const handleFilterChange = ( event : SelectChangeEvent < typeof filterState > ) => {
91101 const filters = filterState . length > 0 ? [ ] : [ "Только непроверенные" as Filter ]
92102 localStorage . setItem ( FilterStorageKey , filters . join ( ", " ) )
@@ -100,9 +110,12 @@ const StudentSolutionsPage: FC = () => {
100110 currentTaskId,
101111 taskStudentsSolutionsPreview,
102112 courseId,
103- homeworkSolutionsStats
113+ homeworkSolutionsStats,
114+ courseMentors
104115 } = studentSolutionsState
105116
117+ const secondMentor = courseMentors . find ( x => x . userId == secondMentorId )
118+
106119 const currentTaskSolutionsPreview = taskStudentsSolutionsPreview . find ( x => x . taskId === + currentTaskId )
107120 const currentTaskSolutions = currentTaskSolutionsPreview ?. studentSolutionsPreview || [ ]
108121
@@ -157,7 +170,7 @@ const StudentSolutionsPage: FC = () => {
157170 ? [ ]
158171 : homeworks . map ( h => h . statsForTasks ! [ taskIndexInHomework ] . taskId ! )
159172
160- const getTaskData = async ( taskId : string , fullUpdate : boolean ) => {
173+ const getTaskData = async ( taskId : string , secondMentorId : string | undefined , fullUpdate : boolean ) => {
161174 const task = await ApiSingleton . tasksApi . tasksGetTask ( + taskId ! )
162175
163176 if ( ! fullUpdate && versionsOfCurrentTask . includes ( + taskId ) ) {
@@ -173,14 +186,16 @@ const StudentSolutionsPage: FC = () => {
173186 const {
174187 taskSolutions,
175188 courseId,
176- statsForTasks
177- } = await ApiSingleton . solutionsApi . solutionsGetTaskSolutionsPageData ( + taskId ! )
189+ statsForTasks,
190+ courseMentors
191+ } = await ApiSingleton . solutionsApi . solutionsGetTaskSolutionsPageData ( + taskId ! , secondMentorId )
178192
179193 const studentSolutionsPreview = taskSolutions ! . map ( ts => ( {
180194 taskId : ts . taskId ! ,
181195 studentSolutionsPreview : ts . studentSolutions ! . map ( studentSolutions => {
182196 const ratedSolutionInfo = StudentStatsUtils . calculateLastRatedSolutionInfo ( studentSolutions . solutions ! , task . maxRating ! )
183197 return {
198+ hasDifferentReviewer : studentSolutions . hasDifferentReviewer ! ,
184199 student : studentSolutions . student ! , ...ratedSolutionInfo ,
185200 solutions : studentSolutions . solutions !
186201 }
@@ -194,6 +209,7 @@ const StudentSolutionsPage: FC = () => {
194209 currentTaskId : taskId ,
195210 homeworkSolutionsStats : statsForTasks ! ,
196211 taskStudentsSolutionsPreview : studentSolutionsPreview ,
212+ courseMentors : courseMentors ! . filter ( x => x . userId !== ApiSingleton . authService . getUserId ( ) ) ,
197213 courseId : courseId !
198214 } )
199215 }
@@ -204,7 +220,7 @@ const StudentSolutionsPage: FC = () => {
204220 } , [ courseId ] )
205221
206222 useEffect ( ( ) => {
207- getTaskData ( taskId ! , false )
223+ getTaskData ( taskId ! , secondMentorId , false )
208224 } , [ taskId ] )
209225
210226 useEffect ( ( ) => {
@@ -221,9 +237,8 @@ const StudentSolutionsPage: FC = () => {
221237 : < TaskAltIcon color = { isSelected ? "primary" : "success" } />
222238 }
223239
224- const renderStudentListItem = ( student : StudentDataDto ) => {
225- if ( ! student . characteristics || student . characteristics . tags ?. length === 0 ) return student . surname + " " + student . name
226- const tags = student . characteristics . tags !
240+ const renderStudentListItem = ( student : StudentDataDto , hasDifferentReviewer : boolean ) => {
241+ const tags = student . characteristics ?. tags || [ ]
227242
228243 const hasGoodCharacteristics = tags . some ( x => x . startsWith ( "+" ) )
229244 const hasBadCharacteristics = tags . some ( x => x . startsWith ( "-" ) )
@@ -232,13 +247,20 @@ const StudentSolutionsPage: FC = () => {
232247 ? < s > { student . surname + " " + student . name } </ s >
233248 : student . surname + " " + student . name
234249
235- if ( ! hasGoodCharacteristics && ! hasBadCharacteristics ) return studentFio
236-
237250 return < div > { studentFio }
238251 < sup style = { { paddingLeft : 5 } } >
239252 { hasGoodCharacteristics && < ThumbUpIcon color = { "success" } style = { { fontSize : 14 } } /> }
240253 { hasBadCharacteristics && < ThumbDownIcon color = { "error" } style = { { fontSize : 14 } } /> }
241254 </ sup >
255+ { hasDifferentReviewer && secondMentor && < Typography
256+ style = { {
257+ color : "GrayText" ,
258+ fontSize : "12px" ,
259+ lineHeight : '1.2'
260+ } }
261+ >
262+ { secondMentor . name } { secondMentor . surname }
263+ </ Typography > }
242264 </ div >
243265 }
244266
@@ -281,6 +303,23 @@ const StudentSolutionsPage: FC = () => {
281303 </ Grid >
282304 < Grid container spacing = { 3 } style = { { marginTop : '1px' } } direction = { "row" } >
283305 < Grid item xs = { 12 } sm = { 12 } md = { 4 } lg = { 3 } >
306+ { courseMentors . length > 0 && < Autocomplete
307+ fullWidth
308+ freeSolo = { false }
309+ size = { "medium" }
310+ options = { courseMentors }
311+ getOptionLabel = { ( option ) => option . name ! + ' ' + option . surname ! }
312+ value = { secondMentor }
313+ onChange = { async ( _ , newValue ) => {
314+ setSecondMentorId ( newValue ?. userId )
315+ await getTaskData ( currentTaskId , newValue ?. userId , true )
316+ } }
317+ renderInput = { params => < TextField
318+ { ...params }
319+ label = "Другие решения"
320+ placeholder = "Выберите преподавателя"
321+ /> }
322+ /> }
284323 < Stack direction = { "row" } alignItems = { "center" } >
285324 < Checkbox
286325 onChange = { handleFilterChange }
@@ -294,7 +333,8 @@ const StudentSolutionsPage: FC = () => {
294333 color,
295334 solutionsDescription,
296335 lastRatedSolution,
297- student
336+ student,
337+ hasDifferentReviewer
298338 } , idx ) => {
299339 const { userId} = student
300340 const storageKey = {
@@ -332,7 +372,9 @@ const StudentSolutionsPage: FC = () => {
332372 size = { "small" }
333373 label = { lastRatedSolution == undefined ? "?" : lastRatedSolution . rating } />
334374 </ Tooltip > }
335- < ListItemText primary = { renderStudentListItem ( student ) } />
375+ < ListItemText
376+ key = { student . userId }
377+ primary = { renderStudentListItem ( student , hasDifferentReviewer ) } />
336378 </ Stack >
337379 </ ListItemButton >
338380 </ Link >
@@ -375,7 +417,7 @@ const StudentSolutionsPage: FC = () => {
375417 courseStudents = { courseStudents }
376418 onSolutionRateClick = { async ( ) => {
377419 //const nextStudentIndex = studentSolutionsPreview.findIndex(x => x.student.userId !== currentStudentId && x.lastSolution && x.lastSolution.state === Solution.StateEnum.NUMBER_0)
378- await getTaskData ( currentTaskId , true )
420+ await getTaskData ( currentTaskId , secondMentorId , true )
379421 //else navigate(`/task/${currentTaskId}/${studentSolutionsPreview[nextStudentIndex].student.userId}`)
380422 } }
381423 />
0 commit comments