diff --git a/package.json b/package.json
index de5c7c4a..b346c227 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"react-input-mask": "^2.0.4",
"react-rangeslider": "^2.2.0",
"react-swipeable": "^7.0.1",
+ "react-transition-group": "^4.4.5",
"react-usestateref": "^1.0.9",
"usehooks-ts": "^3.1.0",
"zustand": "^4.5.4"
@@ -29,6 +30,7 @@
"@types/react-dom": "^18",
"@types/react-input-mask": "^3.0.5",
"@types/react-rangeslider": "^2.2.7",
+ "@types/react-transition-group": "^4.4.11",
"autoprefixer": "^10.4.19",
"eslint": "^8",
"eslint-config-next": "14.2.5",
diff --git a/public/img/components/products/highlight.svg b/public/img/components/products/highlight.svg
new file mode 100644
index 00000000..15f384ed
--- /dev/null
+++ b/public/img/components/products/highlight.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/img/components/products/stream.png b/public/img/components/products/stream.png
index 37fe026c..bd33cd8e 100644
Binary files a/public/img/components/products/stream.png and b/public/img/components/products/stream.png differ
diff --git a/public/img/pages/home/showreel/preview.png b/public/img/pages/home/showreel/preview.png
new file mode 100644
index 00000000..15cfe3ba
Binary files /dev/null and b/public/img/pages/home/showreel/preview.png differ
diff --git a/public/videos/pages/home/showreel_1080p_4000k_h264.mp4 b/public/videos/pages/home/showreel.mp4
similarity index 100%
rename from public/videos/pages/home/showreel_1080p_4000k_h264.mp4
rename to public/videos/pages/home/showreel.mp4
diff --git a/public/videos/pages/home/technology.mp4 b/public/videos/pages/home/technology.mp4
new file mode 100644
index 00000000..be90d697
Binary files /dev/null and b/public/videos/pages/home/technology.mp4 differ
diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx
index 20690892..ce485998 100644
--- a/src/components/Layout/Header.tsx
+++ b/src/components/Layout/Header.tsx
@@ -38,7 +38,7 @@ export function Header() {
{width >= 1280 && }
-
+
О компании
Блог
@@ -48,7 +48,7 @@ export function Header() {
diff --git a/src/components/Layout/ModalContainer.tsx b/src/components/Layout/ModalContainer.tsx
index 801626d0..95370325 100644
--- a/src/components/Layout/ModalContainer.tsx
+++ b/src/components/Layout/ModalContainer.tsx
@@ -7,10 +7,10 @@ export function ModalContainer() {
return (
modal && (
-
-
e.stopPropagation()} className="cursor-default">
- {modal}
-
+
+ {/*
e.stopPropagation()} className="cursor-default"> */}
+ {modal}
+ {/*
*/}
)
);
diff --git a/src/components/Layout/ModalWithProducts.tsx b/src/components/Layout/ModalWithProducts.tsx
index 92c27d07..49313174 100644
--- a/src/components/Layout/ModalWithProducts.tsx
+++ b/src/components/Layout/ModalWithProducts.tsx
@@ -1,7 +1,9 @@
import Products from '@/consts/products.json';
import { useModalStore } from '@/stores/useModalStore';
+import { AnimatePresence, motion } from 'framer-motion';
import Image from 'next/image';
-import { useEffect } from 'react';
+import { useEffect, useRef, useState } from 'react';
+import { useOnClickOutside } from 'usehooks-ts';
import { CloseIcon } from '../icons/CloseIcon';
interface IProduct {
@@ -11,40 +13,66 @@ interface IProduct {
image: string;
}
-export default function ModalWithProducts() {
+export function ModalWithProducts() {
const { setModal } = useModalStore();
+ const [show, setShow] = useState(true);
+ const ref = useRef
(null);
+
+ useOnClickOutside(ref, () => setShow(false));
useEffect(() => {
const listener = (e: KeyboardEvent) => {
- if (e.key === 'Escape') {
- setModal(false);
- }
+ if (e.key === 'Escape') setShow(false);
};
document.addEventListener('keydown', listener);
return () => document.removeEventListener('keydown', listener);
- }, [setModal]);
+ }, []);
return (
-
-
- GRAFF.estate
-
-
-
- {Products.map((product, index) => (
-
- ))}
-
-
+
+ GRAFF.estate
+
+
+
+ {Products.map((product, index) => (
+
+ ))}
+
+
+ )}
+
);
}
@@ -55,9 +83,13 @@ function ProductItem({
className,
}: Omit & { className?: string }) {
return (
-
@@ -76,9 +108,11 @@ function ProductItem({
src={image}
alt={title}
fill
- className="object-contain object-bottom !relative"
+ priority
+ sizes="100% 100%"
+ className="object-contain !relative object-bottom"
/>
-
+
);
}
diff --git a/src/components/Layout/ProductsList.tsx b/src/components/Layout/ProductsList.tsx
index 2a23871c..ded6a34d 100644
--- a/src/components/Layout/ProductsList.tsx
+++ b/src/components/Layout/ProductsList.tsx
@@ -1,17 +1,29 @@
'use client';
import { useModalStore } from '@/stores/useModalStore';
+import { useEffect, useState } from 'react';
import { ChevronDownIcon } from '../icons/ChevronDownIcon';
import { ChevronUpIcon } from '../icons/ChevronUpIcon';
-import ModalWithProducts from './ModalWithProducts';
+import { ModalWithProducts } from './ModalWithProducts';
export function ProductsList() {
const { setModal, modal } = useModalStore();
+ const [show, setShow] = useState(false);
+
+ useEffect(() => {
+ setShow(!!modal);
+ }, [modal]);
return (