178 lines
5.8 KiB
TypeScript
178 lines
5.8 KiB
TypeScript
"use client"
|
||
|
||
import { useState, useEffect } from "react"
|
||
import { useParams, useHistory, useLocation } from "react-router-dom"
|
||
|
||
import HeaderNav from "../components/HeaderNav"
|
||
import BottomNavigation from "../components/BottomNavigation"
|
||
|
||
import { connect } from "../confconnect"
|
||
|
||
import { getRouteExerciseByIndex } from "../shared/consts/router"
|
||
import { ArrowIcon } from "../components/icons/ArrowIcon"
|
||
|
||
import type { Course } from "../pages/Courses"
|
||
|
||
export interface CourseExercises {
|
||
id: number
|
||
id_course: number
|
||
id_exercise: number
|
||
exercise: Exercise
|
||
day: number
|
||
position: number
|
||
repeats: number
|
||
time: string
|
||
DeletedAt: string | null
|
||
}
|
||
|
||
interface Exercise {
|
||
id: number
|
||
title: string
|
||
}
|
||
|
||
export const CourseExercises = () => {
|
||
const history = useHistory()
|
||
const { id } = useParams<{ id: string }>()
|
||
|
||
const location = useLocation<{ course?: Course }>()
|
||
const course = location.state?.course
|
||
|
||
const [course_exercises, setExercises] = useState<CourseExercises[]>([])
|
||
const [selectedDay, setSelectedDay] = useState<number | null>(null)
|
||
|
||
const token = localStorage.getItem("authToken")
|
||
|
||
useEffect(() => {
|
||
console.log(token)
|
||
if (!token) {
|
||
console.log("Токен не найден")
|
||
return
|
||
}
|
||
|
||
connect
|
||
.get(`/pacient/${id}`, {
|
||
headers: {
|
||
Authorization: `Bearer ${token}`,
|
||
"Content-Type": "application/json",
|
||
},
|
||
})
|
||
.then((response) => {
|
||
console.log("Данные упражнения курса:", response.data.course_exercises)
|
||
setExercises(response.data.course_exercises)
|
||
})
|
||
.catch((error) => {
|
||
if (error.response) {
|
||
console.error("Ошибка ответа сервера:", error.response.status, error.response.data)
|
||
} else if (error.request) {
|
||
console.error("Нет ответа от сервера:", error.request)
|
||
} else {
|
||
console.error("Ошибка при настройке запроса:", error.message)
|
||
}
|
||
})
|
||
}, [])
|
||
|
||
useEffect(() => {
|
||
if (course_exercises.length > 0 && selectedDay === null) {
|
||
setSelectedDay(course_exercises[0].day)
|
||
}
|
||
}, [course_exercises])
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const uniqueDays = Array.from(new Set(course_exercises.map((ex) => ex.day))).sort((a, b) => a - b)
|
||
const dayMap: { [key: number]: number } = {}
|
||
|
||
uniqueDays.forEach((day, index) => {
|
||
dayMap[day] = index + 1
|
||
})
|
||
|
||
console.log('Уникальные дни', uniqueDays)
|
||
|
||
const daysNav = uniqueDays.map((day) => dayMap[day])
|
||
|
||
const days = Array.from(new Set(course_exercises.map((ex) => ex.day))).sort((a, b) => a - b)
|
||
|
||
const filteredExercises =
|
||
selectedDay !== null ? 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={"курс"} />
|
||
|
||
<div className="px-6 mb-8">
|
||
<div className="flex flex-col sm:flex-row justify-between content-center mb-6">
|
||
<h2 className="text-xl font-black text-[#5F5C5C]">Упражнения</h2>
|
||
<span className="text-sm text-gray-500">Количество упражнений: {course_exercises.length}</span>
|
||
</div>
|
||
|
||
{days.length > 1 && (
|
||
<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"
|
||
: "bg-white text-gray-600 hover:bg-gray-100"
|
||
}`}
|
||
>
|
||
День {daysNav[index]}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className="exercise-list mb-20">
|
||
{filteredExercises.length > 0 ? (
|
||
filteredExercises.map((item, index) => (
|
||
<div
|
||
key={index}
|
||
onClick={() => {
|
||
history.push(
|
||
getRouteExerciseByIndex(
|
||
item.id_course.toString(),
|
||
index, // Используем индекс из отфильтрованного массива
|
||
selectedDay || undefined, // Передаем выбранный день для контекста
|
||
),
|
||
)
|
||
}}
|
||
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>
|
||
<h3 className="text-xs sm:text-base">Упражнение {index + 1}</h3>
|
||
<h3 className="text-base sm:text-xl font-semibold text-gray-600">{item.exercise.title}</h3>
|
||
</div>
|
||
<ArrowIcon className="text-cyan-600" />
|
||
</div>
|
||
|
||
<div className="h-0.5 w-full bg-gray-200 my-3"></div>
|
||
|
||
<div className="flex gap-10 text-xs text-gray-500">
|
||
<p>Повторений: {item.repeats}</p>
|
||
<p>Время выполнения: {item.time}</p>
|
||
</div>
|
||
</div>
|
||
))
|
||
) : (
|
||
<p>Нет упражнений для отображения</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
<BottomNavigation />
|
||
</div>
|
||
)
|
||
}
|