add group chat
This commit is contained in:
@@ -1,124 +1,126 @@
|
||||
import { FC, useEffect } from "react";
|
||||
import MissionItem from "./MissionItem";
|
||||
import { FC, useEffect } from 'react';
|
||||
import MissionItem from './MissionItem';
|
||||
import {
|
||||
Contest,
|
||||
fetchMySubmissions,
|
||||
setContestStatus,
|
||||
} from "../../../redux/slices/contests";
|
||||
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
|
||||
import { PrimaryButton } from "../../../components/button/PrimaryButton";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { arrowLeft } from "../../../assets/icons/header";
|
||||
Contest,
|
||||
fetchMySubmissions,
|
||||
setContestStatus,
|
||||
} from '../../../redux/slices/contests';
|
||||
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
|
||||
import { PrimaryButton } from '../../../components/button/PrimaryButton';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { arrowLeft } from '../../../assets/icons/header';
|
||||
|
||||
export interface Article {
|
||||
id: number;
|
||||
name: string;
|
||||
tags: string[];
|
||||
id: number;
|
||||
name: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
interface ContestMissionsProps {
|
||||
contest?: Contest;
|
||||
contest?: Contest;
|
||||
}
|
||||
|
||||
const ContestMissions: FC<ContestMissionsProps> = ({ contest }) => {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useAppDispatch();
|
||||
const { submissions, status } = useAppSelector(
|
||||
(state) => state.contests.fetchMySubmissions
|
||||
);
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useAppDispatch();
|
||||
const { submissions, status } = useAppSelector(
|
||||
(state) => state.contests.fetchMySubmissions,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (contest) dispatch(fetchMySubmissions(contest.id));
|
||||
}, [contest]);
|
||||
useEffect(() => {
|
||||
if (contest) dispatch(fetchMySubmissions(contest.id));
|
||||
}, [contest]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status == "successful") {
|
||||
dispatch(setContestStatus({ key: "fetchMySubmissions", status: "idle" }));
|
||||
useEffect(() => {
|
||||
if (status == 'successful') {
|
||||
dispatch(
|
||||
setContestStatus({ key: 'fetchMySubmissions', status: 'idle' }),
|
||||
);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
if (!contest) {
|
||||
return <></>;
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
if (!contest) {
|
||||
return <></>;
|
||||
}
|
||||
const solvedCount = (contest.missions ?? []).filter((mission) =>
|
||||
submissions.some(
|
||||
(s) =>
|
||||
s.solution.missionId === mission.id &&
|
||||
s.solution.status === 'Accepted: All tests passed',
|
||||
),
|
||||
).length;
|
||||
|
||||
const solvedCount = (contest.missions ?? []).filter((mission) =>
|
||||
submissions.some(
|
||||
(s) =>
|
||||
s.solution.missionId === mission.id &&
|
||||
s.solution.status === "Accepted: All tests passed"
|
||||
)
|
||||
).length;
|
||||
const totalCount = contest.missions?.length ?? 0;
|
||||
|
||||
const totalCount = contest.missions?.length ?? 0;
|
||||
return (
|
||||
<div className=" h-screen grid grid-rows-[74px,40px,1fr] p-[20px] gap-[20px]">
|
||||
<div className="">
|
||||
<div className="h-[50px] text-[40px] text-liquid-white font-bold">
|
||||
{contest.name}
|
||||
</div>
|
||||
<div className="flex justify-between h-[24px] items-center gap-[10px]">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={arrowLeft}
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate(`/home/contests`);
|
||||
}}
|
||||
/>
|
||||
<span className="text-liquid-light font-bold text-[18px]">
|
||||
Контест #{contest.id}
|
||||
</span>
|
||||
</div>
|
||||
<div>{contest.attemptDurationMinutes ?? 0} минут</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="text-liquid-white text-[16px] font-bold">{`${solvedCount}/${totalCount} Решено`}</div>
|
||||
<PrimaryButton
|
||||
onClick={() => {
|
||||
navigate(`/contest/${contest.id}/submissions`);
|
||||
}}
|
||||
text="Мои посылки"
|
||||
/>
|
||||
</div>
|
||||
|
||||
return (
|
||||
<div className=" h-screen grid grid-rows-[74px,40px,1fr] p-[20px] gap-[20px]">
|
||||
<div className="">
|
||||
<div className="h-[50px] text-[40px] text-liquid-white font-bold">
|
||||
{contest.name}
|
||||
<div className="h-full min-h-0 overflow-y-scroll medium-scrollbar flex flex-col gap-[20px]">
|
||||
<div className="w-full">
|
||||
{(contest.missions ?? []).map((v, i) => {
|
||||
const missionSubmissions = submissions.filter(
|
||||
(s) => s.solution.missionId === v.id,
|
||||
);
|
||||
|
||||
const hasSuccess = missionSubmissions.some(
|
||||
(s) =>
|
||||
s.solution.status ==
|
||||
'Accepted: All tests passed',
|
||||
);
|
||||
|
||||
const status = hasSuccess
|
||||
? 'success'
|
||||
: missionSubmissions.length > 0
|
||||
? 'error'
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<MissionItem
|
||||
contestId={contest.id}
|
||||
key={i}
|
||||
id={v.id}
|
||||
name={v.name}
|
||||
timeLimit={v.timeLimitMilliseconds}
|
||||
memoryLimit={v.memoryLimitBytes}
|
||||
status={status}
|
||||
type={i % 2 ? 'second' : 'first'}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between h-[24px] items-center gap-[10px]">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={arrowLeft}
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate(`/home/contests`);
|
||||
}}
|
||||
/>
|
||||
<span className="text-liquid-light font-bold text-[18px]">
|
||||
Контест #{contest.id}
|
||||
</span>
|
||||
</div>
|
||||
<div>{contest.attemptDurationMinutes ?? 0} минут</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="text-liquid-white text-[16px] font-bold">{`${solvedCount}/${totalCount} Решено`}</div>
|
||||
<PrimaryButton
|
||||
onClick={() => {
|
||||
navigate(`/contest/${contest.id}/submissions`);
|
||||
}}
|
||||
text="Мои посылки"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="h-full min-h-0 overflow-y-scroll medium-scrollbar flex flex-col gap-[20px]">
|
||||
<div className="w-full">
|
||||
{(contest.missions ?? []).map((v, i) => {
|
||||
const missionSubmissions = submissions.filter(
|
||||
(s) => s.solution.missionId === v.id
|
||||
);
|
||||
|
||||
const hasSuccess = missionSubmissions.some(
|
||||
(s) => s.solution.status == "Accepted: All tests passed"
|
||||
);
|
||||
|
||||
console.log(missionSubmissions);
|
||||
|
||||
const status = hasSuccess
|
||||
? "success"
|
||||
: missionSubmissions.length > 0
|
||||
? "error"
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<MissionItem
|
||||
contestId={contest.id}
|
||||
key={i}
|
||||
id={v.id}
|
||||
name={v.name}
|
||||
timeLimit={v.timeLimitMilliseconds}
|
||||
memoryLimit={v.memoryLimitBytes}
|
||||
status={status}
|
||||
type={i % 2 ? "second" : "first"}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default ContestMissions;
|
||||
|
||||
Reference in New Issue
Block a user