Refactor TaskWorkspace to conditionally display learning materials with a button for user interaction. Update TaskPage to filter task navigation buttons based on accessibility, improving user experience in task management.
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:
@@ -76,7 +76,29 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack align="stretch" gap={3}>
|
<VStack align="stretch" gap={3}>
|
||||||
|
{/* Дополнительные материалы - показываются сверху */}
|
||||||
|
{task.learningMaterial && showLearningMaterial && (
|
||||||
|
<LearningMaterialViewer
|
||||||
|
content={task.learningMaterial}
|
||||||
|
linesPerPage={30}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box borderWidth="1px" borderRadius="md" borderColor="gray.200" p={4} bg="white" shadow="sm">
|
<Box borderWidth="1px" borderRadius="md" borderColor="gray.200" p={4} bg="white" shadow="sm">
|
||||||
|
{/* Кнопка для показа дополнительного материала */}
|
||||||
|
{task.learningMaterial && !showLearningMaterial && (
|
||||||
|
<HStack justify="center" mb={4}>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
colorScheme="blue"
|
||||||
|
onClick={() => setShowLearningMaterial(true)}
|
||||||
|
>
|
||||||
|
📚 Прочитать доп. материал
|
||||||
|
</Button>
|
||||||
|
</HStack>
|
||||||
|
)}
|
||||||
|
|
||||||
<Text fontSize="lg" fontWeight="bold" mb={3} color="gray.800">
|
<Text fontSize="lg" fontWeight="bold" mb={3} color="gray.800">
|
||||||
{task.title}
|
{task.title}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -249,30 +271,8 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
>
|
>
|
||||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>{task.description}</ReactMarkdown>
|
<ReactMarkdown remarkPlugins={[remarkGfm]}>{task.description}</ReactMarkdown>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Кнопка для показа дополнительного материала */}
|
|
||||||
{task.learningMaterial && !showLearningMaterial && (
|
|
||||||
<HStack justify="center" mt={4}>
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
variant="outline"
|
|
||||||
colorScheme="blue"
|
|
||||||
onClick={() => setShowLearningMaterial(true)}
|
|
||||||
>
|
|
||||||
📚 Прочитать доп. материал
|
|
||||||
</Button>
|
|
||||||
</HStack>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Дополнительные материалы - показываются отдельно */}
|
|
||||||
{task.learningMaterial && showLearningMaterial && (
|
|
||||||
<LearningMaterialViewer
|
|
||||||
content={task.learningMaterial}
|
|
||||||
linesPerPage={30}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* Статус проверки и результат - фиксированное место */}
|
{/* Статус проверки и результат - фиксированное место */}
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ export const TaskPage = () => {
|
|||||||
|
|
||||||
const handleTaskComplete = () => {
|
const handleTaskComplete = () => {
|
||||||
if (!chain || currentTaskIndex === -1) return
|
if (!chain || currentTaskIndex === -1) return
|
||||||
|
|
||||||
const nextTaskIndex = currentTaskIndex + 1
|
const nextTaskIndex = currentTaskIndex + 1
|
||||||
const nextTask = chain.tasks[nextTaskIndex]
|
const nextTask = chain.tasks[nextTaskIndex]
|
||||||
|
|
||||||
if (nextTask) {
|
if (nextTask) {
|
||||||
// Обновляем прогресс перед переходом
|
// Обновляем прогресс перед переходом
|
||||||
storage.setFurthestTaskIndex(chain.id, nextTaskIndex)
|
storage.setFurthestTaskIndex(chain.id, nextTaskIndex)
|
||||||
@@ -97,15 +97,15 @@ export const TaskPage = () => {
|
|||||||
|
|
||||||
const handleNavigateToTask = (newTaskId: string) => {
|
const handleNavigateToTask = (newTaskId: string) => {
|
||||||
if (!chain) return
|
if (!chain) return
|
||||||
|
|
||||||
const newTaskIndex = chain.tasks.findIndex(t => t.id === newTaskId)
|
const newTaskIndex = chain.tasks.findIndex(t => t.id === newTaskId)
|
||||||
if (newTaskIndex === -1) return
|
if (newTaskIndex === -1) return
|
||||||
|
|
||||||
// Проверяем доступность
|
// Проверяем доступность
|
||||||
if (!isTaskAccessible(newTaskIndex)) {
|
if (!isTaskAccessible(newTaskIndex)) {
|
||||||
return // Не переходим к заблокированному заданию
|
return // Не переходим к заблокированному заданию
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновляем прогресс при переходе
|
// Обновляем прогресс при переходе
|
||||||
const newFurthest = Math.max(furthestTaskIndex, newTaskIndex)
|
const newFurthest = Math.max(furthestTaskIndex, newTaskIndex)
|
||||||
if (newFurthest > furthestTaskIndex) {
|
if (newFurthest > furthestTaskIndex) {
|
||||||
@@ -115,6 +115,7 @@ export const TaskPage = () => {
|
|||||||
navigate(URLs.task(chain.id, newTaskId))
|
navigate(URLs.task(chain.id, newTaskId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Проверяем доступность текущего задания при загрузке
|
// Проверяем доступность текущего задания при загрузке
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (chain && currentTaskIndex >= 0 && !isTaskAccessible(currentTaskIndex)) {
|
if (chain && currentTaskIndex >= 0 && !isTaskAccessible(currentTaskIndex)) {
|
||||||
@@ -138,7 +139,7 @@ export const TaskPage = () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const taskProgress = `Задание ${currentTaskIndex + 1}`
|
const taskProgress = `Задание`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -146,12 +147,12 @@ export const TaskPage = () => {
|
|||||||
<Box bg="gray.50" minH="100vh" py={4} px={{ base: 4, md: 8 }}>
|
<Box bg="gray.50" minH="100vh" py={4} px={{ base: 4, md: 8 }}>
|
||||||
<Box maxW="1200px" mx="auto">
|
<Box maxW="1200px" mx="auto">
|
||||||
{/* Навигация по заданиям */}
|
{/* Навигация по заданиям */}
|
||||||
<Box
|
<Box
|
||||||
bg="white"
|
bg="white"
|
||||||
borderWidth="1px"
|
borderWidth="1px"
|
||||||
borderColor="gray.200"
|
borderColor="gray.200"
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
p={3}
|
p={3}
|
||||||
mb={4}
|
mb={4}
|
||||||
shadow="sm"
|
shadow="sm"
|
||||||
>
|
>
|
||||||
@@ -160,29 +161,36 @@ export const TaskPage = () => {
|
|||||||
<Text fontSize="sm" fontWeight="medium" color="gray.600" mr={2}>
|
<Text fontSize="sm" fontWeight="medium" color="gray.600" mr={2}>
|
||||||
Задания:
|
Задания:
|
||||||
</Text>
|
</Text>
|
||||||
{chain.tasks.map((t, index) => {
|
{chain.tasks
|
||||||
const isAccessible = isTaskAccessible(index)
|
.filter((_, index) => {
|
||||||
const isCurrent = t.id === taskId
|
const isAccessible = isTaskAccessible(index)
|
||||||
|
// Показываем все доступные + только следующую недоступную
|
||||||
return (
|
return isAccessible || index === furthestTaskIndex + 1
|
||||||
<Button
|
})
|
||||||
key={t.id}
|
.map((t) => {
|
||||||
size="sm"
|
const taskIndex = chain.tasks.indexOf(t)
|
||||||
variant={isCurrent ? 'solid' : isAccessible ? 'outline' : 'ghost'}
|
const isAccessible = isTaskAccessible(taskIndex)
|
||||||
colorScheme={isCurrent ? 'teal' : 'gray'}
|
const isCurrent = t.id === taskId
|
||||||
// @ts-expect-error Chakra UI v2 uses isDisabled
|
|
||||||
isDisabled={!isAccessible}
|
return (
|
||||||
onClick={() => isAccessible && handleNavigateToTask(t.id)}
|
<Button
|
||||||
minW="40px"
|
key={t.id}
|
||||||
opacity={isAccessible ? 1 : 0.5}
|
size="sm"
|
||||||
cursor={isAccessible ? 'pointer' : 'not-allowed'}
|
variant={isCurrent ? 'solid' : isAccessible ? 'outline' : 'ghost'}
|
||||||
>
|
colorScheme={isCurrent ? 'teal' : 'gray'}
|
||||||
{isAccessible ? index + 1 : `🔒${index + 1}`}
|
// @ts-expect-error Chakra UI v2 uses isDisabled
|
||||||
</Button>
|
isDisabled={!isAccessible}
|
||||||
)
|
onClick={() => isAccessible && handleNavigateToTask(t.id)}
|
||||||
})}
|
minW="40px"
|
||||||
|
opacity={isAccessible ? 1 : 0.5}
|
||||||
|
cursor={isAccessible ? 'pointer' : 'not-allowed'}
|
||||||
|
>
|
||||||
|
{isAccessible ? taskIndex + 1 : `🔒${taskIndex + 1}`}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
Reference in New Issue
Block a user