сохранение текущего прогресса на сервере в БД / модели user_exercise_course

This commit is contained in:
Tatyana 2025-09-02 11:51:08 +03:00
parent b2f1db84c6
commit 3d5cd3a4ac

View File

@ -12,6 +12,7 @@ import BottomNavigation from "../components/BottomNavigation";
// import { getRouteCourseComplete } from "../shared/consts/router"; // import { getRouteCourseComplete } from "../shared/consts/router";
import { connect } from "../confconnect"; import { connect } from "../confconnect";
import axios from "axios"
//В TypeScript ключевое слово interface используется для определения интерфейсов — это способ описать структуру объектов, то есть какие свойства и методы у них есть, и какие типы данных они содержат //В TypeScript ключевое слово interface используется для определения интерфейсов — это способ описать структуру объектов, то есть какие свойства и методы у них есть, и какие типы данных они содержат
@ -56,29 +57,8 @@ export const Exercise = () => {
// Ограничение — прогресс сохраняется только на устройстве пользователя. // Ограничение — прогресс сохраняется только на устройстве пользователя.
// Если нужно синхронизировать между устройствами или сохранять историю, потребуется бэкенд. // Если нужно синхронизировать между устройствами или сохранять историю, потребуется бэкенд.
//сохраняем прогресс //сохраняем прогресс
const handlePause = () => {
const currentProgress = {
exerciseId: exercise?.id,
position: currentTime,
set: currentSet,
};
localStorage.setItem('exerciseProgress', JSON.stringify(currentProgress));
console.log('прогресс:', currentProgress)
// Отправляем на сервер
connect.post(`pacient/${courseId}/${exerciseId}`, currentProgress)
console.log('Отправляемые данные:', currentProgress);
connect.post('http://localhost:8093/pacient/1/2', currentProgress)
.then((response) => {
console.log('Ответ сервера при отправке прогресса:', response.status);
// Можно добавить обработку успешного ответа
})
.catch((error) => {
console.error('Ошибка при отправке прогресса:', error);
// Обработка ошибок
});
};
// В начале упражнения // Восстановление прогресса при загрузке
useEffect(() => { useEffect(() => {
const savedProgress = localStorage.getItem('exerciseProgress'); const savedProgress = localStorage.getItem('exerciseProgress');
if (savedProgress) { if (savedProgress) {
@ -104,8 +84,8 @@ export const Exercise = () => {
connect connect
.get(`pacient/${courseId}/${exerciseId}`) .get(`pacient/${courseId}/${exerciseId}`)
.then((response) => { .then((response) => {
console.log("Response status:", response.status) // console.log("Response status:", response.status)
console.log("Response data:", response.data) // console.log("Response data:", response.data)
const exerciseData = response.data const exerciseData = response.data
@ -151,6 +131,43 @@ export const Exercise = () => {
}) })
}, [courseId, exerciseId]) }, [courseId, exerciseId])
const handlePause = async () => {
// Формируем данные в том формате, который ожидает сервер
const progressData = {
time_users: formatTime(currentTime), // Отправляем как строку в формате MM:SS
status: currentSet, // Отправляем текущий подход как статус
}
// Сохраняем в localStorage
localStorage.setItem(
"exerciseProgress",
JSON.stringify({
exerciseId: exercise?.id,
position: currentTime,
set: currentSet,
}),
)
try {
console.log("Отправляем данные:", progressData)
// Используем connect (axios) вместо прямого axios
const response = await connect.post(`pacient/${courseId}/${exerciseId}`, progressData)
console.log("Ответ сервера при отправке прогресса:", response.status)
console.log("Прогресс успешно сохранен на сервере")
} catch (error) {
console.error("Ошибка при отправке прогресса:", error)
if (error.response) {
console.error("Ответ сервера:", error.response.status, error.response.data)
}
}
}
useEffect(() => { useEffect(() => {
let interval: NodeJS.Timeout | undefined let interval: NodeJS.Timeout | undefined
if (isPlaying) { if (isPlaying) {
@ -363,15 +380,18 @@ export const Exercise = () => {
<div className="flex space-x-3"> <div className="flex space-x-3">
<button <button
onClick={() => { onClick={() => {
setIsPlaying(!isPlaying) if (!isPlaying) {
handlePause() setIsPlaying(true);
} else {
handlePause();
setIsPlaying(false);
}
} }
} }
className={`flex-1 font-bold py-3 px-4 rounded-xl transition-all duration-300 transform hover:scale-105 flex items-center justify-center space-x-2 cursor-pointer ${isPlaying className={`flex-1 font-bold py-3 px-4 rounded-xl transition-all duration-300 transform hover:scale-105 flex items-center justify-center space-x-2 cursor-pointer ${isPlaying
? "bg-gray-400 text-white shadow-lg" ? "bg-gray-400 text-white shadow-lg"
: "bg-orange-400 hover:bg-orange-500 text-white shadow-lg" : "bg-orange-400 text-white shadow-lg"
}`} }`}
> >
{isPlaying ? ( {isPlaying ? (
@ -406,30 +426,6 @@ export const Exercise = () => {
</button> </button>
{/* <button
onClick={() => {
const newSet = Math.min(currentSet + 1, totalSets);
setCurrentSet(newSet);
}}
onMouseDown={() => setIsActive(true)}
onMouseUp={() => setIsActive(false)}
onMouseLeave={() => setIsActive(false)}
onTouchStart={() => setIsActive(true)}
onTouchEnd={() => setIsActive(false)}
className={`cursor-pointer px-6 py-3 font-bold rounded-xl transition-all duration-300 hover:shadow-lg border border-gray-200 hover:bg-orange-400 hover:text-white flex items-center justify-center ${!isActive ? "bg-white text-orange-400 scale-100" : "bg-orange-400 text-white scale-105"}`}
>
<CheckIcon
className="w-6 h-6"
/>
</button> */}
</div> </div>
</div> </div>
</div> </div>