Update TaskWorkspace component to integrate ReactMarkdown for enhanced task description rendering. Add remark-gfm support for GitHub Flavored Markdown, improving text formatting and presentation. Update package dependencies in package.json and package-lock.json to include react-markdown and remark-gfm.
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:
1479
package-lock.json
generated
1479
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -35,8 +35,10 @@
|
|||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^6.23.1",
|
"react-router-dom": "^6.23.1",
|
||||||
|
"remark-gfm": "^4.0.1",
|
||||||
"typescript-eslint": "^8.6.0"
|
"typescript-eslint": "^8.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
Textarea,
|
Textarea,
|
||||||
VStack,
|
VStack,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
|
import ReactMarkdown from 'react-markdown'
|
||||||
|
import remarkGfm from 'remark-gfm'
|
||||||
|
|
||||||
import type { ChallengeTask } from '../../__data__/types'
|
import type { ChallengeTask } from '../../__data__/types'
|
||||||
import { useChallenge } from '../../context/ChallengeContext'
|
import { useChallenge } from '../../context/ChallengeContext'
|
||||||
@@ -24,7 +26,6 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
taskId: task.id,
|
taskId: task.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
const descriptionBg = 'gray.50'
|
|
||||||
const isChecking = !!queueStatus || isSubmitting
|
const isChecking = !!queueStatus || isSubmitting
|
||||||
const isAccepted = finalSubmission?.status === 'accepted'
|
const isAccepted = finalSubmission?.status === 'accepted'
|
||||||
const needsRevision = finalSubmission?.status === 'needs_revision'
|
const needsRevision = finalSubmission?.status === 'needs_revision'
|
||||||
@@ -37,13 +38,178 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack align="stretch" gap={3}>
|
<VStack align="stretch" gap={3}>
|
||||||
<Box borderWidth="1px" borderRadius="md" borderColor="gray.200" p={3} bg={descriptionBg}>
|
<Box borderWidth="1px" borderRadius="md" borderColor="gray.200" p={4} bg="white" shadow="sm">
|
||||||
<Text fontSize="md" fontWeight="semibold" mb={1}>
|
<Text fontSize="lg" fontWeight="bold" mb={3} color="gray.800">
|
||||||
{task.title}
|
{task.title}
|
||||||
</Text>
|
</Text>
|
||||||
<Text whiteSpace="pre-line" color="gray.700" fontSize="sm">
|
<Box
|
||||||
{task.description}
|
color="gray.700"
|
||||||
</Text>
|
fontSize="sm"
|
||||||
|
lineHeight="1.7"
|
||||||
|
css={{
|
||||||
|
// Заголовки
|
||||||
|
'& h1': {
|
||||||
|
fontSize: '1.75em',
|
||||||
|
fontWeight: '700',
|
||||||
|
marginTop: '1.2em',
|
||||||
|
marginBottom: '0.6em',
|
||||||
|
color: '#2D3748',
|
||||||
|
borderBottom: '2px solid #E2E8F0',
|
||||||
|
paddingBottom: '0.3em'
|
||||||
|
},
|
||||||
|
'& h2': {
|
||||||
|
fontSize: '1.5em',
|
||||||
|
fontWeight: '600',
|
||||||
|
marginTop: '1em',
|
||||||
|
marginBottom: '0.5em',
|
||||||
|
color: '#2D3748'
|
||||||
|
},
|
||||||
|
'& h3': {
|
||||||
|
fontSize: '1.25em',
|
||||||
|
fontWeight: '600',
|
||||||
|
marginTop: '0.8em',
|
||||||
|
marginBottom: '0.4em',
|
||||||
|
color: '#2D3748'
|
||||||
|
},
|
||||||
|
'& h4': {
|
||||||
|
fontSize: '1.1em',
|
||||||
|
fontWeight: '600',
|
||||||
|
marginTop: '0.6em',
|
||||||
|
marginBottom: '0.3em',
|
||||||
|
color: '#4A5568'
|
||||||
|
},
|
||||||
|
// Параграфы
|
||||||
|
'& p': {
|
||||||
|
marginTop: '0.75em',
|
||||||
|
marginBottom: '0.75em',
|
||||||
|
lineHeight: '1.8'
|
||||||
|
},
|
||||||
|
// Списки
|
||||||
|
'& ul, & ol': {
|
||||||
|
marginLeft: '1.5em',
|
||||||
|
marginTop: '0.75em',
|
||||||
|
marginBottom: '0.75em',
|
||||||
|
paddingLeft: '0.5em'
|
||||||
|
},
|
||||||
|
'& li': {
|
||||||
|
marginTop: '0.4em',
|
||||||
|
marginBottom: '0.4em',
|
||||||
|
lineHeight: '1.7'
|
||||||
|
},
|
||||||
|
'& li > p': {
|
||||||
|
marginTop: '0.25em',
|
||||||
|
marginBottom: '0.25em'
|
||||||
|
},
|
||||||
|
// Инлайн-код
|
||||||
|
'& code': {
|
||||||
|
backgroundColor: '#EDF2F7',
|
||||||
|
color: '#C53030',
|
||||||
|
padding: '0.15em 0.4em',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '0.9em',
|
||||||
|
fontFamily: 'Monaco, Consolas, "Courier New", monospace',
|
||||||
|
fontWeight: '500'
|
||||||
|
},
|
||||||
|
// Блоки кода
|
||||||
|
'& pre': {
|
||||||
|
backgroundColor: '#1A202C',
|
||||||
|
color: '#E2E8F0',
|
||||||
|
padding: '1em 1.2em',
|
||||||
|
borderRadius: '8px',
|
||||||
|
overflowX: 'auto',
|
||||||
|
marginTop: '1em',
|
||||||
|
marginBottom: '1em',
|
||||||
|
border: '1px solid #2D3748',
|
||||||
|
fontSize: '0.9em',
|
||||||
|
lineHeight: '1.6'
|
||||||
|
},
|
||||||
|
'& pre code': {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
color: '#E2E8F0',
|
||||||
|
padding: '0',
|
||||||
|
fontFamily: 'Monaco, Consolas, "Courier New", monospace'
|
||||||
|
},
|
||||||
|
// Цитаты
|
||||||
|
'& blockquote': {
|
||||||
|
borderLeft: '4px solid #4299E1',
|
||||||
|
paddingLeft: '1em',
|
||||||
|
paddingTop: '0.5em',
|
||||||
|
paddingBottom: '0.5em',
|
||||||
|
marginLeft: '0',
|
||||||
|
marginTop: '1em',
|
||||||
|
marginBottom: '1em',
|
||||||
|
fontStyle: 'italic',
|
||||||
|
color: '#4A5568',
|
||||||
|
backgroundColor: '#EBF8FF',
|
||||||
|
borderRadius: '0 4px 4px 0'
|
||||||
|
},
|
||||||
|
'& blockquote p': {
|
||||||
|
marginTop: '0.25em',
|
||||||
|
marginBottom: '0.25em'
|
||||||
|
},
|
||||||
|
// Ссылки
|
||||||
|
'& a': {
|
||||||
|
color: '#3182CE',
|
||||||
|
textDecoration: 'underline',
|
||||||
|
fontWeight: '500',
|
||||||
|
transition: 'color 0.2s',
|
||||||
|
'&:hover': {
|
||||||
|
color: '#2C5282'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Горизонтальная линия
|
||||||
|
'& hr': {
|
||||||
|
border: 'none',
|
||||||
|
borderTop: '2px solid #E2E8F0',
|
||||||
|
marginTop: '1.5em',
|
||||||
|
marginBottom: '1.5em'
|
||||||
|
},
|
||||||
|
// Таблицы
|
||||||
|
'& table': {
|
||||||
|
borderCollapse: 'collapse',
|
||||||
|
width: '100%',
|
||||||
|
marginTop: '1em',
|
||||||
|
marginBottom: '1em',
|
||||||
|
fontSize: '0.95em'
|
||||||
|
},
|
||||||
|
'& table thead': {
|
||||||
|
backgroundColor: '#F7FAFC'
|
||||||
|
},
|
||||||
|
'& table th': {
|
||||||
|
border: '1px solid #E2E8F0',
|
||||||
|
padding: '0.75em 1em',
|
||||||
|
textAlign: 'left',
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#2D3748'
|
||||||
|
},
|
||||||
|
'& table td': {
|
||||||
|
border: '1px solid #E2E8F0',
|
||||||
|
padding: '0.75em 1em',
|
||||||
|
textAlign: 'left'
|
||||||
|
},
|
||||||
|
'& table tr:nth-of-type(even)': {
|
||||||
|
backgroundColor: '#F7FAFC'
|
||||||
|
},
|
||||||
|
// Выделение (strong, em)
|
||||||
|
'& strong': {
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#2D3748'
|
||||||
|
},
|
||||||
|
'& em': {
|
||||||
|
fontStyle: 'italic'
|
||||||
|
},
|
||||||
|
// Изображения
|
||||||
|
'& img': {
|
||||||
|
maxWidth: '100%',
|
||||||
|
height: 'auto',
|
||||||
|
borderRadius: '8px',
|
||||||
|
marginTop: '1em',
|
||||||
|
marginBottom: '1em'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ReactMarkdown remarkPlugins={[remarkGfm]}>{task.description}</ReactMarkdown>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Статус проверки */}
|
{/* Статус проверки */}
|
||||||
|
|||||||
Reference in New Issue
Block a user