7 Commits
v1.4.0 ... main

Author SHA1 Message Date
05c291120d 1.4.3
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 21:30:57 +03:00
4fd2e5660c Enhance LearningMaterialViewer and TaskWorkspace components to open links in a new tab with appropriate security attributes. This improves user experience by ensuring external links are handled safely.
Some checks are pending
platform/bro-js/challenge-pl/pipeline/head Build queued...
2025-12-15 21:30:50 +03:00
842bb959ab 1.4.2
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 21:22:34 +03:00
eb5bc8a10a Update authUser mutation to accept optional workplaceNumber parameter and adjust login function accordingly. Enhance API logging for authentication requests to include workplaceNumber for better debugging.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 18:03:10 +03:00
a0ac758049 Add refreshChains function to ChallengeContext and integrate it into ChainsPage for improved data management. This allows for manual refreshing of chain data when the component mounts, enhancing user experience.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-15 17:43:21 +03:00
23ec02e29a 1.4.1
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 16:05:18 +03:00
1291519cda Refactor TaskWorkspace to use getFeatureValue for feature flag retrieval, improving clarity and consistency in skip button functionality.
Some checks failed
platform/bro-js/challenge-pl/pipeline/head There was a failure building this commit
2025-12-14 16:05:05 +03:00
8 changed files with 57 additions and 12 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "challenge",
"version": "1.4.0",
"version": "1.4.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "challenge",
"version": "1.4.0",
"version": "1.4.3",
"license": "ISC",
"dependencies": {
"@brojs/cli": "^1.9.4",

View File

@@ -1,6 +1,6 @@
{
"name": "challenge",
"version": "1.4.0",
"version": "1.4.3",
"description": "",
"main": "./src/index.tsx",
"scripts": {

View File

@@ -33,7 +33,7 @@ export const api = createApi({
}),
tagTypes: ['Chains', 'Chain', 'UserStats', 'SystemStats', 'Submissions', 'Queue'],
endpoints: (builder) => ({
authUser: builder.mutation<ChallengeAuthResponse, { nickname: string }>({
authUser: builder.mutation<ChallengeAuthResponse, { nickname: string; workplaceNumber?: string }>({
query: (body) => ({
url: '/auth',
method: 'POST',

View File

@@ -234,7 +234,14 @@ export const LearningMaterialViewer = ({
}
}}
>
<ReactMarkdown remarkPlugins={[remarkGfm]}>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
a: ({ node: _node, ...props }) => (
<a {...props} target="_blank" rel="noopener noreferrer" />
)
}}
>
{pages[currentPage]}
</ReactMarkdown>
</Box>

View File

@@ -9,7 +9,7 @@ import {
} from '@chakra-ui/react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { useFeature } from '@brojs/cli'
import { getFeatureValue } from '@brojs/cli'
import type { ChallengeTask } from '../../__data__/types'
import { useChallenge } from '../../context/ChallengeContext'
@@ -29,7 +29,7 @@ export const TaskWorkspace = ({ task, onTaskComplete, onTaskSkip }: TaskWorkspac
})
// Проверяем, включена ли кнопка пропуска через feature flag
const skipEnabled = useFeature('challenge', 'task.skip.enabled', 'false') === 'true'
const skipEnabled = getFeatureValue('challenge', 'task.skip.enabled', 'false').value === 'true'
// Сохраняем последний результат, чтобы блок не исчезал
const [lastResult, setLastResult] = useState<typeof finalSubmission>(null)
@@ -274,7 +274,16 @@ export const TaskWorkspace = ({ task, onTaskComplete, onTaskSkip }: TaskWorkspac
}
}}
>
<ReactMarkdown remarkPlugins={[remarkGfm]}>{task.description}</ReactMarkdown>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
a: ({ node: _node, ...props }) => (
<a {...props} target="_blank" rel="noopener noreferrer" />
)
}}
>
{task.description}
</ReactMarkdown>
</Box>
</Box>

View File

@@ -65,6 +65,7 @@ interface ChallengeContextValue {
login: (nickname: string, workplaceNumber: string) => Promise<void>
logout: () => void
refreshStats: () => Promise<void>
refreshChains: () => Promise<void>
eventEmitter: ChallengeEventEmitter
pollingManager: PollingManager
metricsCollector: MetricsCollector
@@ -96,10 +97,23 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
const [authUser, { isLoading: isAuthLoading }] = useAuthUserMutation()
const [triggerStats, statsResult] = useLazyGetUserStatsQuery()
const { data: chainsData, isLoading: isChainsLoading } = useGetChainsQuery(undefined, {
const {
data: chainsData,
isLoading: isChainsLoading,
refetch: refetchChains,
} = useGetChainsQuery(undefined, {
skip: !userId,
})
const refreshChains = useCallback(async () => {
if (!userId) {
return
}
cacheRef.current.clear('chains')
await refetchChains()
}, [refetchChains, userId])
useEffect(() => {
if (chainsData) {
setChains(chainsData)
@@ -146,7 +160,10 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
const login = useCallback(
async (nicknameValue: string, workplaceNumberValue: string) => {
const response = await authUser({ nickname: nicknameValue }).unwrap()
const response = await authUser({
nickname: nicknameValue,
workplaceNumber: workplaceNumberValue || undefined
}).unwrap()
setUserId(response.userId)
setNickname(nicknameValue)
setWorkplaceNumber(workplaceNumberValue)
@@ -189,6 +206,7 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
login,
logout,
refreshStats,
refreshChains,
eventEmitter,
pollingManager,
metricsCollector,
@@ -213,6 +231,7 @@ export const ChallengeProvider = ({ children }: PropsWithChildren) => {
personalDashboard,
pollingManager,
refreshStats,
refreshChains,
saveDraft,
stats,
userId,

View File

@@ -10,7 +10,7 @@ import type { ChallengeChain } from '../../__data__/types'
export const ChainsPage = () => {
const navigate = useNavigate()
const { nickname } = useChallenge()
const { nickname, refreshChains } = useChallenge()
// Проверяем авторизацию
useEffect(() => {
@@ -24,6 +24,10 @@ export const ChainsPage = () => {
}
}, [navigate, nickname])
useEffect(() => {
refreshChains()
}, [refreshChains])
const handleSelectChain = (chain: ChallengeChain) => {
storage.setSelectedChainId(chain.id)

View File

@@ -24,7 +24,13 @@ router.use((req, res, next) => {
// Challenge API endpoints
router.post('/challenge/auth', (req, res) => {
res.json(readJson('auth.json'))
const { nickname, workplaceNumber } = req.body
const response = readJson('auth.json')
// Логируем для отладки
console.log('Auth request:', { nickname, workplaceNumber })
res.json(response)
})
router.get('/challenge/chains', (req, res) => {