diff --git a/src/components/landing/BenefitsSection/BenefitsSection.tsx b/src/components/landing/BenefitsSection/BenefitsSection.tsx
new file mode 100644
index 0000000..6132df2
--- /dev/null
+++ b/src/components/landing/BenefitsSection/BenefitsSection.tsx
@@ -0,0 +1,48 @@
+import React, { FC } from 'react';
+import {
+ MdEco,
+ MdMiscellaneousServices,
+ MdPlace,
+ MdHandshake,
+} from 'react-icons/md';
+import { Heading, HStack, List, Text, VStack } from '@chakra-ui/react';
+import { CtaButton, PageSection } from '../';
+import { ListItem } from './ListItem';
+
+export const BenefitsSection: FC = () => {
+ return (
+
+
+ Преимущества экологичной автомойки
+
+ Откройте для себя преимущества наших услуг по химчистке автомобилей
+
+
+
+ {[
+ {
+ Icon: MdEco,
+ children: 'Экологически безопасные продукты',
+ },
+ {
+ Icon: MdMiscellaneousServices,
+ children: 'Быстрое и эффективное обслуживание',
+ },
+ {
+ Icon: MdPlace,
+ children: 'Удобный мобильный доступ',
+ },
+ {
+ Icon: MdHandshake,
+ children: 'Надежный и заслуживающий доверия',
+ },
+ ].map((props, i) => (
+
+ ))}
+
+
+
+
+
+ );
+};
diff --git a/src/components/landing/BenefitsSection/ListItem/ListItem.tsx b/src/components/landing/BenefitsSection/ListItem/ListItem.tsx
new file mode 100644
index 0000000..4c9343d
--- /dev/null
+++ b/src/components/landing/BenefitsSection/ListItem/ListItem.tsx
@@ -0,0 +1,16 @@
+import React, { FC, PropsWithChildren } from 'react';
+import { ListIcon, ListItem as ChakraListItem } from '@chakra-ui/react';
+import { IconType } from 'react-icons';
+
+type ListItemProps = PropsWithChildren & {
+ Icon: IconType;
+};
+
+export const ListItem: FC = ({ Icon, children }) => {
+ return (
+
+
+ {children}
+
+ );
+};
diff --git a/src/components/landing/BenefitsSection/ListItem/index.ts b/src/components/landing/BenefitsSection/ListItem/index.ts
new file mode 100644
index 0000000..de932bf
--- /dev/null
+++ b/src/components/landing/BenefitsSection/ListItem/index.ts
@@ -0,0 +1 @@
+export { ListItem } from './ListItem';
\ No newline at end of file
diff --git a/src/components/landing/BenefitsSection/index.ts b/src/components/landing/BenefitsSection/index.ts
new file mode 100644
index 0000000..d10431b
--- /dev/null
+++ b/src/components/landing/BenefitsSection/index.ts
@@ -0,0 +1 @@
+export { BenefitsSection } from './BenefitsSection';
\ No newline at end of file
diff --git a/src/components/landing/CtaButton/CtaButton.tsx b/src/components/landing/CtaButton/CtaButton.tsx
new file mode 100644
index 0000000..a1168f3
--- /dev/null
+++ b/src/components/landing/CtaButton/CtaButton.tsx
@@ -0,0 +1,11 @@
+import React, { FC } from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { ButtonProps, Button } from '@chakra-ui/react';
+
+export const CtaButton: FC = (props) => {
+ return (
+
+ );
+};
diff --git a/src/components/landing/CtaButton/index.ts b/src/components/landing/CtaButton/index.ts
new file mode 100644
index 0000000..08818cf
--- /dev/null
+++ b/src/components/landing/CtaButton/index.ts
@@ -0,0 +1 @@
+export { CtaButton } from './CtaButton';
\ No newline at end of file
diff --git a/src/components/landing/Footer/Copyright/Copyright.tsx b/src/components/landing/Footer/Copyright/Copyright.tsx
new file mode 100644
index 0000000..bc26f23
--- /dev/null
+++ b/src/components/landing/Footer/Copyright/Copyright.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+import { Text } from '@chakra-ui/react';
+
+const currentYear = new Date().getFullYear();
+
+export const Copyright: FC = () => {
+ return © {currentYear} DryMaster. Все права защищены;
+};
diff --git a/src/components/landing/Footer/Copyright/index.ts b/src/components/landing/Footer/Copyright/index.ts
new file mode 100644
index 0000000..f80e480
--- /dev/null
+++ b/src/components/landing/Footer/Copyright/index.ts
@@ -0,0 +1 @@
+export { Copyright } from './Copyright';
\ No newline at end of file
diff --git a/src/components/landing/Footer/Footer.tsx b/src/components/landing/Footer/Footer.tsx
new file mode 100644
index 0000000..26b8462
--- /dev/null
+++ b/src/components/landing/Footer/Footer.tsx
@@ -0,0 +1,27 @@
+import React, { FC } from 'react';
+import { Link, List, ListItem } from '@chakra-ui/react';
+import { Link as RouterLink } from 'react-router-dom';
+import { SiteLogo, PageSection } from '../';
+import { Copyright } from './Copyright';
+
+export const Footer: FC = () => {
+ return (
+
+
+
+
+ {[
+ { to: '#', label: 'Политика конфиденциальности' },
+ { to: '#', label: 'Условия обслуживания' },
+ { to: '#', label: 'FAQ' },
+ ].map(({ to, label }, i) => (
+
+
+ {label}
+
+
+ ))}
+
+
+ );
+};
diff --git a/src/components/landing/Footer/index.ts b/src/components/landing/Footer/index.ts
new file mode 100644
index 0000000..f6e9523
--- /dev/null
+++ b/src/components/landing/Footer/index.ts
@@ -0,0 +1 @@
+export { Footer } from './Footer';
\ No newline at end of file
diff --git a/src/components/landing/HeroSection/HeroSection.tsx b/src/components/landing/HeroSection/HeroSection.tsx
new file mode 100644
index 0000000..4816c26
--- /dev/null
+++ b/src/components/landing/HeroSection/HeroSection.tsx
@@ -0,0 +1,60 @@
+import React, { FC } from 'react';
+import { Box, Heading, Text, Center, VStack, BoxProps } from '@chakra-ui/react';
+import { DemoVideo } from '../../../assets/videos';
+import { DemoVideoPosterImg } from '../../../assets/images';
+import { CtaButton, SiteLogo, PageSection } from '../';
+
+type HeroSectionProps = Pick;
+
+export const HeroSection: FC = ({ flexShrink }) => {
+ return (
+
+
+
+
+
+
+
+
+ Оживите свою поездку с помощью экологически чистого ухода!
+
+
+ Ощутите максимальное удобство сухой мойки автомобилей, созданной для
+ того, чтобы планета стала чище
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/components/landing/HeroSection/index.ts b/src/components/landing/HeroSection/index.ts
new file mode 100644
index 0000000..ac31a65
--- /dev/null
+++ b/src/components/landing/HeroSection/index.ts
@@ -0,0 +1 @@
+export { HeroSection } from './HeroSection';
\ No newline at end of file
diff --git a/src/components/landing/PageSection/PageSection.tsx b/src/components/landing/PageSection/PageSection.tsx
new file mode 100644
index 0000000..23c04fe
--- /dev/null
+++ b/src/components/landing/PageSection/PageSection.tsx
@@ -0,0 +1,12 @@
+import React, { FC, PropsWithChildren } from 'react';
+import { StackProps, VStack } from '@chakra-ui/react';
+
+type PageSectionProps = StackProps & PropsWithChildren;
+
+export const PageSection: FC = ({ children, ...restProps }) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/landing/PageSection/index.ts b/src/components/landing/PageSection/index.ts
new file mode 100644
index 0000000..5289ae0
--- /dev/null
+++ b/src/components/landing/PageSection/index.ts
@@ -0,0 +1 @@
+export { PageSection } from './PageSection';
\ No newline at end of file
diff --git a/src/components/landing/SiteLogo/SiteLogo.tsx b/src/components/landing/SiteLogo/SiteLogo.tsx
new file mode 100644
index 0000000..449a117
--- /dev/null
+++ b/src/components/landing/SiteLogo/SiteLogo.tsx
@@ -0,0 +1,10 @@
+import React, { FC } from 'react';
+import { Image } from '@chakra-ui/react';
+import { LogoSvg } from '../../../assets/icons';
+
+export const SiteLogo: FC = () => {
+ return ;
+};
+
+// todo: add i18n for alt
+// todo: replace Image by SVG React component
\ No newline at end of file
diff --git a/src/components/landing/SiteLogo/index.ts b/src/components/landing/SiteLogo/index.ts
new file mode 100644
index 0000000..48bcc7d
--- /dev/null
+++ b/src/components/landing/SiteLogo/index.ts
@@ -0,0 +1 @@
+export { SiteLogo } from './SiteLogo';
diff --git a/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/ReviewCard.tsx b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/ReviewCard.tsx
new file mode 100644
index 0000000..fcf3697
--- /dev/null
+++ b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/ReviewCard.tsx
@@ -0,0 +1,37 @@
+import React, { FC } from 'react';
+import { Card, Avatar, Text } from '@chakra-ui/react';
+
+type ReviewCardProps = {
+ firstname: string;
+ lastname: string;
+ picture: string;
+ text: string;
+};
+
+export const ReviewCard: FC = ({
+ firstname,
+ lastname,
+ picture,
+ text,
+}) => {
+ const name = [firstname, lastname].join(' ');
+
+ return (
+
+
+
+ {text}
+
+
+ );
+};
diff --git a/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/index.ts b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/index.ts
new file mode 100644
index 0000000..1582f4d
--- /dev/null
+++ b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewCard/index.ts
@@ -0,0 +1 @@
+export { ReviewCard } from './ReviewCard';
\ No newline at end of file
diff --git a/src/components/landing/SocialProofSection/ReviewsSlider/ReviewsSlider.tsx b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewsSlider.tsx
new file mode 100644
index 0000000..be89118
--- /dev/null
+++ b/src/components/landing/SocialProofSection/ReviewsSlider/ReviewsSlider.tsx
@@ -0,0 +1,73 @@
+import React, { FC, useEffect, useState } from 'react';
+import {
+ Tab,
+ TabList,
+ TabPanel,
+ TabPanels,
+ Tabs,
+ Text,
+} from '@chakra-ui/react';
+import { mockReviews } from '../../../../mocks/landing';
+import { ReviewCard } from './ReviewCard';
+
+const reviewsCount = mockReviews.length;
+const SLIDE_CHANGE_INTERVAL = 5000;
+
+export const ReviewsSlider: FC = () => {
+ const [activeTab, setActiveTab] = useState(0);
+ const [isSlideShowStopped, setIsSlideShowStopped] = useState(false);
+
+ useEffect(() => {
+ const timer = setInterval(() => {
+ const newActiveTab = (activeTab + 1) % reviewsCount;
+ setActiveTab(newActiveTab);
+ }, SLIDE_CHANGE_INTERVAL);
+
+ if (isSlideShowStopped) {
+ clearInterval(timer);
+ }
+
+ return () => {
+ clearInterval(timer);
+ };
+ }, [activeTab]);
+
+ return (
+ {
+ setIsSlideShowStopped(true);
+ setActiveTab(selectedTab);
+ }}
+ display='flex'
+ flexDir='column'
+ alignItems='center'
+ variant='soft-rounded'
+ colorScheme='gray'
+ >
+
+ {mockReviews.map(({ id }, i) => (
+
+ {i}
+
+ ))}
+
+
+ {mockReviews.map(({ id, ...reviewProps }) => (
+
+
+
+ ))}
+
+
+ );
+};
diff --git a/src/components/landing/SocialProofSection/ReviewsSlider/index.ts b/src/components/landing/SocialProofSection/ReviewsSlider/index.ts
new file mode 100644
index 0000000..773341e
--- /dev/null
+++ b/src/components/landing/SocialProofSection/ReviewsSlider/index.ts
@@ -0,0 +1 @@
+export { ReviewsSlider } from './ReviewsSlider';
\ No newline at end of file
diff --git a/src/components/landing/SocialProofSection/SocialProofSection.tsx b/src/components/landing/SocialProofSection/SocialProofSection.tsx
new file mode 100644
index 0000000..d2ec90a
--- /dev/null
+++ b/src/components/landing/SocialProofSection/SocialProofSection.tsx
@@ -0,0 +1,19 @@
+import React, { FC } from 'react';
+import {
+ Heading,
+ HStack,
+} from '@chakra-ui/react';
+import { CtaButton, PageSection } from '../';
+import { ReviewsSlider } from './ReviewsSlider';
+
+export const SocialProofSection: FC = () => {
+ return (
+
+ Нас выбирают
+
+
+
+
+
+ );
+};
diff --git a/src/components/landing/SocialProofSection/index.ts b/src/components/landing/SocialProofSection/index.ts
new file mode 100644
index 0000000..e20037f
--- /dev/null
+++ b/src/components/landing/SocialProofSection/index.ts
@@ -0,0 +1 @@
+export { SocialProofSection } from './SocialProofSection';
\ No newline at end of file
diff --git a/src/components/landing/index.ts b/src/components/landing/index.ts
new file mode 100644
index 0000000..54cda58
--- /dev/null
+++ b/src/components/landing/index.ts
@@ -0,0 +1,7 @@
+export * from './CtaButton';
+export * from './PageSection';
+export * from './BenefitsSection'; // CtaButton, PageSection
+export * from './SocialProofSection'; // CtaButton, PageSection
+export * from './SiteLogo';
+export * from './Footer'; // PageSection, SiteLogo
+export * from './HeroSection'; // CtaButton, PageSection, SiteLogo
\ No newline at end of file