надо решить проблему с роутингом по упражнениям курса / у нас должны учитываться дни, т.к. массив упражнений фильтруется по дням и маршруты неверные получаются
This commit is contained in:
parent
2b9c198e44
commit
f9e5d3614a
@ -15,6 +15,7 @@ import type { Course } from "../pages/Courses";
|
||||
// import { Exercise } from "./Exercise";
|
||||
|
||||
export interface CourseExercises {
|
||||
id: number;
|
||||
id_course: number;
|
||||
id_exercise: number;
|
||||
exercise: Exercise;
|
||||
@ -42,6 +43,8 @@ export const CourseExercises = () => {
|
||||
const [course_exercises, setExercises] = useState<CourseExercises[]>([]);
|
||||
const [selectedDay, setSelectedDay] = useState<number | null>(null);
|
||||
|
||||
|
||||
|
||||
const token = localStorage.getItem('authToken');
|
||||
|
||||
useEffect(() => {
|
||||
@ -60,13 +63,10 @@ export const CourseExercises = () => {
|
||||
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Response status:', response.status);
|
||||
console.log('Данные страницы упражнения курса:', response.data);
|
||||
// setPacientData(response.data);
|
||||
console.log('Данные упражнения курса:', response.data.course_exercises);
|
||||
|
||||
setExercises(response.data.course_exercises);
|
||||
|
||||
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response) {
|
||||
@ -88,27 +88,6 @@ export const CourseExercises = () => {
|
||||
}
|
||||
}, [course_exercises]);
|
||||
|
||||
//Этот код — это React-хук useEffect, который выполняет определённый блок кода при изменении зависимостей. Давайте разберём его подробно:
|
||||
//Он следит за изменением массива course_exercises. Когда course_exercises обновляется (например, загружается с сервера или изменяется), он проверяет:
|
||||
|
||||
// Есть ли в массиве упражнения (course_exercises.length > 0)
|
||||
// И выбран ли уже день (selectedDay === null)
|
||||
// Если оба условия выполняются, то:
|
||||
|
||||
// Устанавливает selectedDay в значение day первого элемента массива course_exercises[0].
|
||||
// Почему это нужно?
|
||||
// Это логика инициализации:
|
||||
|
||||
// Когда данные о упражнениях загружены впервые, и пользователь ещё не выбрал день (selectedDay равен null),
|
||||
// автоматически выбирается первый день из загруженных упражнений.
|
||||
// Почему [course_exercises] в конце?
|
||||
// Это массив зависимостей. Он говорит React:
|
||||
|
||||
// Запускать этот эффект только тогда, когда course_exercises изменится.
|
||||
|
||||
// Без этого эффекта он бы запускался при каждом рендере, что нежелательно.
|
||||
|
||||
|
||||
const uniqueDays = Array.from(new Set(course_exercises.map(ex => ex.day))).sort((a, b) => a - b);
|
||||
|
||||
const dayMap: { [key: number]: number } = {};
|
||||
@ -125,13 +104,12 @@ export const CourseExercises = () => {
|
||||
? course_exercises.filter(ex => ex.day === selectedDay)
|
||||
: course_exercises;
|
||||
|
||||
|
||||
console.log('отфильтрованный список по дням',filteredExercises)
|
||||
|
||||
return (
|
||||
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
||||
<HeaderNav item={course?.title ?? 'Название курса'} text={'курс'} />
|
||||
{/* Это выражение использует оператор опциональной цепочки (?.) и оператор нулевого слияния (??).
|
||||
Если course не null и не undefined, то взять его свойство title, иначе — вернуть undefined*/}
|
||||
|
||||
<div className="px-6 mb-8">
|
||||
{/* Заголовок секции */}
|
||||
<div className="flex flex-col sm:flex-row justify-between content-center mb-6">
|
||||
@ -147,10 +125,13 @@ export const CourseExercises = () => {
|
||||
<div className="mb-6">
|
||||
<div className="flex flex-wrap gap-2 overflow-x-auto pb-2">
|
||||
{days.map((day, index) => (
|
||||
|
||||
|
||||
<button
|
||||
key={day}
|
||||
onClick={() => {
|
||||
setSelectedDay(day);
|
||||
|
||||
}}
|
||||
className={`flex-shrink-0 px-4 py-2 rounded-full text-xs sm:text-sm font-semibold transition-all duration-300 inline-block ${selectedDay === day
|
||||
? "bg-[#2BACBE] text-white shadow-lg"
|
||||
@ -167,11 +148,21 @@ export const CourseExercises = () => {
|
||||
|
||||
|
||||
<div className="exercise-list mb-20">
|
||||
{filteredExercises.length > 0 ? (
|
||||
{
|
||||
|
||||
|
||||
filteredExercises.length > 0 ? (
|
||||
filteredExercises.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
onClick={() => history.push(getRouteExercise(item.id_course.toString(), item.id_exercise.toString()))}
|
||||
onClick={() => {
|
||||
|
||||
// console.log(course_exercises.map(ex => ex.id_exercise))
|
||||
|
||||
|
||||
// Передаем id_course и индекс из полного массива
|
||||
history.push(getRouteExercise(item.id_course.toString(), item.id_exercise.toString()));
|
||||
}}
|
||||
className="p-4 mb-4 cursor-pointer hover:scale-105 transition duration-300 glass-morphism rounded-3xl border border-white/50 shadow-2xl overflow-hidden backdrop-blur-2xl relative">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
|
@ -28,7 +28,7 @@ export interface Exercise {
|
||||
sessionname: string // Название тренировочной сессии
|
||||
}
|
||||
|
||||
// Описываем параметры, которые приходят из URL страницы
|
||||
|
||||
interface RouteParams {
|
||||
courseId: string // ID курса (программы тренировок)
|
||||
exerciseId: string // ID конкретного упражнения
|
||||
@ -38,41 +38,14 @@ export const Exercise = () => {
|
||||
// Получаем функции для навигации и параметры из URL
|
||||
const history = useHistory()
|
||||
const { courseId, exerciseId } = useParams<RouteParams>()
|
||||
|
||||
// ========== ОСНОВНЫЕ СОСТОЯНИЯ КОМПОНЕНТА ==========
|
||||
// Состояние для хранения данных упражнения (null = данные еще не загружены)
|
||||
// Мы говорим TypeScript, что переменная exercise может быть либо объектом типа Exercise, либо null. Это важно, потому что изначально у нас нет данных (например, мы их ещё не загрузили), и состояние пустое — null
|
||||
|
||||
|
||||
// exercise — это переменная/ текущее значение состояния, которое может быть объектом Exercise или null.
|
||||
// setExercise — функция, с помощью которой можно обновить exercise.
|
||||
|
||||
|
||||
// useState<string>("") — это вызов функции useState с аргументом "" (пустая строка).
|
||||
// Внутри угловых скобок <string> мы указываем тип состояния (TypeScript).
|
||||
// В круглых скобках ("") — передаём начальное значение состояния.
|
||||
|
||||
const [exercise, setExercise] = useState<Exercise | null>(null)
|
||||
// useState<Exercise | null>(null) — это вызов функции useState с начальным значением null
|
||||
|
||||
// Состояние загрузки (true = идет загрузка, false = загрузка завершена)
|
||||
const [loading, setLoading] = useState(true)
|
||||
// если TypeScript может сам вывести тип из переданного начального значения, то указывать тип явно не обязательно
|
||||
|
||||
// Состояние ошибки (пустая строка = нет ошибки, текст = описание ошибки)
|
||||
// С помощью ДЕСТРУКТУРИЗАЦИИ МАССИВА мы присваиваем первый элемент массива переменной error, а второй — функции setError
|
||||
// Деструктуризация массива — это удобный синтаксис в JavaScript/TypeScript, который позволяет распаковать значения из массива в отдельные переменные
|
||||
// Когда начальное значение — null или undefined, и TypeScript не может понять, какого типа будет состояние.
|
||||
const [error, setError] = useState<string>("")
|
||||
|
||||
// ========== СОСТОЯНИЯ ТАЙМЕРУ УПРАЖНЕНИЯ ==========
|
||||
// Играет ли сейчас таймер упражнения (true = идет, false = на паузе)
|
||||
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
|
||||
// Текущее время выполнения упражнения в секундах (0 = начало)
|
||||
const [currentTime, setCurrentTime] = useState(0)
|
||||
|
||||
// Общее время упражнения в секундах (по умолчанию 15 минут = 900 секунд)
|
||||
const [totalTime, setTotalTime] = useState(900)
|
||||
|
||||
// ========== СОСТОЯНИЯ ПОДХОДОВ (СЕТОВ) ==========
|
||||
|
@ -4,7 +4,7 @@ export const getRouteHome = () => `/home`
|
||||
export const getRouteForgotPassword = () => `/forgot-password`
|
||||
export const getRouteCourses = () => `/courses`
|
||||
export const getRouteCourseExercises = (id: number | string) => `/course/${id}`
|
||||
export const getRouteExercise = (courseId: number | string, exerciseId: number | string) =>
|
||||
`/course/${courseId}/${exerciseId}`
|
||||
export const getRouteExercise = (courseId: number | string, day: number | string, exerciseId: number | string) =>
|
||||
`/course/${courseId}/${day}/${exerciseId}`
|
||||
export const getRouteSettings = () => `/settings`
|
||||
export const getRouteCourseComplete = () => `/course-complete`
|
||||
|
Loading…
x
Reference in New Issue
Block a user