Лаба 4

This commit is contained in:
spacyboy 2023-12-21 18:42:34 +04:00
parent d0af1c80a3
commit 4901100066
38 changed files with 5484 additions and 0 deletions

View File

@ -0,0 +1,26 @@
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',
'linebreak-style': 'off',
'import/no-extraneous-dependencies': 'off'
},
}

24
4_laba_IP_project/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -0,0 +1,10 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md)
uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast
Refresh

View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Ульяновский Кондитер</title>
</head>
<body>
<div id="root" class="h-100 d-flex flex-column"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

4344
4_laba_IP_project/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
{
"name": "lec4",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0",
"bootstrap": "^5.3.2",
"react-bootstrap": "^2.9.1",
"react-bootstrap-icons": "^1.10.3",
"prop-types": "^15.8.1"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
"eslint": "^8.45.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": "^4.4.5"
}
}

View File

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img"
class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257">
<defs>
<linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%">
<stop offset="0%" stop-color="#41D1FF"></stop>
<stop offset="100%" stop-color="#BD34FE"></stop>
</linearGradient>
<linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%">
<stop offset="0%" stop-color="#FFEA83"></stop>
<stop offset="8.333%" stop-color="#FFDD35"></stop>
<stop offset="100%" stop-color="#FFA800"></stop>
</linearGradient>
</defs>
<path fill="url(#IconifyId1813088fe1fbc01fb466)"
d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path>
<path fill="url(#IconifyId1813088fe1fbc01fb467)"
d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,44 @@
/*#root {*/
/* max-width: 1280px;*/
/* margin: 0 auto;*/
/* padding: 2rem;*/
/* text-align: center;*/
/*}*/
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

View File

@ -0,0 +1,28 @@
import {useState} from 'react';
import PropTypes from 'prop-types';
import {Container} from 'react-bootstrap';
import {Outlet} from 'react-router-dom';
import './App.css';
import LeftBar from './components/LeftBar/LeftBar.jsx';
import Header from './components/Header/Header.jsx';
const App = ({routes}) => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const toggleShow = () => {
setShow((s) => !s);
};
return (
<>
<Container className='p-2' as="main" fluid>
<Outlet/>
</Container>
<Header toggleShow={toggleShow}/>
<LeftBar show={show} handleClose={handleClose} routes={routes}/>
</>
);
};
App.propTypes = {
routes: PropTypes.array,
};
export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,6 @@
.back_arrow { /*стрелка назад*/
height: 4vh;
position: absolute;
top: 7vh;
left: 3vw;
}

View File

@ -0,0 +1,15 @@
import './BackArrow.css';
import backarrow from '../../assets/back_arrow_icon.png';
const BackArrow = () => {
const goBack = () => {
window.history.back();
};
return (
<div id="BackArrow" onClick={goBack}>
<img className="back_arrow " src={backarrow} alt="back_arrow"/>
</div>
);
};
export default BackArrow;

View File

@ -0,0 +1,33 @@
.top_pannel { /*отступ слева в top_pannel*/
margin-left: 20vw;
}
.icon-container { /* сдвиг top_pannel*/
margin-right: 5vw;
}
.text_containter { /* сдвиг top_pannel*/
margin-left: 5vw;
}
header nav a:hover { /* подчеркивание текста top_pannel*/
text-decoration: underline;
}
.arrow_and_cities { /*чтобы все было на одном уровне, стрелка и город top_pannel*/
display: flex;
align-items: center;
}
.btn_open {
background-image: url('../../assets/open_sidebar.png');
background-color: transparent;
background-size: cover;
position: fixed;
margin-top: 0vh;
margin-left: 3vh;
border: none;
height: 4vh;
width: 3vw;
}

View File

