@@ -20,7 +20,11 @@ import {
2020 NavItem ,
2121 NavLink ,
2222} from "reactstrap" ;
23- import { useMergedProblemMap } from "../../../../api/APIClient" ;
23+ import { FcCancel , FcCheckmark } from "react-icons/all" ;
24+ import {
25+ useMergedProblemMap ,
26+ useVirtualContestSubmissions ,
27+ } from "../../../../api/APIClient" ;
2428import {
2529 useLoginState ,
2630 useVirtualContest ,
@@ -45,19 +49,57 @@ import { generatePathWithParams } from "../../../../utils/QueryString";
4549import { ProblemLink } from "../../../../components/ProblemLink" ;
4650import { joinContest , leaveContest } from "../ApiClient" ;
4751import { GoogleCalendarButton } from "../../../../components/GoogleCalendarButton" ;
48- import { ContestTable } from "./ContestTable" ;
52+ import { ProblemId , UserId } from "../../../../interfaces/Status" ;
53+ import { constructPointOverrideMap , ContestTable } from "./ContestTable" ;
4954import { LockoutContestTable } from "./LockoutContestTable" ;
5055import { TrainingContestTable } from "./TrainingContestTable" ;
5156import { compareProblem } from "./util" ;
57+ import {
58+ ReducedProblemResult ,
59+ reduceUserContestResult ,
60+ } from "./ResultCalcUtil" ;
61+
62+ const Problems = ( props : {
63+ readonly problems : VirtualContestProblem [ ] ;
64+ readonly atCoderUserId : UserId ;
65+ readonly start : number ;
66+ readonly end : number ;
67+ } ) => {
68+ const submissions = useVirtualContestSubmissions (
69+ [ props . atCoderUserId ] ,
70+ props . problems . map ( ( p ) => p . item . id ) ,
71+ props . start ,
72+ props . end ,
73+ false
74+ ) ;
75+ const pointOverrideMap = constructPointOverrideMap ( props . problems ) ;
76+ const showUserResults =
77+ props . atCoderUserId !== "" &&
78+ submissions . data !== null &&
79+ submissions . data !== undefined ;
80+ const results = submissions . data
81+ ? reduceUserContestResult ( submissions . data , ( id ) =>
82+ pointOverrideMap . get ( id )
83+ )
84+ : new Map < UserId , ReducedProblemResult > ( ) ;
85+ const ResultIcon = ( props : { id : ProblemId } ) => {
86+ const result = results . get ( props . id ) ;
87+ if ( ! result ) return null ;
88+ if ( result . accepted ) {
89+ return < FcCheckmark /> ;
90+ } else {
91+ return < FcCancel /> ;
92+ }
93+ } ;
5294
53- const Problems = ( props : { problems : VirtualContestProblem [ ] } ) => {
5495 const sortedItems = props . problems
5596 . map ( ( p ) => ( {
5697 contestId : p . contestId ,
5798 title : p . title ,
5899 ...p . item ,
59100 } ) )
60101 . sort ( compareProblem ) ;
102+
61103 return (
62104 < div className = "my-2" >
63105 < Row >
@@ -75,12 +117,13 @@ const Problems = (props: { problems: VirtualContestProblem[] }) => {
75117 </ Row >
76118 < Row >
77119 < Col >
78- < Table striped size = "sm" >
120+ < Table striped bordered size = "sm" >
79121 < thead >
80122 < tr >
81123 < th > </ th >
82124 < th > Problem Name</ th >
83125 < th className = "text-center" > Score</ th >
126+ { showUserResults && < th > </ th > }
84127 </ tr >
85128 </ thead >
86129 < tbody >
@@ -109,6 +152,11 @@ const Problems = (props: { problems: VirtualContestProblem[] }) => {
109152 ) }
110153 </ td >
111154 < td className = "text-center" > { p . point !== null && p . point } </ td >
155+ { showUserResults && (
156+ < td className = "text-center" >
157+ < ResultIcon id = { p . id } />
158+ </ td >
159+ ) }
112160 </ tr >
113161 ) ) }
114162 </ tbody >
@@ -216,9 +264,15 @@ const NormalContestTabTypes = ["Problems", "Standings"] as const;
216264type NormalContestTabType = typeof NormalContestTabTypes [ number ] ;
217265const TAB_PARAM = "activeTab" ;
218266
219- const NormalContestPage = ( props : StandingsProps ) => {
267+ interface NormalContestPageProps extends StandingsProps {
268+ readonly enableEstimatedPerformances : boolean ;
269+ readonly atCoderUserId : string ;
270+ readonly penaltySecond : number ;
271+ }
272+
273+ const NormalContestPage = ( props : NormalContestPageProps ) => {
220274 const location = useLocation ( ) ;
221- const { showProblems, problems } = props ;
275+ const { showProblems } = props ;
222276 const tabs : NormalContestTabType [ ] = showProblems
223277 ? [ "Problems" , "Standings" ]
224278 : [ "Standings" ] ;
@@ -253,7 +307,7 @@ const NormalContestPage = (props: StandingsProps) => {
253307 </ Col >
254308 </ Row >
255309
256- { activeTab === "Problems" && < Problems problems = { problems } /> }
310+ { activeTab === "Problems" && < Problems { ... props } /> }
257311 { activeTab === "Standings" && < Standings { ...props } /> }
258312 </ >
259313 ) ;
0 commit comments