diff --git a/index.html b/index.html index 74f12a5..dda7fdb 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,36 @@ - - Vite + React + TS + + + + + + + + + + + + + + Graff.event - Интерактивные выставочные решения
diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..80321b0 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/video_slider/1.mp4 b/src/assets/video_slider/1.mp4 new file mode 100644 index 0000000..c9781f6 Binary files /dev/null and b/src/assets/video_slider/1.mp4 differ diff --git a/src/assets/video_slider/2.mp4 b/src/assets/video_slider/2.mp4 new file mode 100644 index 0000000..5ee371e Binary files /dev/null and b/src/assets/video_slider/2.mp4 differ diff --git a/src/assets/video_slider/3.mp4 b/src/assets/video_slider/3.mp4 new file mode 100644 index 0000000..84026e2 Binary files /dev/null and b/src/assets/video_slider/3.mp4 differ diff --git a/src/assets/video_slider/4.mp4 b/src/assets/video_slider/4.mp4 new file mode 100644 index 0000000..0ecd299 Binary files /dev/null and b/src/assets/video_slider/4.mp4 differ diff --git a/src/components/Clients.tsx b/src/components/Clients.tsx index 214bcca..ba04763 100644 --- a/src/components/Clients.tsx +++ b/src/components/Clients.tsx @@ -1,13 +1,18 @@ import { clients } from '../consts/clients'; +import { IClient } from '../types/IClient'; export function Clients() { return ( -
-
+
+
-
+
-
+
@@ -29,7 +34,7 @@ function MarqueeHalf({ reversed = false, items, }: { - items: { src: string }[]; + items: IClient[]; reversed?: boolean; }) { return ( @@ -43,14 +48,14 @@ function MarqueeHalf({ > {items.map(client => (
{client.src}
))} diff --git a/src/components/Contacts.tsx b/src/components/Contacts.tsx index ec7be76..a5a5118 100644 --- a/src/components/Contacts.tsx +++ b/src/components/Contacts.tsx @@ -6,8 +6,12 @@ import { TelegramIcon } from './icons/TelegramIcon'; import { VKIcon } from './icons/VKIcon'; import { YoutubeIcon } from './icons/YoutubeIcon'; import { Link } from 'react-router-dom'; +import { useModalStore } from '../stores/modalStore'; +import { ModalWithForm } from './Layout/ModalWithForm'; export function Contacts() { + const setModal = useModalStore(state => state.setModal); + return (
} className="self-end row-start-2 px-6 py-4 lg:col-span-3 sm:max-lg:mb-20 max-sm:mb-14" width="full" + onClick={() => setModal()} > Оставить заявку @@ -33,6 +38,9 @@ export function Contacts() { className="py-4" width="full" icon={} + onClick={() => { + window.location.href = 'mailto:info@graff.tech'; + }} > Написать @@ -41,6 +49,9 @@ export function Contacts() { className="py-4" width="full" icon={} + onClick={() => { + window.location.href = 'tel:88007700067'; + }} > Позвонить diff --git a/src/components/Devices.tsx b/src/components/Devices.tsx index 9ffefab..03ccd33 100644 --- a/src/components/Devices.tsx +++ b/src/components/Devices.tsx @@ -114,8 +114,6 @@ function Device({ title, description, img }: IDevice) { setDescriptionHeight(descriptionRef.current?.clientHeight ?? 0); }, [descriptionRef, expanded]); - useEffect(() => console.log(descriptionHeight), [descriptionHeight]); - return ( + + Создаем систему для{' '} + <span className="text-gradient"> + эффективного взаимодействия с клиентами + </span>{' '} + с помощью интерактивных инструментов и анализа пользовательского опыта + +
+ + +
+
+ {interactions.map(({ video }, index) => ( + setCurrent(index)} + /> + ))} +
+
+ ); +} + +export function InteractionSlide({ + active, + video, + onClick, +}: { + video: string; + active: boolean; + onClick?: () => void; +}) { + const ref = useRef(null); + + useEffect(() => { + if (active) ref.current?.play(); + else ref.current?.pause(); + }, [active]); + + return ( + + + ); +} diff --git a/src/components/Layout/Ellipse.tsx b/src/components/Layout/Ellipse.tsx index 51ba377..78b2b4c 100644 --- a/src/components/Layout/Ellipse.tsx +++ b/src/components/Layout/Ellipse.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; export function Ellipse() { const ref = useRef(null); @@ -7,22 +7,20 @@ export function Ellipse() { const y = useRef(0); const [mousePos, setMousePos] = useState([0, 0]); - function handleMouseMove(e: MouseEvent) { - x.current = - e.clientX - (e.currentTarget as HTMLElement).getBoundingClientRect().left; - y.current = - e.clientY - (e.currentTarget as HTMLElement).getBoundingClientRect().top; - } + const handleMouseMove = useCallback((e: MouseEvent) => { + x.current = e.clientX; + y.current = e.clientY; + }, []); - function animate() { + const animate = useCallback(() => { if (ref.current) { setMousePos(([prevX, prevY]) => [ - prevX + (x.current - prevX) / 15, - prevY + (y.current - prevY) / 15, + prevX + (x.current - prevX) / 10, + prevY + (y.current - prevY) / 10, ]); } requestRef.current = requestAnimationFrame(animate); - } + }, []); useEffect(() => { document.body?.addEventListener('mousemove', handleMouseMove); @@ -32,13 +30,13 @@ export function Ellipse() { cancelAnimationFrame(requestRef.current!); document.body?.removeEventListener('mousemove', handleMouseMove); }; - }, []); + }, [animate, handleMouseMove]); return (
); } diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index f878743..122d0db 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -2,7 +2,6 @@ import { Outlet } from 'react-router-dom'; import { Footer } from './Footer'; import { Header } from './Header'; import { Contacts } from '../Contacts'; -import { Clients } from '../Clients'; import { ScrollToHashElement } from './ScrollToHashElement'; import { ModalContainer } from './ModalContainer'; import { Ellipse } from './Ellipse'; @@ -19,7 +18,6 @@ export function Layout() { {width >= 1024 && } -