@ -0,0 +1,51 @@
import {Link} from 'react-router-dom';
import Button from 'react-bootstrap/Button';
import './Header.css';
import arrowicon from '../../assets/arrow_icon.png';
import accicon from '../../assets/acc_icon.png';
import shopicon from '../../assets/shop_icon.png';
import searchicon from '../../assets/search_icon.png';
const header = ({toggleShow, name}) => {
return (
<header>
<nav className="navbar navbar-expand-md navbar-white fixed-top">
<div className="btn_open_sidebar">
<Button variant="primary" onClick={() => toggleShow()} className="btn_open me-2">
{name}
</Button>
</div>
<div className="container-fluid top_pannel">
<div className="navbar-collapse collapse justify-content-start" id="navbarNav">
<div className="navbar-nav text_containter">
<div className="arrow_and_cities">
<img className="icon_top" src={arrowicon} alt="arrow_icon"/>
<a className="nav-link"
style={{color: 'black'}}>Ульяновск</a> {/* Используем объект стилей для атрибута style */}
</div>
<a className="nav-link adress" style={{marginLeft: '40px', color: 'black'}}>Адреса
магазинов</a> {/* Используем объект стилей для атрибута style */}
</div>
</div>
<div className="navbar-collapse collapse justify-content-end"
id="navbarNav1"> {/* Перемещаем закрывающий тег внутрь предыдущего тега */}
<div className="navbar-nav icon-container">
<Link to="/Page2">
<img className="icon_top" src={accicon} alt="acc_icon"/>
</Link>
<Link to="/Page3">
<img className="icon_top" src={shopicon} alt="shop_icon"/>
</Link>
<Link to="/Page2">
<img className="icon_top" src={searchicon} alt="search_icon"/>
</Link>
</div>
</div>
</div>
</nav>
</header>
);
};
export default header;

View File

@ -0,0 +1,51 @@
.logo_sidebar { /*размеры лого sidebar*/
width: 17vh;
}
.list_font { /*текст sidebar*/
line-height: 3;
font-size: 2.4vh;
color: #5d5d5d;
}
.offcanvas-start.show { /*ширина sidebar*/
width: 25vw;
border: none;
}
.offcanvas-header { /*настройки header sidebar*/
margin-top: 8vh;
height: 15%;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: auto;
}
.offcanvas-body { /*настройки body sidebar*/
position: relative;
display: flex;
justify-content: center;
margin-top: auto;
overflow-y: auto;
}
.social_network img { /*иконки соц сетей*/
margin-top: 1vh;
height: 3.5vh;
margin-right: 1vw;
}
.list_sidebar { /* список sidebar*/
top: 10vh;
position: absolute;
}
.btn_open_sidebar {
/*position: absolute;*/
top: 10px;
left: 10px;
z-index: 1000;
background-color: #a60000;
}

View File

@ -0,0 +1,88 @@
import {Link} from 'react-router-dom';
import Offcanvas from 'react-bootstrap/Offcanvas';
import PropTypes from 'prop-types';
import './LeftBar.css';
import logo from '../../assets/logo.png';
import Whatsappicon from '../../assets/whatsapp_icon.png';
import vkicon from '../../assets/vk_icon.png';
const options = [
{
name: 'Enable body scrolling',
scroll: true,
backdrop: false,
},
];
function OffCanvasExample({
name,
show,
handleClose,
...props
}) {
return (
<>
<Offcanvas show={show} onHide={handleClose} {...props}>
<Offcanvas.Header closeButton>
<Link to="/Page1">
<img className="logo_sidebar" src={logo} alt="shop_icon"/>
</Link>
</Offcanvas.Header>
<Offcanvas.Body>
<div className="list_sidebar">
<div className="list_font">
<ul>
<li>Клубника в шоколаде</li>
<li>Бананы в шоколаде</li>
<li>Конфеты</li>
<li>Шоколад</li>
<li>Медианты</li>
</ul>
</div>
</div>
<div className="bottom_sidebar">
<div className='h0'>8 800 700 34 21
<div className="take_order" style={{color: '#25e000'}}>Сделать заказ</div>
</div>
<div className="social_network">
<img className="vk" src={vkicon} alt="vk"/>
<img className="whatsapp" src={Whatsappicon} alt="whatsapp"/>
</div>
</div>
</Offcanvas.Body>
</Offcanvas>
</>
);
}
OffCanvasExample.propTypes = {
name: PropTypes.string.isRequired,
show: PropTypes.bool.isRequired,
handleClose: PropTypes.func.isRequired,
};
function LeftBar({
name,
show,
handleClose,
}) {
return (
<>
{options.map((props, idx) => (
<OffCanvasExample
name={name}
show={show}
handleClose={handleClose}
key={idx} {...props} />
))}
</>
);
}
LeftBar.propTypes = {
name: PropTypes.string.isRequired,
show: PropTypes.bool.isRequired,
handleClose: PropTypes.func.isRequired,
};
export default LeftBar;

View File

@ -0,0 +1,12 @@
.my-navbar {
background-color: #a60000 !important;
}
.my-navbar .link a:hover {
text-decoration: underline !important;
}
.my-navbar .logo {
width: 26px;
height: 26px;
}

