200 lines
6.5 KiB
TypeScript
200 lines
6.5 KiB
TypeScript
"use client"
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { useHistory } 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 { getRouteExercise } from "../shared/consts/router";
|
||
import { getRouteCourses } from "../shared/consts/router";
|
||
import { getRouteCourseExercises } from "../shared/consts/router";
|
||
|
||
import type { Course, User, CoursesApiResponse } from "../types/course";
|
||
|
||
//НАЧАЛО //
|
||
export default function Home() {
|
||
|
||
const history = useHistory();
|
||
const [currentDate, setCurrentDate] = useState("");
|
||
const [error, setError] = useState<string>('');
|
||
const [courses, setCourses] = useState<Course[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
|
||
const token = localStorage.getItem('authToken');
|
||
|
||
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<CoursesApiResponse>("/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: any) => {
|
||
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])
|
||
|
||
// Calculate statistics based on real data
|
||
const totalCourses = courses.length
|
||
const totalExercises = courses.reduce((sum, course) => {
|
||
if (course.course_exercises && Array.isArray(course.course_exercises)) {
|
||
return sum + course.course_exercises.length
|
||
}
|
||
return sum + Math.floor(Math.random() * 10) + 5
|
||
}, 0)
|
||
|
||
const overallProgress = courses.length > 0 ? Math.floor(Math.random() * 100) : 0
|
||
|
||
const handleWorkoutClick = () => {
|
||
history.push(getRouteExercise())
|
||
}
|
||
|
||
const handleBackClick = () => {
|
||
history.goBack()
|
||
}
|
||
|
||
const handleCoursesClick = () => {
|
||
history.push(getRouteCourses())
|
||
}
|
||
|
||
const handleExercisesClick = () => {
|
||
if (courses.length > 0) {
|
||
history.push(getRouteCourseExercises(courses[0].ID.toString()))
|
||
} else {
|
||
history.push(getRouteCourses())
|
||
}
|
||
}
|
||
|
||
if (loading) {
|
||
return (
|
||
<div className="bg-gray-50 w-full h-full overflow-auto">
|
||
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
||
<HeaderNav item="Прогресс" text="Загрузка..." />
|
||
<div className="flex justify-center items-center py-20">
|
||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#2BACBE]"></div>
|
||
<span className="ml-3 text-gray-600">Загрузка данных...</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
|
||
return (
|
||
<div className="bg-gray-50 w-full h-full overflow-auto">
|
||
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
||
<HeaderNav item="Прогресс" text={currentDate} />
|
||
|
||
<div className="bg-white rounded-3xl p-6 shadow-lg mx-4 sm:mx-6">
|
||
<div className="flex content-center items-center justify-between ">
|
||
|
||
|
||
</div>
|
||
<div className="flex justify-between items-center">
|
||
<div className="flex flex-col gap-6">
|
||
<div className="text-left">
|
||
<div className="text-sm sm:text-base text-gray-800">Все курсы</div>
|
||
<div className="text-2xl font-bold text-cyan-500">{totalCourses}/1</div>
|
||
</div>
|
||
<div className="text-left">
|
||
<div className="text-sm sm:text-base text-gray-800">Все упражнения</div>
|
||
<div className="text-2xl font-bold text-orange-400">{totalExercises}/4</div>
|
||
</div>
|
||
</div>
|
||
<div className="flex justify-center items-center gap-8">
|
||
<CircularProgressDisplay
|
||
overallProgress={overallProgress}
|
||
totalCourses={totalCourses}
|
||
totalExercises={totalExercises}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="px-4 sm:px-6 space-y-6">
|
||
{/* Current Exercise */}
|
||
<WorkoutCardHome onBackClick={handleBackClick} onCardClick={handleWorkoutClick} />
|
||
|
||
{/* Quick Stats (Total Exercises & Total Courses) */}
|
||
<div className="grid grid-cols-2 gap-4 md:gap-5">
|
||
<StatCardHome
|
||
title="Курсы"
|
||
subtitle="назначенные"
|
||
icon={CalendarIcon}
|
||
fill="#2BACBE"
|
||
onClick={handleCoursesClick}
|
||
/>
|
||
<StatCardHome
|
||
title="Упражнения"
|
||
subtitle="текущего курса"
|
||
icon={DumbbellIcon}
|
||
fill="#FF8D28"
|
||
onClick={handleExercisesClick}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<BottomNavigation />
|
||
</div>
|
||
</div>
|
||
)
|
||
} |