Lab4
24
Lab4/.eslintrc.cjs
Normal file
@ -0,0 +1,24 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'airbnb-base',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parserOptions: { ecmaVersion: 12, sourceType: 'module' },
|
||||
settings: { react: { version: '18.2' } },
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
'indent': 'off',
|
||||
'no-console': 'off',
|
||||
'arrow-body-style': 'off',
|
||||
'implicit-arrow-linebreak': 'off',
|
||||
},
|
||||
}
|
15
Lab4/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "msedge",
|
||||
"request": "launch",
|
||||
"name": "Launch Edge",
|
||||
"url": "http://localhost:5173",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
]
|
||||
}
|
BIN
Lab4/Otchet_Laboratornaya_rabota_4_Elatomtsev_Lev_PIbd-23.doc
Normal file
150
Lab4/data.json
Normal file
15
Lab4/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Inkoria</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root" class="h-100 d-flex flex-column"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
14
Lab4/jsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"target": "ES2020",
|
||||
"jsx": "react",
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/node_modules/*"
|
||||
]
|
||||
}
|
4079
Lab4/package-lock.json
generated
Normal file
33
Lab4/package.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "l4",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||
"dev": "vite",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "6.5.1",
|
||||
"bootstrap": "5.3.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.18.0",
|
||||
"react-bootstrap": "^2.9.1",
|
||||
"react-bootstrap-icons": "^1.10.3",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.3",
|
||||
"vite": "5.0.10",
|
||||
"@types/react": "^18.2.15",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@vitejs/plugin-react": "^4.0.3"
|
||||
}
|
||||
}
|
29
Lab4/public/favicon.svg
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="120.000000pt" height="120.000000pt" viewBox="0 0 120.000000 120.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,120.000000) scale(0.009375,-0.009375)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M5990 11035 c-404 -39 -762 -116 -1120 -241 -165 -57 -418 -164 -565
|
||||
-239 -344 -176 -695 -413 -972 -657 -128 -113 -398 -388 -498 -508 -518 -624
|
||||
-864 -1356 -1009 -2140 -102 -551 -102 -1149 0 -1700 145 -784 491 -1516 1009
|
||||
-2140 172 -207 475 -499 703 -677 119 -94 431 -304 562 -378 700 -399 1486
|
||||
-605 2299 -605 524 0 983 74 1466 235 550 183 1007 433 1475 809 176 141 540
|
||||
508 682 686 561 706 890 1486 999 2370 30 239 37 713 15 950 -69 730 -270
|
||||
1355 -634 1975 -310 526 -775 1033 -1292 1407 -598 433 -1294 712 -2067 827
|
||||
-267 40 -775 53 -1053 26z m-1671 -1370 c223 -59 371 -250 371 -479 0 -143
|
||||
-45 -253 -145 -353 -193 -193 -497 -196 -696 -7 -99 95 -149 218 -149 363 1
|
||||
225 148 416 367 476 65 18 186 18 252 0z m396 -1866 c182 -155 398 -338 480
|
||||
-409 262 -223 1703 -1446 1890 -1605 99 -84 322 -273 495 -420 l315 -268 6
|
||||
1004 c3 552 7 1221 8 1487 l1 482 48 -4 c26 -2 215 -4 421 -5 l374 -1 -6
|
||||
-1507 c-4 -830 -7 -1815 -7 -2190 l0 -682 -162 -3 -163 -3 -90 75 c-161 135
|
||||
-1014 857 -2644 2236 -410 348 -747 631 -747 630 -4 -5 -14 -1484 -14 -2133
|
||||
l0 -793 -437 0 -436 0 6 1298 c4 713 7 1701 7 2195 l0 897 163 0 162 -1 330
|
||||
-280z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
3
Lab4/src/App.css
Normal file
@ -0,0 +1,3 @@
|
||||
.hide-overflow-x {
|
||||
overflow-x: hidden;
|
||||
}
|
24
Lab4/src/App.jsx
Normal file
@ -0,0 +1,24 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Container } from 'react-bootstrap';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import './App.css';
|
||||
import Footer from './components/footer/Footer.jsx';
|
||||
import Navigation from './components/navigation/Navigation.jsx';
|
||||
|
||||
const App = ({ routes }) => {
|
||||
return (
|
||||
<div className="hide-overflow-x">
|
||||
<Navigation routes={routes}></Navigation>
|
||||
<Container as="main" fluid>
|
||||
<Outlet />
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
App.propTypes = {
|
||||
routes: PropTypes.array,
|
||||
};
|
||||
|
||||
export default App;
|
BIN
Lab4/src/assets/banners/banner1.jpg
Normal file
After Width: | Height: | Size: 182 KiB |
BIN
Lab4/src/assets/banners/banner2.jpg
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
Lab4/src/assets/banners/banner3.jpg
Normal file
After Width: | Height: | Size: 137 KiB |
BIN
Lab4/src/assets/banners/banner4.jpg
Normal file
After Width: | Height: | Size: 241 KiB |
BIN
Lab4/src/assets/banners/banner5.jpg
Normal file
After Width: | Height: | Size: 363 KiB |
BIN
Lab4/src/assets/banners/banner6.jpg
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
Lab4/src/assets/icons/inst.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Lab4/src/assets/icons/tg.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Lab4/src/assets/icons/vk.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Lab4/src/assets/icons/whatsapp.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Lab4/src/assets/logo/logotransp.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
Lab4/src/assets/sp/sp1.jpg
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
Lab4/src/assets/sp/sp2.jpg
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
Lab4/src/assets/sp/sp3.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
Lab4/src/assets/sp/sp4.jpg
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
Lab4/src/assets/sp/sp5.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
Lab4/src/assets/sp/sp6.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
Lab4/src/assets/ukr/ukr1.jpg
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
Lab4/src/assets/ukr/ukr10.jpg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
Lab4/src/assets/ukr/ukr11.jpg
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
Lab4/src/assets/ukr/ukr12.jpg
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
Lab4/src/assets/ukr/ukr13.jpg
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
Lab4/src/assets/ukr/ukr14.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
Lab4/src/assets/ukr/ukr15.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
Lab4/src/assets/ukr/ukr2.jpg
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
Lab4/src/assets/ukr/ukr3.jpg
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
Lab4/src/assets/ukr/ukr4.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
Lab4/src/assets/ukr/ukr5.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
Lab4/src/assets/ukr/ukr6.jpg
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
Lab4/src/assets/ukr/ukr7.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
Lab4/src/assets/ukr/ukr8.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
Lab4/src/assets/ukr/ukr9.jpg
Normal file
After Width: | Height: | Size: 63 KiB |
0
Lab4/src/components/accordion/Accordion.css
Normal file
23
Lab4/src/components/accordion/Accordion.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './Accordion.css';
|
||||
|
||||
const Accordion = ({ title, content }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='square rounded-4 bg-black p-3 m-2' onClick={() => setIsOpen(!isOpen)}>
|
||||
<h3 className='fs-1 text-white'>{title}</h3>
|
||||
</div>
|
||||
{isOpen && <p className='rounded-4 bg-black text-white p-3 m-4'>{content}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Accordion.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
content: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Accordion;
|
25
Lab4/src/components/banner/Banner.css
Normal file
@ -0,0 +1,25 @@
|
||||
#banner {
|
||||
margin: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#banner img {
|
||||
border: 1px solid #3c3c3f;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#banner img.banner-show {
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
transition: opacity 1s, visibility 0s;
|
||||
}
|
||||
|
||||
#banner img.banner-hide {
|
||||
height: 0;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 1s, visibility 0s 1s;
|
||||
}
|
43
Lab4/src/components/banner/Banner.jsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import banner1 from '../../assets/banners/banner1.jpg';
|
||||
import banner2 from '../../assets/banners/banner2.jpg';
|
||||
import banner3 from '../../assets/banners/banner3.jpg';
|
||||
import banner4 from '../../assets/banners/banner4.jpg';
|
||||
import banner5 from '../../assets/banners/banner5.jpg';
|
||||
import banner6 from '../../assets/banners/banner6.jpg';
|
||||
import './Banner.css';
|
||||
|
||||
const Banner = () => {
|
||||
const [currentBanner, setCurrentBanner] = useState(0);
|
||||
const banners = [banner1, banner2, banner3, banner4, banner5, banner6];
|
||||
|
||||
const getBannerClass = (index) => {
|
||||
return currentBanner === index ? 'banner-show' : 'banner-hide';
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const bannerInterval = setInterval(
|
||||
() => {
|
||||
console.info('Banner changed');
|
||||
let current = currentBanner + 1;
|
||||
if (current === banners.length) {
|
||||
current = 0;
|
||||
}
|
||||
setCurrentBanner(current);
|
||||
},
|
||||
5000,
|
||||
);
|
||||
return () => clearInterval(bannerInterval);
|
||||
});
|
||||
|
||||
return (
|
||||
<div id="banner" >
|
||||
{
|
||||
banners.map((banner, index) =>
|
||||
<img key={index} className={getBannerClass(index)} src={banner} alt={`banner${index}`} />)
|
||||
}
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
export default Banner;
|
0
Lab4/src/components/footer/Footer.css
Normal file
39
Lab4/src/components/footer/Footer.jsx
Normal file
@ -0,0 +1,39 @@
|
||||
import './Footer.css';
|
||||
import {
|
||||
Container,
|
||||
Row,
|
||||
Col,
|
||||
} from 'react-bootstrap';
|
||||
|
||||
const Footer = () => {
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<Container fluid className="bg-black text-secondary pt-4" id="footer">
|
||||
<Row className="lh-1">
|
||||
<Col className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 d-flex justify-content-start">
|
||||
<ul className="list-unstyled">
|
||||
<p>
|
||||
© ООО INKORIA, {year}
|
||||
</p>
|
||||
<p>
|
||||
<a href="" className="underlined text-secondary">Авторизация</a>
|
||||
</p>
|
||||
</ul>
|
||||
</Col>
|
||||
<Col className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 d-flex justify-content-start">
|
||||
<ul className="list-unstyled">
|
||||
<p>
|
||||
Контактная информация:
|
||||
</p>
|
||||
<p>
|
||||
т. + 7 (996) 953-68-27, e-mail: inkoria@mail.ru
|
||||
</p>
|
||||
</ul>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
0
Lab4/src/components/formOtz/FormOtz.css
Normal file
18
Lab4/src/components/formOtz/FormOtz.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import './FormOtz.css';
|
||||
|
||||
const FormOtz = ({ title, text }) => {
|
||||
return (
|
||||
<div className="square rounded-4 m-3 p-3 bg-black col-11 col-sm-11 col-md-11 col-lg-2 col-xl-3">
|
||||
<p className="fs-4 text-white">{title}</p>
|
||||
<p className="text-white">{text}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FormOtz.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FormOtz;
|
0
Lab4/src/components/formSp/FormSp.css
Normal file
20
Lab4/src/components/formSp/FormSp.jsx
Normal file
@ -0,0 +1,20 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import './FormSp.css';
|
||||
|
||||
const FormSp = ({ imageSrc, title, text }) => {
|
||||
return (
|
||||
<div className="square rounded-4 m-3 p-0 bg-black col-11 col-sm-11 col-md-11 col-lg-2 col-xl-3">
|
||||
<img src={imageSrc} className="square rounded-top-4 d-block w-100 p-0 object-fit-cover" alt={title} />
|
||||
<p className="text-center fs-2 mt-1 mb-0 text-white fw-bold">{title}</p>
|
||||
<p className="text-center fs-5 mb-3 mt-0 text-white">{text}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FormSp.propTypes = {
|
||||
imageSrc: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FormSp;
|
0
Lab4/src/components/formsUsl/FormUsl.css
Normal file
18
Lab4/src/components/formsUsl/FormUsl.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import './FormUsl.css';
|
||||
|
||||
const FormUsl = ({ title, text }) => {
|
||||
return (
|
||||
<div className="square rounded-4 m-3 p-3 bg-black col-11 col-sm-11 col-md-11 col-lg-3 col-xl-3 text-center align-items-center justify-content-center text-center">
|
||||
<p className="fs-3 text-white fw-bold">{title}</p>
|
||||
<p className="fs-5 text-white">{text}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FormUsl.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FormUsl;
|
0
Lab4/src/components/map/Map.css
Normal file
13
Lab4/src/components/map/Map.jsx
Normal file
@ -0,0 +1,13 @@
|
||||
import './Map.css';
|
||||
import { } from 'react-bootstrap';
|
||||
|
||||
const Map = () => {
|
||||
return (
|
||||
<iframe className="d-block w-100 square rounded-4 object-fit-cover"
|
||||
src="https://yandex.ru/map-widget/v1/?ll=48.395364%2C54.326638&mode=search&oid=183869084795&ol=biz&sctx=ZAAAAAgBEAAaKAoSCe%2FlPjkKMkhAEd2XM9sVKktAEhIJfEYiNIKNvz8R%2FFbrxOV4pT8iBgABAgMEBSgKOABA8J8NSAFiIW1pZGRsZV9wb3N0ZmlsdGVyX3RocmVzaGNoYWluPTAuNGIcbWlkZGxlX3Bvc3RmaWx0ZXJfdGhyZXNoPTAuNGIucmVsZXZfcmFua2luZ19tc2VfZm9ybXVsYT0xLjA6bXNlX2RjMzM5NDQzX2V4cGJQcmVhcnI9c2NoZW1lX0xvY2FsL0dlby9CdXNHZW9DaG9vc2UvVGFrZVJ1YnJpY0ZpcnN0U2FtZUJ5UmVzdWx0c01zZVRocmVzaG9sZD0wLjRqAnJ1nQHNzEw9oAEAqAEAvQGVqpI%2BwgEG%2B6jO%2B6wF6gEA8gEA%2BAEAggIHaW5rb3JpYYoCAJICAJoCDGRlc2t0b3AtbWFwcw%3D%3D&sll=48.395364%2C54.326638&sspn=0.014475%2C0.004926&text=inkoria&z=17.09"
|
||||
height="300">
|
||||
</iframe>
|
||||
);
|
||||
};
|
||||
|
||||
export default Map;
|
0
Lab4/src/components/name/Name.css
Normal file
14
Lab4/src/components/name/Name.jsx
Normal file
@ -0,0 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import './Name.css';
|
||||
|
||||
const Name = ({ title }) => {
|
||||
return (
|
||||
<h1 className="text-center display-3 m-3 text-black fw-bold lh-lg">{title}</h1>
|
||||
);
|
||||
};
|
||||
|
||||
Name.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Name;
|
36
Lab4/src/components/navigation/Navigation.css
Normal file
@ -0,0 +1,36 @@
|
||||
header {
|
||||
background-color: #000000;
|
||||
font-size: 2.2vh;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
color: #B2309D !important;
|
||||
}
|
||||
|
||||
header a:hover:not(.active) {
|
||||
color: #FF9FEF;
|
||||
}
|
||||
|
||||
#logo {
|
||||
background-color: #FFFFFF;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#logo:hover {
|
||||
background-color: #FF9FEF;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.row img {
|
||||
background-color: #FFFFFF;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.row img:hover {
|
||||
background-color: #FF9FEF;
|
||||
z-index: -1;
|
||||
}
|
80
Lab4/src/components/navigation/Navigation.jsx
Normal file
@ -0,0 +1,80 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Container,
|
||||
Nav,
|
||||
Navbar,
|
||||
Image,
|
||||
Row,
|
||||
Col,
|
||||
} from 'react-bootstrap';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import './Navigation.css';
|
||||
import whatsapp from '../../assets/icons/whatsapp.png';
|
||||
import inst from '../../assets/icons/inst.png';
|
||||
import vk from '../../assets/icons/vk.png';
|
||||
import tg from '../../assets/icons/tg.png';
|
||||
import logo from '../../assets/logo/logotransp.png';
|
||||
|
||||
const Navigation = ({ routes }) => {
|
||||
const location = useLocation();
|
||||
const indexPageLink = routes.filter((route) => route.index === false).shift();
|
||||
const pages = routes.filter((route) => Object.prototype.hasOwnProperty.call(route, 'title'));
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="fixed-top">
|
||||
<Navbar expand='lg' data-bs-theme='dark' className='my-navbar'>
|
||||
<Container fluid>
|
||||
<Navbar.Brand as={Link} to={indexPageLink?.path ?? '/'}>
|
||||
<div id="logo">
|
||||
<Image src={logo} alt="Логотип INKORIA"></Image>
|
||||
</div>
|
||||
</Navbar.Brand>
|
||||
<Navbar.Toggle aria-controls='main-navbar' />
|
||||
<Navbar.Collapse id='main-navbar'>
|
||||
<Nav className='me-auto link nav-fill w-100 justify-content-center align-items-center fw-bold' activeKey={location.pathname}>
|
||||
{
|
||||
pages.map((page) =>
|
||||
<Nav.Link as={Link} key={page.path} eventKey={page.path} to={page.path ?? '/'}>
|
||||
{page.title}
|
||||
</Nav.Link>)
|
||||
}
|
||||
<Row id="social-icons">
|
||||
<Col className="d-none d-xl-block">
|
||||
<a href="https://www.wa.me/79969536827"><Image src={whatsapp}></Image></a>
|
||||
</Col>
|
||||
<Col className="d-none d-xl-block">
|
||||
<a href="https://www.instagram.com/vrode__anya"><Image src={inst}></Image></a>
|
||||
</Col>
|
||||
<Col className="d-none d-xl-block">
|
||||
<a href="https://www.vk.com/vrode_anya"><Image src={vk}></Image></a>
|
||||
</Col>
|
||||
<Col className="d-none d-xl-block">
|
||||
<Link href="https://www.t.me/vrode_anyya"><Image src={tg}></Image></Link>
|
||||
</Col>
|
||||
</Row>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</Container>
|
||||
</Navbar >
|
||||
</header>
|
||||
<header>
|
||||
<Navbar expand='lg' className='my-navbar'>
|
||||
<Container fluid>
|
||||
<Navbar.Brand as={Link} to={indexPageLink?.path ?? '/'}>
|
||||
<div id="logo">
|
||||
<Image src={logo} alt="Логотип INKORIA"></Image>
|
||||
</div>
|
||||
</Navbar.Brand>
|
||||
</Container>
|
||||
</Navbar >
|
||||
</header>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Navigation.propTypes = {
|
||||
routes: PropTypes.array,
|
||||
};
|
||||
|
||||
export default Navigation;
|
5
Lab4/src/index.css
Normal file
@ -0,0 +1,5 @@
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-color: #B2309D;
|
||||
min-height: 100vh;
|
||||
}
|
62
Lab4/src/main.jsx
Normal file
@ -0,0 +1,62 @@
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
|
||||
import App from './App.jsx';
|
||||
import './index.css';
|
||||
import ErrorPage from './pages/ErrorPage.jsx';
|
||||
import Welcome from './pages/Welcome.jsx';
|
||||
import Uslugi from './pages/Uslugi.jsx';
|
||||
import Ukrasheniya from './pages/Ukrasheniya.jsx';
|
||||
import Specialisty from './pages/Specialisty.jsx';
|
||||
import Faq from './pages/Faq.jsx';
|
||||
import Otzyvy from './pages/Otzyvy.jsx';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
index: true,
|
||||
path: '/',
|
||||
element: <Welcome />,
|
||||
title: 'ГЛАВНАЯ',
|
||||
},
|
||||
{
|
||||
path: '/uslugi',
|
||||
element: <Uslugi />,
|
||||
title: 'УСЛУГИ',
|
||||
},
|
||||
{
|
||||
path: '/ukrasheniya',
|
||||
element: <Ukrasheniya />,
|
||||
title: 'УКРАШЕНИЯ',
|
||||
},
|
||||
{
|
||||
path: '/specialisty',
|
||||
element: <Specialisty />,
|
||||
title: 'СПЕЦИАЛИСТЫ',
|
||||
},
|
||||
{
|
||||
path: '/otzyvy',
|
||||
element: <Otzyvy />,
|
||||
title: 'ОТЗЫВЫ',
|
||||
},
|
||||
{
|
||||
path: '/faq',
|
||||
element: <Faq />,
|
||||
title: 'FAQ',
|
||||
},
|
||||
];
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: <App routes={routes} />,
|
||||
children: routes,
|
||||
errorElement: <ErrorPage />,
|
||||
},
|
||||
]);
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
</React.StrictMode>,
|
||||
);
|
19
Lab4/src/pages/ErrorPage.jsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { Alert, Button, Container } from 'react-bootstrap';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
const ErrorPage = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Container fluid className="p-2 row justify-content-center">
|
||||
<Container className='col-md-6'>
|
||||
<Alert variant="danger">
|
||||
Страница не найдена
|
||||
</Alert>
|
||||
<Button className="w-25 mt-2" variant="primary" onClick={() => navigate(-1)}>Назад</Button>
|
||||
</Container>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorPage;
|
26
Lab4/src/pages/Faq.jsx
Normal file
@ -0,0 +1,26 @@
|
||||
import {
|
||||
Container,
|
||||
} from 'react-bootstrap';
|
||||
import Accordion from '../components/accordion/Accordion.jsx';
|
||||
import Name from '../components/name/Name.jsx';
|
||||
|
||||
const Faq = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Name title="FAQ"/>
|
||||
<Accordion title="Что такое пирсинг?" content="Пирсинг - это процесс прокола кожи и введения украшения (обычно кольца, штифта или балла) в результате модификации тела. Он может быть выполнен на разных частях тела, включая уши, нос, губы, язык, брови, пупок и многие другие." />
|
||||
<Accordion title="Бывает ли пирсинг безболезненным?" content="Боль при пирсинге может различаться в зависимости от места прокола, индивидуальной чувствительности и мастерства пирсера. Некоторые люди могут испытывать лишь небольшую боль или дискомфорт, а другие - более сильные ощущения. Однако, мастера пирсинга используют специальное оборудование и техники, чтобы сделать процесс как можно более комфортным для клиента." />
|
||||
<Accordion title="Как подготовиться к пирсингу?" content="Перед пирсингом рекомендуется следующее:
|
||||
- Выбрать сертифицированного и опытного мастера пирсинга
|
||||
- Изучить место пирсинга
|
||||
- Не употреблять алкоголь перед процедурой" />
|
||||
<Accordion title="Как ухаживать за пирсингом после процедуры?" content="Уход за пирсингом является важной частью процесса заживления. Рекомендации по уходу могут различаться в зависимости от места пирсинга. Однако, в целом следующие советы могут быть полезными:
|
||||
- Регулярно очищайте пирсинг с помощью нежного мыла и воды.
|
||||
- Избегайте касания пирсинга грязными руками и трения об одежду.
|
||||
- Следуйте инструкциям по использованию мазей или кремов."/>
|
||||
<Accordion title="Как долго заживает пирсинг?" content="Время заживления пирсинга может варьироваться в зависимости от места пирсинга, вашего здоровья и других факторов. Обычно уши заживают примерно за 6-8 недель, нос - около 2-4 месяцев, а пирсинги с длинными канюлями (например, языка или пупка) могут заживать от 4 до 12 недель. Важно понимать, что время заживления может быть индивидуальным и может отличаться для каждого человека."/>
|
||||
<Accordion title="Какие могут быть осложнения и риски при пирсинге?" content="Пирсинг, так же как и любая другая процедура, сопряжен со своими рисками. Осложнения могут включать инфекцию, аллергические реакции на металлы, кровотечение, а также риск повреждения нервов или других тканей. Поэтому очень важно обратиться к опытному мастеру пирсинга, соблюдать все рекомендации по уходу и следить за своими ощущениями после выполнения пирсинга"/>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
export default Faq;
|
40
Lab4/src/pages/Otzyvy.jsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { Container, Row } from 'react-bootstrap';
|
||||
import FormOtz from '../components/formOtz/FormOtz.jsx';
|
||||
import Name from '../components/name/Name.jsx';
|
||||
|
||||
const Otzyvy = () => {
|
||||
return (
|
||||
<>
|
||||
<Name title="Отзывы"/>
|
||||
|
||||
<Container>
|
||||
<Row className = "d-flex justify-content-between text-white">
|
||||
<FormOtz title="Кирилл Пятаков" text=" Я был очень доволен своим первым опытом пирсинга в этой студии. Персонал
|
||||
был профессиональным и добрым, они сразу ответили на все мои вопросы и
|
||||
посвятили достаточно времени, чтобы убедиться, что я полностью понимаю
|
||||
процесс. Результат был идеальным, и я чувствую, что я нашел место, где
|
||||
могу делать пирсинги и доверять им своё тело." />
|
||||
<FormOtz title="Анна Долгова" text="Я получил свой пирсинг в этой студии несколько месяцев назад, и я до сих
|
||||
пор в восторге от результата. Чистота и гигиена здесь на самом высоком
|
||||
уровне, что очень важно для меня. Работники были терпеливыми и
|
||||
вежливыми, учитывая мои нервы и волнения. Теперь я регулярно посещаю
|
||||
эту студию, чтобы обновить свой пирсинг и получить консультацию по
|
||||
уходу за ним." />
|
||||
<FormOtz title="Анна Долгова" text="Я получил свой пирсинг в этой студии несколько месяцев назад, и я до сих
|
||||
пор в восторге от результата. Чистота и гигиена здесь на самом высоком
|
||||
уровне, что очень важно для меня. Работники были терпеливыми и
|
||||
вежливыми, учитывая мои нервы и волнения. Теперь я регулярно посещаю
|
||||
эту студию, чтобы обновить свой пирсинг и получить консультацию по
|
||||
уходу за ним." />
|
||||
<FormOtz title="Анна Долгова" text="Я получил свой пирсинг в этой студии несколько месяцев назад, и я до сих
|
||||
пор в восторге от результата. Чистота и гигиена здесь на самом высоком
|
||||
уровне, что очень важно для меня. Работники были терпеливыми и
|
||||
вежливыми, учитывая мои нервы и волнения. Теперь я регулярно посещаю
|
||||
эту студию, чтобы обновить свой пирсинг и получить консультацию по
|
||||
уходу за ним." />
|
||||
</Row>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default Otzyvy;
|
28
Lab4/src/pages/Specialisty.jsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { Container, Row } from 'react-bootstrap';
|
||||
import FormSp from '../components/formSp/FormSp.jsx';
|
||||
import Name from '../components/name/Name.jsx';
|
||||
import sp1 from '../assets/sp/sp1.jpg';
|
||||
import sp2 from '../assets/sp/sp2.jpg';
|
||||
import sp3 from '../assets/sp/sp3.jpg';
|
||||
import sp4 from '../assets/sp/sp4.jpg';
|
||||
import sp5 from '../assets/sp/sp5.jpg';
|
||||
import sp6 from '../assets/sp/sp6.jpg';
|
||||
|
||||
const Specialisty = () => {
|
||||
return (
|
||||
<>
|
||||
<Name title="Специалисты"/>
|
||||
<Container>
|
||||
<Row className="d-flex justify-content-between">
|
||||
<FormSp imageSrc={sp1} title="Дмитрий Кузнецов" text="мастер" />
|
||||
<FormSp imageSrc={sp2} title="Максим Булаев" text="мастер" />
|
||||
<FormSp imageSrc={sp3} title="Даниил Касушкин" text="мастер" />
|
||||
<FormSp imageSrc={sp4} title="Софья Ильина" text="мастер" />
|
||||
<FormSp imageSrc={sp5} title="Анна Милашина" text="мастер" />
|
||||
<FormSp imageSrc={sp6} title="Сергей Князькин" text="мастер" />
|
||||
</Row>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default Specialisty;
|
16
Lab4/src/pages/Ukrasheniya.jsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
import Name from '../components/name/Name.jsx';
|
||||
|
||||
const Ukrasheniya = () => {
|
||||
return (
|
||||
<>
|
||||
<Name title="Украшения"/>
|
||||
<Button id="items-add" variant="info">Добавить товар</Button>
|
||||
<Table className="mt-2" striped>
|
||||
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Ukrasheniya;
|
25
Lab4/src/pages/Uslugi.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { Container, Row } from 'react-bootstrap';
|
||||
import FormUsl from '../components/formsUsl/FormUsl.jsx';
|
||||
import Name from '../components/name/Name.jsx';
|
||||
|
||||
const Uslugi = () => {
|
||||
return (
|
||||
<>
|
||||
<Name title="Услуги"/>
|
||||
<Container>
|
||||
<Row className="row d-flex justify-content-between">
|
||||
<FormUsl title="Консультация" text="Получите профессиональную консультацию перед проколом" />
|
||||
<FormUsl title="Стандартный прокол" text="Прокол ушей, носа, языка, губ, септум и др." />
|
||||
<FormUsl title="Сложный прокол" text="Прокол хрящей, трагус, снаг и др." />
|
||||
<FormUsl title="Чистка украшений" text="Очистка и полировка ваших украшений" />
|
||||
<FormUsl title="Анодирование" text="Разнообразные цветовые варианты для украшений"/>
|
||||
<FormUsl title="Восстановление" text="Восстановление старых заросших каналов"/>
|
||||
<FormUsl title="Чистка прокола" text="Чистка прокола от грязи и выделений"/>
|
||||
<FormUsl title="Удаление" text="Качественное удаление пирсинга"/>
|
||||
<FormUsl title="Другие" text="Напишите нам, чтобы узнать больше"/>
|
||||
</Row>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default Uslugi;
|
30
Lab4/src/pages/Welcome.jsx
Normal file
@ -0,0 +1,30 @@
|
||||
import {
|
||||
Button,
|
||||
Container,
|
||||
Row,
|
||||
Col,
|
||||
} from 'react-bootstrap';
|
||||
import Banner from '../components/banner/Banner.jsx';
|
||||
import Map from '../components/map/Map.jsx';
|
||||
|
||||
const Welcome = () => {
|
||||
return (
|
||||
<Container fluid className="p-0">
|
||||
<Row className="p-0">
|
||||
<Col xs={12} sm={12} md={12} lg={12} xl={6} className="p-0">
|
||||
<Banner />
|
||||
</Col>
|
||||
<Col className="d-flex m-auto p-3 col-12 col-sm-12 col-md-12 col-lg-12 col-xl-6 text-black flex-column align-items-center text-center">
|
||||
<h1 className="display-5 mb-3 text-black">Добро пожаловать в INKORIA</h1>
|
||||
<div className="col-12">
|
||||
<Map />
|
||||
</div>
|
||||
<Button type="button" className="btn col-6 btn-lg mt-3 bg-black text-white">
|
||||
<a href="https://n879755.yclients.com" className="text-white">Записаться</a>
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
export default Welcome;
|
12
Lab4/vite.config.js
Normal file
@ -0,0 +1,12 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
sourcemap: true,
|
||||
chunkSizeWarningLimit: 1024,
|
||||
emptyOutDir: true,
|
||||
},
|
||||
});
|