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

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

View File

@ -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",

View File

@ -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": "Начать экзамен",

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