вывод номера дня в шапке на странице отдельного упражнения
This commit is contained in:
parent
8029d6907f
commit
28c7d6d0f8
@ -1,23 +1,23 @@
|
|||||||
import { Switch, Route, Redirect } from "react-router-dom"
|
import { Switch, Route, Redirect } from "react-router-dom"
|
||||||
|
|
||||||
import Welcome from "./pages/Welcome";
|
import Welcome from "./pages/Welcome"
|
||||||
import Login from "./pages/Login";
|
import Login from "./pages/Login"
|
||||||
import Home from "./pages/Home";
|
import Home from "./pages/Home"
|
||||||
import ForgotPasword from "./pages/ForgotPassword";
|
import ForgotPasword from "./pages/ForgotPassword"
|
||||||
import { Courses } from "./pages/Courses";
|
import { Courses } from "./pages/Courses"
|
||||||
import { CourseExercises } from "./pages/CourseExercises";
|
import { CourseExercises } from "./pages/CourseExercises"
|
||||||
import { Exercise } from "./pages/Exercise";
|
import { Exercise } from "./pages/Exercise"
|
||||||
|
|
||||||
import Settings from "./pages/Settings";
|
import Settings from "./pages/Settings"
|
||||||
import CourseComplete from "./pages/CourseComplete";
|
import CourseComplete from "./pages/CourseComplete"
|
||||||
|
|
||||||
import { getRouteWelcome } from "./shared/consts/router";
|
import { getRouteWelcome } from "./shared/consts/router"
|
||||||
import { getRouteLogin } from "./shared/consts/router";
|
import { getRouteLogin } from "./shared/consts/router"
|
||||||
import { getRouteHome } from "./shared/consts/router";
|
import { getRouteHome } from "./shared/consts/router"
|
||||||
import { getRouteForgotPassword } from "./shared/consts/router";
|
import { getRouteForgotPassword } from "./shared/consts/router"
|
||||||
import { getRouteCourses } from "./shared/consts/router";
|
import { getRouteCourses } from "./shared/consts/router"
|
||||||
import { getRouteSettings } from "./shared/consts/router";
|
import { getRouteSettings } from "./shared/consts/router"
|
||||||
import { getRouteCourseComplete } from "./shared/consts/router";
|
import { getRouteCourseComplete } from "./shared/consts/router"
|
||||||
|
|
||||||
const AppRoutes = () => (
|
const AppRoutes = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
@ -31,6 +31,7 @@ const AppRoutes = () => (
|
|||||||
<Route path={getRouteForgotPassword()} component={ForgotPasword} />
|
<Route path={getRouteForgotPassword()} component={ForgotPasword} />
|
||||||
<Route exact path={getRouteCourses()} component={Courses} />
|
<Route exact path={getRouteCourses()} component={Courses} />
|
||||||
<Route exact path="/course/:id" component={CourseExercises} />
|
<Route exact path="/course/:id" component={CourseExercises} />
|
||||||
|
<Route exact path="/course/:courseId/exercise/:exerciseIndex" component={Exercise} />
|
||||||
<Route exact path="/course/:courseId/:exerciseId" component={Exercise} />
|
<Route exact path="/course/:courseId/:exerciseId" component={Exercise} />
|
||||||
<Route path={getRouteSettings()} component={Settings} />
|
<Route path={getRouteSettings()} component={Settings} />
|
||||||
<Route path={getRouteCourseComplete()} component={CourseComplete} />
|
<Route path={getRouteCourseComplete()} component={CourseComplete} />
|
||||||
|
@ -1,139 +1,120 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react"
|
||||||
import { useParams, useHistory, useLocation } from "react-router-dom";
|
import { useParams, useHistory, useLocation } from "react-router-dom"
|
||||||
|
|
||||||
import HeaderNav from "../components/HeaderNav";
|
import HeaderNav from "../components/HeaderNav"
|
||||||
import BottomNavigation from "../components/BottomNavigation";
|
import BottomNavigation from "../components/BottomNavigation"
|
||||||
|
|
||||||
import { connect } from '../confconnect';
|
import { connect } from "../confconnect"
|
||||||
|
|
||||||
import { getRouteExercise } from "../shared/consts/router";
|
import { getRouteExerciseByIndex } from "../shared/consts/router"
|
||||||
import { ArrowIcon } from "../components/icons/ArrowIcon";
|
import { ArrowIcon } from "../components/icons/ArrowIcon"
|
||||||
|
|
||||||
import type { Course } from "../pages/Courses";
|
import type { Course } from "../pages/Courses"
|
||||||
// import { Exercise } from "./Exercise";
|
|
||||||
|
|
||||||
export interface CourseExercises {
|
export interface CourseExercises {
|
||||||
id: number;
|
id: number
|
||||||
id_course: number;
|
id_course: number
|
||||||
id_exercise: number;
|
id_exercise: number
|
||||||
exercise: Exercise;
|
exercise: Exercise
|
||||||
day: number;
|
day: number
|
||||||
position: number;
|
position: number
|
||||||
repeats: number;
|
repeats: number
|
||||||
time: string;
|
time: string
|
||||||
DeletedAt: string | null;
|
DeletedAt: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Exercise {
|
interface Exercise {
|
||||||
id: number;
|
id: number
|
||||||
title: string;
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const CourseExercises = () => {
|
export const CourseExercises = () => {
|
||||||
const history = useHistory();
|
const history = useHistory()
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<{ id: string }>()
|
||||||
|
|
||||||
const location = useLocation<{ course?: Course }>();
|
const location = useLocation<{ course?: Course }>()
|
||||||
const course = location.state?.course;
|
const course = location.state?.course
|
||||||
|
|
||||||
|
const [course_exercises, setExercises] = useState<CourseExercises[]>([])
|
||||||
|
const [selectedDay, setSelectedDay] = useState<number | null>(null)
|
||||||
|
|
||||||
const [course_exercises, setExercises] = useState<CourseExercises[]>([]);
|
const token = localStorage.getItem("authToken")
|
||||||
const [selectedDay, setSelectedDay] = useState<number | null>(null);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const token = localStorage.getItem('authToken');
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(token)
|
console.log(token)
|
||||||
if (!token) {
|
if (!token) {
|
||||||
console.log('Токен не найден');
|
console.log("Токен не найден")
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connect.get(`/pacient/${id}`, {
|
connect
|
||||||
|
.get(`/pacient/${id}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
'Content-Type': 'application/json',
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
|
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
console.log('Данные упражнения курса:', response.data.course_exercises);
|
console.log("Данные упражнения курса:", response.data.course_exercises)
|
||||||
|
setExercises(response.data.course_exercises)
|
||||||
setExercises(response.data.course_exercises);
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
console.error('Ошибка ответа сервера:', error.response.status, error.response.data);
|
console.error("Ошибка ответа сервера:", error.response.status, error.response.data)
|
||||||
|
|
||||||
} else if (error.request) {
|
} else if (error.request) {
|
||||||
console.error('Нет ответа от сервера:', error.request);
|
console.error("Нет ответа от сервера:", error.request)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error('Ошибка при настройке запроса:', error.message);
|
console.error("Ошибка при настройке запроса:", error.message)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (course_exercises.length > 0 && selectedDay === null) {
|
if (course_exercises.length > 0 && selectedDay === null) {
|
||||||
setSelectedDay(course_exercises[0].day);
|
setSelectedDay(course_exercises[0].day)
|
||||||
}
|
}
|
||||||
}, [course_exercises]);
|
}, [course_exercises])
|
||||||
|
|
||||||
const uniqueDays = Array.from(new Set(course_exercises.map(ex => ex.day))).sort((a, b) => a - b);
|
const uniqueDays = Array.from(new Set(course_exercises.map((ex) => ex.day))).sort((a, b) => a - b)
|
||||||
|
|
||||||
const dayMap: { [key: number]: number } = {};
|
const dayMap: { [key: number]: number } = {}
|
||||||
|
|
||||||
uniqueDays.forEach((day, index) => {
|
uniqueDays.forEach((day, index) => {
|
||||||
dayMap[day] = index + 1;
|
dayMap[day] = index + 1
|
||||||
});
|
})
|
||||||
|
|
||||||
const daysNav = uniqueDays.map(day => dayMap[day]);
|
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 days = Array.from(new Set(course_exercises.map((ex) => ex.day))).sort((a, b) => a - b)
|
||||||
|
|
||||||
const filteredExercises = selectedDay !== null
|
const filteredExercises =
|
||||||
? course_exercises.filter(ex => ex.day === selectedDay)
|
selectedDay !== null ? course_exercises.filter((ex) => ex.day === selectedDay) : course_exercises
|
||||||
: course_exercises;
|
|
||||||
|
|
||||||
console.log('отфильтрованный список по дням',filteredExercises)
|
console.log("отфильтрованный список по дням", filteredExercises)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
||||||
<HeaderNav item={course?.title ?? 'Название курса'} text={'курс'} />
|
<HeaderNav item={course?.title ?? "Название курса"} text={"курс"} />
|
||||||
|
|
||||||
<div className="px-6 mb-8">
|
<div className="px-6 mb-8">
|
||||||
{/* Заголовок секции */}
|
|
||||||
<div className="flex flex-col sm:flex-row justify-between content-center mb-6">
|
<div className="flex flex-col sm:flex-row justify-between content-center mb-6">
|
||||||
<h2 className="text-xl font-black text-[#5F5C5C]">Упражнения</h2>
|
<h2 className="text-xl font-black text-[#5F5C5C]">Упражнения</h2>
|
||||||
<span className="text-sm text-gray-500">Количество упражнений: {course_exercises.length}</span>
|
<span className="text-sm text-gray-500">Количество упражнений: {course_exercises.length}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* <p>{JSON.stringify(course_exercises)}</p> */}
|
|
||||||
|
|
||||||
|
|
||||||
{/* Кнопки выбора дня */}
|
|
||||||
{days.length > 1 && (
|
{days.length > 1 && (
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex flex-wrap gap-2 overflow-x-auto pb-2">
|
<div className="flex flex-wrap gap-2 overflow-x-auto pb-2">
|
||||||
{days.map((day, index) => (
|
{days.map((day, index) => (
|
||||||
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
key={day}
|
key={day}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedDay(day);
|
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
|
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-[#2BACBE] text-white shadow-lg"
|
||||||
: "bg-white text-gray-600 hover:bg-gray-100"
|
: "bg-white text-gray-600 hover:bg-gray-100"
|
||||||
}`}
|
}`}
|
||||||
@ -145,41 +126,34 @@ console.log('отфильтрованный список по дням',filtered
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className="exercise-list mb-20">
|
<div className="exercise-list mb-20">
|
||||||
{
|
{filteredExercises.length > 0 ? (
|
||||||
|
|
||||||
|
|
||||||
filteredExercises.length > 0 ? (
|
|
||||||
filteredExercises.map((item, index) => (
|
filteredExercises.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
history.push(
|
||||||
// console.log(course_exercises.map(ex => ex.id_exercise))
|
getRouteExerciseByIndex(
|
||||||
|
item.id_course.toString(),
|
||||||
|
index, // Используем индекс из отфильтрованного массива
|
||||||
// Передаем id_course и индекс из полного массива
|
selectedDay || undefined, // Передаем выбранный день для контекста
|
||||||
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">
|
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 className="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-xs sm:text-base">Упражнение {++index}</h3>
|
<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>
|
<h3 className="text-base sm:text-xl font-semibold text-gray-600">{item.exercise.title}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ArrowIcon className="text-cyan-600" />
|
<ArrowIcon className="text-cyan-600" />
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="h-0.5 w-full bg-gray-200 my-3"></div>
|
<div className="h-0.5 w-full bg-gray-200 my-3"></div>
|
||||||
|
|
||||||
<div className="flex gap-10 text-xs text-gray-500">
|
<div className="flex gap-10 text-xs text-gray-500">
|
||||||
<p>Повторений: {item.repeats}</p>
|
<p>Повторений: {item.repeats}</p>
|
||||||
|
|
||||||
<p>Время выполнения: {item.time}</p>
|
<p>Время выполнения: {item.time}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -192,27 +166,5 @@ console.log('отфильтрованный список по дням',filtered
|
|||||||
|
|
||||||
<BottomNavigation />
|
<BottomNavigation />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// type ButtonTheme = 'primary' | 'secondary' | 'contrast';
|
|
||||||
|
|
||||||
// interface ButtonProps {
|
|
||||||
// onClick: (event: MouseEvent) =>
|
|
||||||
// theme: ButtonTheme
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const Button = (props: ButtonProps) => {
|
|
||||||
// const {theme} = props;
|
|
||||||
// return <button className={theme === 'primary' ? 'bg-teal-500 text-black' : "ajksdf"}>кнопка</button>
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const Page = () => {
|
|
||||||
// const t: ButtonTheme = 'contrast'
|
|
||||||
// return (
|
|
||||||
// <div>
|
|
||||||
// <Button onClick={() => {}} theme={t}/>
|
|
||||||
// </div>
|
|
||||||
// )
|
|
||||||
// }
|
|
File diff suppressed because it is too large
Load Diff
@ -6,5 +6,11 @@ export const getRouteCourses = () => `/courses`
|
|||||||
export const getRouteCourseExercises = (id: number | string) => `/course/${id}`
|
export const getRouteCourseExercises = (id: number | string) => `/course/${id}`
|
||||||
export const getRouteExercise = (courseId: number | string, exerciseId: number | string) =>
|
export const getRouteExercise = (courseId: number | string, exerciseId: number | string) =>
|
||||||
`/course/${courseId}/${exerciseId}`
|
`/course/${courseId}/${exerciseId}`
|
||||||
|
|
||||||
|
export const getRouteExerciseByIndex = (courseId: number | string, exerciseIndex: number, day?: number) => {
|
||||||
|
const dayParam = day ? `?day=${day}` : ""
|
||||||
|
return `/course/${courseId}/exercise/${exerciseIndex}${dayParam}`
|
||||||
|
}
|
||||||
|
|
||||||
export const getRouteSettings = () => `/settings`
|
export const getRouteSettings = () => `/settings`
|
||||||
export const getRouteCourseComplete = () => `/course-complete`
|
export const getRouteCourseComplete = () => `/course-complete`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user