landing tourism
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*
|
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
8
.idea/API.iml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/API.iml" filepath="$PROJECT_DIR$/.idea/API.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
1
.yarnrc
Normal file
@ -0,0 +1 @@
|
||||
"@frontend:registry" "https://penahub.gitlab.yandexcloud.net/api/v4/packages/npm/"
|
18075
package-lock.json
generated
Normal file
61
package.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "tourismland",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@frontend/kitui": "^1.0.63",
|
||||
"@mui/icons-material": "^5.14.1",
|
||||
"@mui/material": "^5.14.2",
|
||||
"@mui/styled-engine-sc": "^5.12.0",
|
||||
"@mui/x-date-pickers": "^6.11.2",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.39",
|
||||
"@types/react": "^18.2.17",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"classnames": "^2.3.2",
|
||||
"cra-template-typescript": "1.2.0",
|
||||
"moment": "^2.29.4",
|
||||
"axios": "^1.4.0",
|
||||
"formik": "^2.4.3",
|
||||
"immer": "^10.0.2",
|
||||
"notistack": "^3.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"styled-components": "^5.3.11",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4",
|
||||
"yup": "^1.2.0",
|
||||
"zustand": "^4.4.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"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 |
44
public/index.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
|
||||
<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`.
|
||||
-->
|
||||
<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:
|
36
src/App.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { Navigate, Route, Routes, useLocation, useNavigate } from "react-router-dom";
|
||||
import LandingTourism from "./pages/landing/LandingTourism";
|
||||
import SignupDialog from "./pages/auth/Signup";
|
||||
|
||||
|
||||
|
||||
|
||||
function App() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
if (location.state?.redirectTo)
|
||||
return (
|
||||
<Navigate
|
||||
to={location.state.redirectTo}
|
||||
replace
|
||||
state={{ backgroundLocation: location }}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{location.state?.backgroundLocation &&
|
||||
<Routes>
|
||||
<Route path="/signup" element={<SignupDialog />} />
|
||||
|
||||
</Routes>
|
||||
}
|
||||
<Routes location={location.state?.backgroundLocation || location}>
|
||||
<Route path="/" element={<LandingTourism/>} />
|
||||
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
128
src/components/passwordInput.tsx
Normal file
@ -0,0 +1,128 @@
|
||||
import {
|
||||
FormControl,
|
||||
IconButton,
|
||||
InputLabel,
|
||||
SxProps,
|
||||
TextField,
|
||||
TextFieldProps,
|
||||
Theme,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import * as React from "react";
|
||||
import InputAdornment from "@mui/material/InputAdornment";
|
||||
import Visibility from "@mui/icons-material/Visibility";
|
||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
label?: string;
|
||||
bold?: boolean;
|
||||
gap?: string;
|
||||
color?: string;
|
||||
FormInputSx?: SxProps<Theme>;
|
||||
TextfieldProps: TextFieldProps;
|
||||
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
export default function PasswordInput({
|
||||
id,
|
||||
label,
|
||||
bold = false,
|
||||
gap = "10px",
|
||||
onChange,
|
||||
TextfieldProps,
|
||||
color,
|
||||
FormInputSx,
|
||||
}: Props) {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
const labelFont = upMd
|
||||
? bold
|
||||
? theme.typography.p1
|
||||
: { ...theme.typography.body1, fontWeight: 500 }
|
||||
: theme.typography.body2;
|
||||
|
||||
const placeholderFont = upMd ? undefined : { fontWeight: 400, fontSize: "16px", lineHeight: "19px" };
|
||||
|
||||
const [showPassword, setShowPassword] = React.useState(false);
|
||||
|
||||
const handleClickShowPassword = () => setShowPassword((show) => !show);
|
||||
|
||||
const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
fullWidth
|
||||
variant="standard"
|
||||
sx={{
|
||||
gap,
|
||||
// mt: "10px",
|
||||
...FormInputSx,
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<InputLabel
|
||||
shrink
|
||||
htmlFor={id}
|
||||
sx={{
|
||||
position: "inherit",
|
||||
color: "black",
|
||||
transform: "none",
|
||||
...labelFont,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</InputLabel>
|
||||
<TextField
|
||||
{...TextfieldProps}
|
||||
fullWidth
|
||||
id={id}
|
||||
sx={{
|
||||
"& .MuiInputBase-root": {
|
||||
height: "48px",
|
||||
borderRadius: "8px",
|
||||
},
|
||||
}}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
right: "15px",
|
||||
top: "5px",
|
||||
}}
|
||||
>
|
||||
{showPassword ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
sx: {
|
||||
padding: "0px",
|
||||
border: "1px solid" + theme.palette.gray.main,
|
||||
backgroundColor: color,
|
||||
borderRadius: "8px",
|
||||
height: "48px",
|
||||
color: "black",
|
||||
...placeholderFont,
|
||||
"& .MuiInputBase-input": {
|
||||
boxSizing: "border-box",
|
||||
height: "100%",
|
||||
padding: "14px",
|
||||
},
|
||||
},
|
||||
}}
|
||||
onChange={onChange}
|
||||
type={showPassword ? "text" : "password"}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
BIN
src/fonts/Rubik-Light.woff2
Normal file
BIN
src/fonts/Rubik-VariableFont_wght.ttf
Normal file
15
src/images/Burger.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { FC, SVGProps } from "react";
|
||||
|
||||
export const Burger: FC<SVGProps<SVGSVGElement>> = (props) => (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1_35)">
|
||||
<path d="M21.7778 18C22.0893 18.0003 22.3889 18.0979 22.6154 18.2728C22.842 18.4478 22.9783 18.687 22.9965 18.9414C23.0148 19.1958 22.9136 19.4464 22.7137 19.6418C22.5137 19.8373 22.2301 19.9629 21.9208 19.993L21.7778 20H2.22222C1.9107 19.9997 1.61107 19.9021 1.38455 19.7272C1.15803 19.5522 1.02171 19.313 1.00346 19.0586C0.9852 18.8042 1.08638 18.5536 1.28632 18.3582C1.48627 18.1627 1.76988 18.0371 2.07922 18.007L2.22222 18H21.7778ZM21.7778 11C22.1019 11 22.4128 11.1054 22.642 11.2929C22.8712 11.4804 23 11.7348 23 12C23 12.2652 22.8712 12.5196 22.642 12.7071C22.4128 12.8946 22.1019 13 21.7778 13H2.22222C1.89807 13 1.58719 12.8946 1.35798 12.7071C1.12877 12.5196 1 12.2652 1 12C1 11.7348 1.12877 11.4804 1.35798 11.2929C1.58719 11.1054 1.89807 11 2.22222 11H21.7778ZM21.7778 4C22.1019 4 22.4128 4.10536 22.642 4.29289C22.8712 4.48043 23 4.73478 23 5C23 5.26522 22.8712 5.51957 22.642 5.70711C22.4128 5.89464 22.1019 6 21.7778 6H2.22222C1.89807 6 1.58719 5.89464 1.35798 5.70711C1.12877 5.51957 1 5.26522 1 5C1 4.73478 1.12877 4.48043 1.35798 4.29289C1.58719 4.10536 1.89807 4 2.22222 4H21.7778Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1_35">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
);
|
BIN
src/images/backgroundHero.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
3
src/images/dashRight.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="502" height="280" viewBox="0 0 502 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M407.987 1C537.487 47.5 585.988 298.803 176.486 212.5C-19.5147 171.193 -7.01318 258 6.98486 279" stroke="#9A9AAF" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
</svg>
|
After Width: | Height: | Size: 299 B |
3
src/images/leftDash.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="502" height="280" viewBox="0 0 502 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M94.0011 1C-35.4992 47.5 -84.0001 298.803 325.502 212.5C521.503 171.193 509.001 258 495.003 279" stroke="#9A9AAF" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
</svg>
|
After Width: | Height: | Size: 299 B |
32
src/images/leftDashPlane.svg
Normal file
@ -0,0 +1,32 @@
|
||||
<svg width="502" height="280" viewBox="0 0 502 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M94.0011 1C-35.4992 47.5 -84.0001 298.803 325.502 212.5C521.503 171.193 509.001 258 495.003 279" stroke="#9A9AAF" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
<g filter="url(#filter0_d_1_471)">
|
||||
<path d="M357.472 205.391C357.925 207.955 354.382 210.678 351.841 211.129L334.967 214.272L325.009 239.132C324.369 240.731 322.958 241.893 321.266 242.214C319.58 242.534 318.073 241.114 318.292 239.412L321.198 216.859L304.281 220.01L301.365 225.861C301.005 226.584 300.324 227.095 299.529 227.239C297.849 227.544 296.346 226.151 296.523 224.452L297.349 216.544L293.85 209.386C293.099 207.85 294.009 206.019 295.687 205.69C296.509 205.529 297.357 205.774 297.968 206.347L302.719 210.808L319.506 207.682L309.083 187.51C308.301 185.997 309.204 184.159 310.88 183.853C312.604 183.538 314.369 184.137 315.546 185.436L333.336 205.061L350.21 201.918C352.675 201.414 357.077 202.907 357.472 205.391Z" fill="url(#paint0_linear_1_471)"/>
|
||||
</g>
|
||||
<path d="M319.356 208.765L302.534 211.891L299.175 216.062L356.791 205.825C356.784 205.755 356.775 205.684 356.762 205.614C356.377 203.441 352.595 202.497 350.125 203.001L333.215 206.144L319.356 208.765Z" fill="url(#paint1_linear_1_471)"/>
|
||||
<path d="M320.858 215.838L304.062 218.82L299.465 216.106L356.713 205.707C356.732 205.775 356.748 205.844 356.761 205.914C357.063 207.544 354.076 210.028 351.594 210.424L334.711 213.422L320.858 215.838Z" fill="url(#paint2_linear_1_471)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_1_471" x="290.784" y="183.771" width="79.5274" height="78.2888" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="5" dy="12"/>
|
||||
<feGaussianBlur stdDeviation="3.9"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.375047 0 0 0 0 0.352487 0 0 0 0 0.404053 0 0 0 0.17 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1_471"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1_471" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_471" x1="336.551" y1="189.831" x2="325.725" y2="246.2" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7B7CD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_471" x1="342.076" y1="198.995" x2="331.052" y2="234.56" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C9C9DD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_471" x1="336.04" y1="217.608" x2="304.566" y2="208.761" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9A9AAF"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
26
src/images/logo.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { FC, SVGProps } from "react";
|
||||
|
||||
export const Logo: FC<SVGProps<SVGSVGElement>> = (props) => (
|
||||
<svg
|
||||
{...props}
|
||||
viewBox="0 0 149 58"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_1_21)">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M21.5086 2.75764C15.4327 2.05384 11.241 8.58037 7.34204 13.2981C3.92034 17.4383 1.37259 22.1148 1.07666 27.4802C0.761826 33.1885 1.79731 39.1334 5.6862 43.32C9.69195 47.6324 15.6924 50.3571 21.5086 49.4762C26.8418 48.6684 29.2017 42.8117 33.1723 39.1568C37.4837 35.1882 45.516 33.3424 45.4046 27.4802C45.293 21.609 36.8157 20.4597 32.7367 16.2397C28.5117 11.8685 27.5442 3.45677 21.5086 2.75764Z" fill="#7E2AEA"/>
|
||||
<circle cx="36.6272" cy="47.2429" r="3.3526" fill="#7E2AEA"/>
|
||||
<circle cx="33.2743" cy="10.0479" r="1.27718" fill="#7E2AEA"/>
|
||||
<path d="M53.7046 26.1072C53.3322 22.4867 51.6289 19.1334 48.9248 16.6973C46.2208 14.2612 42.7085 12.9158 39.069 12.9218C38.5522 12.9221 38.0358 12.9491 37.5219 13.0028C33.903 13.3828 30.5531 15.0894 28.1181 17.7933C25.6831 20.4973 24.3356 24.0071 24.3355 27.6458V27.6458V48.6801H30.6458V39.7405C33.113 41.457 36.0476 42.3747 39.0532 42.3698C39.5699 42.3697 40.0863 42.3426 40.6002 42.2888C42.5233 42.0867 44.3877 41.5078 46.087 40.5852C47.7863 39.6626 49.2872 38.4143 50.504 36.9115C51.7209 35.4088 52.6299 33.6812 53.179 31.8272C53.7282 29.9732 53.9068 28.0292 53.7046 26.1061V26.1072ZM45.6001 32.9433C44.9069 33.8044 44.0498 34.5194 43.0784 35.0469C42.1069 35.5744 41.0405 35.9039 39.9408 36.0164C39.6459 36.0471 39.3497 36.0625 39.0532 36.0627C37.1448 36.0609 35.2937 35.4105 33.8037 34.218C32.3137 33.0256 31.2734 31.362 30.8534 29.5004C30.4335 27.6388 30.6589 25.6897 31.4927 23.9731C32.3265 22.2565 33.7191 20.8743 35.4419 20.0534C37.1647 19.2325 39.1154 19.0217 40.9739 19.4556C42.8323 19.8895 44.488 20.9423 45.6692 22.4412C46.8504 23.9401 47.487 25.796 47.4745 27.7044C47.4619 29.6127 46.8009 31.4601 45.6001 32.9433Z" fill="currentColor"/>
|
||||
<path d="M70.1684 12.9218C69.6516 12.9221 69.1352 12.9491 68.6213 13.0028C64.8716 13.3977 61.4163 15.216 58.9675 18.083C56.5187 20.95 55.263 24.6472 55.4594 28.4125C55.6557 32.1779 57.2891 35.7244 60.0227 38.3212C62.7564 40.9179 66.3821 42.367 70.1526 42.3698C70.6693 42.3696 71.1857 42.3426 71.6997 42.2888C74.4032 42.001 76.9749 40.9725 79.1314 39.3167C81.2879 37.6609 82.9455 35.442 83.9216 32.9044H76.729L76.6995 32.9412C75.7782 34.08 74.5755 34.9585 73.2105 35.4899C71.8455 36.0212 70.3654 36.187 68.9166 35.9708C67.4678 35.7546 66.1006 35.164 64.9502 34.2572C63.7998 33.3505 62.906 32.1591 62.3573 30.801H84.5484C85.0157 28.6512 84.996 26.4241 84.4909 24.2829C83.9858 22.1417 83.008 20.1407 81.6292 18.4264C80.2504 16.7121 78.5056 15.328 76.5225 14.3756C74.5394 13.4231 72.3683 12.9264 70.1684 12.9218V12.9218ZM62.3573 24.4907C62.9317 23.0767 63.8791 21.8452 65.0983 20.9272C66.3176 20.0093 67.7631 19.4395 69.2807 19.2784C69.5756 19.2478 69.8719 19.2323 70.1684 19.2321C71.8444 19.2293 73.4829 19.7288 74.8723 20.6661C76.2618 21.6034 77.3386 22.9355 77.9637 24.4907H62.3573Z" fill="currentColor"/>
|
||||
<path d="M100.136 12.9218C97.7245 12.918 95.3586 13.5812 93.3002 14.8381V12.9218H86.9899V42.3698H93.3002V26.0683C93.3002 24.2552 94.0204 22.5164 95.3024 21.2344C96.5844 19.9524 98.3232 19.2321 100.136 19.2321C101.949 19.2321 103.688 19.9524 104.97 21.2344C106.252 22.5164 106.972 24.2552 106.972 26.0683V42.3698H113.283V26.0683C113.283 22.5816 111.898 19.2378 109.432 16.7723C106.967 14.3069 103.623 12.9218 100.136 12.9218Z" fill="currentColor"/>
|
||||
<path d="M144.835 29.5274V12.9219H138.525V15.5511C136.058 13.834 133.123 12.9161 130.118 12.9219C129.601 12.9221 129.084 12.9491 128.571 13.0028C124.821 13.3977 121.365 15.2161 118.917 18.0831C116.468 20.9501 115.212 24.6472 115.409 28.4126C115.605 32.1779 117.238 35.7244 119.972 38.3212C122.706 40.918 126.331 42.3671 130.102 42.3698C130.619 42.3696 131.135 42.3426 131.649 42.2889C135.316 41.9135 138.707 40.1663 141.141 37.3973C143.032 39.9275 145.771 41.6925 148.856 42.3698V35.7546C147.659 35.2123 146.643 34.3366 145.93 33.2323C145.217 32.1281 144.837 30.8418 144.835 29.5274ZM136.649 32.9412C135.955 33.8021 135.098 34.517 134.127 35.0445C133.155 35.572 132.089 35.9016 130.989 36.0143C130.695 36.045 130.398 36.0604 130.102 36.0606C127.946 36.0605 125.872 35.2328 124.309 33.7484C122.745 32.2639 121.811 30.2359 121.7 28.0829C121.588 25.9299 122.307 23.8161 123.708 22.1778C125.11 20.5395 127.087 19.5016 129.231 19.2784C129.526 19.2478 129.821 19.2323 130.118 19.2321C131.706 19.2335 133.262 19.6845 134.605 20.5331C135.948 21.3816 137.023 22.593 137.706 24.0271C138.389 25.4613 138.653 27.0595 138.466 28.637C138.278 30.2145 137.649 31.7068 136.649 32.9412Z" fill="currentColor"/>
|
||||
<path d="M123.338 57.5645V54.1748C123.106 54.4753 122.816 54.7144 122.469 54.8921C122.122 55.0656 121.747 55.1523 121.345 55.1523C120.579 55.1523 119.949 54.8646 119.454 54.2891C118.87 53.6162 118.578 52.7043 118.578 51.5532C118.578 50.4699 118.851 49.6257 119.396 49.0205C119.947 48.4111 120.628 48.1064 121.44 48.1064C121.889 48.1064 122.276 48.2017 122.602 48.3921C122.932 48.5825 123.224 48.8703 123.478 49.2554V48.2588H125.122V57.5645H123.338ZM123.396 51.5469C123.396 50.8571 123.254 50.3451 122.97 50.0107C122.691 49.6722 122.34 49.5029 121.917 49.5029C121.485 49.5029 121.123 49.6743 120.831 50.0171C120.543 50.3599 120.399 50.9036 120.399 51.6484C120.399 52.389 120.539 52.9243 120.818 53.2544C121.098 53.5802 121.443 53.7432 121.853 53.7432C122.264 53.7432 122.623 53.5591 122.932 53.1909C123.241 52.8228 123.396 52.2747 123.396 51.5469ZM131.317 55V53.9907C131.072 54.3504 130.748 54.634 130.346 54.8413C129.948 55.0487 129.527 55.1523 129.083 55.1523C128.63 55.1523 128.224 55.0529 127.864 54.854C127.505 54.6551 127.244 54.3758 127.083 54.0161C126.923 53.6564 126.842 53.1592 126.842 52.5244V48.2588H128.626V51.3564C128.626 52.3044 128.658 52.8862 128.721 53.1021C128.789 53.3136 128.91 53.4829 129.083 53.6099C129.257 53.7326 129.477 53.7939 129.743 53.7939C130.048 53.7939 130.321 53.7114 130.562 53.5464C130.803 53.3771 130.968 53.1698 131.057 52.9243C131.146 52.6746 131.19 52.0674 131.19 51.1025V48.2588H132.974V55H131.317ZM134.828 47.3447V45.6943H136.611V47.3447H134.828ZM134.828 55V48.2588H136.611V55H134.828ZM137.729 55V53.6099L140.255 50.709C140.67 50.235 140.976 49.8986 141.175 49.6997C140.968 49.7124 140.695 49.7209 140.356 49.7251L137.976 49.7378V48.2588H143.549V49.522L140.972 52.4927L140.064 53.4766C140.56 53.4469 140.866 53.4321 140.985 53.4321H143.746V55H137.729Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1_21">
|
||||
<rect width="149" height="57.6774" fill="currentColor"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
63
src/images/plansHero.svg
Normal file
@ -0,0 +1,63 @@
|
||||
<svg width="523" height="662" viewBox="0 0 523 662" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M425.5 1.00001C573 24 553.001 249.807 357 208.5C-52.502 122.197 -105 513.745 194.454 628C233.244 642.8 260.941 654.667 271.941 660.5" stroke="url(#paint0_linear_1_39)" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
<g filter="url(#filter0_d_1_39)">
|
||||
<path d="M109.548 578.985C105.741 582.675 97.1036 579.806 93.4427 576.034L68.8849 551.156L15.5863 562.729C12.1587 563.473 8.58822 562.418 6.11538 559.931C3.65117 557.452 4.3265 553.29 7.44801 551.717L48.8086 530.882L24.1877 505.94L10.9904 507.699C9.35913 507.917 7.72083 507.352 6.57019 506.175C4.13841 503.689 4.77405 499.564 7.84164 497.925L22.1249 490.292L30.2059 476.221C31.9402 473.202 36.0664 472.648 38.5359 475.103C39.7451 476.305 40.3018 478.016 40.0315 479.7L37.9274 492.806L62.359 517.556L84.4906 476.954C86.1507 473.909 90.282 473.334 92.71 475.811C95.2092 478.361 96.2137 482.021 95.3663 485.489L82.5622 537.894L107.12 562.772C110.783 566.355 113.288 575.483 109.548 578.985Z" fill="url(#paint1_linear_1_39)"/>
|
||||
</g>
|
||||
<path d="M60.3594 518.539L35.8874 493.73L25.0186 492.824L108.037 578.332C108.148 578.24 108.256 578.144 108.361 578.043C111.587 574.914 108.863 567.455 105.194 563.864L80.596 538.926L60.3594 518.539Z" fill="url(#paint2_linear_1_39)"/>
|
||||
<path d="M50.142 529.147L25.9429 504.218L25.2767 493.367L108.148 578.07C108.054 578.179 107.956 578.284 107.852 578.386C105.448 580.756 97.8496 578.551 94.3493 574.816L70.0252 549.758L50.142 529.147Z" fill="url(#paint3_linear_1_39)"/>
|
||||
<g filter="url(#filter1_d_1_39)">
|
||||
<path d="M319.221 202.542C319.671 199.978 323.932 198.63 326.475 199.076L343.406 201.894L361.265 181.939C362.414 180.656 364.138 180.047 365.837 180.324C367.531 180.6 368.462 182.449 367.673 183.974L357.229 204.173L374.204 206.998L378.945 202.497C379.531 201.941 380.345 201.693 381.141 201.83C382.825 202.118 383.76 203.941 383.012 205.477L379.531 212.626L380.371 220.549C380.552 222.249 379.07 223.658 377.381 223.393C376.554 223.264 375.84 222.744 375.462 221.996L372.524 216.179L355.679 213.375L358.575 235.895C358.792 237.584 357.315 239.003 355.636 238.717C353.907 238.423 352.454 237.257 351.792 235.634L341.787 211.107L324.856 208.289C322.368 207.92 318.742 205.012 319.221 202.542Z" fill="url(#paint4_linear_1_39)"/>
|
||||
</g>
|
||||
<path d="M356.191 212.409L373.068 215.224L377.651 212.454L320.009 202.367C319.991 202.436 319.976 202.505 319.963 202.575C319.582 204.749 322.813 206.93 325.307 207.301L342.271 210.131L356.191 212.409Z" fill="url(#paint5_linear_1_39)"/>
|
||||
<path d="M357.199 205.249L374.002 208.191L377.393 212.314L320.041 202.504C320.047 202.434 320.056 202.364 320.067 202.293C320.341 200.658 323.997 199.346 326.465 199.823L343.355 202.78L357.199 205.249Z" fill="url(#paint6_linear_1_39)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_1_39" x="1.81987" y="473.561" width="122.378" height="140.937" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="5" dy="26"/>
|
||||
<feGaussianBlur stdDeviation="3.9"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.206771 0 0 0 0 0.206771 0 0 0 0 0.206771 0 0 0 0.2 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1_39"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1_39" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_1_39" x="316.378" y="180.258" width="79.6951" height="82.2957" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="5" dy="16"/>
|
||||
<feGaussianBlur stdDeviation="3.9"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.357347 0 0 0 0 0.346199 0 0 0 0 0.37168 0 0 0 0.27 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1_39"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1_39" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_39" x1="279.04" y1="660.5" x2="496" y2="76" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_39" x1="111.922" y1="525.937" x2="4.48008" y2="572.001" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7B7CD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_39" x1="102.767" y1="545.715" x2="30.1928" y2="567.704" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C9C9DD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_39" x1="64.4801" y1="556.778" x2="43.4882" y2="493.589" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9A9AAF"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_1_39" x1="333.557" y1="224.319" x2="363.011" y2="175.053" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7B7CD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_1_39" x1="331.5" y1="213.818" x2="354.024" y2="184.169" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C9C9DD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_1_39" x1="343.538" y1="198.392" x2="370.087" y2="217.471" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9A9AAF"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
3
src/images/rightDash.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="471" height="313" viewBox="0 0 471 313" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.98557 312C-8.01248 291 -15.783 186.015 175.487 245.5C511.499 350 523 71.5 393.5 25C354.71 10.2 352.5 8 329.501 1.5" stroke="#9A9AAF" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
</svg>
|
After Width: | Height: | Size: 321 B |
32
src/images/rightDashPlane.svg
Normal file
@ -0,0 +1,32 @@
|
||||
<svg width="502" height="280" viewBox="0 0 502 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M407.987 1C537.487 47.5 585.988 298.803 176.486 212.5C-19.5147 171.193 -7.01318 258 6.98486 279" stroke="#9A9AAF" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="25 50"/>
|
||||
<g filter="url(#filter0_d_1_457)">
|
||||
<path d="M142.452 205.928C142.891 203.362 147.146 201.997 149.691 202.431L166.634 205.177L184.408 185.145C185.551 183.857 187.272 183.241 188.973 183.51C190.668 183.779 191.606 185.624 190.824 187.152L180.467 207.396L197.453 210.149L202.175 205.627C202.759 205.068 203.572 204.818 204.369 204.951C206.053 205.232 206.996 207.051 206.255 208.59L202.805 215.754L203.679 223.673C203.867 225.372 202.392 226.788 200.701 226.53C199.874 226.404 199.157 225.887 198.776 225.141L195.813 219.336L178.957 216.605L181.949 239.112C182.173 240.8 180.702 242.225 179.022 241.947C177.292 241.66 175.834 240.501 175.164 238.88L165.055 214.397L148.112 211.652C145.622 211.293 141.984 208.4 142.452 205.928Z" fill="url(#paint0_linear_1_457)"/>
|
||||
</g>
|
||||
<path d="M179.464 215.636L196.353 218.38L200.924 215.589L143.239 205.75C143.221 205.819 143.207 205.888 143.195 205.958C142.822 208.134 146.063 210.301 148.558 210.662L165.535 213.419L179.464 215.636Z" fill="url(#paint1_linear_1_457)"/>
|
||||
<path d="M180.441 208.472L197.257 211.342L200.665 215.45L143.272 205.887C143.278 205.817 143.286 205.747 143.297 205.676C143.564 204.04 147.215 202.712 149.684 203.179L166.587 206.063L180.441 208.472Z" fill="url(#paint2_linear_1_457)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_1_457" x="139.611" y="183.448" width="79.7003" height="78.3337" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="5" dy="12"/>
|
||||
<feGaussianBlur stdDeviation="3.9"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.375047 0 0 0 0 0.352487 0 0 0 0 0.404053 0 0 0 0.17 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1_457"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1_457" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_457" x1="156.882" y1="227.644" x2="186.123" y2="178.252" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7B7CD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_457" x1="154.779" y1="217.152" x2="177.175" y2="187.406" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C9C9DD"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_457" x1="166.751" y1="201.674" x2="193.382" y2="220.639" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9A9AAF"/>
|
||||
<stop offset="1" stop-color="#9A9AAF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
7
src/images/telegramIcon.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { FC, SVGProps } from "react";
|
||||
|
||||
export const TelegramIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM16.64 8.8C16.49 10.38 15.84 14.22 15.51 15.99C15.37 16.74 15.09 16.99 14.83 17.02C14.25 17.07 13.81 16.64 13.25 16.27C12.37 15.69 11.87 15.33 11.02 14.77C10.03 14.12 10.67 13.76 11.24 13.18C11.39 13.03 13.95 10.7 14 10.49C14.0069 10.4582 14.006 10.4252 13.9973 10.3938C13.9886 10.3624 13.9724 10.3337 13.95 10.31C13.89 10.26 13.81 10.28 13.74 10.29C13.65 10.31 12.25 11.24 9.52 13.08C9.12 13.35 8.76 13.49 8.44 13.48C8.08 13.47 7.4 13.28 6.89 13.11C6.26 12.91 5.77 12.8 5.81 12.45C5.83 12.27 6.08 12.09 6.55 11.9C9.47 10.63 11.41 9.79 12.38 9.39C15.16 8.23 15.73 8.03 16.11 8.03C16.19 8.03 16.38 8.05 16.5 8.15C16.6 8.23 16.63 8.34 16.64 8.42C16.63 8.48 16.65 8.66 16.64 8.8Z" fill="#8F4BE5"/>
|
||||
</svg>
|
||||
);
|
7
src/images/vkIcon.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { FC, SVGProps } from "react";
|
||||
|
||||
export const VkIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.579 6.85501C21.719 6.39001 21.579 6.04901 20.917 6.04901H18.724C18.166 6.04901 17.911 6.34401 17.771 6.66801C17.771 6.66801 16.656 9.38701 15.076 11.15C14.566 11.663 14.333 11.825 14.055 11.825C13.916 11.825 13.714 11.663 13.714 11.198V6.85501C13.714 6.29701 13.553 6.04901 13.088 6.04901H9.642C9.294 6.04901 9.084 6.30701 9.084 6.55301C9.084 7.08101 9.874 7.20301 9.955 8.69101V11.919C9.955 12.626 9.828 12.755 9.548 12.755C8.805 12.755 6.997 10.026 5.924 6.90201C5.715 6.29501 5.504 6.05001 4.944 6.05001H2.752C2.125 6.05001 2 6.34501 2 6.66901C2 7.25101 2.743 10.131 5.461 13.94C7.273 16.541 9.824 17.951 12.148 17.951C13.541 17.951 13.713 17.638 13.713 17.098V15.132C13.713 14.506 13.846 14.38 14.287 14.38C14.611 14.38 15.169 14.544 16.47 15.797C17.956 17.283 18.202 17.95 19.037 17.95H21.229C21.855 17.95 22.168 17.637 21.988 17.019C21.791 16.404 21.081 15.509 20.139 14.45C19.627 13.846 18.862 13.196 18.629 12.871C18.304 12.452 18.398 12.267 18.629 11.895C18.63 11.896 21.301 8.13401 21.579 6.85501Z" fill="#8F4BE5"/>
|
||||
</svg>
|
||||
);
|
7
src/images/whatsappIcon.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { FC, SVGProps } from "react";
|
||||
|
||||
export const WhatsappIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.05 4.91C18.1332 3.98392 17.0412 3.24967 15.8376 2.75005C14.6341 2.25043 13.3431 1.99546 12.04 2C6.58 2 2.13 6.45 2.13 11.91C2.13 13.66 2.59 15.36 3.45 16.86L2.05 22L7.3 20.62C8.75 21.41 10.38 21.83 12.04 21.83C17.5 21.83 21.95 17.38 21.95 11.92C21.95 9.27 20.92 6.78 19.05 4.91ZM12.04 20.15C10.56 20.15 9.11 19.75 7.84 19L7.54 18.82L4.42 19.64L5.25 16.6L5.05 16.29C4.22775 14.977 3.79114 13.4592 3.79 11.91C3.79 7.37 7.49 3.67 12.03 3.67C14.23 3.67 16.3 4.53 17.85 6.09C18.6175 6.85396 19.2257 7.76266 19.6394 8.76342C20.0531 9.76419 20.264 10.8371 20.26 11.92C20.28 16.46 16.58 20.15 12.04 20.15ZM16.56 13.99C16.31 13.87 15.09 13.27 14.87 13.18C14.64 13.1 14.48 13.06 14.31 13.3C14.14 13.55 13.67 14.11 13.53 14.27C13.39 14.44 13.24 14.46 12.99 14.33C12.74 14.21 11.94 13.94 11 13.1C10.26 12.44 9.77 11.63 9.62 11.38C9.48 11.13 9.6 11 9.73 10.87C9.84 10.76 9.98 10.58 10.1 10.44C10.22 10.3 10.27 10.19 10.35 10.03C10.43 9.86 10.39 9.72 10.33 9.6C10.27 9.48 9.77 8.26 9.57 7.76C9.37 7.28 9.16 7.34 9.01 7.33H8.53C8.36 7.33 8.1 7.39 7.87 7.64C7.65 7.89 7.01 8.49 7.01 9.71C7.01 10.93 7.9 12.11 8.02 12.27C8.14 12.44 9.77 14.94 12.25 16.01C12.84 16.27 13.3 16.42 13.66 16.53C14.25 16.72 14.79 16.69 15.22 16.63C15.7 16.56 16.69 16.03 16.89 15.45C17.1 14.87 17.1 14.38 17.03 14.27C16.96 14.16 16.81 14.11 16.56 13.99Z" fill="#8F4BE5"/>
|
||||
</svg>
|
||||
);
|
24
src/index.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { theme } from './utils/theme';
|
||||
import { ThemeProvider } from "@mui/material/styles";
|
||||
import App from './App';
|
||||
import { SnackbarProvider } from "notistack";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { CssBaseline } from "@mui/material";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<SnackbarProvider>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</SnackbarProvider>
|
||||
</ThemeProvider>
|
||||
</React.StrictMode>
|
||||
);
|
39
src/kit/Header.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import React from "react";
|
||||
import Section from "./section";
|
||||
import {IconButton, useMediaQuery, useTheme} from "@mui/material";
|
||||
import {Logo} from "../images/logo";
|
||||
import {Burger} from "../images/Burger";
|
||||
|
||||
export default function Header() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
|
||||
return (
|
||||
<Section
|
||||
tag={"header"}
|
||||
bg={"#FFFFFF33"}
|
||||
mwidth={"1160px"}
|
||||
sxsect={{
|
||||
minHeight: isMobile ? "51px" : "80px",
|
||||
borderBottom: "1px solid #E3E3E3",
|
||||
position: "absolute",
|
||||
padding: isMobile ? "0 16px" : isTablet ? "0 40px" : "0 20px",
|
||||
zIndex: 3,
|
||||
}}
|
||||
sxcont={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
{/*<Link to="/">*/}
|
||||
<Logo width={isMobile ? 100 : 149} color={"white"}/>
|
||||
{/*</Link>*/}
|
||||
<IconButton>
|
||||
<Burger/>
|
||||
</IconButton>
|
||||
</Section>
|
||||
);
|
||||
}
|
82
src/kit/footer.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import { Typography, useMediaQuery, Box, useTheme, Button } from "@mui/material";
|
||||
import {Logo} from "../images/logo";
|
||||
import Section from "./section";
|
||||
|
||||
|
||||
|
||||
export default function Footer() {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
return (
|
||||
<Section
|
||||
tag="footer"
|
||||
bg={"#252734"}
|
||||
mwidth={"1160px"}
|
||||
sxsect={{
|
||||
height: isMobile ? "550px" : "236px",
|
||||
padding: isMobile ? "0 16px" : isTablet ? "0 40px" : "0 20px",
|
||||
position: "relative",
|
||||
alignItems: "start",
|
||||
zIndex: 10,
|
||||
}}
|
||||
sxcont={{
|
||||
display: "flex",
|
||||
flexDirection: isMobile ? "column" : "row",
|
||||
justifyContent: "normal",
|
||||
alignItems: isMobile ? "normal" : "flex-start",
|
||||
gap: isMobile ? "40px" : "136px",
|
||||
padding: 0,
|
||||
marginTop: "60px"
|
||||
}}
|
||||
>
|
||||
<Box sx={{ ml: isMobile ? "0" : isTablet ? "40px" : "0" }}>
|
||||
<Box
|
||||
sx={{
|
||||
width: "124px",
|
||||
height: "48px",
|
||||
backgroundSize: "contain",
|
||||
}}
|
||||
>
|
||||
<Logo width={124} color={"white"}/>
|
||||
</Box>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "rgba(114, 112, 116, 1)",
|
||||
fontSize: "14px",
|
||||
marginTop: "10px"
|
||||
}}>
|
||||
(c) 2023 Examplelink.com
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: isMobile ? "column" : "row",
|
||||
flexWrap: "wrap",
|
||||
alignItems: isMobile ? undefined : "start",
|
||||
// mt: isMobile ? undefined : "45px",
|
||||
gap: isMobile ? "18px" : "145px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "18px",
|
||||
alignItems: isMobile ? "baseline" : undefined
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="pena-navitem-dark"
|
||||
href={"https://docs.pena.digital/docs"}
|
||||
>
|
||||
Пользовательское соглашение
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Section>
|
||||
);
|
||||
}
|
50
src/kit/section.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import * as React from "react";
|
||||
import Box from "@mui/material/Box";
|
||||
import { SxProps, Theme, useMediaQuery } from "@mui/material";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
|
||||
interface Props {
|
||||
sxsect?: SxProps<Theme>;
|
||||
mwidth: string;
|
||||
padding?: string;
|
||||
tag: React.ElementType;
|
||||
bg: string;
|
||||
children: React.ReactNode;
|
||||
sxcont?: SxProps<Theme>;
|
||||
}
|
||||
|
||||
|
||||
export default function Section(props: Props) {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
return (
|
||||
<Box
|
||||
component={props.tag}
|
||||
backgroundColor={props.bg}
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontFamily: "Rubik",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
...props.sxsect,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
maxWidth={props.mwidth}
|
||||
sx={{
|
||||
width: "100%",
|
||||
padding: isTablet ? (isMobile ? "0 16px" : "0 40px") : "0 20px",
|
||||
// [theme.breakpoints.down(600)]: {
|
||||
// padding: "0 16px",
|
||||
// },
|
||||
...props.sxcont,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
215
src/pages/auth/Signup.tsx
Normal file
@ -0,0 +1,215 @@
|
||||
import { Box, Button, Dialog, IconButton, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useFormik } from "formik";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { object, ref, string } from "yup";
|
||||
import { useEffect, useState } from "react";
|
||||
import { PenaTextField, RegisterRequest, RegisterResponse, getMessageFromFetchError } from "@frontend/kitui";
|
||||
import { makeRequest } from "@frontend/kitui";
|
||||
// import { setUserId, useUserStore } from "../../stores/user";
|
||||
import { cardShadow } from "../../utils/theme";
|
||||
import PasswordInput from "../../components/passwordInput";
|
||||
import {Logo} from "../../images/logo";
|
||||
|
||||
//
|
||||
// interface Values {
|
||||
// email: string;
|
||||
// password: string;
|
||||
// repeatPassword: string;
|
||||
// }
|
||||
//
|
||||
// const initialValues: Values = {
|
||||
// email: "",
|
||||
// password: "",
|
||||
// repeatPassword: "",
|
||||
// };
|
||||
|
||||
// const validationSchema = object({
|
||||
// email: string().required("Поле обязательно").email("Введите корректный email"),
|
||||
// password: string()
|
||||
// .min(8, "Минимум 8 символов")
|
||||
// .matches(/^[.,:;-_+\d\w]+$/, "Некорректные символы")
|
||||
// .required("Поле обязательно"),
|
||||
// repeatPassword: string()
|
||||
// .oneOf([ref("password"), undefined], "Пароли не совпадают")
|
||||
// .required("Повторите пароль"),
|
||||
// });
|
||||
|
||||
export default function SignupDialog() {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(true);
|
||||
// const user = useUserStore((state) => state.user);
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
// const formik = useFormik<Values>({
|
||||
// initialValues,
|
||||
// validationSchema,
|
||||
// onSubmit: (values, formikHelpers) => {
|
||||
// makeRequest<RegisterRequest, RegisterResponse>({
|
||||
// url: "https://hub.pena.digital/auth/register",
|
||||
// body: {
|
||||
// login: values.email.trim(),
|
||||
// password: values.password.trim(),
|
||||
// phoneNumber: "+7",
|
||||
// },
|
||||
// useToken: false,
|
||||
// withCredentials: true,
|
||||
// })
|
||||
// .then((result) => {
|
||||
// setUserId(result._id);
|
||||
// })
|
||||
// .catch((error: any) => {
|
||||
// const errorMessage = getMessageFromFetchError(error);
|
||||
// if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// formikHelpers.setSubmitting(false);
|
||||
// });
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// useEffect(
|
||||
// function redirectIfSignedIn() {
|
||||
// if (user) navigate("/mymetrics", { replace: true });
|
||||
// },
|
||||
// [navigate, user]
|
||||
// );
|
||||
|
||||
function handleClose() {
|
||||
setIsDialogOpen(false);
|
||||
setTimeout(() => navigate("/"), theme.transitions.duration.leavingScreen);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isDialogOpen}
|
||||
onClose={handleClose}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
width: "600px",
|
||||
maxWidth: "600px",
|
||||
},
|
||||
}}
|
||||
slotProps={{
|
||||
backdrop: {
|
||||
style: {
|
||||
backgroundColor: "rgb(0 0 0 / 0.7)",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="form"
|
||||
// onSubmit={formik.handleSubmit}
|
||||
// noValidate
|
||||
sx={{
|
||||
position: "relative",
|
||||
backgroundColor: "white",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
p: upMd ? "50px" : "18px",
|
||||
pb: upMd ? "40px" : "30px",
|
||||
gap: "15px",
|
||||
borderRadius: "12px",
|
||||
boxShadow: cardShadow,
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
onClick={handleClose}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
right: "7px",
|
||||
top: "7px",
|
||||
}}
|
||||
>
|
||||
<CloseIcon sx={{ transform: "scale(1.5)" }} />
|
||||
</IconButton>
|
||||
<Box sx={{ mt: upMd ? undefined : "62px" }}>
|
||||
<Logo width={upMd ? 233 : 196} color="black" />
|
||||
</Box>
|
||||
<Typography
|
||||
sx={{
|
||||
color: theme.palette.gray.dark,
|
||||
mt: "5px",
|
||||
mb: upMd ? "35px" : "33px",
|
||||
}}
|
||||
>
|
||||
Регистрация
|
||||
</Typography>
|
||||
<PenaTextField
|
||||
// value={formik.values.email}
|
||||
// placeholder={"username"}
|
||||
// onBlur={formik.handleBlur}
|
||||
// error={formik.touched.email && Boolean(formik.errors.email)}
|
||||
// helperText={formik.touched.email && formik.errors.email}
|
||||
// onChange={formik.handleChange}
|
||||
backgroundColor="#F2F3F7"
|
||||
id="email"
|
||||
label="Email"
|
||||
gap={upMd ? "10px" : "10px"}
|
||||
/>
|
||||
<PasswordInput
|
||||
TextfieldProps={{
|
||||
// value: formik.values.password,
|
||||
// placeholder: "Не менее 8 символов",
|
||||
// onBlur: formik.handleBlur,
|
||||
// error: formik.touched.password && Boolean(formik.errors.password),
|
||||
// helperText: formik.touched.password && formik.errors.password,
|
||||
// autoComplete: "new-password",
|
||||
}}
|
||||
// onChange={formik.handleChange}
|
||||
color="#F2F3F7"
|
||||
id="password"
|
||||
label="Пароль"
|
||||
gap={upMd ? "10px" : "10px"}
|
||||
/>
|
||||
<PasswordInput
|
||||
TextfieldProps={{
|
||||
// value: formik.values.repeatPassword,
|
||||
// placeholder: "Не менее 8 символов",
|
||||
// onBlur: formik.handleBlur,
|
||||
// error: formik.touched.repeatPassword && Boolean(formik.errors.repeatPassword),
|
||||
// helperText: formik.touched.repeatPassword && formik.errors.repeatPassword,
|
||||
// autoComplete: "new-password",
|
||||
}}
|
||||
// onChange={formik.handleChange}
|
||||
color="#F2F3F7"
|
||||
id="repeatPassword"
|
||||
label="Повторить пароль"
|
||||
gap={upMd ? "10px" : "10px"}
|
||||
/>
|
||||
<Button
|
||||
variant="pena-contained-dark"
|
||||
fullWidth
|
||||
type="submit"
|
||||
// disabled={formik.isSubmitting}
|
||||
sx={{
|
||||
py: "12px",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.purple.dark,
|
||||
},
|
||||
"&:active": {
|
||||
color: "white",
|
||||
backgroundColor: "black",
|
||||
},
|
||||
}}
|
||||
>Зарегистрироваться</Button>
|
||||
{/*<Link*/}
|
||||
{/* component={RouterLink}*/}
|
||||
{/* to="/signin"*/}
|
||||
{/* state={{ backgroundLocation: location.state.backgroundLocation }}*/}
|
||||
{/* sx={{*/}
|
||||
{/* color: theme.palette.purple.main,*/}
|
||||
{/* mt: "auto",*/}
|
||||
{/* }}*/}
|
||||
{/*>*/}
|
||||
{/* Вход в личный кабинет*/}
|
||||
{/*</Link>*/}
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
18
src/pages/landing/LandingTourism.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import Header from "../../kit/Header";
|
||||
import Hero from "./hero";
|
||||
import Footer from "../../kit/footer";
|
||||
import QuizInteractive from "./quizInteractive";
|
||||
|
||||
|
||||
export default function LandingTourism() {
|
||||
return (
|
||||
<div style={{overflow: "hidden"}}>
|
||||
<Header/>
|
||||
<Hero/>
|
||||
<QuizInteractive/>
|
||||
<Footer/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
112
src/pages/landing/hero.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
import Section from "../../kit/section";
|
||||
import BackgroundHero from "../../images/backgroundHero.png"
|
||||
import {Box, Button, IconButton, Typography, useMediaQuery, useTheme} from "@mui/material";
|
||||
import plansHero from "../../images/plansHero.svg"
|
||||
import {VkIcon} from "../../images/vkIcon";
|
||||
import {WhatsappIcon} from "../../images/whatsappIcon";
|
||||
import {TelegramIcon} from "../../images/telegramIcon";
|
||||
import {Link, useLocation} from "react-router-dom";
|
||||
|
||||
export default function Hero() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isBigMonitor = useMediaQuery(theme.breakpoints.up(1440));
|
||||
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1200));
|
||||
const location = useLocation();
|
||||
return(
|
||||
<Section
|
||||
tag={"section"}
|
||||
bg={""}
|
||||
mwidth={"1160px"}
|
||||
sxsect={{
|
||||
minHeight: isMobile ? "766px" : "810px",
|
||||
borderBottom: "1px solid #E3E3E3",
|
||||
position: "relative",
|
||||
alignItems: isMobile ? "flex-start" : "center",
|
||||
padding: isMobile ? "118px 16px 0 16px" : isTablet ? "0 40px" : "0 20px",
|
||||
backgroundImage: `url(${BackgroundHero})`,
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: isBigMonitor ? "100%" : undefined,
|
||||
backgroundPosition: isTablet ? "center" : undefined
|
||||
}}
|
||||
sxcont={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
padding: 0,
|
||||
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: isMobile ? "5px" : "30px",
|
||||
height: "100%",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "flex-start",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h2" color={"white"}>Наименование</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
maxWidth: isTablet ? "715px" : "420px",
|
||||
minHeight: "64px",
|
||||
}}
|
||||
>
|
||||
<Typography variant="body1" color={"white"} sx={{maxWidth: isTablet ? "426px" : undefined}}>
|
||||
Идейные соображения высшего порядка обуславливают
|
||||
создание системы обучения кадров, соответствует насущным потребностям.
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
variant="pena-contained-light"
|
||||
component={Link}
|
||||
to={"/signup"}
|
||||
state={{backgroundLocation: location.state}}
|
||||
sx={{
|
||||
marginTop: isMobile ? "35px" : isTablet ? "10px" : undefined,
|
||||
zIndex: 2
|
||||
}}
|
||||
>
|
||||
Оставить заявку
|
||||
</Button>
|
||||
|
||||
<Box sx={{display: "flex", position: "relative",
|
||||
top: isMobile ? "257px" : "100px",}}>
|
||||
<IconButton><VkIcon/></IconButton>
|
||||
<IconButton><WhatsappIcon/></IconButton>
|
||||
<IconButton><TelegramIcon/></IconButton>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
component={"img"}
|
||||
src={plansHero}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: isMobile
|
||||
? undefined
|
||||
: isTablet
|
||||
? "-133px"
|
||||
: isSmallMonitor
|
||||
? "-146px"
|
||||
: "-116px",
|
||||
maxWidth: isMobile ? "403px" : isTablet ? "425px" : "810px",
|
||||
width: isMobile ? "100%" : undefined,
|
||||
left: isMobile
|
||||
? "102px"
|
||||
: isTablet
|
||||
? "564px"
|
||||
: isSmallMonitor
|
||||
? "460px"
|
||||
: "769px",
|
||||
top: isMobile ? "157px" : undefined,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Section>
|
||||
)
|
||||
}
|
211
src/pages/landing/quizInteractive.tsx
Normal file
@ -0,0 +1,211 @@
|
||||
import {Box, Typography, useMediaQuery, useTheme} from "@mui/material";
|
||||
import dashRightTop from "../../images/rightDash.svg";
|
||||
import dashRight from "../../images/dashRight.svg"
|
||||
import dashRightPlane from "../../images/rightDashPlane.svg";
|
||||
import dashLeft from "../../images/leftDash.svg";
|
||||
import dashLeftPlane from "../../images/leftDashPlane.svg";
|
||||
import Section from "../../kit/section";
|
||||
import * as React from "react";
|
||||
import zIndex from "@mui/material/styles/zIndex";
|
||||
|
||||
export default function QuizInteractive() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1200));
|
||||
return(
|
||||
<Section
|
||||
tag={"section"}
|
||||
bg={"#F2F3F7"}
|
||||
sxsect={{
|
||||
// minHeight: "7049px",
|
||||
marginTop: isMobile ? "-65px" : "-100px",
|
||||
alignItems: "flex-start",
|
||||
zIndex: 2,
|
||||
position: "relative",
|
||||
borderRadius: isMobile ? "30px 30px 0 0" : "80px 80px 0 0"
|
||||
}}
|
||||
mwidth={"1160px"}
|
||||
sxcont={{
|
||||
padding: isMobile
|
||||
? "80px 16px 44px 16px"
|
||||
: isTablet
|
||||
? "125px 40px 0 40px"
|
||||
: "130px 0px 0 0px",
|
||||
position: "relative",
|
||||
boxSizing: "border-box",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
color="#ffffff"
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
flexDirection: "column",
|
||||
marginBottom: isMobile ? "10px" : "65px",
|
||||
gap: isMobile ? "55px" : "60px",
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<Typography variant="h6" fontSize="36px" color={"#000000"} maxWidth={"500px"} lineHeight={"normal"}>
|
||||
Как будут выглядеть квизы на вашем сайте
|
||||
</Typography>
|
||||
<Typography fontSize="18px" color={"#4D4D4D"} marginTop={"20px"}>Интерактивные</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: isMobile ? "70px" : "140px"
|
||||
}}
|
||||
>
|
||||
<QuizBox zIndex={9}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashRightTop}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-159px" : "-316px",
|
||||
right: isMobile ? "-72px" : isTablet ? "-19px" : "-68px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={8}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashLeft}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
zIndex: 1,
|
||||
top: isMobile ? "-134px" : isTablet ? "-277px" : "-282px",
|
||||
left: isMobile ? "32px" : isTablet ? "49px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={7}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashRightPlane}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-133px" : isTablet ? "-277px" : "-282px",
|
||||
right: isMobile ? "24px" : isTablet ? "51px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={6}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashLeft}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-134px" : isTablet ? "-277px" : "-282px",
|
||||
left: isMobile ? "32px" : isTablet ? "49px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={5}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashRight}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-134px" : "-281px",
|
||||
right: isTablet ? "50px" : "-96px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={4}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashLeftPlane}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-134px" : isTablet ? "-277px" : "-282px",
|
||||
left: isMobile ? "31px" : isTablet ? "50px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={3}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashRight}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-134px" : "-281px",
|
||||
right: isTablet ? "50px" : "-96px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={2}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashLeft}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-134px" : isTablet ? "-277px" : "-282px",
|
||||
left: isMobile ? "32px" : isTablet ? "49px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
<QuizBox zIndex={1}>
|
||||
<Typography>interactive</Typography>
|
||||
<Box
|
||||
component={"img"}
|
||||
src={dashRightPlane}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: isMobile ? "-133px" : isTablet ? "-277px" : "-282px",
|
||||
right: isMobile ? "24px" : isTablet ? "51px" : "-97px",
|
||||
width: isMobile ? "70%" : undefined
|
||||
}}
|
||||
/>
|
||||
</QuizBox>
|
||||
</Box>
|
||||
</Box>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode,
|
||||
zIndex?: number
|
||||
}
|
||||
|
||||
function QuizBox (props: Props) {
|
||||
const theme = useTheme()
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
return(
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: "1160px",
|
||||
height: isMobile ? "634px" : isTablet ? "491px" : "608px",
|
||||
borderRadius: "12px",
|
||||
backgroundColor: "#FFFFFF",
|
||||
position: "relative",
|
||||
zIndex: props.zIndex,
|
||||
boxShadow: "0px 2.767256498336792px 8.550822257995605px 0px #D2D0E111"
|
||||
|
||||
}}
|
||||
> {props.children}</Box>
|
||||
)
|
||||
}
|
1
src/react-app-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
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';
|
25
src/utils/date.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { getDeclension } from "./declension";
|
||||
|
||||
|
||||
export function isDateToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return date.getTime() > today.getTime();
|
||||
}
|
||||
|
||||
const avgDaysInMonth = 30.43692;
|
||||
const avgDaysInYear = 365.242199;
|
||||
|
||||
export function formatDateWithDeclention(numberOfDays: number) {
|
||||
if (numberOfDays === 0) return "0 дней";
|
||||
|
||||
const years = Math.floor(numberOfDays / avgDaysInYear);
|
||||
const months = Math.floor(numberOfDays % avgDaysInYear / avgDaysInMonth);
|
||||
const days = Math.floor(numberOfDays % avgDaysInYear % avgDaysInMonth);
|
||||
|
||||
const yearsDisplay = years > 0 ? `${years} ${getDeclension(years, "год")}` : "";
|
||||
const monthsDisplay = months > 0 ? `${months} ${getDeclension(months, "месяц")}` : "";
|
||||
const daysDisplay = days > 0 ? `${days} ${getDeclension(days, "день")}` : "";
|
||||
|
||||
return `${yearsDisplay} ${monthsDisplay} ${daysDisplay}`;
|
||||
}
|
25
src/utils/declension.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { PrivilegeValueType } from "@frontend/kitui";
|
||||
|
||||
|
||||
function declension(number: number, declensions: string[], cases = [2, 0, 1, 1, 1, 2]) {
|
||||
return declensions[
|
||||
number % 100 > 4 && number % 100 < 20
|
||||
? 2
|
||||
: cases[number % 10 < 5 ? number % 10 : 5]
|
||||
];
|
||||
}
|
||||
|
||||
export function getDeclension(number: number, word: PrivilegeValueType | "месяц" | "год"): string {
|
||||
switch (word) {
|
||||
case "шаблон":
|
||||
return declension(number, ["шаблон", "шаблона", "шаблонов"]);
|
||||
case "день":
|
||||
return declension(number, ["день", "дня", "дней"]);
|
||||
case "месяц":
|
||||
return declension(number, ["месяц", "месяца", "месяцев"]);
|
||||
case "год":
|
||||
return declension(number, ["год", "года", "лет"]);
|
||||
case "МБ":
|
||||
return "МБ";
|
||||
}
|
||||
};
|
33
src/utils/theme.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { penaMuiTheme } from "@frontend/kitui";
|
||||
import { ThemeOptions, createTheme } from "@mui/material";
|
||||
import { deepmerge } from "@mui/utils";
|
||||
|
||||
|
||||
|
||||
|
||||
const themeOverrides: ThemeOptions = {
|
||||
components: {
|
||||
MuiTypography: {
|
||||
variants: [
|
||||
{
|
||||
props: { variant: "h2-card-number" },
|
||||
style: {
|
||||
fontSize: "80px",
|
||||
lineHeight: "100%",
|
||||
fontWeight: 400,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
declare module "@mui/material/Typography" {
|
||||
interface TypographyPropsVariantOverrides {
|
||||
"h2-card-number": true;
|
||||
}
|
||||
}
|
||||
export const theme = createTheme(deepmerge(penaMuiTheme, themeOverrides));
|
||||
|
||||
export const cardShadow = "0px 15px 80px rgb(210 208 225 / 70%)";
|
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"
|
||||
]
|
||||
}
|