"use client" import { useEffect, useState } from "react" import { useHistory } from "react-router-dom" // import { useParams } from "react-router-dom" import { CalendarIcon } from "../components/icons/CalendarIcon" import { DumbbellIcon } from "../components/icons/DumbbellIcon" import HeaderNav from "../components/HeaderNav" import BottomNavigation from "../components/BottomNavigation" import CircularProgressDisplay from "../components/CircularProgressDisplay" import { StatCardHome } from "../components/cards/StatCardHome" import { WorkoutCardHome } from "../components/cards/WorkoutCardHome" import { connect } from "../confconnect" import { getRouteExerciseByIndex } from "../shared/consts/router" import { getRouteCourses } from "../shared/consts/router" import { getRouteCourseExercises } from "../shared/consts/router" import type { Course, User, CoursesApiResponse } from "../types/course" interface CourseExercises { id_exercise: number day: number position: number title: string desc: string time: string count: number repeats: number } interface CurrentExercise { courseId: string exerciseId: string exerciseIndex: number day: number title: string position: number isCompleted: boolean } interface ProgressStats { completedExercises: number totalExercises: number completedCourses: number totalCourses: number overallProgress: number } export default function Home() { const history = useHistory() const [currentDate, setCurrentDate] = useState("") const [error, setError] = useState("") const [courses, setCourses] = useState([]) const [loading, setLoading] = useState(true) const [currentExercise, setCurrentExercise] = useState(null) const [loadingCurrentExercise, setLoadingCurrentExercise] = useState(false) const [progressStats, setProgressStats] = useState({ completedExercises: 0, totalExercises: 0, completedCourses: 0, totalCourses: 0, overallProgress: 0, }) const token = localStorage.getItem("authToken") const calculateProgressStats = async (coursesList: Course[]): Promise => { let totalExercises = 0 let completedExercises = 0 let completedCourses = 0 for (const course of coursesList) { try { // Получаем упражнения для каждого курса const response = await connect.get(`/pacient/${course.id}`, { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }) console.log("!получили по запросу", response.data) //упражнения курса const exercises = response.data.course_exercises || [] totalExercises += exercises.length let courseCompletedExercises = 0 // Проверяем каждое упражнение на завершенность for (const exercise of exercises) { const storageKey = `exerciseProgress_${course.id}_${exercise.id_exercise}_day_${exercise.day}` const savedProgress = localStorage.getItem(storageKey) if (savedProgress) { const progress = JSON.parse(savedProgress) const isCompleted = progress.status === 1 && progress.completedSets && progress.completedSets.length >= exercise.count if (isCompleted) { completedExercises++ courseCompletedExercises++ } } } // Курс считается завершенным если все упражнения выполнены if (exercises.length > 0 && courseCompletedExercises === exercises.length) { completedCourses++ } } catch (error) { console.error(`Ошибка при получении упражнений для курса ${course.id}:`, error) // Если не удалось загрузить упражнения, считаем что в курсе 0 упражнений } } const overallProgress = totalExercises > 0 ? Math.round((completedExercises / totalExercises) * 100) : 0 return { completedExercises, totalExercises, completedCourses, totalCourses: coursesList.length, overallProgress, } } const getCurrentExercise = async () => { if (courses.length === 0) return setLoadingCurrentExercise(true) try { let targetCourse: Course | null = null // Проходим по всем курсам и ищем незавершенный for (const course of courses) { // Загружаем упражнения для каждого курса const response = await connect.get(`/pacient/${course.id}`, { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }) const exercises = response.data.course_exercises || [] if (exercises.length === 0) continue // Пропускаем курсы без упражнений // Проверяем, есть ли незавершенные упражнения в этом курсе let hasIncompleteExercises = false let completedCount = 0 for (const exercise of exercises) { const storageKey = `exerciseProgress_${course.id}_${exercise.id_exercise}_day_${exercise.day}` const savedProgress = localStorage.getItem(storageKey) let isCompleted = false if (savedProgress) { const progress = JSON.parse(savedProgress) isCompleted = progress.status === 1 && progress.completedSets && progress.completedSets.length >= exercise.count } if (isCompleted) { completedCount++ } else { hasIncompleteExercises = true } } // Если в курсе есть незавершенные упражнения, выбираем его if (hasIncompleteExercises) { targetCourse = course break // Берем первый найденный незавершенный курс } } // Если все курсы завершены, берем последний курс if (!targetCourse && courses.length > 0) { targetCourse = courses[courses.length - 1] } if (!targetCourse) { setCurrentExercise(null) return } // Загружаем упражнения выбранного курса const response = await connect.get(`/pacient/${targetCourse.id}`, { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }) const exercises = response.data.course_exercises || [] if (exercises.length === 0) { setCurrentExercise(null) return } // Группируем упражнения по дням const exercisesByDay = exercises.reduce((acc: any, exercise: CourseExercises) => { if (!acc[exercise.day]) { acc[exercise.day] = [] } acc[exercise.day].push(exercise) return acc }, {}) // Ищем первое незавершенное упражнение let foundExercise: CurrentExercise | null = null for (const day of Object.keys(exercisesByDay).sort((a, b) => Number(a) - Number(b))) { const dayExercises = exercisesByDay[day].sort( (a: CourseExercises, b: CourseExercises) => a.position - b.position, ) for (let i = 0; i < dayExercises.length; i++) { const exercise = dayExercises[i] // Проверяем прогресс упражнения в localStorage const storageKey = `exerciseProgress_${targetCourse.id}_${exercise.id_exercise}_day_${day}` const savedProgress = localStorage.getItem(storageKey) let isCompleted = false if (savedProgress) { const progress = JSON.parse(savedProgress) isCompleted = progress.status === 1 && progress.completedSets && progress.completedSets.length >= exercise.count } if (!isCompleted) { foundExercise = { courseId: targetCourse.id.toString(), exerciseId: exercise.id_exercise.toString(), exerciseIndex: i, day: Number(day), title: exercise.title, position: exercise.position, isCompleted: false, } break } } if (foundExercise) break } // Если все упражнения завершены, берем последнее if (!foundExercise && exercises.length > 0) { const lastExercise = exercises[exercises.length - 1] foundExercise = { courseId: targetCourse.id.toString(), exerciseId: lastExercise.id_exercise.toString(), exerciseIndex: exercises.length - 1, day: lastExercise.day, title: lastExercise.title, position: lastExercise.position, isCompleted: true, } } setCurrentExercise(foundExercise) } catch (error) { console.error("Ошибка при получении текущего упражнения:", error) } finally { setLoadingCurrentExercise(false) } } useEffect(() => { console.log(token) if (!token) { setError("Токен не найден") setLoading(false) return } setCurrentDate( new Date().toLocaleDateString("ru-RU", { year: "numeric", month: "long", day: "numeric", }), ) setLoading(true) connect .get("/pacient/courses") .then((response) => { console.log("Response data:", response.data) const users = response.data.courses || [] const allCourses: Course[] = [] users.forEach((user: User) => { if (user.Courses && Array.isArray(user.Courses)) { user.Courses.forEach((course) => { allCourses.push({ id: course.id, title: course.title, desc: course.desc, url_file_img: course.url_file_img, course_exercises: course.course_exercises, }) }) } }) setCourses(allCourses) setError("") }) .catch((error) => { if (error.response) { console.error("Ошибка ответа сервера:", error.response.status, error.response.data) setError(`Ошибка сервера: ${error.response.status}`) } else if (error.request) { console.error("Нет ответа от сервера:", error.request) setError("Нет ответа от сервера") } else { console.error("Ошибка при настройке запроса:", error.message) setError(`Ошибка: ${error.message}`) } }) .finally(() => { setLoading(false) }) }, [token]) useEffect(() => { if (courses.length > 0 && !loading) { getCurrentExercise() calculateProgressStats(courses).then((stats) => { setProgressStats(stats) }) } }, [courses, loading]) const handleWorkoutClick = () => { if (currentExercise) { // Используем правильный роут с day параметром history.push( getRouteExerciseByIndex(currentExercise.courseId, currentExercise.exerciseIndex, currentExercise.day), ) } else { // Fallback если нет текущего упражнения history.push(getRouteExerciseByIndex(1, 0, 1)) } } const handleBackClick = () => { history.goBack() } const handleCoursesClick = () => { history.push(getRouteCourses()) } const handleExercisesClick = () => { if (currentExercise) { // Используем courseId из текущего упражнения (незавершенный курс) history.push(getRouteCourseExercises(Number.parseInt(currentExercise.courseId))) } else if (courses.length > 0) { // Fallback к первому курсу если нет текущего упражнения history.push(getRouteCourseExercises(courses[0].id)) } else { // Fallback к странице курсов если нет курсов history.push(getRouteCourses()) } } if (loading) { return (
Загрузка данных...
) } return (
Все курсы
{progressStats.completedCourses}/{progressStats.totalCourses}
Все упражнения
{progressStats.completedExercises}/{progressStats.totalExercises}
) }