(Desktop 12) landing page layout
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
56
package.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "hub_frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@mui/material": "^5.10.14",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^13.0.0",
|
||||
"@testing-library/user-event": "^13.2.1",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.4.2",
|
||||
"web-vitals": "^2.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
],
|
||||
"rules": {
|
||||
"quotes": [
|
||||
"warn",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 3.8 KiB |
46
public/index.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Web site created using create-react-app" />
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<title>React App</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
BIN
public/logo192.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
public/logo512.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
25
public/manifest.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
3
public/robots.txt
Normal file
@ -0,0 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
9
src/App.test.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
14
src/App.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { CssBaseline, ThemeProvider } from "@mui/material";
|
||||
import { theme } from "./utils/muiTheme";
|
||||
import Landing from "./components/landing/Landing";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<Landing />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
BIN
src/assets/card-pages-background1.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
src/assets/card-pages-background2.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
src/assets/card-pages-background3.png
Normal file
After Width: | Height: | Size: 43 KiB |
19
src/assets/logo_PenaHab.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg width="180" height="70" viewBox="0 0 180 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_122_333)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.9138 3.31953C18.594 2.47163 13.5439 10.3345 8.84663 16.0182C4.72431 21.0062 1.6549 26.6402 1.29838 33.1042C0.919075 39.9813 2.16658 47.1434 6.85174 52.1872C11.6777 57.3826 18.9068 60.6653 25.9138 59.604C32.3391 58.6308 35.1822 51.5749 39.9658 47.1716C45.16 42.3905 54.837 40.1667 54.7027 33.1042C54.5683 26.0308 44.3552 24.6462 39.441 19.5621C34.3509 14.2959 33.1853 4.16182 25.9138 3.31953Z" fill="#7E2AEA"/>
|
||||
<circle cx="44.126" cy="56.9181" r="4.03906" fill="#7E2AEA"/>
|
||||
<circle cx="40.0865" cy="12.1038" r="1.53869" fill="#7E2AEA"/>
|
||||
<path d="M64.699 31.4509C64.2503 27.0891 62.1983 23.0492 58.9405 20.1143C55.6828 17.1794 51.4514 15.5585 47.0666 15.5658C46.4441 15.5661 45.822 15.5986 45.2028 15.6634C40.8429 16.1211 36.807 18.1771 33.8735 21.4347C30.9399 24.6923 29.3165 28.9208 29.3164 33.3046V33.3046V58.6457H36.9188V47.8758C39.8912 49.9436 43.4267 51.0493 47.0476 51.0434C47.6702 51.0432 48.2923 51.0106 48.9115 50.9458C51.2282 50.7024 53.4744 50.0049 55.5216 48.8934C57.5688 47.7818 59.3771 46.2779 60.8431 44.4675C62.3091 42.6571 63.4042 40.5757 64.0658 38.3421C64.7274 36.1084 64.9425 33.7664 64.699 31.4496V31.4509ZM54.935 39.6868C54.0999 40.7241 53.0673 41.5855 51.897 42.2211C50.7266 42.8566 49.4418 43.2536 48.117 43.3891C47.7617 43.426 47.4048 43.4446 47.0476 43.4449C44.7485 43.4427 42.5183 42.6591 40.7233 41.2225C38.9282 39.7859 37.6749 37.7817 37.1689 35.5389C36.663 33.2961 36.9346 30.9479 37.9391 28.8798C38.9436 26.8117 40.6213 25.1465 42.6969 24.1576C44.7725 23.1686 47.1226 22.9147 49.3616 23.4374C51.6005 23.9601 53.5952 25.2285 55.0183 27.0343C56.4414 28.8401 57.2083 31.076 57.1932 33.3751C57.1781 35.6742 56.3818 37.8999 54.935 39.6868Z" fill="white"/>
|
||||
<path d="M84.5348 15.5659C83.9123 15.5661 83.2902 15.5987 82.671 15.6634C78.1535 16.1392 73.9907 18.3298 71.0405 21.7839C68.0903 25.2379 66.5776 29.6921 66.8141 34.2284C67.0507 38.7647 69.0184 43.0374 72.3119 46.1658C75.6053 49.2943 79.9734 51.0401 84.5158 51.0435C85.1384 51.0433 85.7605 51.0107 86.3797 50.9459C89.6368 50.5992 92.7351 49.3601 95.3331 47.3652C97.9312 45.3704 99.9282 42.6971 101.104 39.6399H92.4388L92.4033 39.6843C91.2933 41.0563 89.8444 42.1147 88.1999 42.7548C86.5554 43.395 84.7722 43.5947 83.0268 43.3343C81.2814 43.0738 79.6342 42.3622 78.2482 41.2698C76.8622 40.1774 75.7855 38.7421 75.1244 37.1058H101.859C102.422 34.5159 102.399 31.8328 101.79 29.2532C101.181 26.6736 100.003 24.2628 98.3424 22.1975C96.6813 20.1322 94.5791 18.4648 92.19 17.3173C89.8009 16.1698 87.1853 15.5714 84.5348 15.5659V15.5659ZM75.1244 29.5035C75.8165 27.8 76.9578 26.3163 78.4267 25.2104C79.8956 24.1046 81.6371 23.418 83.4655 23.224C83.8207 23.1871 84.1777 23.1685 84.5348 23.1682C86.5541 23.1648 88.528 23.7666 90.202 24.8958C91.876 26.025 93.1732 27.6299 93.9263 29.5035H75.1244Z" fill="white"/>
|
||||
<path d="M120.638 15.5659C117.732 15.5613 114.882 16.3602 112.402 17.8745V15.5659H104.8V51.0435H112.402V31.4041C112.402 29.2198 113.27 27.125 114.814 25.5805C116.359 24.0359 118.454 23.1682 120.638 23.1682C122.822 23.1682 124.917 24.0359 126.462 25.5805C128.006 27.125 128.874 29.2198 128.874 31.4041V51.0435H136.476V31.4041C136.476 27.2035 134.808 23.175 131.837 20.2048C128.867 17.2345 124.839 15.5659 120.638 15.5659Z" fill="white"/>
|
||||
<path d="M174.491 35.5715V15.5659H166.889V18.7335C163.917 16.6648 160.381 15.559 156.76 15.5659C156.138 15.5662 155.516 15.5987 154.896 15.6635C150.379 16.1392 146.216 18.3299 143.266 21.7839C140.316 25.2379 138.803 29.6921 139.039 34.2284C139.276 38.7647 141.244 43.0374 144.537 46.1659C147.831 49.2944 152.199 51.0402 156.741 51.0435C157.364 51.0432 157.986 51.0107 158.605 50.9459C163.023 50.4938 167.108 48.3888 170.04 45.0529C172.319 48.1011 175.618 50.2275 179.335 51.0435V43.0737C177.893 42.4204 176.669 41.3655 175.81 40.0351C174.951 38.7047 174.493 37.1551 174.491 35.5715ZM164.629 39.6843C163.793 40.7215 162.761 41.5828 161.59 42.2182C160.42 42.8537 159.135 43.2509 157.811 43.3867C157.455 43.4236 157.098 43.4422 156.741 43.4424C154.144 43.4423 151.646 42.4452 149.762 40.6567C147.879 38.8683 146.753 36.4251 146.619 33.8312C146.484 31.2374 147.35 28.6908 149.039 26.717C150.727 24.7433 153.109 23.4929 155.692 23.224C156.047 23.1871 156.403 23.1684 156.76 23.1682C158.674 23.1699 160.548 23.7133 162.166 24.7356C163.784 25.7579 165.079 27.2173 165.903 28.9451C166.726 30.6728 167.043 32.5983 166.817 34.4988C166.592 36.3993 165.833 38.1971 164.629 39.6843Z" fill="white"/>
|
||||
<path d="M147.519 54.8936V59.1273C148.231 58.2947 149.082 57.8784 150.072 57.8784C150.58 57.8784 151.038 57.9727 151.446 58.1612C151.855 58.3497 152.161 58.5906 152.365 58.8838C152.575 59.177 152.716 59.5017 152.79 59.8578C152.868 60.2139 152.907 60.7663 152.907 61.5151V66.4085H150.7V62.0021C150.7 61.1276 150.658 60.5725 150.575 60.3369C150.491 60.1013 150.342 59.9154 150.127 59.7792C149.917 59.6378 149.653 59.5672 149.334 59.5672C148.967 59.5672 148.64 59.6562 148.352 59.8342C148.064 60.0122 147.852 60.2819 147.716 60.6432C147.585 60.9993 147.519 61.5282 147.519 62.2299V66.4085H145.312V54.8936H147.519Z" fill="white"/>
|
||||
<path d="M160.644 66.4085V65.1597C160.341 65.6048 159.94 65.9556 159.442 66.2122C158.95 66.4688 158.429 66.5971 157.879 66.5971C157.319 66.5971 156.816 66.474 156.371 66.2279C155.926 65.9818 155.604 65.6362 155.405 65.1911C155.206 64.746 155.107 64.1307 155.107 63.3452V58.0669H157.314V61.9C157.314 63.0729 157.353 63.7929 157.432 64.06C157.515 64.3218 157.665 64.5313 157.879 64.6884C158.094 64.8402 158.366 64.9162 158.696 64.9162C159.073 64.9162 159.411 64.814 159.71 64.6098C160.008 64.4004 160.212 64.1438 160.322 63.8401C160.432 63.5311 160.487 62.7797 160.487 61.5858V58.0669H162.694V66.4085H160.644Z" fill="white"/>
|
||||
<path d="M164.894 66.4085V54.8936H167.101V59.0409C167.782 58.2659 168.588 57.8784 169.52 57.8784C170.536 57.8784 171.376 58.2476 172.041 58.9859C172.706 59.719 173.039 60.7741 173.039 62.1513C173.039 63.5756 172.699 64.6727 172.018 65.4424C171.342 66.2122 170.52 66.5971 169.551 66.5971C169.075 66.5971 168.604 66.4792 168.138 66.2436C167.677 66.0027 167.279 65.6493 166.944 65.1832V66.4085H164.894ZM167.085 62.0571C167.085 62.9211 167.221 63.5599 167.493 63.9736C167.876 64.5601 168.384 64.8533 169.017 64.8533C169.504 64.8533 169.918 64.6465 170.258 64.2328C170.604 63.8139 170.777 63.1567 170.777 62.2613C170.777 61.3083 170.604 60.6223 170.258 60.2034C169.913 59.7792 169.47 59.5672 168.931 59.5672C168.402 59.5672 167.962 59.774 167.611 60.1877C167.26 60.5961 167.085 61.2192 167.085 62.0571Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_122_333">
|
||||
<rect width="179.509" height="69.4872" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 6.6 KiB |
BIN
src/assets/pena_illustration01.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/pena_illustration02.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
src/assets/pena_illustration03.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/pena_illustration04.png
Normal file
After Width: | Height: | Size: 19 KiB |
32
src/components/Button.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import { Button as DefaultButton } from "@mui/material";
|
||||
|
||||
|
||||
interface Props {
|
||||
fullWidth?: boolean;
|
||||
backgroundColor?: string;
|
||||
color?: string;
|
||||
variant: "outlined" | "contained";
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Button({ fullWidth = false, backgroundColor, color, variant, children }: Props) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DefaultButton
|
||||
fullWidth={fullWidth}
|
||||
variant={variant}
|
||||
sx={{
|
||||
backgroundColor,
|
||||
color,
|
||||
borderRadius: "8px",
|
||||
px: "41.5px",
|
||||
py: "9px",
|
||||
boxShadow: "none",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DefaultButton>
|
||||
</div>
|
||||
);
|
||||
}
|
19
src/components/NavMenuItem.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { Link, Typography, useTheme } from "@mui/material";
|
||||
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export default function NavMenuItem({ text, isActive = false }: Props) {
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<Link href="#" underline="none">
|
||||
<Typography color={isActive ? theme.palette.custom.brightPurple.main : undefined} variant="medium" >
|
||||
{text}
|
||||
</Typography>
|
||||
</Link>
|
||||
);
|
||||
}
|
49
src/components/Navbar.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import { Box, Button, useTheme } from "@mui/material";
|
||||
import NavMenuItem from "./NavMenuItem";
|
||||
import SectionWrapper from "./SectionWrapper";
|
||||
|
||||
|
||||
export default function Navbar() {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="nav"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.lightPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
px: "20px",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
height: "80px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "30px",
|
||||
}}
|
||||
>
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 2" isActive />
|
||||
<NavMenuItem text="Меню 3" />
|
||||
<NavMenuItem text="Меню 4" />
|
||||
<NavMenuItem text="Меню 5" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 2" />
|
||||
</Box >
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{
|
||||
px: "18px",
|
||||
py: "10px",
|
||||
borderColor: "white",
|
||||
borderRadius: "8px"
|
||||
}}
|
||||
>Личный кабинет</Button>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
31
src/components/SectionWrapper.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Breakpoint, Container, SxProps, Theme } from "@mui/material";
|
||||
import React, { ElementType } from "react";
|
||||
|
||||
|
||||
interface Props {
|
||||
component?: ElementType;
|
||||
sx?: SxProps<Theme>;
|
||||
innerSx: SxProps<Theme>;
|
||||
maxWidth?: false | Breakpoint;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function SectionWrapper({ component, sx, innerSx, children, maxWidth }: Props) {
|
||||
|
||||
return (
|
||||
<Container
|
||||
component={component || "div"}
|
||||
maxWidth={false}
|
||||
disableGutters
|
||||
sx={sx}
|
||||
>
|
||||
<Container
|
||||
disableGutters
|
||||
maxWidth={maxWidth}
|
||||
sx={innerSx}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
</Container>
|
||||
);
|
||||
}
|
27
src/components/UnderlinedLink.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { Link, SxProps, Theme, Typography } from "@mui/material";
|
||||
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
linkHref: string;
|
||||
isHighlighted?: boolean;
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
|
||||
export default function UnderlinedLink({ text, linkHref, isHighlighted = false, sx }: Props) {
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={linkHref}
|
||||
color={isHighlighted ? "text.primary" : "text.secondary"}
|
||||
underline="none"
|
||||
sx={{
|
||||
borderBottom: isHighlighted ? "1px solid #ffffff" : "1px solid #7E2AEA",
|
||||
pb: "3px",
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<Typography variant="medium">{text}</Typography>
|
||||
</Link>
|
||||
);
|
||||
}
|
61
src/components/landing/CardWithLink.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import UnderlinedLink from "../UnderlinedLink";
|
||||
|
||||
|
||||
interface Props {
|
||||
image: string;
|
||||
headerText: string;
|
||||
text: string;
|
||||
linkHref: string;
|
||||
isHighlighted?: boolean;
|
||||
}
|
||||
|
||||
export default function CardWithLink({ image, headerText, text, linkHref, isHighlighted = false }: Props) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "start",
|
||||
padding: "20px",
|
||||
pb: "32px",
|
||||
maxWidth: "360px",
|
||||
maxHeight: "434px",
|
||||
width: "360px",
|
||||
height: "434px",
|
||||
backgroundColor: isHighlighted ? theme.palette.custom.brightPurple.main : theme.palette.custom.grey.main,
|
||||
borderRadius: "12px",
|
||||
boxShadow: `0px 100px 309px rgba(37, 39, 52, 0.24),
|
||||
0px 41.7776px 129.093px rgba(37, 39, 52, 0.172525),
|
||||
0px 22.3363px 69.0192px rgba(37, 39, 52, 0.143066),
|
||||
0px 12.5216px 38.6916px rgba(37, 39, 52, 0.12),
|
||||
0px 6.6501px 20.5488px rgba(37, 39, 52, 0.0969343),
|
||||
0px 2.76726px 8.55082px rgba(37, 39, 52, 0.0674749)`,
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
alignSelf: "center",
|
||||
backgroundImage: `url(${image})`,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
maxHeight: "196px",
|
||||
flexGrow: 1,
|
||||
backgroundSize: "contain",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center",
|
||||
}} />
|
||||
<Typography variant="h5" sx={{ my: "12px" }}>{headerText}</Typography>
|
||||
<Typography>{text}</Typography>
|
||||
<UnderlinedLink
|
||||
linkHref={linkHref}
|
||||
text="Подробнее 🡲"
|
||||
isHighlighted={isHighlighted}
|
||||
sx={{
|
||||
mt: "auto",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
67
src/components/landing/Footer.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import logo_PenaHab from "../../assets/logo_PenaHab.svg";
|
||||
import NavMenuItem from "../NavMenuItem";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
|
||||
|
||||
export default function Footer() {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="footer"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.darkPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
pt: "100px",
|
||||
pb: "75px",
|
||||
px: "20px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "100px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<img src={logo_PenaHab} alt="pena logo" height={48} />
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
flexGrow: 1,
|
||||
justifyItems: "center",
|
||||
gridTemplateColumns: "repeat(3, 1fr)",
|
||||
gridTemplateRows: "repeat(3, 1fr)",
|
||||
rowGap: "18px",
|
||||
}}
|
||||
>
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
<NavMenuItem text="Меню 1" />
|
||||
</Box>
|
||||
<Typography
|
||||
variant="medium"
|
||||
sx={{
|
||||
maxWidth: "275px",
|
||||
}}
|
||||
>
|
||||
Сервисы помогают предпринимателям, маркетологам и агентствам
|
||||
сделать интернет-маркетинг прозрач
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography variant="medium">Конструктор маркетинговых решений. © 2022</Typography>
|
||||
</SectionWrapper>
|
||||
);
|
||||
};
|
29
src/components/landing/Infographics.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
|
||||
|
||||
interface Props {
|
||||
bigText: string;
|
||||
text: string;
|
||||
flex: string;
|
||||
}
|
||||
|
||||
export default function Infographics({ bigText, text, flex }: Props) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
flex,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="infographic"
|
||||
color={theme.palette.custom.brightPurple.main}
|
||||
sx={{
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>{bigText}</Typography>
|
||||
<Typography sx={{ maxWidth: "10em" }}>{text}</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
25
src/components/landing/Landing.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { Box, Divider } from "@mui/material";
|
||||
import Navbar from "../Navbar";
|
||||
import Footer from "./Footer";
|
||||
import Section1 from "./Section1";
|
||||
import Section2 from "./Section2";
|
||||
import Section3 from "./Section3";
|
||||
import Section4 from "./Section4";
|
||||
import Section5 from "./Section5";
|
||||
|
||||
|
||||
export default function Landing() {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Navbar />
|
||||
<Divider sx={{ bgcolor: "custom.divider.main" }} />
|
||||
<Section1 />
|
||||
<Section2 />
|
||||
<Section3 />
|
||||
<Section4 />
|
||||
<Section5 />
|
||||
<Footer />
|
||||
</Box>
|
||||
);
|
||||
}
|
60
src/components/landing/PromoCard.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { Box, SxProps, Theme, Typography, useTheme } from "@mui/material";
|
||||
|
||||
|
||||
interface Props {
|
||||
backgroundImage: any;
|
||||
headerText: string;
|
||||
text: string;
|
||||
textOrientation: "row" | "column";
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
|
||||
export default function PromoCard({ backgroundImage, headerText, text, textOrientation, sx }: Props) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: "300px",
|
||||
width: "500px",
|
||||
borderRadius: "12px",
|
||||
backgroundColor: theme.palette.custom.darkPurple.main,
|
||||
backgroundImage: `url(${backgroundImage})`,
|
||||
p: "20px",
|
||||
boxShadow: `0px 100px 309px rgba(37, 39, 52, 0.24),
|
||||
0px 41.7776px 129.093px rgba(37, 39, 52, 0.172525),
|
||||
0px 22.3363px 69.0192px rgba(37, 39, 52, 0.143066),
|
||||
0px 12.5216px 38.6916px rgba(37, 39, 52, 0.12),
|
||||
0px 6.6501px 20.5488px rgba(37, 39, 52, 0.0969343),
|
||||
0px 2.76726px 8.55082px rgba(37, 39, 52, 0.0674749)`,
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: textOrientation,
|
||||
height: textOrientation === "row" ? "2.6em" : undefined,
|
||||
width: textOrientation === "column" ? "50%" : undefined,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
maxWidth: "80%",
|
||||
flex: "1 1 50%",
|
||||
mb: "20px",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5" sx={{ maxWidth: "75%" }}>{headerText}</Typography>
|
||||
</Box>
|
||||
<Typography sx={{
|
||||
fontSize: "18.48px",
|
||||
lineHeight: "22px",
|
||||
flex: "1 1 50%",
|
||||
overflow: "hidden",
|
||||
pr: "30px",
|
||||
}}>{text}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
82
src/components/landing/Section1.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import logo_PenaHab from "../../assets/logo_PenaHab.svg";
|
||||
import pena_illustration02 from "../../assets/pena_illustration02.png";
|
||||
import Button from "../Button";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
|
||||
|
||||
export default function Section1() {
|
||||
const theme = useTheme();
|
||||
const matchMd = useMediaQuery("@media (min-width: 1100px)");
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="section"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.lightPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
display: "flex",
|
||||
pt: "70px",
|
||||
pb: "40px",
|
||||
px: "20px",
|
||||
gap: "20px",
|
||||
flexDirection: matchMd ? "row" : "column",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: "1 0 0",
|
||||
gap: "70px",
|
||||
order: matchMd ? 1 : 2,
|
||||
}}
|
||||
>
|
||||
{matchMd && <img src={logo_PenaHab} alt="pena logo" width={180} height={70} />}
|
||||
<Typography variant="h2">Сервисы прокачки маркетинга</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
flex: "1 0 0",
|
||||
textAlign: "center",
|
||||
order: matchMd ? 2 : 1,
|
||||
my: matchMd ? undefined : "-90px",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
transform: matchMd ? undefined : "rotate(-90deg)",
|
||||
imageRendering: "pixelated",
|
||||
}}
|
||||
src={pena_illustration02}
|
||||
alt="pena illustration"
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: "1 0 0",
|
||||
alignItems: "start",
|
||||
alignSelf: matchMd ? "center" : "start",
|
||||
mt: "70px",
|
||||
order: 3,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ mb: "11px" }}>
|
||||
<Typography>Покажут эффективность рекламы</Typography>
|
||||
<Typography>Соберут все обращения клиентов</Typography>
|
||||
<Typography>Повысят конверсию сайта</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ mb: "40px" }}>И все это в едином кабинете</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
backgroundColor={theme.palette.custom.brightPurple.main}
|
||||
color={theme.palette.primary.main}
|
||||
>Подробнее</Button>
|
||||
</Box>
|
||||
</SectionWrapper>
|
||||
);
|
||||
};
|
91
src/components/landing/Section2.tsx
Normal file
@ -0,0 +1,91 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import CardWithLink from "./CardWithLink";
|
||||
import pena_illustration01 from "../../assets/pena_illustration01.png";
|
||||
import pena_illustration03 from "../../assets/pena_illustration03.png";
|
||||
import pena_illustration04 from "../../assets/pena_illustration04.png";
|
||||
import UnderlinedLink from "../UnderlinedLink";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
|
||||
|
||||
export default function Section2() {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="section"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.darkPurple.main,
|
||||
mb: "-90px",
|
||||
}}
|
||||
innerSx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "93px",
|
||||
pt: "90px",
|
||||
pb: "20px",
|
||||
px: "20px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "120px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h4" sx={{ flexGrow: 1, maxWidth: "360px" }}>Интеграции, избавляющие от рутины</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "30px",
|
||||
alignItems: "start",
|
||||
flexGrow: 2,
|
||||
mt: "10px",
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
Сервисы помогают предпринимателям, маркетологам и агентствам
|
||||
сделать интернет-маркетинг прозрачным и эффективным. С нами не придется
|
||||
тратить рекламный бюджет впустую и терять клиентов на сайте.
|
||||
</Typography>
|
||||
<UnderlinedLink
|
||||
linkHref="#"
|
||||
text="Подробнее 🡲"
|
||||
sx={{
|
||||
mt: "auto",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: undefined,
|
||||
gap: "40px",
|
||||
}}
|
||||
>
|
||||
<CardWithLink
|
||||
headerText="Шаблонизатор"
|
||||
text="Текст- это текст, который имеет некоторые характеристики реального письменного текс"
|
||||
isHighlighted
|
||||
linkHref="#"
|
||||
image={pena_illustration03}
|
||||
/>
|
||||
<CardWithLink
|
||||
headerText="Опросник"
|
||||
text="Текст- это текст, который имеет некоторые характеристики реального письменного текс"
|
||||
linkHref="#"
|
||||
image={pena_illustration04}
|
||||
/>
|
||||
<CardWithLink
|
||||
headerText="Сокращатель ссылок"
|
||||
text="Текст- это текст, который имеет некоторые характеристики реального письменного текс"
|
||||
linkHref="#"
|
||||
image={pena_illustration01}
|
||||
/>
|
||||
</Box>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
89
src/components/landing/Section3.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import PromoCard from "./PromoCard";
|
||||
import cardPagesBackground1 from "../../assets/card-pages-background1.png";
|
||||
import cardPagesBackground2 from "../../assets/card-pages-background2.png";
|
||||
import cardPagesBackground3 from "../../assets/card-pages-background3.png";
|
||||
import UnderlinedLink from "../UnderlinedLink";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
|
||||
|
||||
export default function Section3() {
|
||||
const theme = useTheme();
|
||||
const matchMd = useMediaQuery("@media (min-width: 1100px)");
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="section"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.lightPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
display: "flex",
|
||||
pt: "170px",
|
||||
pb: "100px",
|
||||
px: "20px",
|
||||
width: "fit-content",
|
||||
margin: "auto",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: matchMd ? "row" : "column",
|
||||
flexWrap: "wrap",
|
||||
rowGap: "58px",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "start",
|
||||
maxWidth: "500px",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{
|
||||
mb: "70px",
|
||||
}}
|
||||
>Узнайте, как наши сервисы решают ваши задачи</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
mb: "20px",
|
||||
}}
|
||||
>
|
||||
<Typography>Покажут эффективность рекламы</Typography>
|
||||
<Typography>Соберут все обращения клиентов</Typography>
|
||||
<Typography>Повысят конверсию сайта</Typography>
|
||||
</Box>
|
||||
<UnderlinedLink
|
||||
linkHref="#"
|
||||
text="Подробнее 🡲"
|
||||
/>
|
||||
</Box>
|
||||
<PromoCard
|
||||
headerText="Общий кабинет"
|
||||
text="Текст-заполнитель — это текст, который имеет некоторые характеристики реального письменного"
|
||||
textOrientation="column"
|
||||
backgroundImage={cardPagesBackground1}
|
||||
/>
|
||||
<PromoCard
|
||||
headerText="Общий кабинет"
|
||||
text="Текст-заполнитель — это текст, который имеет некоторые характеристики реального письменного"
|
||||
textOrientation="row"
|
||||
backgroundImage={cardPagesBackground2}
|
||||
/>
|
||||
<PromoCard
|
||||
headerText="Гибкие тарифы"
|
||||
text="Текст-заполнитель — это текст, который имеет некоторые характеристики реального письменного"
|
||||
textOrientation="column"
|
||||
backgroundImage={cardPagesBackground3}
|
||||
sx={{ mt: matchMd ? "102px" : undefined }}
|
||||
/>
|
||||
</Box>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
60
src/components/landing/Section4.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { useMediaQuery, useTheme } from "@mui/material";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
import Infographics from "./Infographics";
|
||||
|
||||
|
||||
export default function Section4() {
|
||||
const theme = useTheme();
|
||||
const matchMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
const itemsFlex = matchMd ? "1 0 33.333%" : "1 0 50%";
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="section"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.darkPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
rowGap: "80px",
|
||||
px: "20px",
|
||||
pt: "90px",
|
||||
pb: "112px",
|
||||
}}
|
||||
>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="9"
|
||||
text="лет на рынке"
|
||||
/>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="18"
|
||||
text="инструментов в едином кабинете"
|
||||
/>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="5 467"
|
||||
text="клиентов с нами"
|
||||
/>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="15"
|
||||
text="минут на подключение"
|
||||
/>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="24/7"
|
||||
text="с вами служба поддержка"
|
||||
/>
|
||||
<Infographics
|
||||
flex={itemsFlex}
|
||||
bigText="1 000"
|
||||
text="рублей в месяц минимальный тариф"
|
||||
/>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
61
src/components/landing/Section5.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import Button from "../Button";
|
||||
import SectionWrapper from "../SectionWrapper";
|
||||
|
||||
|
||||
export default function Section5() {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
component="section"
|
||||
maxWidth="lg"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.custom.brightPurple.main,
|
||||
}}
|
||||
innerSx={{
|
||||
pt: "100px",
|
||||
pb: "100px",
|
||||
px: "20px"
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<Typography variant="h4" sx={{ mb: "62px" }}>Остались вопросы?</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
gap: "24px",
|
||||
}}
|
||||
>
|
||||
{/** extract buttons as components */}
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
>Подробнее</Button>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
>Подробнее</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
maxWidth: "460px",
|
||||
}}
|
||||
>
|
||||
<Typography>Сервисы помогают предпринимателям, маркетологам и агентствам
|
||||
сделать интернет-маркетинг прозрачным и эффективным. С нами не придется
|
||||
тратить рекламный бюджет впустую и терять клиентов на сайте.</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
13
src/index.css
Normal file
@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
19
src/index.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import reportWebVitals from "./reportWebVitals";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
1
src/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
37
src/mui.d.ts
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import "@material-ui/styles";
|
||||
|
||||
declare module "@mui/material/styles" {
|
||||
interface Palette {
|
||||
custom: {
|
||||
divider: Palette["primary"],
|
||||
lightPurple: Palette["primary"],
|
||||
darkPurple: Palette["primary"],
|
||||
brightPurple: Palette["primary"],
|
||||
grey: Palette["primary"],
|
||||
};
|
||||
}
|
||||
interface PaletteOptions {
|
||||
custom: {
|
||||
divider: PaletteOptions["primary"],
|
||||
lightPurple: PaletteOptions["primary"],
|
||||
darkPurple: PaletteOptions["primary"],
|
||||
brightPurple: PaletteOptions["primary"],
|
||||
grey: PaletteOptions["primary"],
|
||||
};
|
||||
}
|
||||
interface TypographyVariants {
|
||||
medium: React.CSSProperties;
|
||||
infographic: React.CSSProperties;
|
||||
}
|
||||
interface TypographyVariantsOptions {
|
||||
medium?: React.CSSProperties;
|
||||
infographic?: React.CSSProperties;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@mui/material/Typography" {
|
||||
interface TypographyPropsVariantOverrides {
|
||||
medium: true;
|
||||
infographic: true;
|
||||
}
|
||||
}
|
1
src/react-app-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
15
src/reportWebVitals.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { ReportHandler } from "web-vitals";
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
5
src/setupTests.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
96
src/utils/muiTheme.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { createTheme } from "@mui/material";
|
||||
|
||||
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
mode: "dark",
|
||||
primary: {
|
||||
main: "#ffffff",
|
||||
},
|
||||
secondary: {
|
||||
main: "#252734"
|
||||
},
|
||||
text: {
|
||||
primary: "#ffffff",
|
||||
secondary: "#7E2AEA",
|
||||
},
|
||||
custom: {
|
||||
divider: {
|
||||
main: "#E3E3E3",
|
||||
},
|
||||
lightPurple: {
|
||||
main: "#333647",
|
||||
},
|
||||
darkPurple: {
|
||||
main: "#252734",
|
||||
},
|
||||
brightPurple: {
|
||||
main: "#7E2AEA",
|
||||
},
|
||||
grey: {
|
||||
main: "#434657",
|
||||
}
|
||||
}
|
||||
},
|
||||
breakpoints: {
|
||||
values: {
|
||||
xs: 0,
|
||||
sm: 600,
|
||||
md: 900,
|
||||
lg: 1200,
|
||||
xl: 1536,
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
infographic: {
|
||||
fontSize: "80px",
|
||||
lineHeight: "94.8px",
|
||||
fontWeight: 400,
|
||||
},
|
||||
h2: {
|
||||
fontSize: "70px",
|
||||
lineHeight: "70px",
|
||||
fontWeight: 500,
|
||||
},
|
||||
h4: { // H1 в макете
|
||||
fontSize: "36px",
|
||||
lineHeight: "42.66px",
|
||||
fontWeight: 500,
|
||||
},
|
||||
h5: { // H2 в макете
|
||||
fontSize: "24px",
|
||||
lineHeight: "28.44px",
|
||||
fontWeight: 500,
|
||||
},
|
||||
button: {
|
||||
fontSize: "18px",
|
||||
lineHeight: "24px",
|
||||
fontWeight: 400,
|
||||
textTransform: "none",
|
||||
},
|
||||
body1: { // T1 в макете
|
||||
fontSize: "18px",
|
||||
lineHeight: "21.33px",
|
||||
},
|
||||
medium: { // M1 в макете
|
||||
fontSize: "16px",
|
||||
lineHeight: "20px",
|
||||
fontWeight: 500,
|
||||
},
|
||||
fontFamily: [
|
||||
"Rubik",
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
'"Segoe UI"',
|
||||
'"Helvetica Neue"',
|
||||
"Arial",
|
||||
"sans-serif",
|
||||
'"Apple Color Emoji"',
|
||||
'"Segoe UI Emoji"',
|
||||
'"Segoe UI Symbol"',
|
||||
].join(","),
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export { theme };
|
26
tsconfig.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|