режим обучения
{text}
+
Хотите использовать интерактивные тренажеры в обучении?
Давайте обсудим детали.
@@ -18,13 +18,13 @@ export function Feedback() {
}
- className="lg:col-span-3 row-start-2 self-end px-6 py-4 sm:max-lg:mb-20 max-sm:mb-14"
+ 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"
>
Оставить заявку
- Свяжитесь с нами
+ Свяжитесь с нами
-
- Социальные сети
+
+ Социальные сети
-
+
diff --git a/src/components/Main/Distance.tsx b/src/components/Main/Distance.tsx
index 4a70a88..a670999 100644
--- a/src/components/Main/Distance.tsx
+++ b/src/components/Main/Distance.tsx
@@ -3,13 +3,13 @@ import { Title } from '../../ui/Title';
export function Distance() {
return (
-
+
Платформа GRAFF.training поволяет осуществлять
дистанционное обучение с любого
устройства
-
+
Обучающиеся будут получать доступ к системе с высоко детализированной
3D графикой для прохождения сценариев на любом устройстве, без
необходимости установки дополнительного ПО.
@@ -17,12 +17,12 @@ export function Distance() {
diff --git a/src/components/Main/Efficiency.tsx b/src/components/Main/Efficiency.tsx
index a7f5ece..f4fb05b 100644
--- a/src/components/Main/Efficiency.tsx
+++ b/src/components/Main/Efficiency.tsx
@@ -84,17 +84,17 @@ function Figure({
{title}
-
+
{percents}
%
diff --git a/src/components/Main/Ellipse.tsx b/src/components/Main/Ellipse.tsx
index 51ba377..733118f 100644
--- a/src/components/Main/Ellipse.tsx
+++ b/src/components/Main/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);
@@ -14,7 +14,7 @@ export function Ellipse() {
e.clientY - (e.currentTarget as HTMLElement).getBoundingClientRect().top;
}
- function animate() {
+ const animate = useCallback(() => {
if (ref.current) {
setMousePos(([prevX, prevY]) => [
prevX + (x.current - prevX) / 15,
@@ -22,7 +22,7 @@ export function Ellipse() {
]);
}
requestRef.current = requestAnimationFrame(animate);
- }
+ }, []);
useEffect(() => {
document.body?.addEventListener('mousemove', handleMouseMove);
@@ -32,7 +32,7 @@ export function Ellipse() {
cancelAnimationFrame(requestRef.current!);
document.body?.removeEventListener('mousemove', handleMouseMove);
};
- }, []);
+ }, [animate]);
return (
-
-
+
+
-
+
Макет кабины машиниста «Иволга» на выставке ВДНХ
@@ -35,12 +35,12 @@ export function Events() {
-
+
Победа на BuildUP 2023 в номинации IT
-
+
Транспортное и специальное тренажеростроение — 2023
@@ -65,7 +65,7 @@ function LinkButton({ href }: { href: string }) {
const hovered = useHover(ref);
return (
-
+
+
e.stopPropagation()} className="cursor-default">
{modal}
diff --git a/src/components/Main/ModalWithForm.tsx b/src/components/Main/ModalWithForm.tsx
index e161b0b..7073422 100644
--- a/src/components/Main/ModalWithForm.tsx
+++ b/src/components/Main/ModalWithForm.tsx
@@ -1,29 +1,39 @@
-'use client';
-
-import { FormEvent, useEffect, useRef, useState } from 'react';
+import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
import ReactInputMask from 'react-input-mask';
import { ArrowRightIcon } from '../icons/ArrowRightIcon';
import { CloseIcon } from '../icons/CloseIcon';
import { LoaderIcon } from '../icons/LoaderIcon';
import { MailIcon } from '../icons/MailIcon';
-import { phoneCodes } from '../../consts/phoneCodes';
import { api } from '../../api/contactsFormInstance';
import { Button } from '../../ui/Button';
-import { PhoneCode } from '../../types/PhoneCode';
-import { ChevronUpIcon } from '../icons/ChevronUpIcon';
-import { ChevronDownIcon } from '../icons/ChevronDownIcon';
import { useModalStore } from '../../store/modalStore';
+import { SelectPhoneCode } from './SelectPhoneCode';
+import { Country } from 'react-phone-number-input';
+import { getExampleNumber } from 'libphonenumber-js';
+import examples from 'libphonenumber-js/mobile/examples';
export function ModalWithForm() {
const { setModal } = useModalStore();
const [name, setName] = useState('');
- const [phoneCode, setPhoneCode] = useState('+7');
+ const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
+ [string, Country]
+ >(['+7', 'RU']);
const [phone, setPhone] = useState('');
const [email, setEmail] = useState('');
const [description, setDescription] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [isSend, setIsSend] = useState(false);
+ const placeholder = useMemo(
+ () =>
+ getExampleNumber(country, examples)
+ ?.formatInternational()
+ .split(' ')
+ .slice(1)
+ .join(' '),
+ [country],
+ );
+
const textAreaRef = useRef(null);
useEffect(() => {
@@ -79,11 +89,11 @@ export function ModalWithForm() {
{!isSend ? (
-
+
Оставьте заявку
@@ -119,20 +129,20 @@ export function ModalWithForm() {
setPhone(e.target.value)}
- className="bg-transparent rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none peer"
+ placeholder={placeholder}
+ onChange={e => setPhone(e.target.value.replace(/ /g, ''))}
+ className="w-full transition-all bg-transparent rounded-none outline-none h4 placeholder:h4 placeholder:font-medium placeholder:select-none peer"
/>
@@ -201,7 +211,7 @@ export function ModalWithForm() {
) : (
- Спасибо за отправку заявки!
+ Спасибо за отправку заявки!
Мы ценим ваш интерес к нашей компании и в ближайшее время свяжемся
с вами для уточнения деталей проекта.
@@ -221,45 +231,257 @@ export function ModalWithForm() {
);
}
-function SelectPhoneCode({
- currentPhoneCode,
- onClick,
-}: {
- currentPhoneCode: PhoneCode;
- onClick: (phoneCode: PhoneCode) => void;
-}) {
- const [open, setOpen] = useState(false);
+// function SelectPhoneCode({
+// currentPhoneCode,
+// onClick,
+// }: {
+// currentPhoneCode: PhoneCode;
+// onClick: (phoneCode: PhoneCode) => void;
+// }) {
+// const [open, setOpen] = useState(false);
- return (
-
-
- {open && (
-
- {phoneCodes
- .filter(phonecode => phonecode !== currentPhoneCode)
- .map(phoneCode => (
- {
- onClick(phoneCode);
- setOpen(false);
- }}
- >
- {phoneCode}
-
- ))}
-
- )}
-
- );
-}
+// return (
+//
+//
+// {open && (
+//
+// {phoneCodes
+// .filter(phonecode => phonecode !== currentPhoneCode)
+// .map(phoneCode => (
+// {
+// onClick(phoneCode);
+// setOpen(false);
+// }}
+// >
+// {phoneCode}
+//
+// ))}
+//
+// )}
+//
+// );
+// }
+// import ReactInputMask from 'react-input-mask';
+// import { SelectPhoneCode } from './SelectPhoneCode';
+// import { ClassNameWrapper } from '../../hocs/ClassNameWrapper';
+// import { LoaderIcon } from '../icons/LoaderIcon';
+// import { Button } from '../../ui/Button';
+// import { ArrowRightIcon } from '../icons/ArrowRightIcon';
+// import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
+// import { Country } from 'react-phone-number-input';
+// import { api } from '../../api/contactsFormInstance';
+// import { getExampleNumber } from 'libphonenumber-js';
+// import examples from 'libphonenumber-js/mobile/examples';
+
+// export function ModalWithForm({
+// inModal = true,
+// send = () => {},
+// }: {
+// inModal?: boolean;
+// send?: () => void;
+// }) {
+// const [name, setName] = useState('');
+// const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
+// [string, Country]
+// >(['+7', 'RU']);
+// const [phone, setPhone] = useState('');
+// const [email, setEmail] = useState('');
+// const [description, setDescription] = useState('');
+// const [isLoading, setIsLoading] = useState(false);
+
+// const textAreaRef = useRef(null);
+
+// useEffect(() => {
+// if (textAreaRef.current) {
+// textAreaRef.current.style.height = 'auto';
+// textAreaRef.current.style.height =
+// textAreaRef.current.scrollHeight + 'px';
+// }
+// }, [textAreaRef, description]);
+
+// function handleSubmit(e: FormEvent) {
+// e.preventDefault();
+// sendMail();
+// }
+
+// async function sendMail() {
+// setIsLoading(true);
+
+// try {
+// await api
+// .post('mail', {
+// json: {
+// fullname: name,
+// phone: phoneCode + phone,
+// email,
+// request: description,
+// },
+// })
+// .json();
+
+// setIsLoading(false);
+// send?.();
+// } catch (error) {
+// setIsLoading(false);
+// if (error instanceof Error) {
+// alert(error.message);
+// }
+// }
+// }
+
+// const placeholder = useMemo(
+// () =>
+// getExampleNumber(country, examples)
+// ?.formatInternational()
+// .split(' ')
+// .slice(1)
+// .join(' '),
+// [country],
+// );
+
+// return (
+//
+// );
+// }
diff --git a/src/components/Main/Motivation.tsx b/src/components/Main/Motivation.tsx
index 1e600fa..3db80e3 100644
--- a/src/components/Main/Motivation.tsx
+++ b/src/components/Main/Motivation.tsx
@@ -1,9 +1,7 @@
-// import { Marquee } from '../Main/Marquee';
-
export function Motivation() {
return (
-
+
Создаем
интерактивные тренажеры
@@ -18,7 +16,6 @@ export function Motivation() {
производительность
- {/* */}
);
}
diff --git a/src/components/Main/Products/Products.tsx b/src/components/Main/Products/Products.tsx
index f56afc9..1fb0b03 100644
--- a/src/components/Main/Products/Products.tsx
+++ b/src/components/Main/Products/Products.tsx
@@ -60,7 +60,7 @@ export function Products() {
return (
diff --git a/src/components/Main/Products/Tabs/ForTeachingTab.tsx b/src/components/Main/Products/Tabs/ForTeachingTab.tsx
index b9c756b..fa09742 100644
--- a/src/components/Main/Products/Tabs/ForTeachingTab.tsx
+++ b/src/components/Main/Products/Tabs/ForTeachingTab.tsx
@@ -3,45 +3,13 @@ import { useHover } from 'usehooks-ts';
import { getIcon } from '../../../../utils/getIcon';
import { useInView } from 'framer-motion';
-function ForTeachingOption({
- title,
- description,
- type,
-}: {
- title: string;
- description: string;
- type: 'labs' | 'teaching';
-}) {
- const ref = useRef(null);
- const hovered = useHover(ref);
- const isInView = useInView(ref, {
- margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
- });
-
- return (
-
- {getIcon(type, hovered, 'max-sm:hidden min-w-11')}
-
-
- {getIcon(type, hovered || isInView, 'sm:hidden min-w-11')}
- {title}
-
- {description}
-
-
- );
-}
-
export const ForTeaching = forwardRef((_, ref) => {
return (
-
+
Интерактивные тренажеры для учебных заведений
03
@@ -59,7 +27,7 @@ export const ForTeaching = forwardRef((_, ref) => {
поломки оборудования, а также экономить на расходных средствах"
type="labs"
/>
-
+
Оснащение учебных классов и центров всем необходимым для
современного обучения под «ключ»
@@ -72,10 +40,42 @@ export const ForTeaching = forwardRef((_, ref) => {
/>
);
});
+
+function ForTeachingOption({
+ title,
+ description,
+ type,
+}: {
+ title: string;
+ description: string;
+ type: 'labs' | 'teaching';
+}) {
+ const ref = useRef(null);
+ const hovered = useHover(ref);
+ const isInView = useInView(ref, {
+ margin: `0px 0px ${(ref.current?.clientHeight ?? 0) - window.innerHeight}px`,
+ });
+
+ return (
+
+ {getIcon(type, hovered, 'max-sm:hidden min-w-11')}
+
+
+ {getIcon(type, hovered || isInView, 'sm:hidden min-w-11')}
+ {title}
+
+ {description}
+
+
+ );
+}
diff --git a/src/components/Main/Products/Tabs/TrainingsTab.tsx b/src/components/Main/Products/Tabs/TrainingsTab.tsx
index 158407d..fcfdef5 100644
--- a/src/components/Main/Products/Tabs/TrainingsTab.tsx
+++ b/src/components/Main/Products/Tabs/TrainingsTab.tsx
@@ -25,7 +25,7 @@ function TeachingItem({
>
{getIcon(iconType, hovered, 'max-sm:hidden sm:max-lg:mb-[14px] min-w-11')}
-
+
{getIcon(iconType, hovered || isInView, 'sm:hidden min-w-11')}
{title}
@@ -42,9 +42,9 @@ export const IndustrialTrainings = forwardRef<
return (
-
+
diff --git a/src/components/Main/Projects.tsx b/src/components/Main/Projects.tsx
index f972bb9..f8e4190 100644
--- a/src/components/Main/Projects.tsx
+++ b/src/components/Main/Projects.tsx
@@ -36,7 +36,7 @@ import { IProject, Media } from '../../types/Project';
//
//
//
//
@@ -48,15 +48,15 @@ export const Project = forwardRef>(
const [buffering, setBuffering] = useState(true);
return (
-
+
{media === Media.img ? (
) : (
Давайте обсудим детали. @@ -18,13 +18,13 @@ export function Feedback() { } - className="lg:col-span-3 row-start-2 self-end px-6 py-4 sm:max-lg:mb-20 max-sm:mb-14" + 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" > Оставить заявку
Свяжитесь с нами
+Свяжитесь с нами
Социальные сети
+Социальные сети
+
Обучающиеся будут получать доступ к системе с высоко детализированной
3D графикой для прохождения сценариев на любом устройстве, без
необходимости установки дополнительного ПО.
@@ -17,12 +17,12 @@ export function Distance() {
{title}
-
+
{percents}
%
diff --git a/src/components/Main/Ellipse.tsx b/src/components/Main/Ellipse.tsx
index 51ba377..733118f 100644
--- a/src/components/Main/Ellipse.tsx
+++ b/src/components/Main/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);
@@ -14,7 +14,7 @@ export function Ellipse() {
e.clientY - (e.currentTarget as HTMLElement).getBoundingClientRect().top;
}
- function animate() {
+ const animate = useCallback(() => {
if (ref.current) {
setMousePos(([prevX, prevY]) => [
prevX + (x.current - prevX) / 15,
@@ -22,7 +22,7 @@ export function Ellipse() {
]);
}
requestRef.current = requestAnimationFrame(animate);
- }
+ }, []);
useEffect(() => {
document.body?.addEventListener('mousemove', handleMouseMove);
@@ -32,7 +32,7 @@ export function Ellipse() {
cancelAnimationFrame(requestRef.current!);
document.body?.removeEventListener('mousemove', handleMouseMove);
};
- }, []);
+ }, [animate]);
return (
-
-
+
+
-
+
Макет кабины машиниста «Иволга» на выставке ВДНХ
@@ -35,12 +35,12 @@ export function Events() {
-
+
Победа на BuildUP 2023 в номинации IT
-
+
Транспортное и специальное тренажеростроение — 2023
@@ -65,7 +65,7 @@ function LinkButton({ href }: { href: string }) {
const hovered = useHover(ref);
return (
-
+
+
e.stopPropagation()} className="cursor-default">
{modal}
diff --git a/src/components/Main/ModalWithForm.tsx b/src/components/Main/ModalWithForm.tsx
index e161b0b..7073422 100644
--- a/src/components/Main/ModalWithForm.tsx
+++ b/src/components/Main/ModalWithForm.tsx
@@ -1,29 +1,39 @@
-'use client';
-
-import { FormEvent, useEffect, useRef, useState } from 'react';
+import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
import ReactInputMask from 'react-input-mask';
import { ArrowRightIcon } from '../icons/ArrowRightIcon';
import { CloseIcon } from '../icons/CloseIcon';
import { LoaderIcon } from '../icons/LoaderIcon';
import { MailIcon } from '../icons/MailIcon';
-import { phoneCodes } from '../../consts/phoneCodes';
import { api } from '../../api/contactsFormInstance';
import { Button } from '../../ui/Button';
-import { PhoneCode } from '../../types/PhoneCode';
-import { ChevronUpIcon } from '../icons/ChevronUpIcon';
-import { ChevronDownIcon } from '../icons/ChevronDownIcon';
import { useModalStore } from '../../store/modalStore';
+import { SelectPhoneCode } from './SelectPhoneCode';
+import { Country } from 'react-phone-number-input';
+import { getExampleNumber } from 'libphonenumber-js';
+import examples from 'libphonenumber-js/mobile/examples';
export function ModalWithForm() {
const { setModal } = useModalStore();
const [name, setName] = useState('');
- const [phoneCode, setPhoneCode] = useState('+7');
+ const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
+ [string, Country]
+ >(['+7', 'RU']);
const [phone, setPhone] = useState('');
const [email, setEmail] = useState('');
const [description, setDescription] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [isSend, setIsSend] = useState(false);
+ const placeholder = useMemo(
+ () =>
+ getExampleNumber(country, examples)
+ ?.formatInternational()
+ .split(' ')
+ .slice(1)
+ .join(' '),
+ [country],
+ );
+
const textAreaRef = useRef(null);
useEffect(() => {
@@ -79,11 +89,11 @@ export function ModalWithForm() {
{!isSend ? (
-
+
Оставьте заявку
@@ -119,20 +129,20 @@ export function ModalWithForm() {
setPhone(e.target.value)}
- className="bg-transparent rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none peer"
+ placeholder={placeholder}
+ onChange={e => setPhone(e.target.value.replace(/ /g, ''))}
+ className="w-full transition-all bg-transparent rounded-none outline-none h4 placeholder:h4 placeholder:font-medium placeholder:select-none peer"
/>
@@ -201,7 +211,7 @@ export function ModalWithForm() {
) : (
- Спасибо за отправку заявки!
+ Спасибо за отправку заявки!
Мы ценим ваш интерес к нашей компании и в ближайшее время свяжемся
с вами для уточнения деталей проекта.
@@ -221,45 +231,257 @@ export function ModalWithForm() {
);
}
-function SelectPhoneCode({
- currentPhoneCode,
- onClick,
-}: {
- currentPhoneCode: PhoneCode;
- onClick: (phoneCode: PhoneCode) => void;
-}) {
- const [open, setOpen] = useState(false);
+// function SelectPhoneCode({
+// currentPhoneCode,
+// onClick,
+// }: {
+// currentPhoneCode: PhoneCode;
+// onClick: (phoneCode: PhoneCode) => void;
+// }) {
+// const [open, setOpen] = useState(false);
- return (
-
-
- {open && (
-
- {phoneCodes
- .filter(phonecode => phonecode !== currentPhoneCode)
- .map(phoneCode => (
- {
- onClick(phoneCode);
- setOpen(false);
- }}
- >
- {phoneCode}
-
- ))}
-
- )}
-
- );
-}
+// return (
+//
+//
+// {open && (
+//
+// {phoneCodes
+// .filter(phonecode => phonecode !== currentPhoneCode)
+// .map(phoneCode => (
+// {
+// onClick(phoneCode);
+// setOpen(false);
+// }}
+// >
+// {phoneCode}
+//
+// ))}
+//
+// )}
+//
+// );
+// }
+// import ReactInputMask from 'react-input-mask';
+// import { SelectPhoneCode } from './SelectPhoneCode';
+// import { ClassNameWrapper } from '../../hocs/ClassNameWrapper';
+// import { LoaderIcon } from '../icons/LoaderIcon';
+// import { Button } from '../../ui/Button';
+// import { ArrowRightIcon } from '../icons/ArrowRightIcon';
+// import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
+// import { Country } from 'react-phone-number-input';
+// import { api } from '../../api/contactsFormInstance';
+// import { getExampleNumber } from 'libphonenumber-js';
+// import examples from 'libphonenumber-js/mobile/examples';
+
+// export function ModalWithForm({
+// inModal = true,
+// send = () => {},
+// }: {
+// inModal?: boolean;
+// send?: () => void;
+// }) {
+// const [name, setName] = useState('');
+// const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
+// [string, Country]
+// >(['+7', 'RU']);
+// const [phone, setPhone] = useState('');
+// const [email, setEmail] = useState('');
+// const [description, setDescription] = useState('');
+// const [isLoading, setIsLoading] = useState(false);
+
+// const textAreaRef = useRef(null);
+
+// useEffect(() => {
+// if (textAreaRef.current) {
+// textAreaRef.current.style.height = 'auto';
+// textAreaRef.current.style.height =
+// textAreaRef.current.scrollHeight + 'px';
+// }
+// }, [textAreaRef, description]);
+
+// function handleSubmit(e: FormEvent) {
+// e.preventDefault();
+// sendMail();
+// }
+
+// async function sendMail() {
+// setIsLoading(true);
+
+// try {
+// await api
+// .post('mail', {
+// json: {
+// fullname: name,
+// phone: phoneCode + phone,
+// email,
+// request: description,
+// },
+// })
+// .json();
+
+// setIsLoading(false);
+// send?.();
+// } catch (error) {
+// setIsLoading(false);
+// if (error instanceof Error) {
+// alert(error.message);
+// }
+// }
+// }
+
+// const placeholder = useMemo(
+// () =>
+// getExampleNumber(country, examples)
+// ?.formatInternational()
+// .split(' ')
+// .slice(1)
+// .join(' '),
+// [country],
+// );
+
+// return (
+//
+// );
+// }
diff --git a/src/components/Main/Motivation.tsx b/src/components/Main/Motivation.tsx
index 1e600fa..3db80e3 100644
--- a/src/components/Main/Motivation.tsx
+++ b/src/components/Main/Motivation.tsx
@@ -1,9 +1,7 @@
-// import { Marquee } from '../Main/Marquee';
-
export function Motivation() {
return (
-
+
Создаем
интерактивные тренажеры
@@ -18,7 +16,6 @@ export function Motivation() {
производительность
- {/* */}
);
}
diff --git a/src/components/Main/Products/Products.tsx b/src/components/Main/Products/Products.tsx
index f56afc9..1fb0b03 100644
--- a/src/components/Main/Products/Products.tsx
+++ b/src/components/Main/Products/Products.tsx
@@ -60,7 +60,7 @@ export function Products() {
return (
diff --git a/src/components/Main/Products/Tabs/ForTeachingTab.tsx b/src/components/Main/Products/Tabs/ForTeachingTab.tsx
index b9c756b..fa09742 100644
--- a/src/components/Main/Products/Tabs/ForTeachingTab.tsx
+++ b/src/components/Main/Products/Tabs/ForTeachingTab.tsx
@@ -3,45 +3,13 @@ import { useHover } from 'usehooks-ts';
import { getIcon } from '../../../../utils/getIcon';
import { useInView } from 'framer-motion';
-function ForTeachingOption({
- title,
- description,
- type,
-}: {
- title: string;
- description: string;
- type: 'labs' | 'teaching';
-}) {
- const ref = useRef(null);
- const hovered = useHover(ref);
- const isInView = useInView(ref, {
- margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
- });
-
- return (
-
- {getIcon(type, hovered, 'max-sm:hidden min-w-11')}
-
-
- {getIcon(type, hovered || isInView, 'sm:hidden min-w-11')}
- {title}
-
- {description}
-
-
- );
-}
-
export const ForTeaching = forwardRef((_, ref) => {
return (
-
+
Интерактивные тренажеры для учебных заведений
03
@@ -59,7 +27,7 @@ export const ForTeaching = forwardRef((_, ref) => {
поломки оборудования, а также экономить на расходных средствах"
type="labs"
/>
-
+
Оснащение учебных классов и центров всем необходимым для
современного обучения под «ключ»
@@ -72,10 +40,42 @@ export const ForTeaching = forwardRef((_, ref) => {
/>
);
});
+
+function ForTeachingOption({
+ title,
+ description,
+ type,
+}: {
+ title: string;
+ description: string;
+ type: 'labs' | 'teaching';
+}) {
+ const ref = useRef(null);
+ const hovered = useHover(ref);
+ const isInView = useInView(ref, {
+ margin: `0px 0px ${(ref.current?.clientHeight ?? 0) - window.innerHeight}px`,
+ });
+
+ return (
+
+ {getIcon(type, hovered, 'max-sm:hidden min-w-11')}
+
+
+ {getIcon(type, hovered || isInView, 'sm:hidden min-w-11')}
+ {title}
+
+ {description}
+
+
+ );
+}
diff --git a/src/components/Main/Products/Tabs/TrainingsTab.tsx b/src/components/Main/Products/Tabs/TrainingsTab.tsx
index 158407d..fcfdef5 100644
--- a/src/components/Main/Products/Tabs/TrainingsTab.tsx
+++ b/src/components/Main/Products/Tabs/TrainingsTab.tsx
@@ -25,7 +25,7 @@ function TeachingItem({
>
{getIcon(iconType, hovered, 'max-sm:hidden sm:max-lg:mb-[14px] min-w-11')}
-
+
{getIcon(iconType, hovered || isInView, 'sm:hidden min-w-11')}
{title}
@@ -42,9 +42,9 @@ export const IndustrialTrainings = forwardRef<
return (
-
+
diff --git a/src/components/Main/Projects.tsx b/src/components/Main/Projects.tsx
index f972bb9..f8e4190 100644
--- a/src/components/Main/Projects.tsx
+++ b/src/components/Main/Projects.tsx
@@ -36,7 +36,7 @@ import { IProject, Media } from '../../types/Project';
//
//
//
//
@@ -48,15 +48,15 @@ export const Project = forwardRef>(
const [buffering, setBuffering] = useState(true);
return (
-
+
{media === Media.img ? (
) : (
Оставьте заявку
@@ -119,20 +129,20 @@ export function ModalWithForm() {Спасибо за отправку заявки!
+Спасибо за отправку заявки!
Мы ценим ваш интерес к нашей компании и в ближайшее время свяжемся с вами для уточнения деталей проекта. @@ -221,45 +231,257 @@ export function ModalWithForm() { ); } -function SelectPhoneCode({ - currentPhoneCode, - onClick, -}: { - currentPhoneCode: PhoneCode; - onClick: (phoneCode: PhoneCode) => void; -}) { - const [open, setOpen] = useState(false); +// function SelectPhoneCode({ +// currentPhoneCode, +// onClick, +// }: { +// currentPhoneCode: PhoneCode; +// onClick: (phoneCode: PhoneCode) => void; +// }) { +// const [open, setOpen] = useState(false); - return ( -
{ - onClick(phoneCode); - setOpen(false); - }} - > - {phoneCode} -
- ))} -{ +// onClick(phoneCode); +// setOpen(false); +// }} +// > +// {phoneCode} +//
+// ))} +//Создаем интерактивные тренажеры @@ -18,7 +16,6 @@ export function Motivation() { производительность
{title}
-{description}
-
+
Интерактивные тренажеры для учебных заведений
03
@@ -59,7 +27,7 @@ export const ForTeaching = forwardRef+
Оснащение учебных классов и центров всем необходимым для современного обучения под «ключ»
@@ -72,10 +40,42 @@ export const ForTeaching = forwardRef
{title}
+{description}
+
+
{getIcon(iconType, hovered || isInView, 'sm:hidden min-w-11')}
{title}
@@ -42,9 +42,9 @@ export const IndustrialTrainings = forwardRef<
return (
-
+
diff --git a/src/components/Main/Projects.tsx b/src/components/Main/Projects.tsx
index f972bb9..f8e4190 100644
--- a/src/components/Main/Projects.tsx
+++ b/src/components/Main/Projects.tsx
@@ -36,7 +36,7 @@ import { IProject, Media } from '../../types/Project';
//
//
//
//
@@ -48,15 +48,15 @@ export const Project = forwardRef>(
const [buffering, setBuffering] = useState(true);
return (
-
+
{media === Media.img ? (
) : (