- {/* Тонкая нижняя линия */}
+ {/* Нижняя граница с градиентом */}
-
- {/* Логотип */}
-
- {/* Иконка логотипа */}
-
-
- {/* Текст логотипа */}
-
-
- МедРеабилитация
-
-
Центр восстановления
-
+
+ {/* Логотип и название */}
+
+ {/* Иконка с градиентом */}
+
+ {/* Название и описание */}
+
+
+ МедРеабилитация
+
+
Центр восстановления
-
- {/* Меню-бургер */}
-
-
- {/* Выпадающее меню */}
- {menuOpen && (
-
- {/* Фон меню */}
-
-
- {/* Контент меню */}
-
-
-
-
- {/* Разделитель */}
-
-
- {/* Дополнительные опции */}
-
-
-
- И
-
-
-
Иван Петров
-
Пациент
-
-
-
-
-
-
-
- )}
)
}
-
-export default Header
+export default Header
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index 7463d24..ccc6f1e 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,5 +1,19 @@
@import "tailwindcss";
+
+@keyframes gradient {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+}
+
+.animate-gradient {
+ background-size: 300% 300%;
+ animation: gradient 10s ease infinite;
+}
+
+
+
/* Ionic переменные для кастомизации */
:root {
/* Основные цвета приложения */
diff --git a/src/pages/Account.tsx b/src/pages/Account.tsx
new file mode 100644
index 0000000..b2af92b
--- /dev/null
+++ b/src/pages/Account.tsx
@@ -0,0 +1,69 @@
+import type React from "react"
+import { IonPage, IonContent, IonList, IonItem, IonLabel, IonIcon, IonToggle, IonButton } from "@ionic/react"
+import {
+ personCircleOutline,
+ mailOutline,
+ lockClosedOutline,
+ notificationsOutline,
+ moonOutline,
+ logOutOutline,
+} from "ionicons/icons"
+import Header from "../components/Header"
+import Footer from "../components/Footer"
+
+const Account: React.FC = () => {
+ return (
+
+
+
+
+
+

+
Himanshi Kashyap
+
himanshi.kashyap@example.com
+
+
+
+
+
+ Edit Profile
+
+
+
+ Change Email
+
+
+
+ Change Password
+
+
+
+
+
+
+ Notifications
+
+
+
+
+ Dark Mode
+
+
+
+
+
+
+ Log Out
+
+
+
+
+
+ )
+}
+
+export default Account
diff --git a/src/pages/Exercises.tsx b/src/pages/Exercises.tsx
new file mode 100644
index 0000000..4aeffce
--- /dev/null
+++ b/src/pages/Exercises.tsx
@@ -0,0 +1,239 @@
+"use client"
+
+import type React from "react"
+import { useState, useEffect } from "react"
+import {
+ IonContent,
+ IonPage,
+ IonCard,
+ IonCardContent,
+ IonCardHeader,
+ IonCardTitle,
+ IonButton,
+ IonIcon,
+ IonProgressBar,
+} from "@ionic/react"
+import { playOutline, pauseOutline, stopOutline, timerOutline, fitnessOutline, trophyOutline } from "ionicons/icons"
+import ExerciseItem from "../components/ExerciseItem" // Импортируем новый компонент
+
+interface Exercise {
+ id: number
+ name: string
+ duration: number // в секундах
+ description: string
+ difficulty: "easy" | "medium" | "hard"
+ completed: boolean
+ videoUrl?: string // Добавлено поле для URL видео
+}
+
+const ExercisesPage: React.FC = () => {
+ const [currentExercise, setCurrentExercise] = useState
(null)
+ const [timeLeft, setTimeLeft] = useState(0)
+ const [isRunning, setIsRunning] = useState(false)
+ const [isPaused, setIsPaused] = useState(false)
+ const [isAnyVideoPlaying, setIsAnyVideoPlaying] = useState(false) // Новое состояние для отслеживания видео
+
+ const initialExercises: Exercise[] = [
+ {
+ id: 1,
+ name: "Разминка плечевого сустава",
+ duration: 300, // 5 минут
+ description: "Медленные круговые движения плечами для восстановления подвижности",
+ difficulty: "easy",
+ completed: false, // Изначально все не выполнено
+ videoUrl: "/placeholder.svg?height=200&width=300", // Пример видео URL
+ },
+ {
+ id: 2,
+ name: "Упражнения для кисти",
+ duration: 600, // 10 минут
+ description: "Сжимание и разжимание кулака, вращения кистью",
+ difficulty: "medium",
+ completed: false,
+ videoUrl: "/placeholder.svg?height=200&width=300", // Пример видео URL
+ },
+ {
+ id: 3,
+ name: "Растяжка мышц руки",
+ duration: 450, // 7.5 минут
+ description: "Статические упражнения на растяжку поврежденных мышц",
+ difficulty: "hard",
+ completed: false,
+ videoUrl: "/placeholder.svg?height=200&width=300", // Пример видео URL
+ },
+ {
+ id: 4,
+ name: "Укрепление предплечья",
+ duration: 400, // 6.6 минут
+ description: "Упражнения с легкими гантелями для укрепления мышц предплечья",
+ difficulty: "medium",
+ completed: false,
+ videoUrl: "/placeholder.svg?height=200&width=300", // Пример видео URL
+ },
+ {
+ id: 5,
+ name: "Координационные упражнения",
+ duration: 500, // 8.3 минут
+ description: "Упражнения на баланс и мелкую моторику",
+ difficulty: "hard",
+ completed: false,
+ videoUrl: "/placeholder.svg?height=200&width=300", // Пример видео URL
+ },
+ ]
+
+ const [exerciseList, setExerciseList] = useState(() => {
+ // Попытка загрузить состояние из localStorage
+ if (typeof window !== "undefined") {
+ const savedExercises = localStorage.getItem("rehab_exercises")
+ if (savedExercises) {
+ return JSON.parse(savedExercises)
+ }
+ }
+ return initialExercises
+ })
+
+ // Сохранение состояния в localStorage при изменении
+ useEffect(() => {
+ if (typeof window !== "undefined") {
+ localStorage.setItem("rehab_exercises", JSON.stringify(exerciseList))
+ }
+ }, [exerciseList])
+
+ useEffect(() => {
+ let interval: NodeJS.Timeout | undefined
+
+ if (isRunning && !isPaused && timeLeft > 0) {
+ interval = setInterval(() => {
+ setTimeLeft((prevTime) => prevTime - 1)
+ }, 1000)
+ } else if (timeLeft === 0 && currentExercise && isRunning) {
+ // Упражнение завершено
+ setIsRunning(false)
+ setCurrentExercise(null)
+ // Отмечаем упражнение как выполненное
+ setExerciseList((prev) => prev.map((ex) => (ex.id === currentExercise.id ? { ...ex, completed: true } : ex)))
+ }
+
+ return () => {
+ if (interval) clearInterval(interval)
+ }
+ }, [isRunning, isPaused, timeLeft, currentExercise])
+
+ const startExercise = (exercise: Exercise) => {
+ setCurrentExercise(exercise)
+ setTimeLeft(exercise.duration)
+ setIsRunning(true)
+ setIsPaused(false)
+ }
+
+ const pauseExercise = () => {
+ setIsPaused((prev) => !prev)
+ }
+
+ const stopExercise = () => {
+ setIsRunning(false)
+ setIsPaused(false)
+ setCurrentExercise(null)
+ setTimeLeft(0)
+ }
+
+ 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 completedCount = exerciseList.filter((ex) => ex.completed).length
+ const totalCount = exerciseList.length
+ const progressPercentage = totalCount > 0 ? (completedCount / totalCount) * 100 : 0
+
+ // Обработчик для отслеживания состояния воспроизведения видео
+ const handleVideoPlayToggle = (isPlaying: boolean) => {
+ setIsAnyVideoPlaying(isPlaying)
+ }
+
+ return (
+
+
+
+ {/* Общий прогресс */}
+
+
+
+
+ Общий прогресс
+
+
+
+
+
+ Выполнено упражнений
+
+ {completedCount}/{totalCount}
+
+
+
+
{progressPercentage.toFixed(0)}% завершено
+
+
+
+
+ {/* Текущее упражнение (если активно) */}
+ {currentExercise && (
+
+
+
+
+ Текущее упражнение
+
+
+
+
+
{currentExercise.name}
+
+
{formatTime(timeLeft)}
+
+
+
+
+
+ {isPaused ? "Продолжить" : "Пауза"}
+
+
+
+ Остановить
+
+
+
+
+
+ )}
+
+ {/* Список упражнений */}
+
+
+
+ Список упражнений
+
+
+ {exerciseList.map((exercise) => (
+
+ ))}
+
+
+
+
+ )
+}
+
+export default ExercisesPage
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index e818b06..2a77d3d 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -16,6 +16,9 @@ import {
} from "@ionic/react"
import { playOutline, pauseOutline, stopOutline, timerOutline, fitnessOutline, trophyOutline } from "ionicons/icons"
+import Header from "../components/Header"
+import Footer from "../components/Footer"
+
interface Exercise {
id: number
name: string
@@ -135,6 +138,7 @@ const Home: React.FC = () => {
return (
+
{/* Приветствие и статистика */}
@@ -194,6 +198,7 @@ const Home: React.FC = () => {
+
)}
@@ -256,6 +261,7 @@ const Home: React.FC = () => {