запрещен переход по клику на завершенное упражнение

This commit is contained in:
Tatyana 2025-09-09 14:20:49 +03:00
parent 6494bb7625
commit 1de8b09cce
2 changed files with 74 additions and 45 deletions

View File

@ -138,8 +138,7 @@ export const CourseExercises = () => {
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 ${ 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
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"
}`} }`}
@ -161,10 +160,11 @@ export const CourseExercises = () => {
<div <div
key={index} key={index}
onClick={() => { onClick={() => {
history.push(getRouteExerciseByIndex(item.id_course.toString(), index, selectedDay || undefined)) if (!isCompleted) {
history.push(getRouteExerciseByIndex(item.id_course.toString(), index, selectedDay || undefined));
}
}} }}
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 ${isCompleted ? "opacity-60 bg-gray-100/50 cursor-default" : "cursor-pointer"
isCompleted ? "opacity-60 bg-gray-100/50" : ""
}`} }`}
> >
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">

View File

@ -699,22 +699,32 @@ export const Exercise = () => {
title: "Описание упражнения", title: "Описание упражнения",
description: exercise?.desc || "Выполните упражнение согласно инструкции.", description: exercise?.desc || "Выполните упражнение согласно инструкции.",
}, },
{ {
title: "Продолжительность", title: "Подходы",
description: `Время выполнения: ${exercise?.time || 15} минут`,
},
{
title: "Подходы и повторения",
description: `Выполните ${exercise?.count || 1} подход по ${exercise?.repeats || 12} повторений с отдыхом 60 секунд между подходами.`, description: `Выполните ${exercise?.count || 1} подход по ${exercise?.repeats || 12} повторений с отдыхом 60 секунд между подходами.`,
}, },
{ {
title: "Позиция в программе", title: "Динамика",
description: `Это упражнение №${exercise?.position || 1} в программе дня ${exercise?.day || 1}.`, description: "Добавить.",
},
{
title: "Статика",
description: "Добавить",
},
{
title: "Отдых",
description: "Добавить.",
},
{
title: "Продолжительность",
description: `Время выполнения: ${exercise?.time || 5} минут`,
}, },
{ {
title: "Техника безопасности", title: "Техника безопасности",
description: "Следите за правильной техникой выполнения. При появлении боли немедленно прекратите упражнение.", description: "Следите за правильной техникой выполнения. При появлении боли немедленно прекратите упражнение.",
}, },
] ]
// ========== ЭКРАНЫ ЗАГРУЗКИ И ОШИБОК ========== // ========== ЭКРАНЫ ЗАГРУЗКИ И ОШИБОК ==========
@ -806,8 +816,7 @@ export const Exercise = () => {
<button <button
onClick={() => !isCompleted && !isResting && setIsPlaying(!isPlaying)} onClick={() => !isCompleted && !isResting && setIsPlaying(!isPlaying)}
disabled={isCompleted || isResting} disabled={isCompleted || isResting}
className={`w-20 h-20 rounded-full flex items-center justify-center shadow-2xl transition-all duration-300 transform hover:scale-110 ${ className={`w-20 h-20 rounded-full flex items-center justify-center shadow-2xl transition-all duration-300 transform hover:scale-110 ${isPlaying
isPlaying
? "bg-white/20 backdrop-blur-xl border border-white/30" ? "bg-white/20 backdrop-blur-xl border border-white/30"
: "bg-white/30 backdrop-blur-xl border border-white/50" : "bg-white/30 backdrop-blur-xl border border-white/50"
} ${isCompleted || isResting ? "opacity-50 cursor-not-allowed" : ""}`} } ${isCompleted || isResting ? "opacity-50 cursor-not-allowed" : ""}`}
@ -865,8 +874,7 @@ export const Exercise = () => {
return ( return (
<div key={setNumber} className="flex-1 text-center"> <div key={setNumber} className="flex-1 text-center">
<div <div
className={`h-3 rounded-full transition-all duration-300 ${ className={`h-3 rounded-full transition-all duration-300 ${isSetCompleted ? "bg-cyan-500" : isCurrent ? "bg-cyan-500" : "bg-gray-200"
isSetCompleted ? "bg-cyan-500" : isCurrent ? "bg-cyan-500" : "bg-gray-200"
}`} }`}
/> />
<div className="text-xs font-bold mt-1 text-gray-600">{setNumber}</div> <div className="text-xs font-bold mt-1 text-gray-600">{setNumber}</div>
@ -881,8 +889,32 @@ export const Exercise = () => {
</div> </div>
</div> </div>
<div className="px-4 sm:px-6 space-y-4 mb-6"> <div className="px-4 sm:px-6 space-y-4 mb-6">
{exerciseSteps.map((step, index) => ( {exerciseSteps.map((step, index) => {
// Проверяем, если текущий элемент "Динамика", отрендерим карточку с двумя блоками ("Динамика" + "Статика")
if (step.title === "Динамика" && exerciseSteps[index + 1]?.title === "Статика") {
return (
<div
key={`${index}-dynamic-static`}
className="bg-white rounded-2xl p-5 border border-gray-200 shadow-lg hover:shadow-xl transition-all duration-300"
>
<div className="flex space-x-6">
{[step, exerciseSteps[index + 1]].map((subStep, subIndex) => (
<div key={subIndex} className="flex-1">
<h3 className="text-lg font-black text-gray-800 mb-2">{subStep.title}</h3>
<p className="text-gray-600 leading-relaxed text-sm sm:text-base">{subStep.description}</p>
</div>
))}
</div>
</div>
);
}
// Пропускаем элемент "Статика", т.к. он уже отрендерен вместе с "Динамика"
if (step.title === "Статика") {
return null;
}
// Для остальных - рендер стандартный
return (
<div <div
key={index} key={index}
className="bg-white rounded-2xl p-5 border border-gray-200 shadow-lg hover:shadow-xl transition-all duration-300" className="bg-white rounded-2xl p-5 border border-gray-200 shadow-lg hover:shadow-xl transition-all duration-300"
@ -894,16 +926,16 @@ export const Exercise = () => {
</div> </div>
</div> </div>
</div> </div>
))} );
</div> })}
</div>
<div className="fixed bottom-36 left-0 right-0 bg-white/95 backdrop-blur-sm border-t border-gray-200 px-4 sm:px-6 py-4 shadow-xl z-30"> <div className="fixed bottom-36 left-0 right-0 bg-white/95 backdrop-blur-sm border-t border-gray-200 px-4 sm:px-6 py-4 shadow-xl z-30">
<div className="max-w-md mx-auto"> <div className="max-w-md mx-auto">
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div <div
className={`w-2 h-2 rounded-full ${ className={`w-2 h-2 rounded-full ${isCompleted
isCompleted
? "bg-cyan-400" ? "bg-cyan-400"
: isResting : isResting
? `bg-cyan-400 ${!isRestPaused ? "animate-pulse" : ""}` ? `bg-cyan-400 ${!isRestPaused ? "animate-pulse" : ""}`
@ -925,8 +957,7 @@ export const Exercise = () => {
<div className="bg-gray-200 rounded-full h-2 mb-4 overflow-hidden"> <div className="bg-gray-200 rounded-full h-2 mb-4 overflow-hidden">
<div <div
className={`h-2 rounded-full transition-all duration-1000 shadow-sm ${ className={`h-2 rounded-full transition-all duration-1000 shadow-sm ${isCompleted
isCompleted
? "bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600" ? "bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600"
: isResting : isResting
? "bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600" ? "bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600"
@ -958,8 +989,7 @@ export const Exercise = () => {
setIsRestPaused(!isRestPaused) setIsRestPaused(!isRestPaused)
handlePause(completedSets, currentSet, true, restTime, !isRestPaused) handlePause(completedSets, currentSet, true, restTime, !isRestPaused)
}} }}
className={`flex-1 font-bold py-3 px-4 rounded-xl transition-all duration-300 flex items-center justify-center space-x-2 ${ className={`flex-1 font-bold py-3 px-4 rounded-xl transition-all duration-300 flex items-center justify-center space-x-2 ${isRestPaused
isRestPaused
? "bg-yellow-500 hover:bg-yellow-600 text-white" ? "bg-yellow-500 hover:bg-yellow-600 text-white"
: "bg-[#2BACBE] hover:bg-[#2099A8] text-white" : "bg-[#2BACBE] hover:bg-[#2099A8] text-white"
}`} }`}
@ -990,8 +1020,7 @@ export const Exercise = () => {
setIsPlaying(false) 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 ${ 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
isPlaying
? "bg-yellow-500 hover:bg-yellow-600 text-white shadow-lg" ? "bg-yellow-500 hover:bg-yellow-600 text-white shadow-lg"
: "bg-[#2BACBE] hover:bg-[#2099A8] text-white shadow-lg" : "bg-[#2BACBE] hover:bg-[#2099A8] text-white shadow-lg"
}`} }`}