fixed others, added modal with video

This commit is contained in:
2024-07-09 14:31:30 +05:00
parent 616badbc7b
commit e14c5cef52
10 changed files with 165 additions and 51 deletions
+2
View File
@@ -13,12 +13,14 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"react-router-hash-link": "^2.4.3",
"react-swipeable": "^7.0.1",
"zustand": "^4.5.4"
},
"devDependencies": {
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-router-hash-link": "^2.4.9",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
+14 -13
View File
@@ -1,7 +1,8 @@
import { useState } from 'react';
import { PropsWithChildren, useState } from 'react';
import { NavLink } from '../../ui/NavLink';
import { Link } from 'react-router-dom';
import { Lang, useLang } from '../../store/language';
import { HashLink } from 'react-router-hash-link';
export function Navbar() {
const [menuOpen, setMenuOpen] = useState(false);
@@ -19,10 +20,10 @@ export function Navbar() {
/>
</Link>
<div className="flex">
<NavLink text="Типы тренажеров" route="/" />
<NavLink text="Варианты комплектации" route="/" />
<NavLink text="Проекты" route="/" />
<NavLink text="События" route="/" />
<NavLink route="#products">Типы тренажеров</NavLink>
<NavLink route="#trainings">Варианты комплектации</NavLink>
<NavLink route="#projects">Проекты</NavLink>
<NavLink route="#events">События</NavLink>
<button className="btn-text font-semibold text-[#ffffff] bg-gradient-to-r from-[#798FFF] to-[#D375FF] border-x border-[#3D425C] tablet:block mobile:hidden px-10">
Оставить заявку
</button>
@@ -46,10 +47,10 @@ export function Navbar() {
(menuOpen ? ' shadow-[0_0_0_9999px_rgba(0,0,0,.4)]' : '')
}
>
<BurgerLink route="/" text="Типы тренажеров" />
<BurgerLink route="/" text="Варианты комплектации" />
<BurgerLink route="/" text="Проекты" />
<BurgerLink route="/" text="События" />
<BurgerLink route="#products">Типы тренажеров</BurgerLink>
<BurgerLink route="#trainings">Варианты комплектации</BurgerLink>
<BurgerLink route="#projects">Проекты</BurgerLink>
<BurgerLink route="#events">События</BurgerLink>
<div className="grid mobile:max-tablet:grid-cols-[216px_1fr_1fr] tablet:grid-cols-2">
<button className="text-[#ffffff] tablet:hidden font-semibold btn-text bg-gradient-to-r from-[#798FFF] to-[#D375FF] py-[30px] px-10">
Оставить заявку
@@ -63,15 +64,15 @@ export function Navbar() {
);
}
function BurgerLink({ text, route }: { text: string; route: string }) {
function BurgerLink({ children, route }: PropsWithChildren<{ route: string }>) {
return (
<Link
<HashLink
to={route}
className="flex items-center px-10 py-6 gap-1 text-[#ffffff] btn-text bg-[#14161F] w-full font-semibold border-[#3D425C] border-b hover:bg-[#3D425C] active:bg-[#14161F]"
>
<img src="src/assets/cube.svg" alt="" />
{text}
</Link>
{children}
</HashLink>
);
}
+2 -2
View File
@@ -48,13 +48,13 @@ function Figure({
return (
<div
className={
'flex px-6 bg-[#3D425C4D] w-full bg-opacity-30 rounded-2xl pt-6 bg-no-repeat bg-auto xl:bg-[bottom_right_24px] tablet:max-xl:bg-[bottom_right_12px] mobile:bg-[bottom_right_24px] h-[262px]'
'flex px-6 bg-[#3D425C4D] w-full rounded-2xl pt-6 bg-no-repeat bg-auto xl:bg-[bottom_right_24px] tablet:max-xl:bg-[bottom_right_12px] mobile:bg-[bottom_right_24px] h-[262px]'
}
style={{
backgroundImage: `url(src/assets/${variance}_variance_figure.svg)`,
}}
>
<div className="text-[#ffffff] flex flex-col justify-between py-6">
<div className="text-[#ffffff] flex flex-col justify-between py-6 mobile:max-tablet:max-w-[50vw]">
<h6 className="desktop:font-medium l-text">{title}</h6>
<h1 className="font-medium flex items-center tablet-figma:text-[clamp(64px,64px+(100vw-768px)/832*32,96px)] tablet-figma:leading-[clamp(57.6px,57.6px+(100vw-768px)/832*28.8,86.4px)] mobile:text-[64px] mobile:leading-[57.6px]">
{percents}
+4 -1
View File
@@ -4,7 +4,10 @@ import { PropsWithChildren } from 'react';
export function Events() {
return (
<div className="desktop:py-[70px] desktop:px-10 tablet:py-14 tablet:px-6 mobile:px-4">
<div
className="desktop:py-[70px] desktop:px-10 tablet:py-14 tablet:px-6 mobile:px-4"
id="events"
>
<div className="flex desktop:border-t mobile:max-desktop:flex-col border-[#3D425C] pt-5 gap-x-4 w-full">
<MiniTitle text="события" className="mobile:max-tablet:mb-2" />
<div className="desktop:max-desktop-figma:min-w-[clamp(688px,688px+(100vw-1024px)/576*425,1133px)] desktop-figma:min-w-[70.9vw]">
+13 -10
View File
@@ -10,7 +10,10 @@ export function Products() {
const ref = useRef<HTMLDivElement>(null);
return (
<div className="desktop:py-[70px] tablet:max-desktop:pt-14 tablet:max-desktop:pb-8 mobile:max-tablet:py-14 desktop:px-10 tablet:max-desktop:px-6 mobile:max-tablet:px-4">
<div
id="products"
className="desktop:py-[70px] tablet:max-desktop:pt-14 tablet:max-desktop:pb-8 mobile:max-tablet:py-14 desktop:px-10 tablet:max-desktop:px-6 mobile:max-tablet:px-4"
>
<Title className="mb-14 desktop:block mobile:hidden">
Процесс обучения сотрудников станет безопасней и эффективней с
<span
@@ -126,7 +129,7 @@ function TeachingItem({
function TrainingsTab() {
return (
<div className="bg-[#3D425C4D] rounded-xl desktop:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-contain bg-right-bottom bg-[length:55%] desktop:p-10 tablet:max-desktop:p-7 mobile:max-tablet:p-5 bg-no-repeat">
<div className="bg-[#3D425C4D] rounded-xl desktop:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-cover desktop-figma:bg-[30vw_bottom] bg-right-bottom bg-[length:55%] desktop:p-10 tablet:max-desktop:p-7 mobile:max-tablet:p-5 bg-no-repeat">
<div className="desktop:max-w-[455px]">
<div className="tablet:max-desktop:border-b border-[#3D425C] pb-5 tablet:max-desktop:bg-[url('src/assets/mask_group.png')] bg-no-repeat bg-contain bg-right-bottom tablet:max-tablet-figma:bg-[length:40%]">
<div className="tablet:max-desktop:max-w-[326px] mobile:max-tablet:border-b border-[#3D425C]">
@@ -243,7 +246,7 @@ function SimulatorsTab() {
<div className="self-center tablet:max-desktop:max-w-[234px]">
<div {...handlers}>
<div
className="flex desktop:justify-end select-none mobile:max-tablet:relative xl:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop:max-xl:max-w-[300px] tablet:max-desktop:flex-col tablet:flex-wrap gap-2 tablet:max-desktop:mb-10 mobile:max-tablet:duration-1000"
className="flex desktop:justify-end select-none mobile:max-tablet:relative xl:max-desktop-figma:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop-figma:max-w-[44.5vw] desktop:max-xl:max-w-[300px] tablet:max-desktop:flex-col tablet:flex-wrap gap-2 tablet:max-desktop:mb-10 mobile:max-tablet:duration-1000"
style={
width < 640
? {
@@ -259,7 +262,7 @@ function SimulatorsTab() {
<img
key={index}
src={src}
className="rounded-lg mobile:max-tablet:min-w-[clamp(280px,100vw-80px,559px)] object-cover select-none pointer-events-none"
className="rounded-lg mobile:max-tablet:min-w-[clamp(280px,100vw-80px,559px)] object-cover pointer-events-none"
alt=""
/>
))
@@ -267,27 +270,27 @@ function SimulatorsTab() {
<>
<img
src="src/assets/train.png"
className="rounded-lg xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] tablet:max-xl:hidden"
className="rounded-lg xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/dispatcher.png"
className="xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] tablet:max-xl:hidden"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/winda.png"
className="xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] tablet:max-xl:hidden"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/rzhd.png"
className="xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)]"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[22vw]"
alt=""
/>
<img
src="src/assets/rzhd2.png"
className="xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)]"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[22vw]"
alt=""
/>
</>
@@ -315,7 +318,7 @@ function SimulatorsItem({ text }: { text: string }) {
function ForTeachingTab() {
return (
<div className="desktop:bg-[url('src/assets/mask_group2.png')] bg-[#3D425C4D] bg-no-repeat desktop:p-10 tablet:p-7 mobile:p-5 rounded-xl 2xl:bg-contain bg-right desktop:max-2xl:bg-[length:50%]">
<div className="desktop:bg-[url('src/assets/mask_group2.png')] bg-[#3D425C4D] bg-no-repeat desktop:p-10 tablet:p-7 mobile:p-5 rounded-xl 2xl:bg-cover 2xl:bg-[30vw] bg-[right] desktop:max-2xl:bg-[length:50%]">
<div className='tablet:max-desktop:bg-[url("src/assets/mask_group2.png")] bg-no-repeat bg-right bg-[length:50%] tablet:max-desktop:pb-[55px] mobile:max-desktop:border-b border-[#3D425C] tablet:mb-8 mobile:mb-4'>
<h3 className="text-[#ffffff] font-medium desktop:max-w-[455px] tablet:max-w-[326px] mobile:max-tablet:mb-5 h3">
Интерактивные тренажеры для учебных заведений
+6 -4
View File
@@ -6,7 +6,10 @@ import { useSwipeable } from 'react-swipeable';
export function Projects() {
return (
<div className="desktop:py-[70px] desktop:px-10 mobile:py-14 tablet:px-6 mobile:px-5 overflow-hidden select-none">
<div
id="projects"
className="desktop:py-[70px] desktop:px-10 mobile:py-14 tablet:px-6 mobile:px-5 overflow-hidden select-none"
>
<Title className="desktop:mb-14 mobile:mb-6">
<span
className="bg-text-gradient bg-gradient-to-r from-[#798FFF] to-[#D375FF]"
@@ -95,7 +98,6 @@ function Slider({
setSliderOffset(prev => prev + baseOffset);
return [...state.slice(1), state[2]];
}
1;
if (action === 'prev') {
setSliderOffset(-baseOffset * 2);
return [state[state.length - 3], ...state.slice(0, -1)];
@@ -129,7 +131,7 @@ function Slider({
<div
className="flex gap-2 overflow-visible relative mb-[18px] -mr-10 select-none"
style={{
transition: `${sliderOffset === 0 || sliderOffset === -baseOffset * 2 ? 0 : 0.4}s`,
transition: `${sliderOffset === 0 || sliderOffset === -baseOffset * 2 ? 0 : 0.5}s`,
transform: `translateX(${sliderOffset}px)`,
}}
>
@@ -141,8 +143,8 @@ function Slider({
<div className="flex items-center gap-4 desktop:max-desktop-figma:w-[clamp(720px,100vw-465px,1135px)] desktop-figma:w-[70.9vw] mobile:w-full self-start desktop:ml-64">
<button
onClick={() => {
dispatch('prev');
setSlide(prev => (prev === 0 ? order.length - 3 : prev - 1));
dispatch('prev');
}}
className="mobile:max-tablet:hidden"
>
+4 -1
View File
@@ -2,7 +2,10 @@ import { Title } from '../../ui/Title';
export function Trainings() {
return (
<div className="desktop:py-[70px] desktop:px-10 mobile:py-14 tablet:px-7 mobile:px-4">
<div
id="trainings"
className="desktop:py-[70px] desktop:px-10 mobile:py-14 tablet:px-7 mobile:px-4"
>
<Title className="desktop:mb-14 mobile:mb-6">
Предлагаем различные{' '}
<span
+39
View File
@@ -1,11 +1,25 @@
import { useEffect, useState } from 'react';
export function Video() {
const [open, setOpen] = useState(false);
useEffect(() => {
const listener = (event: KeyboardEvent) => {
if (event.key === 'Escape') setOpen(false);
};
document.addEventListener('keydown', listener);
return () => document.removeEventListener('keydown', listener);
}, []);
return (
<>
<div className="flex bg-[url(src/assets/video.png)] desktop:h-[836px] tablet:h-[561px] mobile:h-[400px] bg-cover bg-right bg-no-repeat justify-center">
<button className="self-center mobile:max-tablet:hidden">
<img
src="src/assets/play.svg"
className="desktop:w-[114px] tablet:w-[94px]"
alt=""
onClick={() => setOpen(true)}
/>
</button>
<div className="flex self-end absolute right-0 mobile:max-tablet:hidden">
@@ -13,5 +27,30 @@ export function Video() {
<div className="desktop:w-[260px] tablet:w-[216px] mobile bg-[#14161F]" />
</div>
</div>
{open && (
<div className="fixed top-0 left-0 z-50 w-full h-full flex justify-center items-center overflow-hidden">
<div className="cursor-default" onClick={e => e.stopPropagation()}>
<div className="absolute top-0 left-0 w-screen h-screen overflow-hidden flex justify-center items-start">
<div className="aspect-video w-full">
<button
className="absolute top-6 right-6 p-6 z-60 rounded-full border border-white"
onClick={() => setOpen(false)}
>
<img src="src/assets/cross.svg" alt="" />
</button>
<iframe
className="h-full w-full"
src="https://www.youtube.com/embed/aAGcjf-B42g?si=36dEzF9t4efmUJOA"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
allowFullScreen
></iframe>
</div>
</div>
</div>
</div>
)}
</>
);
}
+15 -6
View File
@@ -1,14 +1,23 @@
import { Link } from 'react-router-dom';
import { PropsWithChildren } from 'react';
import { HashLink } from 'react-router-hash-link';
export function NavLink({ text, route }: { text: string; route: string }) {
export function NavLink({
children,
route,
className = '',
}: PropsWithChildren<{
route: string;
className?: string;
}>) {
return (
<Link
<HashLink
className={
'text-[#ffffff] btn-text font-semibold border-l border-[#3D425C] mobile:hidden py-[30px] px-10 min-[1350px]:block hover:bg-[#3D425C] active:bg-[#14161F]'
'text-[#ffffff] btn-text font-semibold border-l border-[#3D425C] mobile:hidden py-[30px] px-10 min-[1350px]:block hover:bg-[#3D425C] active:bg-[#14161F] ' +
className
}
to={route}
>
{text}
</Link>
{children}
</HashLink>
);
}
+54 -2
View File
@@ -576,6 +576,11 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/history@^4.7.11":
version "4.7.11"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
"@types/prop-types@*":
version "15.7.12"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
@@ -588,6 +593,32 @@
dependencies:
"@types/react" "*"
"@types/react-router-dom@^5.3.0":
version "5.3.3"
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==
dependencies:
"@types/history" "^4.7.11"
"@types/react" "*"
"@types/react-router" "*"
"@types/react-router-hash-link@^2.4.9":
version "2.4.9"
resolved "https://registry.yarnpkg.com/@types/react-router-hash-link/-/react-router-hash-link-2.4.9.tgz#b9f069fb5faeba2477426b3932205d080f72ba99"
integrity sha512-zl/VMj+lfJZhvjOAQXIlBVPNKSK+/fRG8AUHhlP9++LhlA2ziLeTmbRxIMJI3PCiCTS+W/FosEoDRoNOGH0OzA==
dependencies:
"@types/history" "^4.7.11"
"@types/react" "*"
"@types/react-router-dom" "^5.3.0"
"@types/react-router@*":
version "5.1.20"
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c"
integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==
dependencies:
"@types/history" "^4.7.11"
"@types/react" "*"
"@types/react@*", "@types/react@^18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f"
@@ -1485,7 +1516,7 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
loose-envify@^1.1.0:
loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -1575,7 +1606,7 @@ normalize-range@^0.1.2:
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
object-assign@^4.0.1:
object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@@ -1746,6 +1777,15 @@ prettier@^3.3.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.2.tgz#03ff86dc7c835f2d2559ee76876a3914cec4a90a"
integrity sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==
prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.13.1"
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
@@ -1764,6 +1804,11 @@ react-dom@^18.3.1:
loose-envify "^1.1.0"
scheduler "^0.23.2"
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-refresh@^0.14.2:
version "0.14.2"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
@@ -1777,6 +1822,13 @@ react-router-dom@^6.23.1:
"@remix-run/router" "1.16.1"
react-router "6.23.1"
react-router-hash-link@^2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/react-router-hash-link/-/react-router-hash-link-2.4.3.tgz#570824d53d6c35ce94d73a46c8e98673a127bf08"
integrity sha512-NU7GWc265m92xh/aYD79Vr1W+zAIXDWp3L2YZOYP4rCqPnJ6LI6vh3+rKgkidtYijozHclaEQTAHaAaMWPVI4A==
dependencies:
prop-types "^15.7.2"
react-router@6.23.1:
version "6.23.1"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.23.1.tgz#d08cbdbd9d6aedc13eea6e94bc6d9b29cb1c4be9"