Refactor project structure and integrate Redux for state management. Update configuration files for new project name and add Webpack plugins for environment variables. Implement user authentication with Keycloak and create a context for challenge management. Add various components for user interaction, including dashboards and task workspaces. Enhance API integration and add error handling utilities. Introduce analytics and polling mechanisms for improved user experience.
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:
156
src/hooks/useSubmission.ts
Normal file
156
src/hooks/useSubmission.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import {
|
||||
useLazyCheckQueueStatusQuery,
|
||||
useSubmitSolutionMutation,
|
||||
} from '../__data__/api/api'
|
||||
import type { ChallengeSubmission, QueueStatus } from '../__data__/types'
|
||||
import { useChallenge } from '../context/ChallengeContext'
|
||||
|
||||
interface UseSubmissionArgs {
|
||||
taskId: string
|
||||
}
|
||||
|
||||
interface SubmissionResult {
|
||||
result: string
|
||||
setResult: (value: string) => void
|
||||
submit: () => Promise<void>
|
||||
reset: () => void
|
||||
queueStatus: QueueStatus | null
|
||||
finalSubmission: ChallengeSubmission | null
|
||||
isSubmitting: boolean
|
||||
}
|
||||
|
||||
export const useSubmission = ({ taskId }: UseSubmissionArgs): SubmissionResult => {
|
||||
const {
|
||||
userId,
|
||||
eventEmitter,
|
||||
pollingManager,
|
||||
behaviorTracker,
|
||||
metricsCollector,
|
||||
saveDraft,
|
||||
loadDraft,
|
||||
clearDraft,
|
||||
} = useChallenge()
|
||||
|
||||
const [result, setResultState] = useState('')
|
||||
const [queueId, setQueueId] = useState<string | null>(null)
|
||||
const [queueStatus, setQueueStatus] = useState<QueueStatus | null>(null)
|
||||
const [finalSubmission, setFinalSubmission] = useState<ChallengeSubmission | null>(null)
|
||||
|
||||
const [submitSolution, { isLoading: isSubmitting }] = useSubmitSolutionMutation()
|
||||
const [triggerCheckStatus] = useLazyCheckQueueStatusQuery()
|
||||
|
||||
useEffect(() => {
|
||||
behaviorTracker.reset()
|
||||
const draft = loadDraft(taskId)
|
||||
if (draft) {
|
||||
setResultState(draft)
|
||||
behaviorTracker.markDraftUsed()
|
||||
} else {
|
||||
setResultState('')
|
||||
}
|
||||
pollingManager.stop()
|
||||
setQueueId(null)
|
||||
setQueueStatus(null)
|
||||
setFinalSubmission(null)
|
||||
}, [behaviorTracker, loadDraft, pollingManager, taskId])
|
||||
|
||||
const setResult = useCallback(
|
||||
(value: string) => {
|
||||
setResultState(value)
|
||||
behaviorTracker.onTextChange(value)
|
||||
saveDraft(taskId, value)
|
||||
},
|
||||
[behaviorTracker, saveDraft, taskId],
|
||||
)
|
||||
|
||||
const reset = useCallback(() => {
|
||||
setResultState('')
|
||||
setQueueId(null)
|
||||
setQueueStatus(null)
|
||||
setFinalSubmission(null)
|
||||
behaviorTracker.reset()
|
||||
pollingManager.stop()
|
||||
clearDraft(taskId)
|
||||
}, [behaviorTracker, clearDraft, pollingManager, taskId])
|
||||
|
||||
const submit = useCallback(async () => {
|
||||
if (!userId) {
|
||||
throw new Error('Пользователь не авторизован')
|
||||
}
|
||||
if (!result.trim()) {
|
||||
return
|
||||
}
|
||||
|
||||
pollingManager.stop()
|
||||
setFinalSubmission(null)
|
||||
setQueueStatus(null)
|
||||
|
||||
const { queueId: newQueueId } = await submitSolution({ userId, taskId, result }).unwrap()
|
||||
setQueueId(newQueueId)
|
||||
metricsCollector.startTracking(queueStatus?.position ?? 0)
|
||||
|
||||
pollingManager.start(async () => {
|
||||
const status = await triggerCheckStatus(newQueueId, true).unwrap()
|
||||
metricsCollector.incrementPoll()
|
||||
setQueueStatus(status)
|
||||
|
||||
if (status.status === 'completed' && status.submission) {
|
||||
const performanceMetrics = metricsCollector.getMetrics(status.submission)
|
||||
const behaviorMetrics = behaviorTracker.getMetrics(result)
|
||||
|
||||
const eventPayload = {
|
||||
submission: status.submission,
|
||||
performanceMetrics,
|
||||
behaviorMetrics,
|
||||
}
|
||||
|
||||
eventEmitter.emit({
|
||||
type: 'submission_completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
userId,
|
||||
data: eventPayload,
|
||||
})
|
||||
|
||||
setFinalSubmission(status.submission)
|
||||
clearDraft(taskId)
|
||||
pollingManager.stop()
|
||||
return false
|
||||
}
|
||||
|
||||
if (status.status === 'error') {
|
||||
pollingManager.stop()
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}, [
|
||||
behaviorTracker,
|
||||
clearDraft,
|
||||
eventEmitter,
|
||||
metricsCollector,
|
||||
pollingManager,
|
||||
queueStatus?.position,
|
||||
result,
|
||||
submitSolution,
|
||||
taskId,
|
||||
triggerCheckStatus,
|
||||
userId,
|
||||
])
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
result,
|
||||
setResult,
|
||||
submit,
|
||||
reset,
|
||||
queueStatus,
|
||||
finalSubmission,
|
||||
isSubmitting,
|
||||
}),
|
||||
[finalSubmission, isSubmitting, queueStatus, reset, result, setResult, submit],
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user