Add submission status indicators to TaskWorkspace component, including queue status, acceptance, and revision feedback. Enhance UI with loading spinner and conditional rendering for submission results.
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
ceb8910dcb
commit
4c88e7d19a
@ -3,6 +3,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
VStack,
|
VStack,
|
||||||
@ -11,8 +12,6 @@ import {
|
|||||||
import type { ChallengeTask } from '../../__data__/types'
|
import type { ChallengeTask } from '../../__data__/types'
|
||||||
import { useChallenge } from '../../context/ChallengeContext'
|
import { useChallenge } from '../../context/ChallengeContext'
|
||||||
import { useSubmission } from '../../hooks/useSubmission'
|
import { useSubmission } from '../../hooks/useSubmission'
|
||||||
import { CheckStatusView } from './CheckStatusView'
|
|
||||||
import { ResultView } from './ResultView'
|
|
||||||
|
|
||||||
interface TaskWorkspaceProps {
|
interface TaskWorkspaceProps {
|
||||||
task: ChallengeTask
|
task: ChallengeTask
|
||||||
@ -26,6 +25,9 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const descriptionBg = 'gray.50'
|
const descriptionBg = 'gray.50'
|
||||||
|
const isChecking = !!queueStatus || isSubmitting
|
||||||
|
const isAccepted = finalSubmission?.status === 'accepted'
|
||||||
|
const needsRevision = finalSubmission?.status === 'needs_revision'
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (finalSubmission) {
|
if (finalSubmission) {
|
||||||
@ -33,18 +35,8 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
}
|
}
|
||||||
}, [finalSubmission, refreshStats])
|
}, [finalSubmission, refreshStats])
|
||||||
|
|
||||||
if (queueStatus) {
|
|
||||||
return <CheckStatusView status={queueStatus} />
|
|
||||||
}
|
|
||||||
|
|
||||||
if (finalSubmission) {
|
|
||||||
return (
|
|
||||||
<ResultView submission={finalSubmission} onRetry={reset} onNext={onTaskComplete} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack align="stretch" spacing={4}>
|
<VStack align="stretch" gap={4}>
|
||||||
<Box borderWidth="1px" borderRadius="lg" borderColor="gray.200" p={4} bg={descriptionBg}>
|
<Box borderWidth="1px" borderRadius="lg" borderColor="gray.200" p={4} bg={descriptionBg}>
|
||||||
<Text fontSize="lg" fontWeight="semibold" mb={2}>
|
<Text fontSize="lg" fontWeight="semibold" mb={2}>
|
||||||
{task.title}
|
{task.title}
|
||||||
@ -54,6 +46,75 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Статус проверки */}
|
||||||
|
{queueStatus && (
|
||||||
|
<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>
|
||||||
|
</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}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Button onClick={onTaskComplete} colorScheme="green" size="lg">
|
||||||
|
Следующее задание →
|
||||||
|
</Button>
|
||||||
|
</VStack>
|
||||||
|
</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}>
|
||||||
|
Комментарий проверяющего:
|
||||||
|
</Text>
|
||||||
|
<Text whiteSpace="pre-wrap" color="gray.700">
|
||||||
|
{finalSubmission.feedback}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Text fontSize="sm" color="gray.600">
|
||||||
|
Попытка №{finalSubmission?.attemptNumber}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontWeight="medium" mb={2}>
|
<Text fontWeight="medium" mb={2}>
|
||||||
Ваше решение
|
Ваше решение
|
||||||
@ -64,16 +125,24 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
placeholder="Напишите ваше решение..."
|
placeholder="Напишите ваше решение..."
|
||||||
rows={14}
|
rows={14}
|
||||||
bg="white"
|
bg="white"
|
||||||
|
// @ts-expect-error Chakra UI v2 uses isDisabled
|
||||||
|
isDisabled={isChecking || isAccepted}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<HStack justify="flex-end" spacing={3}>
|
<HStack justify="flex-end" gap={3}>
|
||||||
<Button onClick={reset} variant="ghost">
|
{!isAccepted && (
|
||||||
Сбросить
|
<>
|
||||||
</Button>
|
{/* @ts-expect-error Chakra UI v2 uses isDisabled */}
|
||||||
<Button onClick={submit} colorScheme="teal" isLoading={isSubmitting} isDisabled={!result.trim()}>
|
<Button onClick={reset} variant="ghost" isDisabled={isChecking}>
|
||||||
Отправить на проверку
|
Сбросить
|
||||||
</Button>
|
</Button>
|
||||||
|
{/* @ts-expect-error Chakra UI v2 uses isLoading/isDisabled */}
|
||||||
|
<Button onClick={submit} colorScheme="teal" isLoading={isChecking} isDisabled={!result.trim() || isChecking}>
|
||||||
|
{needsRevision ? 'Отправить снова' : 'Отправить на проверку'}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user