From 86f68619cb429db8b4ffa20d1ce74ace14c57c34 Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Mon, 3 Mar 2025 03:15:19 +0900 Subject: [PATCH] test: history --- .../components/FileSolution/index.tsx | 42 +++++++++++++------ .../components/SolutionHistorySheet/index.tsx | 19 ++++++--- .../modules/TaskSolution/index.tsx | 22 ++++++++++ services/frontend/src/shared/types/task.ts | 3 +- 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/FileSolution/index.tsx b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/FileSolution/index.tsx index 5e103b6..ed1a191 100644 --- a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/FileSolution/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/FileSolution/index.tsx @@ -1,17 +1,19 @@ import React from 'react'; -import { FileIcon } from 'lucide-react'; +import { FileIcon, Download } from 'lucide-react'; import { Button } from "@/components/ui/button"; interface FileSolutionProps { selectedFile: File | null; setSelectedFile: (file: File | null) => void; fileInputRef: React.RefObject; + fileUrl?: string | null; } const FileSolution: React.FC = ({ selectedFile, setSelectedFile, - fileInputRef + fileInputRef, + fileUrl = null }) => { const handleFileChange = (event: React.ChangeEvent) => { if (event.target.files && event.target.files[0]) { @@ -42,6 +44,8 @@ const FileSolution: React.FC = ({ } }; + const fileName = selectedFile ? selectedFile.name : fileUrl ? fileUrl.split('/').pop() || 'file' : ''; + return ( <> = ({ accept=".jpg,.jpeg,.png,.pptx,.docx,.pdf,.xlsx,.txt" /> - {selectedFile ? ( + {(selectedFile || fileUrl) ? (
- {selectedFile.name} - {(selectedFile.size / 1024).toFixed(1)} KB - + {fileName} + +
+ {fileUrl && ( + + + Скачать + + )} + +
) : ( @@ -82,7 +98,7 @@ const FileSolution: React.FC = ({ Загрузить файл

- Доступные форматы: jpg, jpeg, png + Доступные форматы: jpg, jpeg, png, pptx, docx, pdf, xlsx, txt

)} diff --git a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/SolutionHistorySheet/index.tsx b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/SolutionHistorySheet/index.tsx index dc8fe95..870d511 100644 --- a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/SolutionHistorySheet/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/components/SolutionHistorySheet/index.tsx @@ -3,20 +3,22 @@ import { Sheet, SheetClose, SheetContent, SheetHeader, SheetTitle } from "@/comp import { Button } from "@/components/ui/button"; import { X } from "lucide-react"; import SolutionStatus from '../SolutionStatus'; -import { Solution } from '@/shared/types/task'; +import { Solution, TaskType } from '@/shared/types/task'; interface SolutionHistorySheetProps { isOpen: boolean; onOpenChange: (open: boolean) => void; solutions: Solution[]; - maxPoints: number + maxPoints: number; + onSolutionSelect: (solution: Solution) => void; } const SolutionHistorySheet: React.FC = ({ isOpen, onOpenChange, solutions, - maxPoints + maxPoints, + onSolutionSelect }) => { return ( @@ -32,10 +34,17 @@ const SolutionHistorySheet: React.FC = ({ -
+
{solutions.length > 0 ? ( solutions.map((solution, index) => ( -
+
{ + onSolutionSelect(solution); + onOpenChange(false); + }} + >
)) diff --git a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx index ea0c35c..d78f313 100644 --- a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx @@ -29,6 +29,7 @@ const TaskSolution: React.FC = ({ }) => { const fileInputRef = useRef(null); const [isHistoryOpen, setIsHistoryOpen] = useState(false); + const [selectedSolutionUrl, setSelectedSolutionUrl] = useState(null); const { id: competitionId } = useParams<{ id: string }>(); const solutionsQuery = useQuery({ @@ -45,6 +46,25 @@ const TaskSolution: React.FC = ({ const latestSolution = solutionHistory && solutionHistory.length > 0 ? solutionHistory[solutionHistory.length - 1] : null; + const handleSolutionSelect = async (solution: Solution) => { + if (!solution.content) return; + + setSelectedSolutionUrl(solution.content); + + try { + if (task.type !== TaskType.FILE) { + const response = await fetch(solution.content); + if (!response.ok) { + throw new Error(`Failed to fetch solution content: ${response.status}`); + } + const text = await response.text(); + setAnswer(text); + } + } catch (error) { + console.error('Error loading solution content:', error); + } + }; + return (
{latestSolution ? ( @@ -64,6 +84,7 @@ const TaskSolution: React.FC = ({ selectedFile={selectedFile} setSelectedFile={setSelectedFile} fileInputRef={fileInputRef} + existingFileUrl={selectedSolutionUrl} /> )} @@ -81,6 +102,7 @@ const TaskSolution: React.FC = ({ onOpenChange={setIsHistoryOpen} solutions={solutionHistory} maxPoints={task.points} + onSolutionSelect={handleSolutionSelect} />
); diff --git a/services/frontend/src/shared/types/task.ts b/services/frontend/src/shared/types/task.ts index 07c6fe1..40d5b4a 100644 --- a/services/frontend/src/shared/types/task.ts +++ b/services/frontend/src/shared/types/task.ts @@ -29,7 +29,8 @@ interface Solution { id: string, status: SolutionStatus, timestamp: string, - earned_points: number + earned_points: number, + content: string } export type {Task, Solution}