2025-07-31 16:25:43 +03:00

155 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import type React from "react"
import { useState } from "react"
import { IonCard, IonCardContent, IonButton, IonIcon, IonBadge } from "@ionic/react"
import { playOutline, videocamOutline, closeCircleOutline } from "ionicons/icons" // Добавлен videocamOutline и closeCircleOutline
interface Exercise {
id: number
name: string
duration: number // в секундах
description: string
difficulty: "easy" | "medium" | "hard"
completed: boolean
videoUrl?: string // Добавлено поле для URL видео
}
interface ExerciseItemProps {
exercise: Exercise
onStart: (exercise: Exercise) => void
isCurrent: boolean
isDisabled: boolean
onVideoPlayToggle: (isPlaying: boolean) => void // Добавлено для уведомления родителя
}
const ExerciseItem: React.FC<ExerciseItemProps> = ({ exercise, onStart, isCurrent, isDisabled, onVideoPlayToggle }) => {
const [showVideo, setShowVideo] = useState(false)
const formatTime = (seconds: number) => {
const mins = Math.floor(seconds / 60)
const secs = seconds % 60
return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`
}
const getDifficultyColor = (difficulty: string) => {
switch (difficulty) {
case "easy":
return "text-emerald-400"
case "medium":
return "text-yellow-400"
case "hard":
return "text-red-400"
default:
return "text-slate-400"
}
}
const getDifficultyBg = (difficulty: string) => {
switch (difficulty) {
case "easy":
return "bg-emerald-500/20 border-emerald-500/30"
case "medium":
return "bg-yellow-500/20 border-yellow-500/30"
case "hard":
return "bg-red-500/20 border-red-500/30"
default:
return "bg-slate-500/20 border-slate-500/30"
}
}
const handleVideoToggle = () => {
setShowVideo((prev) => {
onVideoPlayToggle(!prev) // Уведомляем родителя об изменении состояния видео
return !prev
})
}
return (
<IonCard
className={`${exercise.completed ? "bg-emerald-50/80" : "bg-white/80"} backdrop-blur-sm border border-teal-200/50 shadow-md`}
>
<IonCardContent>
<div className="flex justify-between items-start mb-3">
<div className="flex-1">
<h3 className={`font-semibold ${exercise.completed ? "text-emerald-700" : "text-slate-800"}`}>
{exercise.name}
</h3>
<p className="text-sm text-slate-600 mt-1">{exercise.description}</p>
</div>
{exercise.completed && (
<IonBadge color="success" className="ml-2">
Выполнено
</IonBadge>
)}
</div>
{showVideo && exercise.videoUrl && (
<div className="mb-4 relative">
<video
src={exercise.videoUrl}
controls
poster={`/placeholder.svg?height=200&width=300&query=${encodeURIComponent(exercise.name)}`}
className="w-full rounded-lg"
>
Ваш браузер не поддерживает видео тег.
</video>
<IonButton
fill="clear"
size="small"
onClick={handleVideoToggle}
className="absolute top-2 right-2 text-white bg-black/50 rounded-full"
>
<IonIcon icon={closeCircleOutline} />
</IonButton>
</div>
)}
<div className="flex justify-between items-center">
<div className="flex items-center gap-3">
<span className="text-sm text-slate-500">{formatTime(exercise.duration)}</span>
<IonBadge
className={`${getDifficultyBg(exercise.difficulty)} ${getDifficultyColor(exercise.difficulty)} border`}
>
{exercise.difficulty === "easy" ? "Легко" : exercise.difficulty === "medium" ? "Средне" : "Сложно"}
</IonBadge>
</div>
<div className="flex gap-2">
{exercise.videoUrl && (
<IonButton
size="small"
onClick={handleVideoToggle}
className="bg-gradient-to-r from-blue-500 to-indigo-500"
disabled={isCurrent} // Отключаем кнопку видео, если упражнение активно
>
<IonIcon icon={videocamOutline} slot="start" />
{showVideo ? "Скрыть" : "Видео"}
</IonButton>
)}
{!exercise.completed && !isCurrent && (
<IonButton
size="small"
onClick={() => onStart(exercise)}
className="bg-gradient-to-r from-teal-500 to-cyan-500"
disabled={isDisabled || showVideo} // Отключаем кнопку, если другое упражнение активно или видео проигрывается
>
<IonIcon icon={playOutline} slot="start" />
Начать
</IonButton>
)}
{isCurrent && (
<IonBadge color="primary" className="ml-2 animate-pulse">
Активно
</IonBadge>
)}
</div>
</div>
</IonCardContent>
</IonCard>
)
}
export default ExerciseItem