From ffe4609d7ee491b4e347444b5ab914df9be55588 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 20:20:19 +0300 Subject: [PATCH 1/8] (scope): [body] [footer(s)] --- services/backend/apps/task/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/backend/apps/task/tasks.py b/services/backend/apps/task/tasks.py index e5fd7cd..6839744 100644 --- a/services/backend/apps/task/tasks.py +++ b/services/backend/apps/task/tasks.py @@ -32,7 +32,7 @@ def analyze_data_task(self, submission_id): f"{settings.CHECKER_API_ENDPOINT}/execute", json={ "files": files, - "code": base64.encode(code), + "code": base64.b64encode(code), "answer_file_path": submission.task.answer_file_path, "expected_hash": hashlib.sha256( submission.task.correct_answer_file.read() From 23ae85020638342324e2e24d42b5da00a671efd5 Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Tue, 4 Mar 2025 02:24:40 +0900 Subject: [PATCH 2/8] results modal --- .../CompetitionResultModal/index.tsx | 88 +++++++++++++++++ .../frontend/src/pages/Competition/index.tsx | 95 ++++++++++++------- .../frontend/src/shared/api/competitions.ts | 2 +- .../frontend/src/shared/types/competition.ts | 1 + 4 files changed, 151 insertions(+), 35 deletions(-) create mode 100644 services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx diff --git a/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx b/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx new file mode 100644 index 0000000..565354e --- /dev/null +++ b/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, +} from "@/components/ui/dialog"; +import { Loader2 } from 'lucide-react'; + +export interface CompetitionResult { + task_name: string; + result: number; + max_points: number +} + +interface CompetitionResultsModalProps { + competitionTitle: string; + results: CompetitionResult[] | undefined; + isLoading: boolean; + error: unknown; + isOpen: boolean; + onOpenChange: (open: boolean) => void; +} + +export const CompetitionResultsModal: React.FC = ({ + competitionTitle, + results, + isLoading, + error, + isOpen, + onOpenChange, +}) => { + const renderResultValue = (result: number, maxPoints: number) => { + if (result === -1) { + return На проверке; + } else if (result === -2) { + return Нет ответа; + } else { + return ( + + Зачтено {result}/{maxPoints} баллов + + ); + } + }; + + return ( + + + + Результаты + + Ваши результаты по соревнованию "{competitionTitle}" + + + +
+ {isLoading ? ( +
+ +
+ ) : error ? ( +
+ Произошла ошибка при загрузке результатов +
+ ) : results && results.length > 0 ? ( + results.map((result, index) => ( +
+
{result.task_name}
+
+ {renderResultValue(result.result, result.max_points)} +
+
+ )) + ) : ( +
+ Нет доступных результатов +
+ )} +
+
+
+ ); +}; \ No newline at end of file diff --git a/services/frontend/src/pages/Competition/index.tsx b/services/frontend/src/pages/Competition/index.tsx index ed1320c..6571c4f 100644 --- a/services/frontend/src/pages/Competition/index.tsx +++ b/services/frontend/src/pages/Competition/index.tsx @@ -1,20 +1,23 @@ +import { useState } from "react"; import { useParams, Link, useNavigate } from "react-router-dom"; import { Button } from "@/components/ui/button"; -import { ArrowLeft, Clock, Trophy, BookOpen, BarChart2, AlertCircle } from "lucide-react"; +import { ArrowLeft, Clock, Trophy, BookOpen, AlertCircle, BarChart2 } from "lucide-react"; import ReactMarkdown from "react-markdown"; import { useQuery, useMutation } from "@tanstack/react-query"; -import { getCompetition, startCompetition } from "@/shared/api/competitions"; +import { getCompetition, startCompetition, getCompetitionResults } from "@/shared/api/competitions"; import { getCompetitionTasks } from "@/shared/api/session"; import { Loading } from "@/components/ui/loading"; import { CompetitionType } from "@/shared/types/competition"; import remarkMath from "remark-math"; import remarkGfm from "remark-gfm"; import rehypeKatex from "rehype-katex"; +import { CompetitionResultsModal } from "./components/CompetitionResultModal"; const CompetitionPage = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const competitionId = id || ""; + const [isResultsModalOpen, setIsResultsModalOpen] = useState(false); const competitionQuery = useQuery({ queryKey: ["competition", competitionId], @@ -22,6 +25,12 @@ const CompetitionPage = () => { enabled: !!competitionId, }); + const resultsQuery = useQuery({ + queryKey: ["competitionResults", competitionId], + queryFn: () => getCompetitionResults(competitionId), + enabled: !!competitionId, + }); + const startMutation = useMutation({ mutationFn: () => startCompetition(competitionId), onSuccess: async () => { @@ -60,10 +69,10 @@ const CompetitionPage = () => { const handleStart = () => { startMutation.mutate(); }; - - const handleViewResults = () => { - console.log("sorryan"); - }; + + const hasResults = resultsQuery.data && + resultsQuery.data.length > 0 && + resultsQuery.data.some(result => result.result !== -2); if (competitionQuery.isLoading) { return ; @@ -75,15 +84,6 @@ const CompetitionPage = () => { const competition = competitionQuery.data; - const isCompetitionEnded = () => { - if (!competition?.end_date) return false; - - const endDate = new Date(competition.end_date); - const now = new Date(); - - return now > endDate; - }; - const isCompetitionNotStarted = () => { if (!competition?.start_date) return false; @@ -92,9 +92,19 @@ const CompetitionPage = () => { return now < startDate; }; + + // Check if competition has ended + const isCompetitionEnded = () => { + if (!competition?.end_date) return false; + + const endDate = new Date(competition.end_date); + const now = new Date(); + + return now > endDate; + }; - const competitionEnded = isCompetitionEnded(); const competitionNotStarted = isCompetitionNotStarted(); + const competitionEnded = isCompetitionEnded(); return (
@@ -133,17 +143,17 @@ const CompetitionPage = () => { )}
- {competitionEnded && competition.type === CompetitionType.COMPETITIVE && ( -
- Завершено -
- )} - {competitionNotStarted && competition.type === CompetitionType.COMPETITIVE && (
Скоро начнется
)} + + {competitionEnded && competition.type === CompetitionType.COMPETITIVE && ( +
+ Завершено +
+ )}

@@ -178,17 +188,8 @@ const CompetitionPage = () => { -
- {competitionEnded && competition.type === CompetitionType.COMPETITIVE ? ( - - ) : competitionNotStarted && competition.type === CompetitionType.COMPETITIVE ? ( +
+ {competitionNotStarted && competition.type === CompetitionType.COMPETITIVE ? ( - ) : ( + ) : !competitionEnded ? ( + ) : null} + + {hasResults && ( + + )} + + {competitionEnded && !hasResults && competition.type === CompetitionType.COMPETITIVE && !resultsQuery.isLoading && ( +
+

Соревнование завершено. Результаты пока не доступны.

+
)}
+ + ); }; diff --git a/services/frontend/src/shared/api/competitions.ts b/services/frontend/src/shared/api/competitions.ts index 2c96f4c..4c46882 100644 --- a/services/frontend/src/shared/api/competitions.ts +++ b/services/frontend/src/shared/api/competitions.ts @@ -14,7 +14,7 @@ export const getCompetition = async (id: string) => { }; export const getCompetitionResults = async (id: string) => { - return await userFetch(`/competitions/${id}/results`); + return await userFetch(`/competitions/${id}/results`); } export const startCompetition = async (competitionId: string) => { diff --git a/services/frontend/src/shared/types/competition.ts b/services/frontend/src/shared/types/competition.ts index cff4cd9..2326419 100644 --- a/services/frontend/src/shared/types/competition.ts +++ b/services/frontend/src/shared/types/competition.ts @@ -28,4 +28,5 @@ export enum CompetitionParticipationType { export interface CompetitionResult { task_name: string; result: number; + max_points: number; } \ No newline at end of file From 7af5a812a4751c7fa2f1706b27177fdd60517a9f Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 20:30:19 +0300 Subject: [PATCH 3/8] (scope): [body] [footer(s)] --- services/backend/apps/task/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/backend/apps/task/tasks.py b/services/backend/apps/task/tasks.py index 6839744..64f4658 100644 --- a/services/backend/apps/task/tasks.py +++ b/services/backend/apps/task/tasks.py @@ -32,7 +32,7 @@ def analyze_data_task(self, submission_id): f"{settings.CHECKER_API_ENDPOINT}/execute", json={ "files": files, - "code": base64.b64encode(code), + "code": base64.b64encode(code).decode("utf-8"), "answer_file_path": submission.task.answer_file_path, "expected_hash": hashlib.sha256( submission.task.correct_answer_file.read() From f3a2f5ee23e23be53217da9d8875609576bdb5f9 Mon Sep 17 00:00:00 2001 From: moolcoov Date: Mon, 3 Mar 2025 20:35:47 +0300 Subject: [PATCH 4/8] feat: user --- .../Profile/components/user-stat-block.tsx | 14 +++++++ services/frontend/src/pages/Profile/index.tsx | 6 +-- .../Profile/widgets/user-achievements.tsx | 2 +- .../src/pages/Profile/widgets/user-info.tsx | 2 +- .../src/pages/Profile/widgets/user-stats.tsx | 38 +++++++++++++++++-- services/frontend/src/shared/api/user.ts | 6 ++- services/frontend/src/shared/types/user.ts | 5 +++ 7 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 services/frontend/src/pages/Profile/components/user-stat-block.tsx diff --git a/services/frontend/src/pages/Profile/components/user-stat-block.tsx b/services/frontend/src/pages/Profile/components/user-stat-block.tsx new file mode 100644 index 0000000..3fec3af --- /dev/null +++ b/services/frontend/src/pages/Profile/components/user-stat-block.tsx @@ -0,0 +1,14 @@ +export const UserStatBlock = ({ + value, + description, +}: { + value: number; + description: string; +}) => { + return ( +
+

{value}

+

{description}

+
+ ); +}; diff --git a/services/frontend/src/pages/Profile/index.tsx b/services/frontend/src/pages/Profile/index.tsx index 75cd2ff..d9b61c1 100644 --- a/services/frontend/src/pages/Profile/index.tsx +++ b/services/frontend/src/pages/Profile/index.tsx @@ -1,6 +1,6 @@ import { UserInfo } from "./widgets/user-info"; import { UserAchievements } from "./widgets/user-achievements"; -import { UserStats } from "./widgets/user-stats"; +import { UserStatsSections } from "./widgets/user-stats"; import { useQuery } from "@tanstack/react-query"; import { getCurrentUser } from "@/shared/api/user"; import { Loading } from "@/components/ui/loading"; @@ -25,11 +25,11 @@ const ProfilePage = () => { return (
-
+
- +
); }; diff --git a/services/frontend/src/pages/Profile/widgets/user-achievements.tsx b/services/frontend/src/pages/Profile/widgets/user-achievements.tsx index decd815..8231fbf 100644 --- a/services/frontend/src/pages/Profile/widgets/user-achievements.tsx +++ b/services/frontend/src/pages/Profile/widgets/user-achievements.tsx @@ -11,7 +11,7 @@ export const UserAchievements = ({

Достижения

{achievements && ( -
+
{achievements.map((a) => ( diff --git a/services/frontend/src/pages/Profile/widgets/user-info.tsx b/services/frontend/src/pages/Profile/widgets/user-info.tsx index 3b3b927..808619b 100644 --- a/services/frontend/src/pages/Profile/widgets/user-info.tsx +++ b/services/frontend/src/pages/Profile/widgets/user-info.tsx @@ -2,7 +2,7 @@ import { User } from "@/shared/types/user"; export const UserInfo = ({ user }: { user: User }) => { return ( -
+
{user.avatar && (
{ +import { Loading } from "@/components/ui/loading"; +import { UserStatBlock } from "../components/user-stat-block"; +import { getCurrentUserStats } from "@/shared/api/user"; +import { useQuery } from "@tanstack/react-query"; + +export const UserStatsSections = () => { + const { data: stats, isLoading } = useQuery({ + queryKey: ["user-stats"], + queryFn: getCurrentUserStats, + }); + return ( -
+

Аналитика

-
+ {isLoading ? ( +
+ +
+ ) : stats ? ( +
+ + +
+ ) : ( +
+

+ Что-то пошло не так 😔 +

+
+ )} +
); }; diff --git a/services/frontend/src/shared/api/user.ts b/services/frontend/src/shared/api/user.ts index 84b000d..7640390 100644 --- a/services/frontend/src/shared/api/user.ts +++ b/services/frontend/src/shared/api/user.ts @@ -1,6 +1,10 @@ import { userFetch } from "."; -import { User } from "../types/user"; +import { User, UserStats } from "../types/user"; export const getCurrentUser = async () => { return await userFetch("/me"); }; + +export const getCurrentUserStats = async () => { + return await userFetch("/me/stat"); +}; diff --git a/services/frontend/src/shared/types/user.ts b/services/frontend/src/shared/types/user.ts index 650c8d8..b9e927f 100644 --- a/services/frontend/src/shared/types/user.ts +++ b/services/frontend/src/shared/types/user.ts @@ -12,3 +12,8 @@ export interface Achievement { received_at: Date; icon?: string; } + +export interface UserStats { + total_attempts: number; + solved_tasks: number; +} From 2e0ea88db559b328abc0262c81728d449ba196f9 Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Tue, 4 Mar 2025 02:39:14 +0900 Subject: [PATCH 5/8] results rework --- .../CompetitionResultModal/index.tsx | 56 +++++++++++++++++-- .../frontend/src/pages/Competition/index.tsx | 4 +- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx b/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx index 565354e..b691e77 100644 --- a/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx +++ b/services/frontend/src/pages/Competition/components/CompetitionResultModal/index.tsx @@ -1,3 +1,4 @@ +// src/components/competition/CompetitionResultsModal.tsx import React from 'react'; import { Dialog, @@ -33,13 +34,58 @@ export const CompetitionResultsModal: React.FC = ( }) => { const renderResultValue = (result: number, maxPoints: number) => { if (result === -1) { - return На проверке; + return ( + + На проверке + + ); } else if (result === -2) { - return Нет ответа; + return ( + + Нет ответа + + ); + } else if (result === 0) { + return ( + + Неверно (0/{maxPoints}) + + ); + } else if (result < maxPoints) { + return ( + + Частично верно ({result}/{maxPoints}) + + ); } else { return ( - - Зачтено {result}/{maxPoints} баллов + + Верно ({result}/{maxPoints}) ); } @@ -71,7 +117,7 @@ export const CompetitionResultsModal: React.FC = ( className="flex flex-col md:flex-row justify-between items-start md:items-center p-4 bg-gray-50 rounded-lg border" >
{result.task_name}
-
+
{renderResultValue(result.result, result.max_points)}
diff --git a/services/frontend/src/pages/Competition/index.tsx b/services/frontend/src/pages/Competition/index.tsx index 6571c4f..4cf4911 100644 --- a/services/frontend/src/pages/Competition/index.tsx +++ b/services/frontend/src/pages/Competition/index.tsx @@ -93,7 +93,6 @@ const CompetitionPage = () => { return now < startDate; }; - // Check if competition has ended const isCompetitionEnded = () => { if (!competition?.end_date) return false; @@ -212,7 +211,6 @@ const CompetitionPage = () => {
From d44b2105b0f32b5aefde9c2e9ca24a3944da8f66 Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Tue, 4 Mar 2025 02:44:17 +0900 Subject: [PATCH 6/8] task in navbar have colors --- .../components/CompetitionHeader/index.tsx | 77 ++++++++++++++----- .../src/pages/CompetitionSession/index.tsx | 29 ++++++- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/services/frontend/src/pages/CompetitionSession/components/CompetitionHeader/index.tsx b/services/frontend/src/pages/CompetitionSession/components/CompetitionHeader/index.tsx index d912f1a..9042c91 100644 --- a/services/frontend/src/pages/CompetitionSession/components/CompetitionHeader/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/components/CompetitionHeader/index.tsx @@ -1,8 +1,9 @@ import React, { useState, useEffect } from 'react'; -import { Link, useNavigate } from 'react-router-dom'; +import { Link, useNavigate, useParams } from 'react-router-dom'; import { Task } from '@/shared/types/task'; -import { ArrowLeft, Clock } from 'lucide-react'; +import { ArrowLeft } from 'lucide-react'; import { CompetitionType } from '@/shared/types/competition'; +import { CompetitionResult } from '@/shared/types/competition'; interface CompetitionHeaderProps { title: string; @@ -11,8 +12,9 @@ interface CompetitionHeaderProps { setAnswer: (value: string) => void; setSelectedFile: (file: File | null) => void; competitionType?: CompetitionType; - startDate?: Date; - endDate?: Date; + startDate?: Date | string; + endDate?: Date | string; + taskResults?: CompetitionResult[]; } const CompetitionHeader: React.FC = ({ @@ -23,9 +25,11 @@ const CompetitionHeader: React.FC = ({ setSelectedFile, competitionType, startDate, - endDate + endDate, + taskResults = [] }) => { const navigate = useNavigate(); + const { taskId } = useParams<{ taskId?: string }>(); const [timeLeft, setTimeLeft] = useState(''); const handleTaskSelect = (taskId: string) => { @@ -34,7 +38,7 @@ const CompetitionHeader: React.FC = ({ navigate(`/competition/${competitionId}/tasks/${taskId}`); } - const formatDate = (date?: Date) => { + const formatDate = (date?: Date | string) => { if (!date) return ''; const dateObj = typeof date === 'string' ? new Date(date) : date; @@ -74,6 +78,42 @@ const CompetitionHeader: React.FC = ({ return () => clearInterval(timerInterval); }, [endDate, competitionId, navigate, competitionType]); + const getTaskStatus = (task: Task) => { + const result = taskResults.find(r => r.task_name === task.title); + + let bgColor = 'var(--color-task-uncleared)'; + let textColor = 'var(--color-task-text-uncleared)'; + + if (result) { + if (result.result === -1) { + bgColor = 'var(--color-task-checking)'; + textColor = 'var(--color-task-text-checking)'; + } else if (result.result === -2) { + bgColor = 'var(--color-task-uncleared)'; + textColor = 'var(--color-task-text-uncleared)'; + } else if (result.result === 0) { + bgColor = 'var(--color-task-wrong)'; + textColor = 'var(--color-task-text-wrong)'; + } else if (result.result < result.max_points) { + bgColor = 'var(--color-task-partial)'; + textColor = 'var(--color-task-text-partial)'; + } else if (result.result === result.max_points) { + bgColor = 'var(--color-task-correct)'; + textColor = 'var(--color-task-text-correct)'; + } + } + + const isActive = task.id === taskId; + const activeBorder = isActive ? 'border-2 border-blue-500' : ''; + + return { + backgroundColor: bgColor, + color: textColor, + className: `rounded-lg px-3 py-1.5 font-medium text-sm font-hse-sans cursor-pointer + transition-all hover:brightness-95 flex-shrink-0 ${activeBorder}` + }; + }; + const showTimeSection = competitionType === CompetitionType.COMPETITIVE && (startDate || endDate); return ( @@ -120,18 +160,19 @@ const CompetitionHeader: React.FC = ({
- {tasks.map((task) => ( - - ))} + {tasks.map((task) => { + const { backgroundColor, color, className } = getTaskStatus(task); + return ( + + ); + })}
diff --git a/services/frontend/src/pages/CompetitionSession/index.tsx b/services/frontend/src/pages/CompetitionSession/index.tsx index 42ea9c4..0726903 100644 --- a/services/frontend/src/pages/CompetitionSession/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/index.tsx @@ -1,10 +1,10 @@ import { useState, useEffect } from "react"; -import { useParams, Navigate, useNavigate } from "react-router-dom"; +import { useParams, Navigate } from "react-router-dom"; import CompetitionHeader from "./components/CompetitionHeader"; import TaskContent from "./components/TaskContent"; import TaskSolution from "./modules/TaskSolution"; import { getCompetitionTasks, submitTaskSolution } from "@/shared/api/session"; -import { getCompetition } from "@/shared/api/competitions"; +import { getCompetition, getCompetitionResults } from "@/shared/api/competitions"; import { Loader2 } from "lucide-react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { TaskType } from "@/shared/types/task"; @@ -16,7 +16,6 @@ const CompetitionSession = () => { const [isReloading, setIsReloading] = useState(false); const competitionId = id || ""; const queryClient = useQueryClient(); - const navigate = useNavigate(); const competitionQuery = useQuery({ queryKey: ["competition", competitionId], @@ -30,6 +29,12 @@ const CompetitionSession = () => { enabled: !!competitionId, }); + const resultsQuery = useQuery({ + queryKey: ["competitionResults", competitionId], + queryFn: () => getCompetitionResults(competitionId), + enabled: !!competitionId, + }); + const submitMutation = useMutation({ mutationFn: () => { if (!currentTask || !competitionId) throw new Error("Missing task or competition ID"); @@ -47,10 +52,14 @@ const CompetitionSession = () => { queryKey: ['solutionHistory', competitionId, taskId] }); + queryClient.invalidateQueries({ + queryKey: ['competitionResults', competitionId] + }); + setIsReloading(true); setTimeout(() => { - window.location.reload() + window.location.reload(); setIsReloading(false); }, 2500); }, @@ -61,6 +70,7 @@ const CompetitionSession = () => { const competition = competitionQuery.data; const tasks = tasksQuery.data || []; + const results = resultsQuery.data || []; const isLoading = tasksQuery.isLoading || competitionQuery.isLoading; const error = tasksQuery.error || competitionQuery.error ? "Не удалось загрузить данные. Пожалуйста, попробуйте позже." @@ -113,6 +123,7 @@ const CompetitionSession = () => { competitionType={competition?.type} startDate={competition?.start_date} endDate={competition?.end_date} + taskResults={results} />
@@ -138,6 +149,16 @@ const CompetitionSession = () => { onSubmit={handleSubmit} isSubmitting={isSubmitting} /> + {isReloading && ( +
+
+ +

+ Решение отправлено! Страница обновится через несколько секунд... +

+
+
+ )} ) : (
From f2badd6f25856f8fcc9d39e9af0d634cdcf5de03 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 20:45:03 +0300 Subject: [PATCH 7/8] (scope): [body] [footer(s)] --- services/backend/apps/task/tasks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/backend/apps/task/tasks.py b/services/backend/apps/task/tasks.py index 64f4658..568602a 100644 --- a/services/backend/apps/task/tasks.py +++ b/services/backend/apps/task/tasks.py @@ -15,6 +15,7 @@ def analyze_data_task(self, submission_id): submission = CompetitionTaskSubmission.objects.get(id=submission_id) try: code = submission.content.read() + print("YA SSF") files = [ { "url": ( @@ -42,6 +43,7 @@ def analyze_data_task(self, submission_id): ) response.raise_for_status() result = response.json() + print("HOHOHO") submission.stdout.save("output.txt", ContentFile(result["output"])) submission.result = { From d134b5afa1cd680f5df4c9313d1f77259e0934ee Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Tue, 4 Mar 2025 02:58:34 +0900 Subject: [PATCH 8/8] minor fixes --- services/frontend/src/pages/CompetitionSession/index.tsx | 2 +- .../modules/TaskSolution/components/ActionButtons/index.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/services/frontend/src/pages/CompetitionSession/index.tsx b/services/frontend/src/pages/CompetitionSession/index.tsx index 0726903..b2c8de5 100644 --- a/services/frontend/src/pages/CompetitionSession/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/index.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { useParams, Navigate } from "react-router-dom"; +import { useParams, Navigate } from "react-router-dom"; import CompetitionHeader from "./components/CompetitionHeader"; import TaskContent from "./components/TaskContent"; import TaskSolution from "./modules/TaskSolution"; diff --git a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/ActionButtons/index.tsx b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/ActionButtons/index.tsx index d22ae9c..2aaca0f 100644 --- a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/ActionButtons/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/ActionButtons/index.tsx @@ -30,10 +30,8 @@ const ActionButtons: React.FC = ({ {isCleared ? ( ) : hasSubmissionsLeft ? (