Refactor Header and TaskWorkspace components to enhance UI and user feedback. Header now accepts chainName and taskProgress props for improved context display. TaskWorkspace updates include styling adjustments, conditional rendering for queue status, and feedback messages, streamlining user interaction during task processing.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
This commit is contained in:
parent
bb31cc5c6c
commit
79e3dc9864
@ -3,7 +3,12 @@ import { Box, Button, Flex, Heading, Text } from '@chakra-ui/react'
|
||||
|
||||
import { useChallenge } from '../context/ChallengeContext'
|
||||
|
||||
export const Header = () => {
|
||||
interface HeaderProps {
|
||||
chainName?: string
|
||||
taskProgress?: string
|
||||
}
|
||||
|
||||
export const Header = ({ chainName, taskProgress }: HeaderProps) => {
|
||||
const { nickname, logout } = useChallenge()
|
||||
|
||||
if (!nickname) return null
|
||||
@ -13,11 +18,21 @@ export const Header = () => {
|
||||
<Flex maxW="1200px" mx="auto" justify="space-between" align="center">
|
||||
<Box>
|
||||
<Heading size="md" color="teal.600">
|
||||
Challenge Platform
|
||||
{chainName || 'Challenge Platform'}
|
||||
</Heading>
|
||||
<Text fontSize="sm" color="gray.600" mt={1}>
|
||||
{nickname}
|
||||
</Text>
|
||||
<Flex gap={3} align="center" mt={1}>
|
||||
<Text fontSize="sm" color="gray.600">
|
||||
{nickname}
|
||||
</Text>
|
||||
{taskProgress && (
|
||||
<>
|
||||
<Text fontSize="sm" color="gray.400">•</Text>
|
||||
<Text fontSize="sm" color="gray.600">
|
||||
{taskProgress}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
<Button onClick={logout} variant="ghost" size="sm">
|
||||
Выйти
|
||||
|
||||
@ -36,109 +36,102 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
||||
}, [finalSubmission, refreshStats])
|
||||
|
||||
return (
|
||||
<VStack align="stretch" gap={4}>
|
||||
<Box borderWidth="1px" borderRadius="lg" borderColor="gray.200" p={4} bg={descriptionBg}>
|
||||
<Text fontSize="lg" fontWeight="semibold" mb={2}>
|
||||
<VStack align="stretch" gap={3}>
|
||||
<Box borderWidth="1px" borderRadius="md" borderColor="gray.200" p={3} bg={descriptionBg}>
|
||||
<Text fontSize="md" fontWeight="semibold" mb={1}>
|
||||
{task.title}
|
||||
</Text>
|
||||
<Text whiteSpace="pre-line" color="gray.700">
|
||||
<Text whiteSpace="pre-line" color="gray.700" fontSize="sm">
|
||||
{task.description}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
{/* Статус проверки */}
|
||||
{queueStatus && !finalSubmission && (
|
||||
<Box borderWidth="1px" borderRadius="lg" borderColor="blue.200" bg="blue.50" p={4}>
|
||||
<HStack>
|
||||
<Spinner size="md" color="blue.500" />
|
||||
<VStack align="flex-start" gap={1}>
|
||||
<Text fontWeight="semibold" color="blue.700">
|
||||
{queueStatus.status === 'waiting' ? 'Ожидание в очереди...' : 'Проверяем решение...'}
|
||||
</Text>
|
||||
{typeof queueStatus.position === 'number' && queueStatus.position > 0 && (
|
||||
<Text fontSize="sm" color="blue.600">
|
||||
Позиция в очереди: {queueStatus.position}
|
||||
</Text>
|
||||
)}
|
||||
</VStack>
|
||||
<Box borderWidth="1px" borderRadius="md" borderColor="blue.200" bg="blue.50" p={2}>
|
||||
<HStack gap={2}>
|
||||
<Spinner size="sm" color="blue.500" />
|
||||
<Text fontSize="sm" fontWeight="medium" color="blue.700">
|
||||
{queueStatus.status === 'waiting' ? 'Ожидание в очереди...' : 'Проверяем решение...'}
|
||||
{typeof queueStatus.position === 'number' && queueStatus.position > 0 && ` (позиция: ${queueStatus.position})`}
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Результат проверки - успех */}
|
||||
{isAccepted && (
|
||||
<Box borderWidth="2px" borderRadius="lg" borderColor="green.300" bg="green.50" p={4}>
|
||||
<VStack gap={3}>
|
||||
<Text fontSize="3xl">✅</Text>
|
||||
<Text fontSize="xl" fontWeight="bold" color="green.700">
|
||||
Задание принято!
|
||||
</Text>
|
||||
{finalSubmission?.feedback && (
|
||||
<Box w="100%" bg="white" borderRadius="md" p={3} borderWidth="1px" borderColor="green.200">
|
||||
<Text fontWeight="medium" color="green.800" mb={1}>
|
||||
Комментарий:
|
||||
</Text>
|
||||
<Text whiteSpace="pre-wrap" color="gray.700">
|
||||
{finalSubmission.feedback}
|
||||
<Box borderWidth="1px" borderRadius="md" borderColor="green.300" bg="green.50" p={3}>
|
||||
<HStack justify="space-between" align="start">
|
||||
<HStack align="start" gap={2} flex={1}>
|
||||
<Text fontSize="xl">✅</Text>
|
||||
<Box>
|
||||
<Text fontSize="md" fontWeight="bold" color="green.700">
|
||||
Задание принято!
|
||||
</Text>
|
||||
{finalSubmission?.feedback && (
|
||||
<Text fontSize="sm" color="gray.700" mt={1}>
|
||||
{finalSubmission.feedback}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
<Button onClick={onTaskComplete} colorScheme="green" size="lg">
|
||||
Следующее задание →
|
||||
</HStack>
|
||||
<Button onClick={onTaskComplete} colorScheme="green" size="sm">
|
||||
Следующее →
|
||||
</Button>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Результат проверки - требуется доработка */}
|
||||
{needsRevision && (
|
||||
<Box borderWidth="2px" borderRadius="lg" borderColor="orange.300" bg="orange.50" p={4}>
|
||||
<VStack gap={3}>
|
||||
<Text fontSize="3xl">⚠️</Text>
|
||||
<Text fontSize="xl" fontWeight="bold" color="orange.700">
|
||||
Требуется доработка
|
||||
</Text>
|
||||
{finalSubmission?.feedback && (
|
||||
<Box w="100%" bg="white" borderRadius="md" p={3} borderWidth="1px" borderColor="orange.200">
|
||||
<Text fontWeight="medium" color="orange.800" mb={1}>
|
||||
Комментарий проверяющего:
|
||||
<Box borderWidth="1px" borderRadius="md" borderColor="orange.300" bg="orange.50" p={3}>
|
||||
<HStack align="start" gap={2}>
|
||||
<Text fontSize="xl">⚠️</Text>
|
||||
<Box flex={1}>
|
||||
<HStack>
|
||||
<Text fontSize="md" fontWeight="bold" color="orange.700">
|
||||
Требуется доработка
|
||||
</Text>
|
||||
<Text whiteSpace="pre-wrap" color="gray.700">
|
||||
<Text fontSize="xs" color="gray.600">
|
||||
(попытка №{finalSubmission?.attemptNumber})
|
||||
</Text>
|
||||
</HStack>
|
||||
{finalSubmission?.feedback && (
|
||||
<Text fontSize="sm" color="gray.700" mt={1}>
|
||||
{finalSubmission.feedback}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
<Text fontSize="sm" color="gray.600">
|
||||
Попытка №{finalSubmission?.attemptNumber}
|
||||
</Text>
|
||||
</VStack>
|
||||
)}
|
||||
</Box>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box>
|
||||
<Text fontWeight="medium" mb={2}>
|
||||
<Text fontWeight="medium" mb={1} fontSize="sm">
|
||||
Ваше решение
|
||||
</Text>
|
||||
<Textarea
|
||||
value={result}
|
||||
onChange={(event) => setResult(event.target.value)}
|
||||
placeholder="Напишите ваше решение..."
|
||||
rows={14}
|
||||
rows={8}
|
||||
bg="white"
|
||||
fontSize="sm"
|
||||
// @ts-expect-error Chakra UI v2 uses isDisabled
|
||||
isDisabled={isChecking || isAccepted}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<HStack justify="flex-end" gap={3}>
|
||||
<HStack justify="flex-end" gap={2}>
|
||||
{!isAccepted && (
|
||||
<>
|
||||
{/* @ts-expect-error Chakra UI v2 uses isDisabled */}
|
||||
<Button onClick={reset} variant="ghost" isDisabled={isChecking}>
|
||||
<Button onClick={reset} variant="ghost" size="sm" isDisabled={isChecking}>
|
||||
Сбросить
|
||||
</Button>
|
||||
{/* @ts-expect-error Chakra UI v2 uses isLoading/isDisabled */}
|
||||
<Button onClick={submit} colorScheme="teal" isLoading={isChecking} isDisabled={!result.trim() || isChecking}>
|
||||
<Button onClick={submit} colorScheme="teal" size="sm" isLoading={isChecking} isDisabled={!result.trim() || isChecking}>
|
||||
{needsRevision ? 'Отправить снова' : 'Отправить на проверку'}
|
||||
</Button>
|
||||
</>
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
Heading,
|
||||
Text,
|
||||
} from '@chakra-ui/react'
|
||||
import { Alert } from '@chakra-ui/react/alert'
|
||||
@ -44,11 +41,6 @@ export const MainPage = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleBackToChains = () => {
|
||||
setSelectedChain(null)
|
||||
setSelectedTask(null)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = eventEmitter.on('submission_completed', (event) => {
|
||||
const submission = (event.data as { submission?: { status: string; attemptNumber: number } })?.submission
|
||||
@ -100,11 +92,13 @@ export const MainPage = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const taskProgress = `Задание ${selectedChain.tasks.findIndex(t => t.id === selectedTask?.id) + 1} из ${selectedChain.tasks.length}`
|
||||
|
||||
// Показываем выбранную цепочку и задания
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Box bg="gray.50" minH="100vh" py={8} px={{ base: 4, md: 8 }}>
|
||||
<Header chainName={selectedChain.name} taskProgress={taskProgress} />
|
||||
<Box bg="gray.50" minH="100vh" py={4} px={{ base: 4, md: 8 }}>
|
||||
<Box maxW="1200px" mx="auto">
|
||||
{notification && (
|
||||
<Alert.Root status={notification.status} borderRadius="md" mb={4}>
|
||||
@ -123,20 +117,6 @@ export const MainPage = () => {
|
||||
</Alert.Root>
|
||||
)}
|
||||
|
||||
<Flex justify="space-between" align="center" mb={8}>
|
||||
<Box>
|
||||
<Heading size="lg" mb={1}>
|
||||
{selectedChain.name}
|
||||
</Heading>
|
||||
<Text color="gray.600">
|
||||
Задание {selectedChain.tasks.findIndex(t => t.id === selectedTask?.id) + 1} из {selectedChain.tasks.length}
|
||||
</Text>
|
||||
</Box>
|
||||
<Button onClick={handleBackToChains} variant="outline">
|
||||
Вернуться к цепочкам
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
{selectedTask && (
|
||||
<TaskWorkspace task={selectedTask} onTaskComplete={handleTaskComplete} />
|
||||
)}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user