View File

@ -0,0 +1,46 @@
import PropTypes from 'prop-types';
import {Container, Nav, Navbar} from 'react-bootstrap';
import {Cart2} from 'react-bootstrap-icons';
import {Link, useLocation} from 'react-router-dom';
import './Navigation.css';
const Navigation = ({routes}) => {
const location = useLocation();
const indexPageLink = routes.filter((route) => route.index === false).shift();
const show = routes.filter((route) => route.path === location.pathname).shift();
const pages = routes.filter((route) => Object.prototype.hasOwnProperty.call(route, 'title'));
if (show.hideNavigation) {
return null;
}
return (
<header>
<Navbar expand='md' bg='dark' data-bs-theme='dark' className='my-navbar'>
<Container fluid>
<Navbar.Brand as={Link} to={indexPageLink?.path ?? '/'}>
<Cart2 className='d-inline-block align-top me-1 logo'/>
My shop
</Navbar.Brand>
<Navbar.Toggle aria-controls='main-navbar' hic/>
<Navbar.Collapse id='main-navbar'>
<Nav className='me-auto link' activeKey={location.pathname}>
{
pages.map((page) =>
<Nav.Link as={Link} key={page.path} eventKey={page.path} to={page.path ?? '/'}>
{page.title}
</Nav.Link>)
}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</header>
);
};
Navigation.propTypes = {
routes: PropTypes.array,
};
export default Navigation;

View File

@ -0,0 +1,337 @@
h1 { /*форматирование текста*/
font-size: 4.5vw;
font-family: "Segoe UI Light";
font-weight: lighter;
}
.main_pannel { /*основная панель main_pannel*/
margin-left: 28vw;
margin-top: 5vw;
font-weight: lighter;
max-width: 70%;
}
.table { /*таблица */
margin-top: 5vh;
margin-left: 0vw;
width: 60vw;
}
body {
overflow-x: hidden; /* скрыть горизонтальную прокрутку на всей странице */
}
.objects { /*объекты в таблицe main_pannel*/
width: 17vw;
height: auto;
}
.caption { /*описание к объекту в таблице main_pannel*/
font-weight: lighter;
text-align: center;
font-size: 1.8vw;
/*margin-top: 1vw;*/
}
.caption_2 { /*описание к объекту в цене main_pannel*/
font-weight: lighter;
text-align: center;
font-size: 2.8vw;
color: #5d5d5d;
/*margin-top: 0.3vw;*/
}
.caption_count {
font-weight: lighter;
text-align: center;
font-size: 1.2vw;
margin-top: 0.5vw;
}
.icon_top { /*top_pannel*/
margin-left: 2vw;
width: 1.1vw;
margin-top: 1vh;
}
.nav-link { /* текста top_pannel*/
font-size: calc(0.6vw + 0.6vh);
margin-top: 1vh;
}
header nav { /*заливка панели белым top_pannel*/
background-color: #ffffff
}
header nav a:hover { /* подчеркивание текста top_pannel*/
text-decoration: underline;
}
.bottom_sidebar { /*bottom sidebar*/
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0vh;
flex-direction: column;
margin-top: 60vh;
}
.h0 {
font-size: 2vh;
}
.btn:hover {
background-color: transparent;
}
.btn-close {
position: absolute;
top: 5vh;
right: 5vh;
visibility: hidden;
}
.width_input_mail { /*ширина панели для вводы почты*/
width: 30%;
}
h2 {
font-weight: lighter;
font-size: 4vh;
}
.h2_light {
font-weight: lighter;
font-size: 2vh;
}
.login_pannel { /*2 страница, расположение объектов*/
height: 90vh; /* на весь экран */
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 2vh; /* Добавляет отступы между элементами */
}
.add_object {
height: 90vh; /* на весь экран */
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 1vh; /* Добавляет отступы между элементами */
}
.width_add_object {
width: 25%;
text-align: left;
}
.add_object-button {
background-color: #118500;
border-color: #118500;
}
.view_object {
margin-top: 6vh;
margin-left: 0vw;
display: grid;
grid-template-columns: 1fr 1fr; /* Делит контейнер на две равные колонки */
gap: 6vh; /* Добавляет промежуток между клеточками */
}
.left-cell {
display: flex;
flex-direction: column;
justify-content: space-between;
margin-bottom: 6vh;
margin-top: 6vh;
/*margin-left: 15vw;*/
}
.right-cell {
display: flex;
flex-direction: column;
justify-content: space-between;
margin-bottom: 6vh;
margin-top: 6vh;
}
.main_pannel2 {
height: 100vh; /* на весь экран */
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding-left: 25vw;
}
h3 {
font-weight: lighter;
font-size: 3em;
}
.nav-pills .nav-link {
color: rgba(166, 166, 166, 0.7);
}
.nav-pills .nav-link:hover {
color: black;
}
.nav-pills .nav-link:focus,
.nav-pills .nav-link.active,
.nav-pills .nav-link:visited {
background-color: rgba(0, 255, 49, 0.28);
color: #000000;
}
.objects_basket {
height: 20vh;
}
.caption_basket {
text-align: left;
font-weight: lighter;
font-size: 2.5vh;
background-color: #25e000;
}
.caption_basket_price {
font-weight: lighter;
font-size: 4vh;
background-color: red;
}
.add_object-button:hover {
background-color: rgba(0, 255, 49, 0.28);
color: black;
border-color: #118500;
}
.col {
display: flex;
align-items: center;
justify-content: center;
}
#image-preview {
width: 200px;
margin-bottom: 1.4vh;
}
.clear-float:nth-child(3n+1) {
clear: left;
}
.fa-pencil, .fa-trash {
color: darkgray; /* Change to the desired color */
text-decoration: none; /* Убрать подчеркивание у кнопок */
}
.caption { /*описание к объекту в таблице main_pannel*/
font-weight: lighter;
text-align: center;
font-size: 1.2vw;
margin-top: 1vw;
}
.caption_2 { /*описание к объекту в цене main_pannel*/
font-weight: lighter;
text-align: center;
font-size: 2vw;
color: #5d5d5d;
margin-top: 0.3vw;
}
.caption_link {
text-decoration: none;
}
@media (max-width: 1300px) {
.main_pannel {
margin-left: auto;
margin-right: auto;
}
.table { /*таблица */
margin-left: auto;
margin-right: auto;
width: 60vw;
}
h1 {
text-align: center;
}
.offcanvas-start.show {
border: 1px solid black;
}
.btn-close {
visibility: visible;
}
}
@media (max-width: 800px) {
.col-4 {
width: 100%;
}
.objects { /*объекты в таблицe main_pannel*/
width: 52vw;
height: auto;
}
.caption { /*описание к объекту в таблице main_pannel*/
font-size: 3.2vw;
}
.caption_2 { /*описание к объекту в цене main_pannel*/
font-size: 4vw;
}
.list_font { /*текст sidebar*/
font-size: 2vh;
}
.offcanvas-start.show { /*ширина sidebar*/
width: 100%;
}
.top_pannel {
visibility: hidden;
}
.width_input_mail {
width: 90%;
}
.form-control {
width: 90%;
}
.width_add_object {
width: 90%;
}
.input-group { /*подгон ширины под отсльаные*/
padding-right: 9vw;
}
.view_object {
padding-top: 1vh;
}
}

