Refactor submission filtering and details display to handle various user and task data types; improve search functionality and localization for better user experience.
This commit is contained in:
@@ -76,13 +76,25 @@ export const SubmissionsPage: React.FC = () => {
|
|||||||
const participants: ActiveParticipant[] = stats.activeParticipants || []
|
const participants: ActiveParticipant[] = stats.activeParticipants || []
|
||||||
const submissionsList: ChallengeSubmission[] = submissions || []
|
const submissionsList: ChallengeSubmission[] = submissions || []
|
||||||
|
|
||||||
|
const normalizedSearchQuery = (searchQuery ?? '').toLowerCase()
|
||||||
|
|
||||||
const filteredSubmissions = submissionsList.filter((submission) => {
|
const filteredSubmissions = submissionsList.filter((submission) => {
|
||||||
const user = submission.user as ChallengeUser
|
const rawUser = submission.user as ChallengeUser | string | undefined
|
||||||
const task = submission.task as ChallengeTask
|
const rawTask = submission.task as ChallengeTask | string | undefined
|
||||||
|
|
||||||
|
const nickname =
|
||||||
|
rawUser && typeof rawUser === 'object' && 'nickname' in rawUser
|
||||||
|
? (rawUser.nickname ?? '')
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const title =
|
||||||
|
rawTask && typeof rawTask === 'object' && 'title' in rawTask
|
||||||
|
? (rawTask.title ?? '')
|
||||||
|
: ''
|
||||||
|
|
||||||
const matchesSearch =
|
const matchesSearch =
|
||||||
user.nickname.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
nickname.toLowerCase().includes(normalizedSearchQuery) ||
|
||||||
task.title.toLowerCase().includes(searchQuery.toLowerCase())
|
title.toLowerCase().includes(normalizedSearchQuery)
|
||||||
|
|
||||||
const matchesStatus = statusFilter === 'all' || submission.status === statusFilter
|
const matchesStatus = statusFilter === 'all' || submission.status === statusFilter
|
||||||
|
|
||||||
@@ -337,13 +349,27 @@ export const SubmissionsPage: React.FC = () => {
|
|||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
{filteredSubmissions.map((submission) => {
|
{filteredSubmissions.map((submission) => {
|
||||||
const user = submission.user as ChallengeUser
|
const rawUser = submission.user as ChallengeUser | string | undefined
|
||||||
const task = submission.task as ChallengeTask
|
const rawTask = submission.task as ChallengeTask | string | undefined
|
||||||
|
|
||||||
|
const nickname =
|
||||||
|
rawUser && typeof rawUser === 'object' && 'nickname' in rawUser
|
||||||
|
? (rawUser.nickname ?? '')
|
||||||
|
: typeof rawUser === 'string'
|
||||||
|
? rawUser
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const title =
|
||||||
|
rawTask && typeof rawTask === 'object' && 'title' in rawTask
|
||||||
|
? (rawTask.title ?? '')
|
||||||
|
: typeof rawTask === 'string'
|
||||||
|
? rawTask
|
||||||
|
: ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Row key={submission.id}>
|
<Table.Row key={submission.id}>
|
||||||
<Table.Cell fontWeight="medium">{user.nickname}</Table.Cell>
|
<Table.Cell fontWeight="medium">{nickname}</Table.Cell>
|
||||||
<Table.Cell>{task.title}</Table.Cell>
|
<Table.Cell>{title}</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell>
|
||||||
<StatusBadge status={submission.status} />
|
<StatusBadge status={submission.status} />
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
@@ -405,8 +431,27 @@ const SubmissionDetailsModal: React.FC<SubmissionDetailsModalProps> = ({
|
|||||||
|
|
||||||
if (!submission) return null
|
if (!submission) return null
|
||||||
|
|
||||||
const user = submission.user as ChallengeUser
|
const rawUser = submission.user as ChallengeUser | string | undefined
|
||||||
const task = submission.task as ChallengeTask
|
const rawTask = submission.task as ChallengeTask | string | undefined
|
||||||
|
|
||||||
|
const userNickname =
|
||||||
|
rawUser && typeof rawUser === 'object' && 'nickname' in rawUser
|
||||||
|
? (rawUser.nickname ?? '')
|
||||||
|
: typeof rawUser === 'string'
|
||||||
|
? rawUser
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const taskTitle =
|
||||||
|
rawTask && typeof rawTask === 'object' && 'title' in rawTask
|
||||||
|
? (rawTask.title ?? '')
|
||||||
|
: typeof rawTask === 'string'
|
||||||
|
? rawTask
|
||||||
|
: ''
|
||||||
|
|
||||||
|
const taskDescription =
|
||||||
|
rawTask && typeof rawTask === 'object' && 'description' in rawTask
|
||||||
|
? (rawTask.description ?? '')
|
||||||
|
: ''
|
||||||
|
|
||||||
const formatDate = (dateStr: string) => {
|
const formatDate = (dateStr: string) => {
|
||||||
return new Date(dateStr).toLocaleString('ru-RU', {
|
return new Date(dateStr).toLocaleString('ru-RU', {
|
||||||
@@ -441,7 +486,7 @@ const SubmissionDetailsModal: React.FC<SubmissionDetailsModalProps> = ({
|
|||||||
<Text fontSize="sm" color="gray.600" mb={1}>
|
<Text fontSize="sm" color="gray.600" mb={1}>
|
||||||
{t('challenge.admin.submissions.details.user')}
|
{t('challenge.admin.submissions.details.user')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontWeight="bold">{user.nickname}</Text>
|
<Text fontWeight="bold">{userNickname}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="sm" color="gray.600" mb={1}>
|
<Text fontSize="sm" color="gray.600" mb={1}>
|
||||||
@@ -471,7 +516,7 @@ const SubmissionDetailsModal: React.FC<SubmissionDetailsModalProps> = ({
|
|||||||
{/* Task */}
|
{/* Task */}
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontWeight="bold" mb={2}>
|
<Text fontWeight="bold" mb={2}>
|
||||||
{t('challenge.admin.submissions.details.task')} {task.title}
|
{t('challenge.admin.submissions.details.task')} {taskTitle}
|
||||||
</Text>
|
</Text>
|
||||||
<Box
|
<Box
|
||||||
p={4}
|
p={4}
|
||||||
@@ -482,7 +527,7 @@ const SubmissionDetailsModal: React.FC<SubmissionDetailsModalProps> = ({
|
|||||||
maxH="200px"
|
maxH="200px"
|
||||||
overflowY="auto"
|
overflowY="auto"
|
||||||
>
|
>
|
||||||
<ReactMarkdown>{task.description}</ReactMarkdown>
|
<ReactMarkdown>{taskDescription}</ReactMarkdown>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user