import React, { useState, useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import {
Box,
Heading,
Button,
Input,
Textarea,
VStack,
HStack,
Text,
Field,
Tabs,
} from '@chakra-ui/react'
import ReactMarkdown from 'react-markdown'
import {
useGetTaskQuery,
useCreateTaskMutation,
useUpdateTaskMutation,
} from '../../__data__/api/api'
import { URLs } from '../../__data__/urls'
import { LoadingSpinner } from '../../components/LoadingSpinner'
import { ErrorAlert } from '../../components/ErrorAlert'
import { toaster } from '../../components/ui/toaster'
export const TaskFormPage: React.FC = () => {
const { id } = useParams<{ id: string }>()
const navigate = useNavigate()
const isEdit = !!id
const { t } = useTranslation()
const { data: task, isLoading: isLoadingTask, error: loadError } = useGetTaskQuery(id!, {
skip: !id,
})
const [createTask, { isLoading: isCreating }] = useCreateTaskMutation()
const [updateTask, { isLoading: isUpdating }] = useUpdateTaskMutation()
const [title, setTitle] = useState('')
const [description, setDescription] = useState('')
const [hiddenInstructions, setHiddenInstructions] = useState('')
const [showDescPreview, setShowDescPreview] = useState(false)
useEffect(() => {
if (task) {
setTitle(task.title)
setDescription(task.description)
setHiddenInstructions(task.hiddenInstructions || '')
}
}, [task])
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!title.trim() || !description.trim()) {
toaster.create({
title: t('challenge.admin.common.validation.error'),
description: t('challenge.admin.tasks.validation.fill.required.fields'),
type: 'error',
})
return
}
try {
if (isEdit && id) {
await updateTask({
id,
data: {
title: title.trim(),
description: description.trim(),
hiddenInstructions: hiddenInstructions.trim() || undefined,
},
}).unwrap()
toaster.create({
title: t('challenge.admin.common.success'),
description: t('challenge.admin.tasks.updated'),
type: 'success',
})
} else {
await createTask({
title: title.trim(),
description: description.trim(),
hiddenInstructions: hiddenInstructions.trim() || undefined,
}).unwrap()
toaster.create({
title: t('challenge.admin.common.success'),
description: t('challenge.admin.tasks.created'),
type: 'success',
})
}
navigate(URLs.tasks)
} catch (err: unknown) {
const errorMessage =
(err && typeof err === 'object' && 'data' in err &&
err.data && typeof err.data === 'object' && 'error' in err.data &&
err.data.error && typeof err.data.error === 'object' && 'message' in err.data.error &&
typeof err.data.error.message === 'string')
? err.data.error.message
: t('challenge.admin.tasks.save.error')
toaster.create({
title: t('challenge.admin.common.error'),
description: errorMessage,
type: 'error',
})
}
}
if (isEdit && isLoadingTask) {
return
}
if (isEdit && loadError) {
return
}
const isLoading = isCreating || isUpdating
return (
{isEdit ? t('challenge.admin.tasks.edit.title') : t('challenge.admin.tasks.create.title')}
{/* Title */}
{t('challenge.admin.tasks.field.title')}
setTitle(e.target.value)}
placeholder={t('challenge.admin.tasks.field.title.placeholder')}
maxLength={255}
disabled={isLoading}
/>
{t('challenge.admin.tasks.field.title.helper')}
{/* Description with Markdown */}
{t('challenge.admin.tasks.field.description')}
setShowDescPreview(e.value === 'preview')}
>
{t('challenge.admin.tasks.tab.editor')}
{t('challenge.admin.tasks.tab.preview')}
{description ? (
{description}
) : (
{t('challenge.admin.tasks.preview.empty')}
)}
{t('challenge.admin.tasks.field.description.helper')}
{/* Hidden Instructions */}
{t('challenge.admin.tasks.field.hidden.instructions')}
{t('challenge.admin.tasks.field.hidden.instructions.description')}
{/* Meta info for edit mode */}
{isEdit && task && (
{t('challenge.admin.tasks.meta.created')}{' '}
{new Date(task.createdAt).toLocaleString('ru-RU')}
{task.creator && (
{t('challenge.admin.tasks.meta.author')} {task.creator.preferred_username}
)}
{task.updatedAt !== task.createdAt && (
{t('challenge.admin.tasks.meta.updated')}{' '}
{new Date(task.updatedAt).toLocaleString('ru-RU')}
)}
)}
{/* Actions */}
)
}