View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"target": "ES2020",
"jsx": "preserve",
"strictNullChecks": true,
"strictFunctionTypes": true
},
"exclude": [
"node_modules",
"**/node_modules/*"
]
}

View File

@ -0,0 +1,51 @@
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import ReactDOM from 'react-dom/client';
import {createBrowserRouter, RouterProvider} from 'react-router-dom';
import App from './App.jsx';
import './index.css';
import ErrorPage from './pages/ErrorPage.jsx';
import Page1 from './pages/Page1.jsx';
import Page2 from './pages/Page2.jsx';
import Page3 from './pages/Page3.jsx';
import Page4 from './pages/Page4.jsx';
const routes = [
{
index: true,
path: '/Page1',
element: <Page1/>,
title: 'Главная страница',
},
{
path: '/Page2',
element: <Page2/>,
title: 'Вторая страница',
hideNavigation: true,
},
{
path: '/Page3',
element: <Page3/>,
title: 'Третья страница',
},
{
path: '/Page4',
element: <Page4/>,
title: 'Четвертая страница',
},
];
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>,
);

View 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;

View File

@ -0,0 +1,78 @@
import {Link} from 'react-router-dom';
import Object1 from '../assets/object_1.png';
import Object2 from '../assets/object_2.png';
import Object3 from '../assets/object_3.png';
const Page1 = () => {
return (
<>
<main className="container main_pannel">
<h1>Клубника в шоколаде</h1>
<div className="container table">
<div className="row">
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object1} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object2} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object3} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
</div>
<div className="row">
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object1} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object2} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
<div className="col-4">
<Link to="/Page4" className="caption_link">
<img className="objects" src={Object3} alt="object"/>
<div className="caption"> Букет из клубники 108. <br/>Набор из клубники в шоколаде в
коробке
</div>
<div className="caption_2"> 400</div>
</Link>
</div>
</div>
</div>
</main>
</>
);
};
export default Page1;

