diff --git a/src/pages/Exercise.tsx b/src/pages/Exercise.tsx index b3480f1..eae7de9 100644 --- a/src/pages/Exercise.tsx +++ b/src/pages/Exercise.tsx @@ -49,7 +49,7 @@ export const Exercise = () => { // Состояние ошибки (пустая строка = нет ошибки, текст = описание ошибки) const [error, setError] = useState("") - // ========== СОСТОЯНИЯ ТАЙМЕРА УПРАЖНЕНИЯ ========== + // ========== СОСТОЯНИЯ ТАЙМЕРУ УПРАЖНЕНИЯ ========== // Играет ли сейчас таймер упражнения (true = идет, false = на паузе) const [isPlaying, setIsPlaying] = useState(false) @@ -95,36 +95,46 @@ export const Exercise = () => { // ========== ВОССТАНОВЛЕНИЕ ПРОГРЕССА ПРИ ЗАГРУЗКЕ СТРАНИЦЫ ========== // Этот код выполняется каждый раз при загрузке страницы или изменении упражнения useEffect(() => { - // Пытаемся получить сохраненный прогресс из памяти браузера для конкретного курса и упражнения - const savedProgress = localStorage.getItem(`exerciseProgress_${courseId}_${exerciseId}`) + const loadProgress = async () => { + const serverLoaded = await loadProgressFromServer() - if (savedProgress) { - // Если прогресс найден, преобразуем его из текста в объект - const progress = JSON.parse(savedProgress) + if (!serverLoaded) { + // Fallback to localStorage if server loading failed + console.log("Пытаемся загрузить прогресс из localStorage как резервный вариант") - // Проверяем статус сохраненного прогресса - if (progress.status === 1) { - // СТАТУС 1 = упражнение было полностью завершено ранее - console.log("Найден завершенный прогресс упражнения для курса", courseId) - setIsCompleted(true) // Помечаем как завершенное - setCurrentTime(progress.totalTime || totalTime) // Устанавливаем время на максимум - setCompletedSets(progress.completedSets || []) // Восстанавливаем завершенные подходы - setCurrentSet(progress.set || totalSets) // Устанавливаем текущий подход на последний - setHasSavedProgress(false) // Сбрасываем флаг сохранения - } else { - // СТАТУС 0 = упражнение было на паузе или в процессе выполнения - console.log("Найден незавершенный прогресс упражнения для курса", courseId) - setCurrentTime(progress.position) // Восстанавливаем время выполнения - setCurrentSet(progress.set) // Восстанавливаем номер подхода - setCompletedSets(progress.completedSets || []) // Восстанавливаем завершенные подходы - setIsResting(progress.isResting || false) // Восстанавливаем состояние отдыха - setRestTime(progress.restTime || 0) // Восстанавливаем время отдыха - setIsRestPaused(progress.isRestPaused || false) // Восстанавливаем паузу отдыха - setHasSavedProgress(true) // Помечаем что есть сохраненный прогресс - setIsCompleted(false) // Упражнение не завершено + const savedProgress = localStorage.getItem(`exerciseProgress_${courseId}_${exerciseId}`) + + if (savedProgress) { + // Если прогресс найден, преобразуем его из текста в объект + const progress = JSON.parse(savedProgress) + + // Проверяем статус сохраненного прогресса + if (progress.status === 1) { + // СТАТУС 1 = упражнение было полностью завершено ранее + console.log("Найден завершенный прогресс упражнения для курса", courseId) + setIsCompleted(true) // Помечаем как завершенное + setCurrentTime(progress.totalTime || totalTime) // Устанавливаем время на максимум + setCompletedSets(progress.completedSets || []) // Восстанавливаем завершенные подходы + setCurrentSet(progress.set || totalSets) // Устанавливаем текущий подход на последний + setHasSavedProgress(false) // Сбрасываем флаг сохранения + } else { + // СТАТУС 0 = упражнение было на паузе или в процессе выполнения + console.log("Найден незавершенный прогресс упражнения для курса", courseId) + setCurrentTime(progress.position) // Восстанавливаем время выполнения + setCurrentSet(progress.set) // Восстанавливаем номер подхода + setCompletedSets(progress.completedSets || []) // Восстанавливаем завершенные подходы + setIsResting(progress.isResting || false) // Восстанавливаем состояние отдыха + setRestTime(progress.restTime || 0) // Восстанавливаем время отдыха + setIsRestPaused(progress.isRestPaused || false) // Восстанавливаем паузу отдыха + setHasSavedProgress(true) // Помечаем что есть сохраненный прогресс + setIsCompleted(false) // Упражнение не завершено + } + } } } - }, [exerciseId]) // Код выполняется при изменении ID упражнения + + loadProgress() + }, [courseId, exerciseId, totalTime, totalSets]) // Зависимости для повторного выполнения // ========== ЗАГРУЗКА ДАННЫХ УПРАЖНЕНИЯ С СЕРВЕРА ========== useEffect(() => { @@ -173,8 +183,6 @@ export const Exercise = () => { console.log("Установлено количество подходов:", exerciseData.count) } - loadProgressFromServer(exerciseData.id) - // Загрузка завершена успешно setLoading(false) }) @@ -203,138 +211,78 @@ export const Exercise = () => { // ========== ФУНКЦИЯ ЗАГРУЗКИ ПРОГРЕССА С СЕРВЕРА ========== // Эта функция получает сохраненный прогресс упражнения с бэкенда - const loadProgressFromServer = async (exerciseId: number) => { + const loadProgressFromServer = async () => { try { - console.log("Загружаем сохраненный прогресс с сервера для упражнения:", exerciseId, "в курсе:", courseId) + const response = await fetch(`/api/pacient/${courseId}/${exerciseId}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + // Add authorization header if needed + // 'Authorization': `Bearer ${token}` + }, + }) - const response = await connect.get(`pacient/${courseId}/${exerciseId}/progress?course_id=${courseId}`) - - if (response.data && response.data.length > 0) { - console.log("Найден сохраненный прогресс на сервере для курса", courseId, ":", response.data) - - // Получаем все записи прогресса для этого упражнения В ЭТОМ КУРСЕ - const progressData = response.data - - const filteredProgress = progressData.filter((record: any) => { - // Проверяем что запись относится к текущему курсу - return record.course_id === Number.parseInt(courseId) || record.CourseId === Number.parseInt(courseId) - }) - - console.log("Отфильтрованный прогресс для курса", courseId, ":", filteredProgress) - - // Находим завершенные подходы (status = 1) и незавершенные (status = 0) - const completedSetsFromServer: number[] = [] - let lastIncompleteSet = null - let lastSavedTime = "00:00" - - // Обрабатываем каждую запись прогресса ТОЛЬКО ДЛЯ ТЕКУЩЕГО КУРСА - filteredProgress.forEach((record: any) => { - console.log( - `Обрабатываем запись для курса ${courseId}: подход ${record.set}, статус ${record.status}, время ${record.time_users}`, - ) - - if (record.status === 1) { - // СТАТУС 1 = подход завершен - completedSetsFromServer.push(record.set) - console.log(`Подход ${record.set} завершен`) - } else if (record.status === 0) { - // СТАТУС 0 = подход в процессе или на паузе - lastIncompleteSet = record - lastSavedTime = record.time_users || "00:00" - console.log(`Подход ${record.set} в процессе, время: ${lastSavedTime}`) - } - }) - - // Восстанавливаем состояние на основе данных с сервера - if (completedSetsFromServer.length > 0) { - console.log("Восстанавливаем завершенные подходы:", completedSetsFromServer) - setCompletedSets(completedSetsFromServer) - } - - // Если есть незавершенный подход, восстанавливаем его состояние - if (lastIncompleteSet) { - console.log("Восстанавливаем незавершенный подход:", lastIncompleteSet.set) - - // Конвертируем время из формата MM:SS в секунды - const timeInSeconds = convertTimeToSeconds(lastSavedTime) - - setCurrentSet(lastIncompleteSet.set) // Устанавливаем текущий подход - setCurrentTime(timeInSeconds) // Восстанавливаем время - setHasSavedProgress(true) // Помечаем что есть сохраненный прогресс - setIsCompleted(false) // Упражнение не завершено - - console.log(`Восстановлено состояние: подход ${lastIncompleteSet.set}, время ${timeInSeconds} секунд`) - } - - // Проверяем, завершены ли все подходы - if (completedSetsFromServer.length >= totalSets) { - console.log("ВСЕ ПОДХОДЫ ЗАВЕРШЕНЫ согласно серверу!") - setIsCompleted(true) // Помечаем упражнение как завершенное - setCurrentTime(totalTime) // Устанавливаем время на максимум - setHasSavedProgress(false) // Сбрасываем флаг сохранения - } - } else { - console.log("Прогресс на сервере не найден, начинаем с чистого листа") - // Если прогресса нет, оставляем начальные значения + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) } - } catch (error) { - console.error("Ошибка при загрузке прогресса с сервера:", error) - // Если произошла ошибка, пытаемся загрузить из localStorage как резервный вариант - console.log("Пытаемся загрузить прогресс из localStorage как резервный вариант") + const data = await response.json() - // Пытаемся получить сохраненный прогресс из памяти браузера для конкретного курса и упражнения - const savedProgress = localStorage.getItem(`exerciseProgress_${courseId}_${exerciseId}`) + // Extract user_progress from server response + const userProgress = data.user_progress || [] - if (savedProgress) { - const progress = JSON.parse(savedProgress) + if (userProgress.length > 0) { + // Find the latest progress entry for current exercise + const latestProgress = userProgress.reduce((latest, current) => { + return new Date(current.updated_at || current.created_at) > new Date(latest.updated_at || latest.created_at) + ? current + : latest + }) - console.log("Найден резервный прогресс в localStorage для курса", courseId, ":", progress) + console.log("Загружен прогресс с сервера:", latestProgress) - if (progress.status === 1) { - // СТАТУС 1 = упражнение было полностью завершено ранее + // Convert server data to component state format + if (latestProgress.status === 1) { + // Exercise completed setIsCompleted(true) - setCurrentTime(progress.totalTime || totalTime) - setCompletedSets(progress.completedSets || []) - setCurrentSet(progress.set || totalSets) + setCurrentTime(totalTime) + setCurrentSet(latestProgress.set || totalSets) + setCompletedSets(Array.from({ length: latestProgress.set || totalSets }, (_, i) => i + 1)) setHasSavedProgress(false) } else { - // СТАТУС 0 = упражнение было на паузе или в процессе выполнения - setCurrentTime(progress.position) - setCurrentSet(progress.set) - setCompletedSets(progress.completedSets || []) - setIsResting(progress.isResting || false) - setRestTime(progress.restTime || 0) - setIsRestPaused(progress.isRestPaused || false) + // Exercise in progress or paused + // Parse time_users string to get current position + const timePosition = parseTimeToSeconds(latestProgress.time_users || "00:00") + setCurrentTime(timePosition) + setCurrentSet(latestProgress.set || 1) + setCompletedSets(Array.from({ length: (latestProgress.set || 1) - 1 }, (_, i) => i + 1)) + setIsResting(false) + setRestTime(0) + setIsRestPaused(false) setHasSavedProgress(true) setIsCompleted(false) } + + return true // Successfully loaded from server } + + return false // No progress found on server + } catch (error) { + console.error("Ошибка при загрузке прогресса с сервера:", error) + return false // Failed to load from server } } - // ========== ФУНКЦИЯ КОНВЕРТАЦИИ ВРЕМЕНИ ИЗ MM:SS В СЕКУНДЫ ========== - // Преобразует время из формата "MM:SS" в секунды (например: "02:30" = 150 секунд) - const convertTimeToSeconds = (timeString: string): number => { - try { - // Разделяем строку по двоеточию - const parts = timeString.split(":") + const parseTimeToSeconds = (timeString) => { + if (!timeString || typeof timeString !== "string") return 0 - if (parts.length === 2) { - const minutes = Number.parseInt(parts[0]) || 0 // Получаем минуты - const seconds = Number.parseInt(parts[1]) || 0 // Получаем секунды - const totalSeconds = minutes * 60 + seconds // Конвертируем в секунды - - console.log(`Конвертируем время ${timeString} в ${totalSeconds} секунд`) - return totalSeconds - } else { - console.warn("Неверный формат времени:", timeString) - return 0 - } - } catch (error) { - console.error("Ошибка при конвертации времени:", error) - return 0 + const parts = timeString.split(":") + if (parts.length === 2) { + const minutes = Number.parseInt(parts[0]) || 0 + const seconds = Number.parseInt(parts[1]) || 0 + return minutes * 60 + seconds } + return 0 } // ========== ФУНКЦИЯ СОХРАНЕНИЯ ПРОГРЕССА ПОДХОДА НА СЕРВЕР ==========