вывела подсчет всех курсо и упражнений на домашней странице

This commit is contained in:
Tatyana 2025-09-01 12:47:12 +03:00
parent 00e6cf0222
commit cb05aa77dd
3 changed files with 183 additions and 87 deletions

View File

@ -19,6 +19,16 @@ export interface Course {
course_exercises: CourseExercises; course_exercises: CourseExercises;
} }
interface ResponseData {
courses: User[];
course_exercises: CourseExercises;
}
interface User {
id: number;
name: string;
Courses?: Course[];
}
const ProgressLine = () => { const ProgressLine = () => {
@ -57,7 +67,7 @@ export const Courses = () => {
const [error, setError] = useState<string>(''); const [error, setError] = useState<string>('');
const token = localStorage.getItem('authToken'); const token = localStorage.getItem('authToken');
const [course_exercises, setExercises] = useState<CourseExercises[]>([]); const [, setExercises] = useState<CourseExercises[]>([]);
useEffect(() => { useEffect(() => {
console.log(token) console.log(token)
@ -71,7 +81,7 @@ export const Courses = () => {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
}) })
.then(response => { .then((response: { data: ResponseData }) => {
console.log('Response status:', response.data); console.log('Response status:', response.data);
setExercises(response.data.courses.course_exercises); setExercises(response.data.courses.course_exercises);
@ -91,6 +101,7 @@ export const Courses = () => {
title: course.title, title: course.title,
desc: course.desc, desc: course.desc,
url_file_img: course.url_file_img, url_file_img: course.url_file_img,
course_exercises: course.course_exercises,
}); });
}); });
} }
@ -120,7 +131,7 @@ export const Courses = () => {
// Цвета для прогресс-баров в оттенках cyan // Цвета для прогресс-баров в оттенках cyan
const progressColors = [ const progressColors = [
"from-gray-400 to-cyan-800", "from-cyan-600 to-cyan-900",
]; ];
//item.exercise.title //item.exercise.title
@ -192,7 +203,7 @@ export const Courses = () => {
{/* Информация о прогрессе */} {/* Информация о прогрессе */}
<div className="flex flex-col md:flex-row md:justify-between content-center"> <div className="flex flex-col md:flex-row md:justify-between content-center">
<p className="text-sm text-[#5F5C5C]/70 font-semibold">{progress}% завершено</p> <p className="text-sm text-[#5F5C5C]/70 font-semibold">{progress}% завершено</p>
<p className="text-xs text-[#5F5C5C]/50">{course_exercises} упражнений</p> <p className="text-xs text-[#5F5C5C]/50">{"надо/не надо?"} упражнений</p>
</div> </div>
</div> </div>

View File

@ -15,15 +15,33 @@ import CircularProgressDisplay from "../components/CircularProgressDisplay";
import { StatCardHome } from "../components/cards/StatCardHome"; import { StatCardHome } from "../components/cards/StatCardHome";
import { WorkoutCardHome } from "../components/cards/WorkoutCardHome"; import { WorkoutCardHome } from "../components/cards/WorkoutCardHome";
import { connect } from '../confconnect';
import { getRouteExercise } from "../shared/consts/router"; import { getRouteExercise } from "../shared/consts/router";
import { getRouteCourses } from "../shared/consts/router"; import { getRouteCourses } from "../shared/consts/router";
import { getRouteCourseExercises } from "../shared/consts/router"; import { getRouteCourseExercises } from "../shared/consts/router";
import type { Course, User, CoursesApiResponse } from "../types/course";
//НАЧАЛО //
export default function Home() { export default function Home() {
const history = useHistory()
const [currentDate, setCurrentDate] = useState("") 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(() => { useEffect(() => {
console.log(token)
if (!token) {
setError('Токен не найден');
setLoading(false);
return;
}
setCurrentDate( setCurrentDate(
new Date().toLocaleDateString("ru-RU", { new Date().toLocaleDateString("ru-RU", {
year: "numeric", year: "numeric",
@ -31,39 +49,60 @@ export default function Home() {
day: "numeric", day: "numeric",
}), }),
) )
}, [])
const courses = [ setLoading(true)
{ connect
id: 1, .get<CoursesApiResponse>("/pacient/courses")
name: "Восстановление колена", .then((response) => {
progress: 75, console.log("Response data:", response.data)
color: "from-[#2BACBE] to-cyan-600",
exercises: 12,
nextExercise: "Подъемы ног лежа",
},
{
id: 2,
name: "Укрепление спины",
progress: 45,
color: "from-emerald-500 to-green-600",
exercises: 8,
nextExercise: "Планка",
},
{
id: 3,
name: "Реабилитация плеча",
progress: 90,
color: "from-purple-500 to-pink-600",
exercises: 10,
nextExercise: "Вращения плечами",
},
]
// Calculate overall progress, total courses, total exercises 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 totalCourses = courses.length
const totalExercises = courses.reduce((sum, course) => sum + course.exercises, 0) const totalExercises = courses.reduce((sum, course) => {
const overallProgress = Math.round(courses.reduce((sum, course) => sum + course.progress, 0) / totalCourses) 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 = () => { const handleWorkoutClick = () => {
history.push(getRouteExercise()) history.push(getRouteExercise())
@ -78,8 +117,27 @@ export default function Home() {
} }
const handleExercisesClick = () => { const handleExercisesClick = () => {
history.push(getRouteCourseExercises(":id")) 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 ( return (
<div className="bg-gray-50 w-full h-full overflow-auto"> <div className="bg-gray-50 w-full h-full overflow-auto">
@ -139,4 +197,4 @@ export default function Home() {
</div> </div>
</div> </div>
) )
} }

27
src/types/course.ts Normal file
View File

@ -0,0 +1,27 @@
export interface CourseExercise {
ID: number
title: string
desc: string
day: number
url_file_img?: string
url_file_video?: string
}
export interface Course {
ID: number
title: string
desc: string
url_file_img: string
course_exercises?: CourseExercise[]
}
export interface User {
id: number
name: string
Courses?: Course[]
}
export interface CoursesApiResponse {
courses: User[]
course_exercises?: CourseExercise[]
}