Добавлены новые сообщения об ошибках и возможность повторной генерации уроков с использованием ИИ в компонентах LessonList и LessonForm. Обновлены локализации для поддержки новых функций.

This commit is contained in:
2025-03-23 15:17:55 +03:00
parent 46107cb3d1
commit 5a71314c82
4 changed files with 78 additions and 13 deletions

View File

@@ -26,7 +26,7 @@ import {
SkeletonText,
useStyleConfig
} from '@chakra-ui/react'
import { AddIcon, CheckIcon } from '@chakra-ui/icons'
import { AddIcon, CheckIcon, WarningIcon, RepeatIcon } from '@chakra-ui/icons'
import { useTranslation } from 'react-i18next'
import { FaRobot } from 'react-icons/fa'
import dayjs from 'dayjs'
@@ -52,6 +52,7 @@ interface LessonFormProps {
isLoadingAiSuggestions?: boolean // Индикатор загрузки предложений
onSelectAiSuggestion?: (suggestion: any) => void // Обработчик выбора предложения
selectedAiSuggestion?: any // Выбранное предложение
onRetryAiGeneration?: () => void // Функция для повторного запуска генерации
}
export const LessonForm = ({
@@ -65,7 +66,8 @@ export const LessonForm = ({
aiSuggestions = [],
isLoadingAiSuggestions = false,
onSelectAiSuggestion = () => {},
selectedAiSuggestion
selectedAiSuggestion,
onRetryAiGeneration = () => {}
}: LessonFormProps) => {
const { t } = useTranslation()
const isAiSuggested = lesson && !lesson._id && !lesson.id
@@ -212,7 +214,7 @@ export const LessonForm = ({
</form>
{/* Блок с предложениями ИИ */}
{(aiSuggestions.length > 0 || isLoadingAiSuggestions) && (
{((Array.isArray(aiSuggestions) && aiSuggestions.length > 0) || isLoadingAiSuggestions || typeof aiSuggestions === 'string') && (
<>
<Divider my={6} />
@@ -221,7 +223,7 @@ export const LessonForm = ({
<Heading size="sm" color="blue.500">
{t('journal.pl.lesson.aiSuggested')}
</Heading>
{!isLoadingAiSuggestions && (
{!isLoadingAiSuggestions && Array.isArray(aiSuggestions) && (
<Badge colorScheme="blue" ml={2}>
{aiSuggestions.length} {t('journal.pl.common.lesson').toLowerCase()}
</Badge>
@@ -230,6 +232,31 @@ export const LessonForm = ({
{isLoadingAiSuggestions ? (
renderSkeletons()
) : typeof aiSuggestions === 'string' ? (
<Box
p={4}
bg={useColorModeValue('red.50', 'red.900')}
color={useColorModeValue('red.600', 'red.200')}
borderRadius="md"
borderLeft="3px solid"
borderLeftColor="red.500"
>
<Flex align="center" mb={2}>
<Icon as={WarningIcon} color="red.500" mr={2} />
<Text fontWeight="bold">{t('journal.pl.lesson.aiGenerationError')}</Text>
</Flex>
<Text fontSize="sm" mb={3}>{t('journal.pl.lesson.tryAgainLater')}</Text>
<Button
size="sm"
colorScheme="red"
variant="outline"
leftIcon={<RepeatIcon />}
onClick={onRetryAiGeneration}
isLoading={isLoadingAiSuggestions}
>
{t('journal.pl.lesson.retryGeneration')}
</Button>
</Box>
) : (
<>
<Text fontSize="sm" color={textSecondaryColor} mb={4}>

View File

@@ -105,8 +105,31 @@ const LessonList = () => {
useEffect(() => {
if (isSuccessGenerateLessons) {
console.log(generateLessons)
// Проверяем корректность ответа API
if (typeof generateLessons?.body === 'string') {
toast({
title: t('journal.pl.lesson.aiGenerationError'),
description: t('journal.pl.lesson.tryAgainLater'),
status: 'error',
duration: 5000,
isClosable: true,
});
}
}
}, [isSuccessGenerateLessons])
}, [isSuccessGenerateLessons, generateLessons])
useEffect(() => {
if (errorGenerateLessons) {
toast({
title: t('journal.pl.lesson.aiGenerationError'),
description: t('journal.pl.lesson.tryAgainLater'),
status: 'error',
duration: 5000,
isClosable: true,
});
}
}, [errorGenerateLessons])
const onSubmit = (lessonData) => {
toastRef.current = toast({
@@ -201,11 +224,8 @@ const LessonList = () => {
setSuggestedLessonToCreate(null)
// Сбрасываем флаги генерации, чтобы при повторном открытии формы
// генерация запускалась снова
if (generateLessons) {
// Сбрасываем данные генерации (если в API есть такая возможность)
// или при повторном открытии формы будем перезапрашивать данные
}
// генерация запускалась снова при необходимости
// (особенно если была ошибка в предыдущей генерации)
}
// Обработчик открытия формы создания новой лекции
@@ -213,8 +233,12 @@ const LessonList = () => {
setShowForm(true)
// Запускаем генерацию лекций только при открытии формы создания новой лекции
// и если генерация ещё не была запущена
if (isTeacher(user) && !editLesson && !generateLessons && !isLoadingGenerateLessons) {
// и если генерация ещё не была запущена или предыдущая попытка завершилась с ошибкой
const shouldGenerateAgain = !generateLessons ||
typeof generateLessons?.body === 'string' ||
errorGenerateLessons;
if (isTeacher(user) && !editLesson && (!isLoadingGenerateLessons && shouldGenerateAgain)) {
generateLessonsMutation(courseId)
}
}
@@ -226,6 +250,13 @@ const LessonList = () => {
// Не запускаем генерацию при редактировании
}
// Обработчик повторной генерации предложений ИИ
const handleRetryAiGeneration = () => {
if (isTeacher(user) && !isLoadingGenerateLessons) {
generateLessonsMutation(courseId)
}
}
if (isLoading) {
return <XlSpinner />
}
@@ -294,10 +325,11 @@ const LessonList = () => {
lesson={editLesson || suggestedLessonToCreate || undefined}
title={editLesson ? t('journal.pl.lesson.editTitle') : t('journal.pl.lesson.createTitle')}
nameButton={editLesson ? t('journal.pl.edit') : t('journal.pl.common.create')}
aiSuggestions={generateLessons?.body || []}
aiSuggestions={generateLessons?.body}
isLoadingAiSuggestions={isLoadingGenerateLessons}
onSelectAiSuggestion={handleSelectAiSuggestion}
selectedAiSuggestion={suggestedLessonToCreate}
onRetryAiGeneration={handleRetryAiGeneration}
/>
) : (
<Button