вынесла карточки/картинки в отдельные компоненты/в работе
This commit is contained in:
parent
1197c9ca1d
commit
8c99c4a220
@ -1,48 +1,41 @@
|
|||||||
import { Route } from "react-router-dom"
|
import { Switch, Route, Redirect } from "react-router-dom";
|
||||||
|
|
||||||
import Welcome from "./pages/Welcome"
|
|
||||||
import Login from "./pages/Login"
|
|
||||||
import Home from "./pages/Home"
|
|
||||||
import ForgotPasword from "./pages/ForgotPassword"
|
|
||||||
import Courses from "./pages/Courses"
|
|
||||||
import CourseExercises from "./pages/CourseExercises"
|
|
||||||
import Exercise from "./pages/Exercise"
|
|
||||||
import Settings from "./pages/Settings"
|
|
||||||
import CourseComplete from "./pages/CourseComplete"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { getRouteWelcome } from "./shared/consts/router"
|
|
||||||
import { getRouteLogin } from "./shared/consts/router"
|
|
||||||
import { getRouteHome } from "./shared/consts/router"
|
|
||||||
import { getRouteForgotPassword } from "./shared/consts/router"
|
|
||||||
import { getRouteCourses } from "./shared/consts/router"
|
|
||||||
import { getRouteCourseExercises } from "./shared/consts/router"
|
|
||||||
import { getRouteExercise } from "./shared/consts/router"
|
|
||||||
import { getRouteSettings } from "./shared/consts/router"
|
|
||||||
import { getRouteCourseComplete } from "./shared/consts/router"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import Welcome from "./pages/Welcome";
|
||||||
|
import Login from "./pages/Login";
|
||||||
|
import Home from "./pages/Home";
|
||||||
|
import ForgotPasword from "./pages/ForgotPassword";
|
||||||
|
import Courses from "./pages/Courses";
|
||||||
|
import CourseExercises from "./pages/CourseExercises";
|
||||||
|
import Exercise from "./pages/Exercise";
|
||||||
|
import Settings from "./pages/Settings";
|
||||||
|
import CourseComplete from "./pages/CourseComplete";
|
||||||
|
|
||||||
|
import { getRouteWelcome } from "./shared/consts/router";
|
||||||
|
import { getRouteLogin } from "./shared/consts/router";
|
||||||
|
import { getRouteHome } from "./shared/consts/router";
|
||||||
|
import { getRouteForgotPassword } from "./shared/consts/router";
|
||||||
|
import { getRouteCourses } from "./shared/consts/router";
|
||||||
|
import { getRouteCourseExercises } from "./shared/consts/router";
|
||||||
|
import { getRouteExercise } from "./shared/consts/router";
|
||||||
|
import { getRouteSettings } from "./shared/consts/router";
|
||||||
|
import { getRouteCourseComplete } from "./shared/consts/router";
|
||||||
|
|
||||||
const AppRoutes = () => (
|
const AppRoutes = () => (
|
||||||
<>
|
<Switch>
|
||||||
|
{/* Редирект с корня на /welcome */}
|
||||||
|
<Redirect exact from="/" to={getRouteWelcome()} />
|
||||||
|
|
||||||
|
{/* Остальные маршруты */}
|
||||||
<Route path={getRouteWelcome()} component={Welcome} />
|
<Route path={getRouteWelcome()} component={Welcome} />
|
||||||
<Route path={getRouteLogin()} component={Login} />
|
<Route path={getRouteLogin()} component={Login} />
|
||||||
<Route path={getRouteHome()} component={Home} exact />
|
<Route path={getRouteHome()} component={Home} />
|
||||||
<Route path={getRouteForgotPassword()} component={ForgotPasword} />
|
<Route path={getRouteForgotPassword()} component={ForgotPasword} />
|
||||||
<Route path={getRouteCourses()} component={Courses} />
|
<Route path={getRouteCourses()} component={Courses} />
|
||||||
<Route path={getRouteCourseExercises(':id')} component={CourseExercises} />
|
<Route path={getRouteCourseExercises(':id')} component={CourseExercises} />
|
||||||
<Route path={getRouteExercise(':id')} component={Exercise} />
|
<Route path={getRouteExercise(':id')} component={Exercise} />
|
||||||
<Route path={getRouteSettings()} component={Settings} exact />
|
<Route path={getRouteSettings()} component={Settings} />
|
||||||
<Route path={getRouteCourseComplete()} component={CourseComplete} />
|
<Route path={getRouteCourseComplete()} component={CourseComplete} />
|
||||||
</>
|
</Switch>
|
||||||
)
|
);
|
||||||
|
|
||||||
export default AppRoutes
|
|
||||||
|
|
||||||
|
export default AppRoutes;
|
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
|
Before Width: | Height: | Size: 4.0 KiB |
@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="231" height="414" fill="none"><path fill="#fff" d="m52.63 288.512-18.294 31.7c-2.44 4.288-6.171 7.124-11.196 8.508-5.025 1.385-9.678.846-13.959-1.617-4.28-2.462-7.098-6.211-8.452-11.246-1.353-5.035-.823-9.709 1.592-14.022L87.39 154.363c-11.587-11.944-20.277-25.574-26.07-40.888-5.793-15.313-8.69-31.087-8.69-47.32 0-7.962.69-16 2.068-24.11 1.378-8.11 3.738-16 7.08-23.668 1.829-4.595 5.183-7.584 10.061-8.968 4.879-1.385 9.453-.846 13.721 1.617 4.269 2.462 7.092 6.138 8.47 11.026 1.379 4.888 1.3 9.788-.237 14.701a88.68 88.68 0 0 0-3.421 14.022 93.397 93.397 0 0 0-1.153 14.462c0 16.233 3.964 31.473 11.891 45.721 7.928 14.248 19.209 25.654 33.845 34.217l41.162 23.89c18.904 11.026 32.777 26.878 41.62 47.558C226.579 237.303 231 256.672 231 274.73c0 8.269-.762 16.465-2.287 24.588a126.836 126.836 0 0 1-6.86 23.651c-1.83 4.9-5.184 8.042-10.062 9.427-4.879 1.384-9.605.845-14.178-1.617-4.269-2.451-7.165-6.126-8.69-11.026-1.524-4.901-1.524-9.954 0-15.161 1.525-4.9 2.671-9.727 3.439-14.481a89.033 89.033 0 0 0 1.135-14.462c0-9.801-1.372-19.296-4.117-28.484-2.744-9.188-7.165-17.764-13.263-25.727L70.01 404.744c-2.44 4.288-6.171 7.124-11.196 8.509-5.025 1.384-9.678.845-13.959-1.617-4.28-2.463-7.098-6.212-8.452-11.247-1.353-5.035-.823-9.709 1.592-14.021l45.736-79.479-31.1-18.377Zm132.634-141.499c-10.062 0-18.672-3.596-25.831-10.787-7.16-7.192-10.745-15.847-10.757-25.966-.013-10.12 3.573-18.77 10.757-25.948 7.183-7.18 15.794-10.781 25.831-10.806 10.038-.024 18.654 3.578 25.85 10.806 7.196 7.228 10.775 15.877 10.739 25.948-.037 10.07-3.616 18.725-10.739 25.966-7.123 7.24-15.739 10.836-25.85 10.787ZM139.528 55.13c-7.927 0-14.483-2.757-19.666-8.27s-7.775-11.944-7.775-19.295c0-7.963 2.744-14.548 8.232-19.755C125.808 2.603 132.211 0 139.528 0c7.928 0 14.483 2.756 19.667 8.27 5.183 5.512 7.775 11.944 7.775 19.295 0 7.963-2.744 14.548-8.233 19.755-5.488 5.206-11.891 7.81-19.209 7.81Z"/></svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |
@ -8,91 +8,26 @@ import { getRouteCourses } from "../shared/consts/router"
|
|||||||
import { getRouteCourseExercises } from "../shared/consts/router"
|
import { getRouteCourseExercises } from "../shared/consts/router"
|
||||||
import { getRouteSettings } from "../shared/consts/router"
|
import { getRouteSettings } from "../shared/consts/router"
|
||||||
|
|
||||||
|
import { HomeIcon } from "./icons/HomeIcon"
|
||||||
|
import { CoursesIcon } from "./icons/CoursesIcon"
|
||||||
|
import { ExerciseIcon } from "./icons/ExerciseIcon"
|
||||||
|
import { SettingsIcon } from "./icons/SettingsIcon"
|
||||||
|
|
||||||
|
|
||||||
const BottomNavigation: React.FC = () => {
|
const BottomNavigation: React.FC = () => {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
||||||
// Define SVG icons directly within the component, with active state styling
|
|
||||||
const HomeIcon = ({ active }: { active: boolean; size?: number }) => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 29 29"
|
|
||||||
fill={active ? "#2B8794" : "#ffffff"}
|
|
||||||
stroke={"none"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path d="m23.487 7.993-6.75-4.723c-1.84-1.29-4.665-1.219-6.435.152L4.43 8.005c-1.172.914-2.098 2.79-2.098 4.266v8.087c0 2.989 2.426 5.426 5.415 5.426h12.634a5.417 5.417 0 0 0 5.415-5.414v-7.947c0-1.582-1.02-3.527-2.309-4.43Zm-8.544 13.103c0 .48-.398.88-.879.88a.885.885 0 0 1-.879-.88V17.58c0-.48.399-.879.88-.879.48 0 .878.399.878.88v3.515Z" />
|
|
||||||
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const CoursesIcon = ({ active }: { active: boolean; size?: number }) => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 26 26"
|
|
||||||
fill={active ? "#2B8794" : "#ffffff"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M4.147 9.186c.112-1.3.52-2.328 1.21-3.062.69-.733 1.721-1.232 3.194-1.368l.532-.05V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.344h8.79V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.362l.532.05c1.473.136 2.503.635 3.193 1.368.692.734 1.098 1.763 1.21 3.064H4.15a.017.017 0 0 1-.004-.002ZM4.688 12.118H23.44a.59.59 0 0 1 .586.586v7.22c0 1.668-.417 2.969-1.235 3.85-.81.873-2.1 1.425-4.039 1.425H9.376c-1.939 0-3.228-.552-4.039-1.425-.818-.881-1.235-2.182-1.235-3.85v-7.22a.59.59 0 0 1 .586-.586Zm5.945 6.773a1.759 1.759 0 0 0-1.341 0 1.94 1.94 0 0 0-.554.352l-.018.015-.015.017c-.307.324-.5.77-.5 1.235 0 .465.193.911.5 1.235l.015.017.018.016c.164.148.35.266.553.351.201.084.43.139.671.139.242 0 .47-.055.671-.139.204-.085.389-.203.553-.351l.018-.016.015-.017c.307-.324.501-.77.501-1.235 0-.464-.194-.911-.5-1.235l-.016-.017-.018-.015-.127-.106a1.92 1.92 0 0 0-.426-.246Zm0-4.102a1.759 1.759 0 0 0-1.341 0c-.204.085-.39.203-.554.351l-.023.021-.02.023a1.94 1.94 0 0 0-.352.554c-.083.2-.138.43-.138.67 0 .242.055.47.138.67.085.204.204.39.352.554l.02.024.023.02c.164.148.35.267.553.352.201.083.43.138.671.138.242 0 .47-.055.671-.138.204-.085.389-.204.553-.352l.024-.02.02-.024c.148-.164.267-.35.351-.554.084-.2.14-.428.14-.67 0-.24-.056-.47-.14-.67a1.938 1.938 0 0 0-.351-.554l-.02-.022-.024-.022a1.94 1.94 0 0 0-.553-.35Zm4.1 0a1.66 1.66 0 0 0-1.192-.057l-.148.057a1.942 1.942 0 0 0-.553.351l-.017.016-.016.017c-.307.324-.5.771-.5 1.236 0 .464.193.91.5 1.234l.016.017.017.016c.165.148.35.267.553.352.2.083.43.138.671.138.241 0 .47-.055.67-.138.205-.085.39-.204.555-.352l.017-.015.016-.018c.307-.324.5-.77.5-1.234 0-.465-.193-.912-.5-1.236l-.016-.017-.017-.016-.128-.106a1.922 1.922 0 0 0-.409-.237h.001l-.011-.005c-.003 0-.005-.002-.007-.003h-.001Z" />
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const ExerciseIcon = ({ active }: { active: boolean; size?: number }) => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 29 29"
|
|
||||||
fill={active ? "#2B8794" : "#ffffff"}
|
|
||||||
|
|
||||||
>
|
|
||||||
<g clipPath="url(#a)">
|
|
||||||
<path d="M20.136 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.894-.182-2.595-.715-.672-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.543-2.584 1.215-3.094.701-.533 1.65-.716 2.595-.716ZM7.994 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.893-.182-2.595-.715-.671-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.544-2.584 1.215-3.094.702-.533 1.65-.716 2.595-.716ZM15.154 13.771v.586h-2.18v-.586h2.18Z" />
|
|
||||||
<path d="M26.37 17.873a.885.885 0 0 1-.879-.879v-5.86c0-.48.399-.879.88-.879.48 0 .878.399.878.88v5.86c0 .48-.398.878-.879.878ZM1.758 17.873a.885.885 0 0 1-.88-.879v-5.86c0-.48.4-.879.88-.879s.879.399.879.88v5.86c0 .48-.399.878-.88.878Z" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="a">
|
|
||||||
<path fill="#fff" d="M0,0h28v28h-28z" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const SettingsIcon = ({ active }: { active: boolean; size?: number }) => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 28 28"
|
|
||||||
fill={active ? "#2B8794" : "#ffffff"}
|
|
||||||
// stroke={active ? "none" : "#ffffff"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M24.612 19.045H17.58a.885.885 0 0 1-.879-.879c0-.48.399-.879.88-.879h7.031c.48 0 .88.399.88.88 0 .48-.4.878-.88.878ZM24.612 23.733H17.58a.885.885 0 0 1-.879-.879c0-.48.399-.879.88-.879h7.031c.48 0 .88.399.88.88 0 .48-.4.878-.88.878ZM25.784 9.986V4.665c0-1.653-.75-2.321-2.613-2.321h-4.735c-1.864 0-2.614.668-2.614 2.32v5.31c0 1.664.75 2.32 2.614 2.32h4.735c1.863.012 2.613-.656 2.613-2.308ZM12.306 9.986V4.665c0-1.653-.75-2.321-2.613-2.321H4.958c-1.864 0-2.614.668-2.614 2.32v5.31c0 1.664.75 2.32 2.614 2.32h4.735c1.863.012 2.613-.656 2.613-2.308ZM12.306 23.17v-4.734c0-1.864-.75-2.614-2.613-2.614H4.958c-1.864 0-2.614.75-2.614 2.614v4.735c0 1.863.75 2.613 2.614 2.613h4.735c1.863 0 2.613-.75 2.613-2.613Z" />
|
|
||||||
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ path: getRouteHome(), icon: HomeIcon, label: "Домой" },
|
{ path: getRouteHome(), icon: HomeIcon, label: "Домой" },
|
||||||
{ path: getRouteCourses(), icon: CoursesIcon, label: "Курсы" },
|
{ path: getRouteCourses(), icon: CoursesIcon, label: "Курсы" },
|
||||||
{ path: getRouteCourseExercises(':id'), icon: ExerciseIcon, label: "Тренировка" },
|
{ path: getRouteCourseExercises(":id"), icon: ExerciseIcon, label: "Тренировка" },
|
||||||
{ path: getRouteSettings(), icon: SettingsIcon, label: "Меню" },
|
{ path: getRouteSettings(), icon: SettingsIcon, label: "Меню" },
|
||||||
]
|
]
|
||||||
|
|
||||||
const isActive = (path: string) => {
|
const isActive = (path: string) => {
|
||||||
// Проверка на совпадение или включение
|
// Проверка на совпадение или включение
|
||||||
return location.pathname === path || location.pathname.startsWith(path);
|
return location.pathname === path || location.pathname.startsWith(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -109,29 +44,31 @@ const BottomNavigation: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{/* Active state background (glassmorphism rectangle) */}
|
{/* Active state background (glassmorphism rectangle) */}
|
||||||
<div
|
<div
|
||||||
className={`absolute rounded-2xl shadow-md transition-all duration-300 ease-out bg-white/60 backdrop-blur-md border border-white/20 ${active ? "opacity-100 scale-100 w-20 h-20 top-2" : "opacity-0 scale-0 w-0 h-0 top-0"
|
className={`absolute rounded-2xl shadow-md transition-all duration-300 ease-out bg-white/60 backdrop-blur-md border border-white/20 ${
|
||||||
|
active ? "opacity-100 scale-100 w-20 h-20 top-2" : "opacity-0 scale-0 w-0 h-0 top-0"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{/* Icon and Label container */}
|
{/* Icon and Label container */}
|
||||||
<div
|
<div
|
||||||
className={`relative z-10 flex flex-col items-center justify-center transition-all duration-300 ease-out ${active ? "text-[#145058]" : "text-white/70 translate-y-0 group-hover:text-white"
|
className={`relative z-10 flex flex-col items-center justify-center transition-all duration-300 ease-out ${
|
||||||
|
active ? "text-[#145058]" : "text-white/70 translate-y-0 group-hover:text-white"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
<IconComponent active={active} size={24} />
|
<IconComponent active={active} size={34} />
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">{item.label}</span>
|
<span className="text-xs font-medium">{item.label}</span>
|
||||||
<span className="sr-only">{item.label}</span>
|
<span className="sr-only">{item.label}</span>
|
||||||
</div>
|
</div>
|
||||||
{/* Bottom circle with glow */}
|
{/* Bottom circle with glow */}
|
||||||
<div
|
<div
|
||||||
className={`absolute w-4 h-4 rounded-full border-1 border-cyan-900 shadow-lg shadow-[#2BACBE]/50 animate-pulse transition-all duration-300 ease-out ${active ? "opacity-100 scale-100 translate-y-[40px]" : "opacity-0 scale-0"
|
className={`absolute w-4 h-4 rounded-full border-1 border-cyan-900 shadow-lg shadow-[#2BACBE]/50 animate-pulse transition-all duration-300 ease-out ${
|
||||||
|
active ? "opacity-100 scale-100 translate-y-[40px]" : "opacity-0 scale-0"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{/* Внутренний маленький круг */}
|
{/* Внутренний маленький круг */}
|
||||||
<div className="w-3 h-3 bg-cyan-900 rounded-full mt-[1px] ml-[1px]" />
|
<div className="w-3 h-3 bg-cyan-900 rounded-full mt-[1px] ml-[1px]" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@ -27,9 +27,6 @@ const CourseCard: React.FC<CourseCardProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
onClick={() => history.push(getRouteCourseExercises(':id'))}
|
onClick={() => history.push(getRouteCourseExercises(':id'))}
|
||||||
className="bg-white/30 backdrop-blur-2xl rounded-3xl p-6 border border-white/20 shadow-xl cursor-pointer hover:shadow-2xl transition-all duration-300 transform hover:scale-[1.02]"
|
className="bg-white/30 backdrop-blur-2xl rounded-3xl p-6 border border-white/20 shadow-xl cursor-pointer hover:shadow-2xl transition-all duration-300 transform hover:scale-[1.02]"
|
||||||
|
40
src/components/cards/StatCard.tsx
Normal file
40
src/components/cards/StatCard.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface StatCardProps {
|
||||||
|
title: string
|
||||||
|
subtitle: string
|
||||||
|
icon: React.ComponentType<{ size?: number; className?: string; color?: string }>
|
||||||
|
iconColor: string
|
||||||
|
backgroundIconColor: string
|
||||||
|
onClick: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StatCard: React.FC<StatCardProps> = ({
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
icon: Icon,
|
||||||
|
iconColor,
|
||||||
|
backgroundIconColor,
|
||||||
|
onClick,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClick}
|
||||||
|
className="glass-morphism rounded-3xl text-left border border-white/50 shadow-lg backdrop-blur-xl p-6 text-white transition-transform transform hover:scale-105 duration-300 overflow-hidden cursor-pointer"
|
||||||
|
>
|
||||||
|
{/* Фоновая иконка */}
|
||||||
|
<Icon size={180} color={backgroundIconColor} className="absolute -right-8 -top-8 -rotate-45" />
|
||||||
|
|
||||||
|
{/* Основная иконка */}
|
||||||
|
<div className="w-20 h-20 bg-white/20 rounded-2xl flex items-center justify-center shadow-xl mb-4 z-20 relative">
|
||||||
|
<Icon size={40} color={iconColor} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Текст */}
|
||||||
|
<div className="text-xl font-bold text-gray-800 mb-1 z-20 relative">{title}</div>
|
||||||
|
<div className="text-base text-gray-600 z-20 relative">{subtitle}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
67
src/components/cards/WorkoutCard.tsx
Normal file
67
src/components/cards/WorkoutCard.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface WorkoutCardProps {
|
||||||
|
onBackClick: () => void
|
||||||
|
onCardClick: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WorkoutCard: React.FC<WorkoutCardProps> = ({ onBackClick, onCardClick }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onCardClick}
|
||||||
|
className="bg-gradient-to-r from-[#2BACBE] to-[#1E7F8C] rounded-3xl p-6 shadow-2xl text-white max-w-4xl mx-auto my-8 transition-transform transform hover:scale-105 duration-300 cursor-pointer"
|
||||||
|
>
|
||||||
|
{/* Заголовок и статус */}
|
||||||
|
<div className="flex items-center justify-between flex-wrap mb-6 border-b-2 pb-4">
|
||||||
|
<h2 className="text-xl sm:text-2xl font-extrabold">Тренировка</h2>
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
onBackClick()
|
||||||
|
}}
|
||||||
|
className="w-12 h-12 glass-morphism rounded-2xl flex items-center justify-center border border-white/30 hover:bg-white/30 transition-all duration-300 shadow-lg ml-auto"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6 text-white transform rotate-180"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7L15 5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Основной блок с иконками и прогрессом */}
|
||||||
|
<div className="flex items-start flex-wrap space-x-4 mb-6">
|
||||||
|
{/* Иконка часов */}
|
||||||
|
<div className="relative flex-shrink-0 mr-6">
|
||||||
|
<div className="w-20 h-20 bg-white/70 rounded-2xl flex items-center justify-center shadow-xl transition-transform hover:scale-105 duration-300">
|
||||||
|
{/* Clock SVG */}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 20 20" fill="none">
|
||||||
|
<path
|
||||||
|
fill="#2BACBE"
|
||||||
|
d="M15 1.34A10 10 0 1 1 .005 10.324L0 10l.005-.324A10 10 0 0 1 15 1.34ZM10 4a1 1 0 0 0-.993.883L9 5v5l.009.13a1 1 0 0 0 .197.478l.087.1 3 3 .094.082a1 1 0 0 0 1.226 0l.094-.083.083-.094a1 1 0 0 0 0-1.226l-.083-.094L11 9.585V5l-.007-.117A1 1 0 0 0 10 4Z"
|
||||||
|
/>
|
||||||
|
<polyline points="12,6,12,12,16,14" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
{/* Пульсирующая точка */}
|
||||||
|
<div className="absolute -bottom-1 -right-1 w-6 h-6 bg-white rounded-full shadow-lg animate-pulse flex items-center justify-center">
|
||||||
|
<svg className="w-3 h-3 text-[#2BACBE]" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path d="M8 5v14l11-7z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Информация о упражнении */}
|
||||||
|
<div className="flex flex-col justify-center flex-grow">
|
||||||
|
<h3 className="font-extrabold text-lg mb-2">В процессе</h3>
|
||||||
|
<p className="text-white/70 font-medium mb-4 text-base">Текущее упражнение</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
37
src/components/icons/ArrowIcon.tsx
Normal file
37
src/components/icons/ArrowIcon.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
direction?: "left" | "right" | "up" | "down"
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ArrowIcon: React.FC<IconProps> = ({ size = 24, className = "", direction = "left" }) => {
|
||||||
|
const getRotation = () => {
|
||||||
|
switch (direction) {
|
||||||
|
case "right":
|
||||||
|
return "rotate-0"
|
||||||
|
case "down":
|
||||||
|
return "rotate-90"
|
||||||
|
case "left":
|
||||||
|
return "rotate-180"
|
||||||
|
case "up":
|
||||||
|
return "rotate-270"
|
||||||
|
default:
|
||||||
|
return "rotate-180"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={`${className} transform ${getRotation()}`}
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7L15 5" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
23
src/components/icons/CalendarIcon.tsx
Normal file
23
src/components/icons/CalendarIcon.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
color?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CalendarIcon: React.FC<IconProps> = ({ size = 40, className = "", color = "#2B8794" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 26 26"
|
||||||
|
fill={color}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path d="M4.147 9.186c.112-1.3.52-2.328 1.21-3.062.69-.733 1.721-1.232 3.194-1.368l.532-.05V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.344h8.79V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.362l.532.05c1.473.136 2.503.635 3.193 1.368.692.734 1.098 1.763 1.21 3.064H4.15a.017.017 0 0 1-.004-.002ZM4.688 12.118H23.44a.59.59 0 0 1 .586.586v7.22c0 1.668-.417 2.969-1.235 3.85-.81.873-2.1 1.425-4.039 1.425H9.376c-1.939 0-3.228-.552-4.039-1.425-.818-.881-1.235-2.182-1.235-3.85v-7.22a.59.59 0 0 1 .586-.586Zm5.945 6.773a1.759 1.759 0 0 0-1.341 0 1.94 1.94 0 0 0-.554.352l-.018.015-.015.017c-.307.324-.5.77-.5 1.235 0 .465.193.911.5 1.235l.015.017.018.016c.164.148.35.266.553.351.201.084.43.139.671.139.242 0 .47-.055.671-.139.204-.085.389-.203.553-.351l.018-.016.015-.017c.307-.324.501-.77.501-1.235 0-.464-.194-.911-.5-1.235l-.016-.017-.018-.015-.127-.106a1.92 1.92 0 0 0-.426-.246Zm0-4.102a1.759 1.759 0 0 0-1.341 0c-.204.085-.39.203-.554.351l-.023.021-.02.023a1.94 1.94 0 0 0-.352.554c-.083.2-.138.43-.138.67 0 .242.055.47.138.67.085.204.204.39.352.554l.02.024.023.02c.164.148.35.267.553.352.201.083.43.138.671.138.242 0 .47-.055.671-.138.204-.085.389-.204.553-.352l.024-.02.02-.024c.148-.164.267-.35.351-.554.084-.2.14-.428.14-.67 0-.24-.056-.47-.14-.67a1.938 1.938 0 0 0-.351-.554l-.02-.022-.024-.022a1.94 1.94 0 0 0-.553-.35Zm4.1 0a1.66 1.66 0 0 0-1.192-.057l-.148.057a1.942 1.942 0 0 0-.553.351l-.017.016-.016.017c-.307.324-.5.771-.5 1.236 0 .464.193.91.5 1.234l.016.017.017.016c.165.148.35.267.553.352.2.083.43.138.671.138.241 0 .47-.055.67-.138.205-.085.39-.204.555-.352l.017-.015.016-.018c.307-.324.5-.77.5-1.234 0-.465-.193-.912-.5-1.236l-.016-.017-.017-.016-.128-.106a1.922 1.922 0 0 0-.409-.237h.001l-.011-.005c-.003 0-.005-.002-.007-.003h-.001Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
24
src/components/icons/ClockIcon.tsx
Normal file
24
src/components/icons/ClockIcon.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
color?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ClockIcon: React.FC<IconProps> = ({ size = 40, className = "", color = "#2BACBE" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill={color}
|
||||||
|
d="M15 1.34A10 10 0 1 1 .005 10.324L0 10l.005-.324A10 10 0 0 1 15 1.34ZM10 4a1 1 0 0 0-.993.883L9 5v5l.009.13a1 1 0 0 0 .197.478l.087.1 3 3 .094.082a1 1 0 0 0 1.226 0l.094-.083.083-.094a1 1 0 0 0 0-1.226l-.083-.094L11 9.585V5l-.007-.117A1 1 0 0 0 10 4Z"
|
||||||
|
/>
|
||||||
|
<polyline points="12,6,12,12,16,14" />
|
||||||
|
</svg>
|
||||||
|
)
|
23
src/components/icons/CoursesIcon.tsx
Normal file
23
src/components/icons/CoursesIcon.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
active?: boolean
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CoursesIcon: React.FC<IconProps> = ({ active = false, size = 40, className = "" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 26 26"
|
||||||
|
fill={active ? "#2B8794" : "#ffffff"}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path d="M4.147 9.186c.112-1.3.52-2.328 1.21-3.062.69-.733 1.721-1.232 3.194-1.368l.532-.05V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.344h8.79V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.362l.532.05c1.473.136 2.503.635 3.193 1.368.692.734 1.098 1.763 1.21 3.064H4.15a.017.017 0 0 1-.004-.002ZM4.688 12.118H23.44a.59.59 0 0 1 .586.586v7.22c0 1.668-.417 2.969-1.235 3.85-.81.873-2.1 1.425-4.039 1.425H9.376c-1.939 0-3.228-.552-4.039-1.425-.818-.881-1.235-2.182-1.235-3.85v-7.22a.59.59 0 0 1 .586-.586Zm5.945 6.773a1.759 1.759 0 0 0-1.341 0 1.94 1.94 0 0 0-.554.352l-.018.015-.015.017c-.307.324-.5.77-.5 1.235 0 .465.193.911.5 1.235l.015.017.018.016c.164.148.35.266.553.351.201.084.43.139.671.139.242 0 .47-.055.671-.139.204-.085.389-.203.553-.351l.018-.016.015-.017c.307-.324.501-.77.501-1.235 0-.464-.194-.911-.5-1.235l-.016-.017-.018-.015-.127-.106a1.92 1.92 0 0 0-.426-.246Zm0-4.102a1.759 1.759 0 0 0-1.341 0c-.204.085-.39.203-.554.351l-.023.021-.02.023a1.94 1.94 0 0 0-.352.554c-.083.2-.138.43-.138.67 0 .242.055.47.138.67.085.204.204.39.352.554l.02.024.023.02c.164.148.35.267.553.352.201.083.43.138.671.138.242 0 .47-.055.671-.138.204-.085.389-.204.553-.352l.024-.02.02-.024c.148-.164.267-.35.351-.554.084-.2.14-.428.14-.67 0-.24-.056-.47-.14-.67a1.938 1.938 0 0 0-.351-.554l-.02-.022-.024-.022a1.94 1.94 0 0 0-.553-.35Zm4.1 0a1.66 1.66 0 0 0-1.192-.057l-.148.057a1.942 1.942 0 0 0-.553.351l-.017.016-.016.017c-.307.324-.5.771-.5 1.236 0 .464.193.91.5 1.234l.016.017.017.016c.165.148.35.267.553.352.2.083.43.138.671.138.241 0 .47-.055.67-.138.205-.085.39-.204.555-.352l.017-.015.016-.018c.307-.324.5-.77.5-1.234 0-.465-.193-.912-.5-1.236l-.016-.017-.017-.016-.128-.106a1.922 1.922 0 0 0-.409-.237h.001l-.011-.005c-.003 0-.005-.002-.007-.003h-.001Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
24
src/components/icons/DumbbellIcon.tsx
Normal file
24
src/components/icons/DumbbellIcon.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
color?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DumbbellIcon: React.FC<IconProps> = ({ size = 40, className = "", color = "#FF8D28" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 27 27"
|
||||||
|
fill={color}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path d="M20.136 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.894-.182-2.595-.715-.672-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.543-2.584 1.215-3.094.701-.533 1.65-.716 2.595-.716ZM7.994 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.893-.182-2.595-.715-.671-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.544-2.584 1.215-3.094.702-.533 1.65-.716 2.595-.716ZM15.154 13.771v.586h-2.18v-.586h2.18Z" />
|
||||||
|
<path d="M26.37 17.873a.885.885 0 0 1-.879-.879v-5.86c0-.48.399-.879.88-.879.48 0 .878.399.878.88v5.86c0 .48-.398.878-.879.878ZM1.758 17.873a.885.885 0 0 1-.88-.879v-5.86c0-.48.4-.879.88-.879s.879.399.879.88v5.86c0 .48-.399.878-.88.878Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
28
src/components/icons/ExerciseIcon.tsx
Normal file
28
src/components/icons/ExerciseIcon.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
active?: boolean
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ExerciseIcon: React.FC<IconProps> = ({ active = false, size = 40, className = "" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 29 29"
|
||||||
|
fill={active ? "#2B8794" : "#ffffff"}
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<g clipPath="url(#a)">
|
||||||
|
<path d="M20.136 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.894-.182-2.595-.715-.672-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.543-2.584 1.215-3.094.701-.533 1.65-.716 2.595-.716ZM7.994 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.893-.182-2.595-.715-.671-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.544-2.584 1.215-3.094.702-.533 1.65-.716 2.595-.716ZM15.154 13.771v.586h-2.18v-.586h2.18Z" />
|
||||||
|
<path d="M26.37 17.873a.885.885 0 0 1-.879-.879v-5.86c0-.48.399-.879.88-.879.48 0 .878.399.878.88v5.86c0 .48-.398.878-.879.878ZM1.758 17.873a.885.885 0 0 1-.88-.879v-5.86c0-.48.4-.879.88-.879s.879.399.879.88v5.86c0 .48-.399.878-.88.878Z" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="a">
|
||||||
|
<path fill="#fff" d="M0,0h28v28h-28z" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
)
|
24
src/components/icons/HomeIcon.tsx
Normal file
24
src/components/icons/HomeIcon.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
active?: boolean
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HomeIcon: React.FC<IconProps> = ({ active = false, size = 40, className = "" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 29 29"
|
||||||
|
fill={active ? "#2B8794" : "#ffffff"}
|
||||||
|
stroke="none"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path d="m23.487 7.993-6.75-4.723c-1.84-1.29-4.665-1.219-6.435.152L4.43 8.005c-1.172.914-2.098 2.79-2.098 4.266v8.087c0 2.989 2.426 5.426 5.415 5.426h12.634a5.417 5.417 0 0 0 5.415-5.414v-7.947c0-1.582-1.02-3.527-2.309-4.43Zm-8.544 13.103c0 .48-.398.88-.879.88a.885.885 0 0 1-.879-.88V17.58c0-.48.399-.879.88-.879.48 0 .878.399.878.88v3.515Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
13
src/components/icons/PlayIcon.tsx
Normal file
13
src/components/icons/PlayIcon.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
color?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PlayIcon: React.FC<IconProps> = ({ size = 12, className = "", color = "currentColor" }) => (
|
||||||
|
<svg className={className} width={size} height={size} fill={color} viewBox="0 0 24 24">
|
||||||
|
<path d="M8 5v14l11-7z" />
|
||||||
|
</svg>
|
||||||
|
)
|
23
src/components/icons/SettingsIcon.tsx
Normal file
23
src/components/icons/SettingsIcon.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import type React from "react"
|
||||||
|
|
||||||
|
interface IconProps {
|
||||||
|
active?: boolean
|
||||||
|
size?: number
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SettingsIcon: React.FC<IconProps> = ({ active = false, size = 40, className = "" }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 28 28"
|
||||||
|
fill={active ? "#2B8794" : "#ffffff"}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path d="M24.612 19.045H17.58a.885.885 0 0 1-.879-.879c0-.48.399-.879.88-.879h7.031c.48 0 .88.399.88.88 0 .48-.4.878-.88.878ZM24.612 23.733H17.58a.885.885 0 0 1-.879-.879c0-.48.399-.879.88-.879h7.031c.48 0 .88.399.88.88 0 .48-.4.878-.88.878ZM25.784 9.986V4.665c0-1.653-.75-2.321-2.613-2.321h-4.735c-1.864 0-2.614.668-2.614 2.32v5.31c0 1.664.75 2.32 2.614 2.32h4.735c1.863.012 2.613-.656 2.613-2.308ZM12.306 9.986V4.665c0-1.653-.75-2.321-2.613-2.321H4.958c-1.864 0-2.614.668-2.614 2.32v5.31c0 1.664.75 2.32 2.614 2.32h4.735c1.863.012 2.613-.656 2.613-2.308ZM12.306 23.17v-4.734c0-1.864-.75-2.614-2.613-2.614H4.958c-1.864 0-2.614.75-2.614 2.614v4.735c0 1.863.75 2.613 2.614 2.613h4.735c1.863 0 2.613-.75 2.613-2.613Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
@ -1,16 +1,22 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import { useHistory, Link } from "react-router-dom"
|
import { useHistory } from "react-router-dom"
|
||||||
|
|
||||||
|
|
||||||
|
import { CalendarIcon } from "../components/icons/CalendarIcon"
|
||||||
|
import { DumbbellIcon } from "../components/icons/DumbbellIcon"
|
||||||
|
|
||||||
|
|
||||||
import HeaderNav from "../components/HeaderNav"
|
import HeaderNav from "../components/HeaderNav"
|
||||||
import BottomNavigation from "../components/BottomNavigation"
|
import BottomNavigation from "../components/BottomNavigation"
|
||||||
import CircularProgressDisplay from "../components/CircularProgressDisplay"
|
import CircularProgressDisplay from "../components/CircularProgressDisplay"
|
||||||
|
|
||||||
|
import { WorkoutCard } from "../components/cards/WorkoutCard"
|
||||||
|
import { StatCard } from "../components/cards/StatCard"
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
@ -27,16 +33,12 @@ export default function Home() {
|
|||||||
)
|
)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const courses = [
|
const courses = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: "Восстановление колена",
|
name: "Восстановление колена",
|
||||||
progress: 75,
|
progress: 75,
|
||||||
color: "from-[#2BACBE] to-cyan-600",
|
color: "from-[#2BACBE] to-cyan-600",
|
||||||
icon: "🦵",
|
|
||||||
exercises: 12,
|
exercises: 12,
|
||||||
nextExercise: "Подъемы ног лежа",
|
nextExercise: "Подъемы ног лежа",
|
||||||
},
|
},
|
||||||
@ -45,7 +47,6 @@ export default function Home() {
|
|||||||
name: "Укрепление спины",
|
name: "Укрепление спины",
|
||||||
progress: 45,
|
progress: 45,
|
||||||
color: "from-emerald-500 to-green-600",
|
color: "from-emerald-500 to-green-600",
|
||||||
icon: "🏃♂️",
|
|
||||||
exercises: 8,
|
exercises: 8,
|
||||||
nextExercise: "Планка",
|
nextExercise: "Планка",
|
||||||
},
|
},
|
||||||
@ -54,7 +55,6 @@ export default function Home() {
|
|||||||
name: "Реабилитация плеча",
|
name: "Реабилитация плеча",
|
||||||
progress: 90,
|
progress: 90,
|
||||||
color: "from-purple-500 to-pink-600",
|
color: "from-purple-500 to-pink-600",
|
||||||
icon: "💪",
|
|
||||||
exercises: 10,
|
exercises: 10,
|
||||||
nextExercise: "Вращения плечами",
|
nextExercise: "Вращения плечами",
|
||||||
},
|
},
|
||||||
@ -65,14 +65,26 @@ export default function Home() {
|
|||||||
const totalExercises = courses.reduce((sum, course) => sum + course.exercises, 0)
|
const totalExercises = courses.reduce((sum, course) => sum + course.exercises, 0)
|
||||||
const overallProgress = Math.round(courses.reduce((sum, course) => sum + course.progress, 0) / totalCourses)
|
const overallProgress = Math.round(courses.reduce((sum, course) => sum + course.progress, 0) / totalCourses)
|
||||||
|
|
||||||
|
const handleWorkoutClick = () => {
|
||||||
|
history.push(getRouteExercise(":id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBackClick = () => {
|
||||||
|
history.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCoursesClick = () => {
|
||||||
|
history.push(getRouteCourses())
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleExercisesClick = () => {
|
||||||
|
history.push(getRouteCourseExercises(":id"))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className="bg-gray-50 w-full h-full overflow-auto">
|
<div className="bg-gray-50 w-full h-full overflow-auto">
|
||||||
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
<div className="my-36 min-h-screen max-w-4xl mx-auto">
|
||||||
|
<HeaderNav item="Результаты" text="главная" />
|
||||||
<HeaderNav item='Результаты' text='главная'/>
|
|
||||||
|
|
||||||
<div className="bg-white rounded-3xl p-6 shadow-lg mb-6 mx-4 sm:mx-6">
|
<div className="bg-white rounded-3xl p-6 shadow-lg mb-6 mx-4 sm:mx-6">
|
||||||
<div className="flex items-center justify-between mb-6 border-b-2 border-gray-400 pb-4">
|
<div className="flex items-center justify-between mb-6 border-b-2 border-gray-400 pb-4">
|
||||||
@ -103,117 +115,32 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div onClick={() => history.push(getRouteExercise(':id'))} className="px-4 sm:px-6 space-y-6 ">
|
|
||||||
{/* Current Exercise */}
|
|
||||||
<div className="bg-gradient-to-r from-[#2BACBE] to-[#1E7F8C] rounded-3xl p-6 shadow-2xl text-white max-w-4xl mx-auto my-8 transition-transform transform hover:scale-105 duration-300">
|
|
||||||
{/* Заголовок и статус */}
|
|
||||||
<div className="flex items-center justify-between flex-wrap mb-6 border-b-2 pb-4">
|
|
||||||
<h2 className="text-xl sm:text-2xl font-extrabold">Тренировка</h2>
|
|
||||||
<button
|
|
||||||
onClick={() => history.goBack()}
|
|
||||||
className="w-12 h-12 glass-morphism rounded-2xl flex items-center justify-center border border-white/30 hover:bg-white/30 transition-all duration-300 shadow-lg ml-auto"
|
|
||||||
>
|
|
||||||
<svg className="w-6 h-6 text-white transform rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7L15 5" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{/* Основной блок с иконками и прогрессом */}
|
|
||||||
<div className="flex items-start flex-wrap space-x-4 mb-6">
|
|
||||||
{/* Иконка часов */}
|
|
||||||
<div className="relative flex-shrink-0 mr-6">
|
|
||||||
<div className="w-20 h-20 bg-white/70 rounded-2xl flex items-center justify-center shadow-xl transition-transform hover:scale-105 duration-300">
|
|
||||||
{/* Clock SVG */}
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 20 20" fill="none">
|
|
||||||
<path fill="#2BACBE" d="M15 1.34A10 10 0 1 1 .005 10.324L0 10l.005-.324A10 10 0 0 1 15 1.34ZM10 4a1 1 0 0 0-.993.883L9 5v5l.009.13a1 1 0 0 0 .197.478l.087.1 3 3 .094.082a1 1 0 0 0 1.226 0l.094-.083.083-.094a1 1 0 0 0 0-1.226l-.083-.094L11 9.585V5l-.007-.117A1 1 0 0 0 10 4Z" />
|
|
||||||
<polyline points="12,6,12,12,16,14" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
{/* Пульсирующая точка */}
|
|
||||||
<div className="absolute -bottom-1 -right-1 w-6 h-6 bg-white rounded-full shadow-lg animate-pulse flex items-center justify-center">
|
|
||||||
<svg className="w-3 h-3 text-[#2BACBE]" fill="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path d="M8 5v14l11-7z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* Информация о упражнении */}
|
|
||||||
<div className="flex flex-col justify-center flex-grow">
|
|
||||||
<h3 className="font-extrabold text-lg mb-2">В процессе</h3>
|
|
||||||
<p className="text-white/70 font-medium mb-4 text-base">Текущее упражнение</p>
|
|
||||||
{/* Кнопка с стрелкой */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
<div className="px-4 sm:px-6 space-y-6">
|
||||||
</div>
|
{/* Current Exercise */}
|
||||||
|
<WorkoutCard onBackClick={handleBackClick} onCardClick={handleWorkoutClick} />
|
||||||
|
|
||||||
{/* Quick Stats (Total Exercises & Total Courses) */}
|
{/* Quick Stats (Total Exercises & Total Courses) */}
|
||||||
<div className="grid grid-cols-2 gap-4 md:gap-10">
|
<div className="grid grid-cols-2 gap-4 md:gap-10">
|
||||||
<div onClick={() => history.push(getRouteCourses())} className="glass-morphism rounded-3xl text-left border border-white/50 shadow-lg backdrop-blur-xl p-6 text-white transition-transform transform hover:scale-105 duration-300 overflow-hidden">
|
<StatCard
|
||||||
<svg
|
title="Курсы"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
subtitle="все назначенные"
|
||||||
width={180}
|
icon={CalendarIcon}
|
||||||
height={180}
|
iconColor="#2B8794"
|
||||||
viewBox="0 0 26 26"
|
backgroundIconColor="#E6E5E5"
|
||||||
fill={"#E6E5E5"}
|
onClick={handleCoursesClick}
|
||||||
strokeWidth="2"
|
/>
|
||||||
strokeLinecap="round"
|
<StatCard
|
||||||
strokeLinejoin="round"
|
title="Упражнения"
|
||||||
className="absolute -right-8 -top-8 -rotate-45"
|
subtitle="внутри текущего курса"
|
||||||
>
|
icon={DumbbellIcon}
|
||||||
<path d="M4.147 9.186c.112-1.3.52-2.328 1.21-3.062.69-.733 1.721-1.232 3.194-1.368l.532-.05V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.344h8.79V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.362l.532.05c1.473.136 2.503.635 3.193 1.368.692.734 1.098 1.763 1.21 3.064H4.15a.017.017 0 0 1-.004-.002ZM4.688 12.118H23.44a.59.59 0 0 1 .586.586v7.22c0 1.668-.417 2.969-1.235 3.85-.81.873-2.1 1.425-4.039 1.425H9.376c-1.939 0-3.228-.552-4.039-1.425-.818-.881-1.235-2.182-1.235-3.85v-7.22a.59.59 0 0 1 .586-.586Zm5.945 6.773a1.759 1.759 0 0 0-1.341 0 1.94 1.94 0 0 0-.554.352l-.018.015-.015.017c-.307.324-.5.77-.5 1.235 0 .465.193.911.5 1.235l.015.017.018.016c.164.148.35.266.553.351.201.084.43.139.671.139.242 0 .47-.055.671-.139.204-.085.389-.203.553-.351l.018-.016.015-.017c.307-.324.501-.77.501-1.235 0-.464-.194-.911-.5-1.235l-.016-.017-.018-.015-.127-.106a1.92 1.92 0 0 0-.426-.246Zm0-4.102a1.759 1.759 0 0 0-1.341 0c-.204.085-.39.203-.554.351l-.023.021-.02.023a1.94 1.94 0 0 0-.352.554c-.083.2-.138.43-.138.67 0 .242.055.47.138.67.085.204.204.39.352.554l.02.024.023.02c.164.148.35.267.553.352.201.083.43.138.671.138.242 0 .47-.055.671-.138.204-.085.389-.204.553-.352l.024-.02.02-.024c.148-.164.267-.35.351-.554.084-.2.14-.428.14-.67 0-.24-.056-.47-.14-.67a1.938 1.938 0 0 0-.351-.554l-.02-.022-.024-.022a1.94 1.94 0 0 0-.553-.35Zm4.1 0a1.66 1.66 0 0 0-1.192-.057l-.148.057a1.942 1.942 0 0 0-.553.351l-.017.016-.016.017c-.307.324-.5.771-.5 1.236 0 .464.193.91.5 1.234l.016.017.017.016c.165.148.35.267.553.352.2.083.43.138.671.138.241 0 .47-.055.67-.138.205-.085.39-.204.555-.352l.017-.015.016-.018c.307-.324.5-.77.5-1.234 0-.465-.193-.912-.5-1.236l-.016-.017-.017-.016-.128-.106a1.922 1.922 0 0 0-.409-.237h.001l-.011-.005c-.003 0-.005-.002-.007-.003h-.001Z" />
|
iconColor="#FF8D28"
|
||||||
</svg>
|
backgroundIconColor="#E6E5E5"
|
||||||
<div className="w-20 h-20 bg-white/20 rounded-2xl flex items-center justify-center shadow-xl mb-4 z-20 relative">
|
onClick={handleExercisesClick}
|
||||||
{/* Clock icon SVG */}
|
/>
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 26 26"
|
|
||||||
fill={"#2B8794"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M4.147 9.186c.112-1.3.52-2.328 1.21-3.062.69-.733 1.721-1.232 3.194-1.368l.532-.05V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.344h8.79V2.344a.3.3 0 0 1 .293-.293.3.3 0 0 1 .293.293v2.362l.532.05c1.473.136 2.503.635 3.193 1.368.692.734 1.098 1.763 1.21 3.064H4.15a.017.017 0 0 1-.004-.002ZM4.688 12.118H23.44a.59.59 0 0 1 .586.586v7.22c0 1.668-.417 2.969-1.235 3.85-.81.873-2.1 1.425-4.039 1.425H9.376c-1.939 0-3.228-.552-4.039-1.425-.818-.881-1.235-2.182-1.235-3.85v-7.22a.59.59 0 0 1 .586-.586Zm5.945 6.773a1.759 1.759 0 0 0-1.341 0 1.94 1.94 0 0 0-.554.352l-.018.015-.015.017c-.307.324-.5.77-.5 1.235 0 .465.193.911.5 1.235l.015.017.018.016c.164.148.35.266.553.351.201.084.43.139.671.139.242 0 .47-.055.671-.139.204-.085.389-.203.553-.351l.018-.016.015-.017c.307-.324.501-.77.501-1.235 0-.464-.194-.911-.5-1.235l-.016-.017-.018-.015-.127-.106a1.92 1.92 0 0 0-.426-.246Zm0-4.102a1.759 1.759 0 0 0-1.341 0c-.204.085-.39.203-.554.351l-.023.021-.02.023a1.94 1.94 0 0 0-.352.554c-.083.2-.138.43-.138.67 0 .242.055.47.138.67.085.204.204.39.352.554l.02.024.023.02c.164.148.35.267.553.352.201.083.43.138.671.138.242 0 .47-.055.671-.138.204-.085.389-.204.553-.352l.024-.02.02-.024c.148-.164.267-.35.351-.554.084-.2.14-.428.14-.67 0-.24-.056-.47-.14-.67a1.938 1.938 0 0 0-.351-.554l-.02-.022-.024-.022a1.94 1.94 0 0 0-.553-.35Zm4.1 0a1.66 1.66 0 0 0-1.192-.057l-.148.057a1.942 1.942 0 0 0-.553.351l-.017.016-.016.017c-.307.324-.5.771-.5 1.236 0 .464.193.91.5 1.234l.016.017.017.016c.165.148.35.267.553.352.2.083.43.138.671.138.241 0 .47-.055.67-.138.205-.085.39-.204.555-.352l.017-.015.016-.018c.307-.324.5-.77.5-1.234 0-.465-.193-.912-.5-1.236l-.016-.017-.017-.016-.128-.106a1.922 1.922 0 0 0-.409-.237h.001l-.011-.005c-.003 0-.005-.002-.007-.003h-.001Z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="text-xl font-bold text-gray-800 mb-1 z-20 relative">Курсы</div>
|
|
||||||
<div className="text-base text-gray-600 z-20 relative">все назначенные</div>
|
|
||||||
</div>
|
|
||||||
<div onClick={() => history.push(getRouteCourseExercises(':id'))} className="glass-morphism rounded-3xl text-left border border-white/50 shadow-lg backdrop-blur-xl p-6 text-white transition-transform transform hover:scale-105 duration-300 overflow-hidden">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={180}
|
|
||||||
height={180}
|
|
||||||
viewBox="0 0 26 26"
|
|
||||||
fill={"#E6E5E5"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
className="absolute -right-8 -top-8 -rotate-45"
|
|
||||||
>
|
|
||||||
<path d="M20.136 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.894-.182-2.595-.715-.672-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.543-2.584 1.215-3.094.701-.533 1.65-.716 2.595-.716ZM7.994 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.893-.182-2.595-.715-.671-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.544-2.584 1.215-3.094.702-.533 1.65-.716 2.595-.716ZM15.154 13.771v.586h-2.18v-.586h2.18Z" />
|
|
||||||
<path d="M26.37 17.873a.885.885 0 0 1-.879-.879v-5.86c0-.48.399-.879.88-.879.48 0 .878.399.878.88v5.86c0 .48-.398.878-.879.878ZM1.758 17.873a.885.885 0 0 1-.88-.879v-5.86c0-.48.4-.879.88-.879s.879.399.879.88v5.86c0 .48-.399.878-.88.878Z" />
|
|
||||||
</svg>
|
|
||||||
<div className="w-20 h-20 bg-white/20 rounded-2xl flex items-center justify-center shadow-xl mb-4 z-20 relative">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
viewBox="0 0 27 27"
|
|
||||||
fill={"#FF8D28"}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M20.136 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.894-.182-2.595-.715-.672-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.543-2.584 1.215-3.094.701-.533 1.65-.716 2.595-.716ZM7.994 6.739c.944 0 1.892.183 2.593.716.672.51 1.215 1.417 1.215 3.094v7.03c0 1.677-.543 2.584-1.215 3.095-.701.533-1.65.715-2.593.715-.945 0-1.893-.182-2.595-.715-.671-.51-1.215-1.418-1.215-3.094v-7.031c0-1.677.544-2.584 1.215-3.094.702-.533 1.65-.716 2.595-.716ZM15.154 13.771v.586h-2.18v-.586h2.18Z" />
|
|
||||||
<path d="M26.37 17.873a.885.885 0 0 1-.879-.879v-5.86c0-.48.399-.879.88-.879.48 0 .878.399.878.88v5.86c0 .48-.398.878-.879.878ZM1.758 17.873a.885.885 0 0 1-.88-.879v-5.86c0-.48.4-.879.88-.879s.879.399.879.88v5.86c0 .48-.399.878-.88.878Z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="text-xl font-bold text-gray-800 mb-1 z-20 relative">Упражнения</div>
|
|
||||||
<div className="text-base text-gray-600 z-20 relative">внутри текущего курса </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BottomNavigation />
|
<BottomNavigation />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ import type React from "react"
|
|||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import { useIonRouter } from '@ionic/react';
|
import { useIonRouter } from '@ionic/react';
|
||||||
|
|
||||||
const CourseComplete: React.FC = () => {
|
const Welcome: React.FC = () => {
|
||||||
|
|
||||||
const [animationPhase, setAnimationPhase] = useState(0)
|
const [animationPhase, setAnimationPhase] = useState(0)
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ const CourseComplete: React.FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CourseComplete
|
export default Welcome
|
||||||
|
|
||||||
|
|
||||||
// <svg xmlns="http://www.w3.org/2000/svg" width="292" height="221" viewBox="0 0 292 221" fill="none">
|
// <svg xmlns="http://www.w3.org/2000/svg" width="292" height="221" viewBox="0 0 292 221" fill="none">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user