From f774cd27d8a3afe4347666c50c85034d17d8b660 Mon Sep 17 00:00:00 2001 From: Primakov Alexandr Date: Sat, 13 Dec 2025 19:27:25 +0300 Subject: [PATCH] Implement completion screen in MainPage component to celebrate task achievements. Introduce state management for completed chains and enhance UI with congratulatory messages and a continue button. Remove unused notification logic to streamline the component. --- src/pages/main/main.tsx | 105 +++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/src/pages/main/main.tsx b/src/pages/main/main.tsx index eb60aaf..d43eea8 100644 --- a/src/pages/main/main.tsx +++ b/src/pages/main/main.tsx @@ -1,7 +1,10 @@ import React, { useEffect, useRef, useState } from 'react' import { Box, + Button, + Heading, Text, + VStack, } from '@chakra-ui/react' import { Alert } from '@chakra-ui/react/alert' @@ -16,14 +19,13 @@ const SELECTED_CHAIN_KEY = 'challengeSelectedChainId' const SELECTED_TASK_KEY = 'challengeSelectedTaskId' export const MainPage = () => { - const { nickname, eventEmitter, chains } = useChallenge() + const { nickname, chains } = useChallenge() const [selectedChain, setSelectedChain] = useState(null) const [selectedTask, setSelectedTask] = useState(null) + const [completedChainName, setCompletedChainName] = useState(null) const [isOffline, setIsOffline] = useState(() => typeof navigator !== 'undefined' ? !navigator.onLine : false, ) - const [notification, setNotification] = useState<{ status: 'success' | 'warning'; title: string; description?: string } | null>(null) - const notificationTimeoutRef = useRef(null) const hasRestoredState = useRef(false) // Восстановление состояния при загрузке @@ -66,7 +68,8 @@ export const MainPage = () => { setSelectedTask(nextTask) localStorage.setItem(SELECTED_TASK_KEY, nextTask.id) } else { - // Цепочка завершена, возвращаемся к выбору + // Цепочка завершена - показываем экран поздравления + setCompletedChainName(selectedChain.name) setSelectedChain(null) setSelectedTask(null) localStorage.removeItem(SELECTED_CHAIN_KEY) @@ -74,33 +77,10 @@ export const MainPage = () => { } } - useEffect(() => { - const unsubscribe = eventEmitter.on('submission_completed', (event) => { - const submission = (event.data as { submission?: { status: string; attemptNumber: number } })?.submission - const accepted = submission?.status === 'accepted' + const handleContinueAfterCompletion = () => { + setCompletedChainName(null) + } - if (!accepted) { - return - } - - const title = 'Задание принято' - const description = submission ? `Попытка №${submission.attemptNumber}` : undefined - - if (notificationTimeoutRef.current) { - window.clearTimeout(notificationTimeoutRef.current) - } - - // setNotification({ status: 'success', title, description }) - notificationTimeoutRef.current = window.setTimeout(() => setNotification(null), 4000) - }) - - return () => { - unsubscribe() - if (notificationTimeoutRef.current) { - window.clearTimeout(notificationTimeoutRef.current) - } - } - }, [eventEmitter]) useEffect(() => { const handleOnline = () => setIsOffline(false) @@ -120,6 +100,61 @@ export const MainPage = () => { return } + // Если цепочка завершена, показываем экран поздравления + if (completedChainName) { + return ( + <> +
+ + + + 🎉 + + Поздравляем! + + + Вы успешно выполнили все задания + + + + {completedChainName} + + + + Отличная работа! Вы можете продолжить обучение, выбрав другую цепочку заданий. + + + + + + + ) + } + // Если цепочка не выбрана, показываем селектор цепочек if (!selectedChain) { return ( @@ -138,16 +173,6 @@ export const MainPage = () => {
- {notification && ( - - - - {notification.title} - {notification.description && {notification.description}} - - - )} - {isOffline && (