diff --git a/locales/en.json b/locales/en.json index e196c3e..9948000 100644 --- a/locales/en.json +++ b/locales/en.json @@ -79,6 +79,9 @@ "journal.pl.lesson.createFromSuggestion": "Create", "journal.pl.lesson.aiGenerated": "AI generated content", "journal.pl.lesson.generatingAiSuggestions": "Generating AI lesson suggestions...", + "journal.pl.lesson.aiGenerationError": "Error generating AI suggestions", + "journal.pl.lesson.tryAgainLater": "An error occurred while generating lesson suggestions. Please try again later.", + "journal.pl.lesson.retryGeneration": "Retry Generation", "journal.pl.exam.title": "Exam", "journal.pl.exam.startExam": "Start exam", diff --git a/locales/ru.json b/locales/ru.json index 8df1162..9e0fdcd 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -76,6 +76,9 @@ "journal.pl.lesson.createFromSuggestion": "Создать", "journal.pl.lesson.aiGenerated": "Сгенерировано ИИ", "journal.pl.lesson.generatingAiSuggestions": "Генерация рекомендаций ИИ...", + "journal.pl.lesson.aiGenerationError": "Ошибка генерации рекомендаций ИИ", + "journal.pl.lesson.tryAgainLater": "Произошла ошибка при генерации рекомендаций для занятий. Пожалуйста, попробуйте позже.", + "journal.pl.lesson.retryGeneration": "Повторить генерацию", "journal.pl.exam.title": "Экзамен", "journal.pl.exam.startExam": "Начать экзамен", diff --git a/src/pages/lesson-list/components/lessons-form.tsx b/src/pages/lesson-list/components/lessons-form.tsx index 619fc27..c5a877c 100644 --- a/src/pages/lesson-list/components/lessons-form.tsx +++ b/src/pages/lesson-list/components/lessons-form.tsx @@ -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 = ({ {/* Блок с предложениями ИИ */} - {(aiSuggestions.length > 0 || isLoadingAiSuggestions) && ( + {((Array.isArray(aiSuggestions) && aiSuggestions.length > 0) || isLoadingAiSuggestions || typeof aiSuggestions === 'string') && ( <> @@ -221,7 +223,7 @@ export const LessonForm = ({ {t('journal.pl.lesson.aiSuggested')} - {!isLoadingAiSuggestions && ( + {!isLoadingAiSuggestions && Array.isArray(aiSuggestions) && ( {aiSuggestions.length} {t('journal.pl.common.lesson').toLowerCase()} @@ -230,6 +232,31 @@ export const LessonForm = ({ {isLoadingAiSuggestions ? ( renderSkeletons() + ) : typeof aiSuggestions === 'string' ? ( + + + + {t('journal.pl.lesson.aiGenerationError')} + + {t('journal.pl.lesson.tryAgainLater')} + + ) : ( <> diff --git a/src/pages/lesson-list/lesson-list.tsx b/src/pages/lesson-list/lesson-list.tsx index 2c4c205..950d978 100644 --- a/src/pages/lesson-list/lesson-list.tsx +++ b/src/pages/lesson-list/lesson-list.tsx @@ -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 } @@ -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} /> ) : (