From cdd62757fc15f219ff925063d236bd723042577b Mon Sep 17 00:00:00 2001 From: Tatyana Date: Mon, 25 Aug 2025 15:05:01 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D1=8B=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=20id=20=D0=BA=D1=83=D1=80=D1=81=D0=B0=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=83=20=D0=BA=D1=83?= =?UTF-8?q?=D1=80=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AppRoutes.tsx | 16 +- src/pages/CourseExercises.tsx | 273 ++++++++------------------- src/pages/CourseExercises_ old.tsx | 288 +++++++++++++++++++++++++++++ src/pages/Courses.tsx | 3 + src/shared/consts/router.ts | 2 +- ответы сервера | 17 +- 6 files changed, 396 insertions(+), 203 deletions(-) create mode 100644 src/pages/CourseExercises_ old.tsx diff --git a/src/AppRoutes.tsx b/src/AppRoutes.tsx index 1e58496..ec8b644 100644 --- a/src/AppRoutes.tsx +++ b/src/AppRoutes.tsx @@ -5,8 +5,8 @@ import Login from "./pages/Login"; import Home from "./pages/Home"; import ForgotPasword from "./pages/ForgotPassword"; import { Courses } from "./pages/Courses"; -import { CourseExercises } from "./pages/CourseExercises"; -import { Exercise } from "./pages/Exercise"; +import CourseExercises from "./pages/CourseExercises"; + import Settings from "./pages/Settings"; import CourseComplete from "./pages/CourseComplete"; @@ -15,8 +15,8 @@ import { getRouteLogin } from "./shared/consts/router"; import { getRouteHome } from "./shared/consts/router"; import { getRouteForgotPassword } from "./shared/consts/router"; import { getRouteCourses } from "./shared/consts/router"; -import { getRouteCourseExercises } from "./shared/consts/router"; -import { getRouteExercise } from "./shared/consts/router"; + + import { getRouteSettings } from "./shared/consts/router"; import { getRouteCourseComplete } from "./shared/consts/router"; @@ -31,10 +31,14 @@ const AppRoutes = () => ( - - + + + + + + ); diff --git a/src/pages/CourseExercises.tsx b/src/pages/CourseExercises.tsx index efebf37..5dab2de 100644 --- a/src/pages/CourseExercises.tsx +++ b/src/pages/CourseExercises.tsx @@ -1,7 +1,8 @@ "use client" -import { useState } from "react" -import { useHistory } from "react-router-dom" +import type React from "react" +import { useState, useEffect } from "react" +import { useHistory, useParams } from "react-router-dom" import HeaderNav from "../components/HeaderNav" import BottomNavigation from "../components/BottomNavigation" @@ -9,214 +10,100 @@ import video from "../assets/img/video.mov" import { connect } from '../confconnect'; import { getRouteExercise } from "../shared/consts/router" +import type { Exercise } from "./Exercise" -export const CourseExercises = () => { + +interface RouteParams { + id: string; + title: string; +} + +const CourseExercises: React.FC =() => { const history = useHistory() - // const { id } = useParams<{ id: string }>(); - const [currentSlide, setCurrentSlide] = useState(0) + const { id } = useParams(); // получаем ID курса из URL + const { title } = useParams(); // получаем ID курса из URL + const [currentSlide, setCurrentSlide] = useState(0); + const token = localStorage.getItem('authToken'); + + + useEffect(() => { + console.log(token) + if (!token) { + setError('Токен не найден'); + return; + } + + connect.get(`/pacient/${id}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }) + .then(response => { + console.log('Response status:', response.status); + console.log('') + + // Предполагаемая структура: + // response.data.courses — массив пользователей + const exercises = response.data.exercises || []; + + // Собираем все курсы из всех пользователей + const allCourse: Exercises[] = []; + + users.forEach(user => { + if (user.Courses && Array.isArray(user.Courses)) { + user.Courses.forEach(course => { + // Можно добавить проверку или преобразование + allCourses.push({ + ID: course.id, // или course.ID, зависит от структуры + title: course.title, + desc: course.desc, + url_file_img: course.url_file_img, + }); + }); + } + }); + + setCourses(allCourses); + }) + .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}`); + } + }); + }, [token]); -const course = { - id: 2, - description: 'Очень сильно', - name: 'Качаем ноги', - exercises: [ - { - id: 1, - name: "Подъемы ног лежа", - duration: "15 мин", - sets: 3, - reps: 12, - image: "/placeholder.svg?height=200&width=300", - difficulty: "Легкий", - description: "Укрепление мышц бедра и улучшение подвижности коленного сустава", - calories: 45, - }, - { - id: 2, - name: "Приседания у стены", - duration: "10 мин", - sets: 2, - reps: 15, - image: "/placeholder.svg?height=200&width=300", - difficulty: "Средний", - description: "Безопасные приседания для восстановления силы ног", - calories: 60, - }, - { - id: 3, - name: "Растяжка квадрицепса", - duration: "8 мин", - sets: 1, - reps: 30, - image: "/placeholder.svg?height=200&width=300", - difficulty: "Легкий", - description: "Улучшение гибкости и снятие напряжения", - calories: 25, - }, - { - id: 4, - name: "Укрепление икр", - duration: "12 мин", - sets: 3, - reps: 20, - image: "/placeholder.svg?height=200&width=300", - difficulty: "Средний", - description: "Развитие силы и выносливости икроножных мышц", - calories: 40, - }, - ]} - // Функции для переключения на следующее/предыдущее упражнение - const nextExercise = () => { - setCurrentSlide((prev) => (prev + 1) % course.exercises.length) - } - const prevExercise = () => { - setCurrentSlide((prev) => (prev - 1 + course.exercises.length) % course.exercises.length) - } - const currentExercise = course.exercises[currentSlide] - // const getDifficultyColor = (difficulty: string) => { - // switch (difficulty) { - // case "Легкий": - // return "bg-gradient-to-r from-emerald-400 to-green-500" - // case "Средний": - // return "bg-gradient-to-r from-amber-400 to-orange-500" - // case "Сложный": - // return "bg-gradient-to-r from-red-400 to-pink-500" - // default: - // return "bg-gradient-to-r from-gray-400 to-gray-500" - // } - // } return ( - - -
+
- + +
+

Курс ID: {id}

+ - - {/* Exercise Slider */} -
-
- {/* Exercise Image */} -
-
- - {/* Exercise Info */} -
-

{currentExercise.name}

- - - - -
-
- - {/* Slide indicators */} -
- {course.exercises.map((_, index) => ( -
-
- - {/* Exercise List */} -
-

Все упражнения курса

-
- {course.exercises.map((exercise, index) => ( -
history.push(getRouteExercise(currentExercise.id))} - className={`glass-morphism rounded-2xl p-4 sm:p-6 border border-white/50 shadow-lg cursor-pointer transition-all duration-300 hover:shadow-2xl transform hover:scale-[1.02] backdrop-blur-xl ${index === currentSlide ? "ring-2 ring-[#2BACBE] bg-cyan-50/20" : "" - }`} - > -
-
-
- {index + 1} -
- -
-
-

{exercise.name}

-

{exercise.description}

- -
-
- - - -
-
-
- ))} -
-
+ {/* тут можете использовать id для загрузки данных или другого */} +
-
- ) -} +
+ ); +}; +export default CourseExercises; \ No newline at end of file diff --git a/src/pages/CourseExercises_ old.tsx b/src/pages/CourseExercises_ old.tsx new file mode 100644 index 0000000..dc03f4f --- /dev/null +++ b/src/pages/CourseExercises_ old.tsx @@ -0,0 +1,288 @@ +"use client" + +import { useState, useEffect } from "react" +import { useHistory, useParams } from "react-router-dom" + +import HeaderNav from "../components/HeaderNav" +import BottomNavigation from "../components/BottomNavigation" +import video from "../assets/img/video.mov" + +import { connect } from '../confconnect'; +import { getRouteExercise } from "../shared/consts/router" + +interface CourseExercise { + ID: number; + title: string; + desc: string; + url_file_img: string; +} + + + + +export const CourseExercises = () => { + const history = useHistory() + // const { id } = useParams<{ id: string }>(); + const [currentSlide, setCurrentSlide] = useState(0); + const token = localStorage.getItem('authToken'); + + useEffect(() => { + console.log(token) + if (!token) { + setError('Токен не найден'); + return; + } + + connect.get('/pacient/', { + headers: { + Authorization: `Bearer ${token}`, + }, + }) + .then(response => { + console.log('Response status:', response.status); + + // Предполагаемая структура: + // response.data.courses — массив пользователей + const users = response.data.courses || []; + + // Собираем все курсы из всех пользователей + const allCourses: Course[] = []; + + users.forEach(user => { + if (user.Courses && Array.isArray(user.Courses)) { + user.Courses.forEach(course => { + // Можно добавить проверку или преобразование + allCourses.push({ + ID: course.id, // или course.ID, зависит от структуры + title: course.title, + desc: course.desc, + url_file_img: course.url_file_img, + }); + }); + } + }); + + setCourses(allCourses); + }) + .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}`); + } + }); + }, [token]); + + +const course = { + id: 2, + description: 'Очень сильно', + name: 'Качаем ноги', + exercises: [ + { + id: 1, + name: "Подъемы ног лежа", + duration: "15 мин", + sets: 3, + reps: 12, + image: "/placeholder.svg?height=200&width=300", + difficulty: "Легкий", + description: "Укрепление мышц бедра и улучшение подвижности коленного сустава", + calories: 45, + }, + { + id: 2, + name: "Приседания у стены", + duration: "10 мин", + sets: 2, + reps: 15, + image: "/placeholder.svg?height=200&width=300", + difficulty: "Средний", + description: "Безопасные приседания для восстановления силы ног", + calories: 60, + }, + { + id: 3, + name: "Растяжка квадрицепса", + duration: "8 мин", + sets: 1, + reps: 30, + image: "/placeholder.svg?height=200&width=300", + difficulty: "Легкий", + description: "Улучшение гибкости и снятие напряжения", + calories: 25, + }, + { + id: 4, + name: "Укрепление икр", + duration: "12 мин", + sets: 3, + reps: 20, + image: "/placeholder.svg?height=200&width=300", + difficulty: "Средний", + description: "Развитие силы и выносливости икроножных мышц", + calories: 40, + }, + ]} + + // Функции для переключения на следующее/предыдущее упражнение + const nextExercise = () => { + setCurrentSlide((prev) => (prev + 1) % course.exercises.length) + } + + const prevExercise = () => { + setCurrentSlide((prev) => (prev - 1 + course.exercises.length) % course.exercises.length) + } + const currentExercise = course.exercises[currentSlide] + + // const getDifficultyColor = (difficulty: string) => { + // switch (difficulty) { + // case "Легкий": + // return "bg-gradient-to-r from-emerald-400 to-green-500" + // case "Средний": + // return "bg-gradient-to-r from-amber-400 to-orange-500" + // case "Сложный": + // return "bg-gradient-to-r from-red-400 to-pink-500" + // default: + // return "bg-gradient-to-r from-gray-400 to-gray-500" + // } + // } + + return ( + + + + +
+
+ + + + + {/* Exercise Slider */} +
+
+ {/* Exercise Image */} +
+
+ + {/* Exercise Info */} +
+

{currentExercise.name}

+ + + + +
+
+ + {/* Slide indicators */} +
+ {course.exercises.map((_, index) => ( +
+
+ + + + + + {/* Exercise List */} +
+

Все упражнения курса

+
+ {course.exercises.map((exercise, index) => ( +
history.push(getRouteExercise(currentExercise.id))} + className={`glass-morphism rounded-2xl p-4 sm:p-6 border border-white/50 shadow-lg cursor-pointer transition-all duration-300 hover:shadow-2xl transform hover:scale-[1.02] backdrop-blur-xl ${index === currentSlide ? "ring-2 ring-[#2BACBE] bg-cyan-50/20" : "" + }`} + > +
+
+
+ {index + 1} +
+ +
+
+

{exercise.name}

+

{exercise.description}

+ +
+
+ + + +
+
+
+ ))} +
+
+ + +
+
+ ) +} + + diff --git a/src/pages/Courses.tsx b/src/pages/Courses.tsx index 7f152c1..e604605 100644 --- a/src/pages/Courses.tsx +++ b/src/pages/Courses.tsx @@ -98,6 +98,9 @@ export const Courses = () => { }); }, [token]); + + + // Генерируем случайный прогресс для каждого курса const getRandomProgress = () => Math.floor(Math.random() * 100); diff --git a/src/shared/consts/router.ts b/src/shared/consts/router.ts index a8aa86a..d79cbc7 100644 --- a/src/shared/consts/router.ts +++ b/src/shared/consts/router.ts @@ -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}/exercises`; +export const getRouteCourseExercises = (id: number | string) => `/course/${id}`; export const getRouteExercise = (id: number | string) => `/exercise/${id}`; export const getRouteSettings = () => `/settings`; diff --git a/ответы сервера b/ответы сервера index 9cc9e20..b370c3a 100644 --- a/ответы сервера +++ b/ответы сервера @@ -70,6 +70,17 @@ curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8093/pacient/courses "sessionname": "krasnova@mail.ru" - curl -X GET \ - -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTYxMTEyNDQsInVzZXJfZW1haWwiOiJrcmFzbm92YUBtYWlsLnJ1IiwidXNlcl9pZCI6MjUsInVzZXJfbmFtZSI6ImtyYXNub3ZhQG1haWwucnUiLCJ1c2VyX3JvbGUiOiIifQ.3UyamwJrLVkdjKgUG16lYyKm1jiZAv6MRQW0Tj2Z3Tc" \ - http://localhost:8093/pacient/courses/:course_id \ No newline at end of file +curl -L -X GET \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTYxMTUzMTAsInVzZXJfZW1haWwiOiJrcmFzbm92YUBtYWlsLnJ1IiwidXNlcl9pZCI6MjUsInVzZXJfbmFtZSI6ImtyYXNub3ZhQG1haWwucnUiLCJ1c2VyX3JvbGUiOiIifQ.fkP4uDp9TylgLcVZlb5Zs7Po48DdBk42E0Xf1sHsMwk" \ + http://localhost:8093/pacient/courses/ + + ПОИСК ВНУТРИ КУРСА + + curl -L -X GET \\ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTYxMTUzMTAsInVzZXJfZW1haWwiOiJrcmFzbm92YUBtYWlsLnJ1IiwidXNlcl9pZCI6MjUsInVzZXJfbmFtZSI6ImtyYXNub3ZhQG1haWwucnUiLCJ1c2VyX3JvbGUiOiIifQ.fkP4uDp9TylgLcVZlb5Zs7Po48DdBk42E0Xf1sHsMwk" \ + http://localhost:8093/pacient/1 + + + curl -L -X GET \ + -H "Authorization: Bearer YOUR_JWT_TOKEN" \ + http://localhost:8093/pacient/course/1/ \ No newline at end of file