From 0f12404222b2ded4e55d9e1de61997ce19d1b020 Mon Sep 17 00:00:00 2001 From: rngsurrounded Date: Mon, 3 Mar 2025 03:53:56 +0900 Subject: [PATCH] minor fixes --- .../modules/TaskSolution/index.tsx | 190 +++++++++--------- 1 file changed, 97 insertions(+), 93 deletions(-) diff --git a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx index d78f313..cd2b1d4 100644 --- a/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx +++ b/services/frontend/src/pages/CompetitionSession/modules/TaskSolution/index.tsx @@ -1,111 +1,115 @@ -import React, { useState, useRef } from 'react'; -import { useParams } from 'react-router-dom'; -import { Task, TaskType, Solution } from '@/shared/types/task'; -import { useQuery } from '@tanstack/react-query'; -import { getTaskSolutionHistory } from '@/shared/api/session'; -import SolutionStatus from './components/SolutionStatus'; -import InputSolution from './components/InputSolution'; -import FileSolution from './components/FileSolution'; -import CodeSolution from './components/CodeSolution'; -import ActionButtons from './components/ActionButtons'; -import SolutionHistorySheet from './components/SolutionHistorySheet'; +import React from 'react'; +import { FileIcon, Download } from 'lucide-react'; +import { Button } from "@/components/ui/button"; -interface TaskSolutionProps { - task: Task; - answer: string; - setAnswer: (value: string) => void; +interface FileSolutionProps { selectedFile: File | null; setSelectedFile: (file: File | null) => void; - onSubmit: () => void; + fileInputRef: React.RefObject; + existingFileUrl?: string | null; } -const TaskSolution: React.FC = ({ - task, - answer, - setAnswer, - selectedFile, +const FileSolution: React.FC = ({ + selectedFile, setSelectedFile, - onSubmit, + fileInputRef, + existingFileUrl = null }) => { - const fileInputRef = useRef(null); - const [isHistoryOpen, setIsHistoryOpen] = useState(false); - const [selectedSolutionUrl, setSelectedSolutionUrl] = useState(null); - const { id: competitionId } = useParams<{ id: string }>(); - - const solutionsQuery = useQuery({ - queryKey: ['solutionHistory', competitionId, task.id], - queryFn: () => getTaskSolutionHistory(competitionId || '', task.id), - enabled: !!(competitionId && task.id), - }); - - const solutionHistory = solutionsQuery.data || []; - - const handleOpenHistory = () => { - setIsHistoryOpen(true); + const handleFileChange = (event: React.ChangeEvent) => { + if (event.target.files && event.target.files[0]) { + setSelectedFile(event.target.files[0]); + } }; - 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); - } + const handleFileUploadClick = () => { + fileInputRef.current?.click(); }; + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); + e.currentTarget.classList.add('bg-gray-50'); + }; + + const handleDragLeave = (e: React.DragEvent) => { + e.preventDefault(); + e.currentTarget.classList.remove('bg-gray-50'); + }; + + const handleDrop = (e: React.DragEvent) => { + e.preventDefault(); + e.currentTarget.classList.remove('bg-gray-50'); + + if (e.dataTransfer.files && e.dataTransfer.files[0]) { + setSelectedFile(e.dataTransfer.files[0]); + } + }; + + const fileName = selectedFile + ? selectedFile.name + : existingFileUrl + ? existingFileUrl.split('/').pop() || 'file' + : ''; + + const hasFile = !!selectedFile || !!existingFileUrl; + return ( -
- {latestSolution ? ( - + <> + + + {hasFile ? ( +
+
+ + {fileName} + +
+ {existingFileUrl && !selectedFile && ( + + + Скачать + + )} + +
+
+
) : ( -
- Решение еще не отправлено +
+ + + Загрузить файл + +

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

)} - - {task.type === TaskType.INPUT && ( - - )} - - {task.type === TaskType.FILE && ( - - )} - - {task.type === TaskType.CODE && ( - - )} - - - - -
+ ); }; -export default TaskSolution; \ No newline at end of file +export default FileSolution; \ No newline at end of file