View File

@ -0,0 +1,35 @@
import {Link} from 'react-router-dom';
import BackArrow from '../components/BackArrow/BackArrow.jsx';
import logo from '../assets/logo.png';
const Page2 = () => {
return (
<>
<BackArrow/>
<>
<main className="container-fluid p-2">
<div className="text-center login_pannel">
<img className="logo_sidebar" src={logo} alt="logo"/>
<h2>Войдите или зарегистрируйтесь</h2>
<div className="input-group flex-nowrap width_input_mail">
<span className="input-group-text" id="addon-wrapping">@</span>
<input type="text" className="form-control" placeholder="Введите почту"
aria-label="Username" aria-describedby="addon-wrapping"/>
</div>
<div className="form-check">
<input className="form-check-input" type="checkbox" value="" id="flexCheckDefault"/>
<label className="form-check-label" htmlFor="flexCheckDefault">
<h2 className="h2_light">
Согласен на обработку <Link to="./page2.html">персональных данных</Link>
</h2>
</label>
</div>
</div>
</main>
</>
</>
);
};
export default Page2;

View File

@ -0,0 +1,69 @@
import Object1 from '../assets/object_1.png';
import BackArrow from '../components/BackArrow/BackArrow.jsx';
const Page3 = () => {
return (
<>
<main className="container main_pannel">
<ul className="nav nav-pills mb-3 justify-content-center" id="pills-tab" role="tablist">
<li className="nav-item" role="presentation">
<button className="nav-link active me-2" id="pills-home-tab" data-bs-toggle="pill"
data-bs-target="#pills-home"
type="button" role="tab" aria-controls="pills-home" aria-selected="true">
<h2>Корзина</h2></button>
</li>
<li className="nav-item" role="presentation">
<button className="nav-link" id="pills-profile-tab" data-bs-toggle="pill"
data-bs-target="#pills-profile"
type="button" role="tab" aria-controls="pills-profile" aria-selected="false"><h2>История
Заказов</h2></button>
</li>
</ul>
<div className="tab-content" id="pills-tabContent">
<div className="tab-pane fade show active" id="pills-home" role="tabpanel"
aria-labelledby="pills-home-tab"
tabIndex="0">
<div className="container table">
<div className="row">
<div className="col">
<img className="objects_basket" src={Object1} alt="object"/>
</div>
<div className="col">
<div className="caption_basket"> Букет из клубники 108. <br/>Набор из клубники в
шоколаде в коробке
</div>
</div>
<div className="col">
<div className="caption_basket_price"> 3000</div>
</div>
<div className="col">
<button className="btn btn-primary add_object-button w-100" type="submit">Перейти к
оплате
</button>
</div>
</div>
</div>
<BackArrow/>
</div>
<div className="tab-pane fade" id="pills-profile" role="tabpanel"
aria-labelledby="pills-profile-tab" tabIndex="0">
<div className="container table">
<div className="row">
<div className="col">
<img className="objects_basket" src={Object1} alt="object"/>
</div>
</div>
</div>
</div>
</div>
</main>
</>
);
};
export default Page3;

View File

@ -0,0 +1,28 @@
import {Link} from 'react-router-dom';
import object3 from '../assets/object_1.png';
const Page4 = () => {
return (
<>
<main className="container main_pannel2">
<div className="container view_object d-flex flex-column flex-md-row">
<div className="left-cell">
<img className="objects" src={object3} alt="object"/>
</div>
<div className="right-cell">
<h3>Букет из клубники 108. <br/>Набор из клубники в шоколаде в коробке</h3>
<div>
<h3 style={{fontSize: '24px', color: '#a2a2a2'}}>Итого:</h3>
<h3 className="price_object">3000</h3>
<Link to="page5.html">
<button type="button" className="btn btn-success btn-lg ">Добавить в корзину</button>
</Link>
</div>
</div>
</div>
</main>
</>
);
};
export default Page4;

View File

@ -0,0 +1,12 @@
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
build: {
sourcemap: true,
chunkSizeWarningLimit: 1024,
emptyOutDir: true,
},
});