Compare commits

...

2 Commits

Author SHA1 Message Date
94c04e0b85 Добавлена лаба 3 2023-11-30 21:18:37 +04:00
632d3ab999 Добавлены изменения 2023-11-30 21:17:52 +04:00
58 changed files with 11916 additions and 183 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,13 @@
{
"hash": "db561d3e",
"browserHash": "9eaa2515",
"optimized": {
"@popperjs/core": {
"src": "../../node_modules/@popperjs/core/lib/index.js",
"file": "@popperjs_core.js",
"fileHash": "440b4fd2",
"needsInterop": false
}
},
"chunks": {}
}

View File

@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@ -44,6 +44,7 @@ h1 { /*форматирование текста*/
margin-left: 28vw;
margin-top: 5vw;
font-weight: lighter;
max-width: 70%;
}
.table { /*таблица */
@ -134,7 +135,7 @@ h0 {
}
.btn_open {
background-image: url('open_sidebar.png');
background-image: url('../src/open_sidebar.png');
background-color: transparent;
background-size: cover;
position: fixed;
@ -218,7 +219,7 @@ h2 {
justify-content: space-between;
margin-bottom: 6vh;
margin-top: 6vh;
margin-left: 15vw;
/*margin-left: 15vw;*/
}
.right-cell {
@ -230,11 +231,13 @@ h2 {
}
.main_pannel2 {
height: 90vh; /* на весь экран */
height: 100vh; /* на весь экран */
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding-left: 25vw;
}
h3 {
@ -265,11 +268,13 @@ h3 {
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 {
@ -278,6 +283,11 @@ h3 {
border-color: #118500;
}
.col {
display: flex;
align-items: center;
justify-content: center;
}
@media (max-width: 1300px) {
.main_pannel {
@ -334,10 +344,6 @@ h3 {
visibility: hidden;
}
.input-group {
width: 100%;
}
.width_input_mail {
width: 90%;
}
@ -349,5 +355,14 @@ h3 {
.width_add_object {
width: 90%;
}
.input-group { /*подгон ширины под отсльаные*/
padding-right: 9vw;
}
.view_object {
padding-top: 1vh;
}
}

View File

@ -4,10 +4,10 @@
<meta charset="utf-8">
<title>Ульяновский кондитер</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
@ -24,23 +24,23 @@
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="./arrow_icon.png" alt="arrow_icon">
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./index.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="./test-delete.html" style="margin-left: 40px; color: black;">Адреса
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="./page2.html">
<img class="icon_top" src="./acc_icon.png" alt="acc_icon">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="./page5.html">
<img class="icon_top" src="./shop_icon.png" alt="shop_icon">
<a href="page5.html">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="./page2.html">
<img class="icon_top" src="./search_icon.png" alt="search_icon">
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
@ -53,7 +53,7 @@
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="./index.html">
<img class="logo_sidebar" src="./logo.png" alt="shop_icon">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
@ -77,10 +77,10 @@
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="./page3.html" style="text-decoration: none;">
<img class="vk" src="./whatsapp_icon.png" alt="vk">
<a href="page3.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="./vk_icon.png" alt="whatsapp">
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
@ -102,6 +102,15 @@
window.addEventListener('resize', checkMediaQuery);
</script>
<!--<script>-->
<!-- var name = localStorage.getItem('name');-->
<!-- var age = localStorage.getItem('age');-->
<!-- // Используйте значения на странице-->
<!-- document.getElementById('name_display').textContent = name;-->
<!-- document.getElementById('age_display').textContent = age;-->
<!--</script>-->
<main class="container main_pannel">
<h1>Клубника в шоколаде</h1>
@ -109,22 +118,22 @@
<div class="row">
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_1.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_1.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_2.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_2.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_3.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_3.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
@ -133,22 +142,22 @@
<div class="row">
<div class="col-4">
<a href="./page3.html" style="text-decoration: none;">
<img class="objects" src="./object_1.png" alt="object">
<a href="page3.html" style="text-decoration: none;">
<img class="objects" src="src/object_1.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_2.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_2.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_3.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_3.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
@ -157,22 +166,22 @@
<div class="row">
<div class="col-4">
<a href="./page3.html" style="text-decoration: none;">
<img class="objects" src="./object_1.png" alt="object">
<a href="page3.html" style="text-decoration: none;">
<img class="objects" src="src/object_1.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_2.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_2.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_3.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_3.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
@ -181,22 +190,22 @@
<div class="row">
<div class="col-4">
<a href="./page3.html" style="text-decoration: none;">
<img class="objects" src="./object_1.png" alt="object">
<a href="page3.html" style="text-decoration: none;">
<img class="objects" src="src/object_1.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_2.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_2.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>
</div>
<div class="col-4">
<a href="./page4.html" style="text-decoration: none;">
<img class="objects" src="./object_3.png" alt="object">
<a href="page4.html" style="text-decoration: none;">
<img class="objects" src="src/object_3.png" alt="object">
<div class="caption"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_2"> 400₽</div>
</a>

View File

@ -3,18 +3,18 @@
<meta charset="utf-8">
<title>Ульяновский кондитер</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<main class="container-fluid p-2">
<div class="text-center login_pannel">
<a href="./index.html">
<img class="back_arrow_icon " src="./back_arrow_icon.png" alt="back_arrow">
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="back_arrow">
</a>
<img class="logo_sidebar" src="./logo.png" alt="logo">
<img class="logo_sidebar" src="src/logo.png" alt="logo">
<h2>Войдите или зарегистрируйтесь</h2>
<div class="input-group flex-nowrap width_input_mail">
<span class="input-group-text" id="addon-wrapping">@</span>

View File

@ -3,17 +3,17 @@
<meta charset="utf-8">
<title>Добавить товар</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<main class="container-fluid p-2">
<div class="text-center add_object">
<a href="./index.html">
<img class="back_arrow_icon " src="./back_arrow_icon.png" alt="logo">
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="logo">
</a>
<h2>Добавить товар</h2>
@ -33,13 +33,31 @@
<div class="input-group mb-3 width_add_object">
<input type="file" class="form-control" id="inputGroupFile02">
<label class="input-group-text" for="inputGroupFile02">Upload</label>
</div>
<div class="text-center">
<button class="btn btn-primary add_object-button" type="submit">Добавить</button>
</div>
</div>
<!-- <script>-->
<!-- // Получаем ссылку на кнопку "Добавить"-->
<!-- var addButton = document.querySelector('.add_object-button');-->
<!-- // Добавляем обработчик события на клик по кнопке "Добавить"-->
<!-- addButton.addEventListener('click', function(event) {-->
<!-- // Получаем значения полей ввода-->
<!-- var name = document.getElementById('name_object').value;-->
<!-- var price = document.getElementById('price_object').value;-->
<!-- var count = document.getElementById('count_object').value;-->
<!-- // Сохраняем значения в localStorage-->
<!-- localStorage.setItem('name', name);-->
<!-- localStorage.setItem('price', price);-->
<!-- localStorage.setItem('count', count);-->
<!-- });-->
<!-- </script>-->
</main>
</body>

View File

@ -4,10 +4,10 @@
<meta charset="utf-8">
<title>(Название товара)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<header>
@ -20,23 +20,23 @@
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="./arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./index.html" style=" color: black;">Ульяновск</a>
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="index.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="./test-delete.html" style="margin-left: 40px; color: black;">Адреса
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="./page2.html">
<img class="icon_top" src="./acc_icon.png" alt="acc_icon">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="./page5.html">
<img class="icon_top" src="./shop_icon.png" alt="shop_icon">
<a href="page5.html">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="./page2.html">
<img class="icon_top" src="./search_icon.png" alt="search_icon">
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
@ -46,8 +46,8 @@
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="./index.html">
<img class="logo_sidebar" src="./logo.png" alt="shop_icon">
<a href="index.html">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
@ -68,10 +68,10 @@
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="./page3.html" style="text-decoration: none;">
<img class="vk" src="./whatsapp_icon.png" alt="vk">
<a href="page3.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="./vk_icon.png" alt="whatsapp">
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
@ -96,14 +96,14 @@
<main class="container main_pannel2">
<div class="container view_object d-flex flex-column flex-md-row">
<div class="left-cell">
<img class="objects" src="./object_3.png" alt="object">
<img class="objects" src="src/object_3.png" alt="object">
</div>
<div class="right-cell">
<h3>Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</h3>
<div>
<h3 style="font-size: 24px; color: #a2a2a2; ">Итого:</h3>
<h3 class="price_object">3000₽</h3>
<a href="./page5.html">
<a href="page5.html">
<button type="button" class="btn btn-success btn-lg ">Добавить в корзину</button>
</a>
</div>

View File

@ -4,10 +4,10 @@
<meta charset="UTF-8">
<title>Корзина</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
@ -22,23 +22,23 @@
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="./arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./index.html" style=" color: black;">Ульяновск</a>
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./inddex.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="./test-delete.html" style="margin-left: 40px; color: black;">Адреса
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="./page2.html">
<img class="icon_top" src="./acc_icon.png" alt="acc_icon">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="./page5.html">
<img class="icon_top" src="./shop_icon.png" alt="shop_icon">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="./page2.html">
<img class="icon_top" src="./search_icon.png" alt="search_icon">
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
@ -48,8 +48,8 @@
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="./inex.html">
<img class="logo_sidebar" src="./logo.png" alt="shop_icon">
<a href="index.html">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
@ -70,10 +70,10 @@
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="./page3.html" style="text-decoration: none;">
<img class="vk" src="./whatsapp_icon.png" alt="vk">
<a href="page3.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="./vk_icon.png" alt="whatsapp">
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
@ -98,7 +98,7 @@
<ul class="nav nav-pills mb-3 justify-content-center" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="pills-home-tab" data-bs-toggle="pill" data-bs-target="#pills-home"
<button class="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 class="nav-item" role="presentation">
@ -113,7 +113,7 @@
<div class="container table">
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_1.png" alt="object">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
@ -129,7 +129,7 @@
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_2.png" alt="object">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
@ -144,7 +144,7 @@
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_3.png" alt="object">
<img class="objects_basket" src="src/object_3.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
@ -159,7 +159,7 @@
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_2.png" alt="object">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
@ -174,7 +174,7 @@
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_1.png" alt="object">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
@ -188,20 +188,23 @@
</div>
</div>
</div>
<a href="./index.html">
<img class="back_arrow_icon " src="./back_arrow_icon.png" alt="logo">
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="logo">
</a>
</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">
<div class="container table">
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_1.png" alt="object">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено</button>
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
@ -210,13 +213,15 @@
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_2.png" alt="object">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено</button>
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
@ -224,13 +229,15 @@
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_1.png" alt="object">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено</button>
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
@ -238,13 +245,15 @@
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="./object_3.png" alt="object">
<img class="objects_basket" src="src/object_3.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</div>
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено</button>
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
@ -252,6 +261,7 @@
</div>
</div>
</div>
</div>
</main>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 209 KiB

View File

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 163 KiB

View File

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,29 +4,14 @@
<meta charset="UTF-8">
<title>dasdasd</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./style.css">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasScrolling"
aria-controls="offcanvasScrolling">Enable body scrolling
</button>
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasScrollingLabel">Offcanvas with body scrolling</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<p>Try scrolling the rest of the page to see this option in action.</p>
</div>
</div>
</body>
</html>

View File

@ -7,7 +7,8 @@ export default defineConfig({
input: {
main: resolve(__dirname, 'index.html'),
page2: resolve(__dirname, 'page2.html'),
page3: resolve(__dirname, 'page3.html'),
page3: resolve(__dirname, 'page_edit.html'),
page4: resolve(__dirname, 'page4.html'),
},
},
},

View File

@ -0,0 +1,20 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": "airbnb-base",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"quotes": "off",
"indent": "off",
"no-console": "off",
"no-use-before-define": "off",
"no-alert": "off",
"no-restricted-globals": "off",
"quote-props": "off"
}
}

45
3_laba_IP_project/.gitignore vendored Normal file
View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db
# Ignore dist
dist/

View File

@ -0,0 +1,393 @@
.top_pannel { /*отступ слева в top_pannel*/
margin-left: 20vw;
}
.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;
}
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
}
.icon-container { /* сдвиг top_pannel*/
margin-right: 5vw;
}
.text_containter { /* сдвиг top_pannel*/
margin-left: 5vw;
}
.list_sidebar { /* список sidebar*/
top: 10vh;
position: absolute;
}
header nav a:hover { /* подчеркивание текста top_pannel*/
text-decoration: underline;
}
.social_network img { /*иконки соц сетей*/
margin-top: 1vh;
height: 3.5vh;
margin-right: 1vw;
}
.bottom_sidebar { /*bottom sidebar*/
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0vh;
flex-direction: column;
margin-top: 60vh;
}
.arrow_and_cities { /*чтобы все было на одном уровне, стрелка и город top_pannel*/
display: flex;
align-items: center;
}
h0 {
font-size: 2vh;
}
.btn_open {
background-image: url('../src/open_sidebar.png');
background-color: transparent;
background-size: cover;
position: fixed;
margin-top: 0vh;
margin-left: 3vh;
border: none;
height: 4vh;
width: 3vw;
}
.btn:hover {
background-color: transparent;
}
.btn-close {
position: absolute;
top: 5vh;
right: 5vh;
visibility: hidden;
}
.width_input_mail { /*ширина панели для вводы почты*/
width: 30%;
}
.back_arrow_icon { /*стрелка назад*/
height: 4vh;
position: absolute;
top: 4vh;
left: 3vw;
}
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; /* Убрать подчеркивание у кнопок */
}
@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;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,185 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Ульяновский кондитер</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<header>
<nav class="navbar navbar-expand-md navbar-white fixed-top">
<div class="btn_open_sidebar">
<button class="btn_open btn-primary" type="button" data-bs-toggle="offcanvas"
data-bs-target="#offcanvasScrolling" aria-controls="offcanvasScrolling"></button>
</div>
<div class="container-fluid top_pannel">
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./index.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="page3.html">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="./index.html">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="list_sidebar">
<div class="list_font">
<ul>
<li>Клубника в шоколаде</li>
<li>Бананы в шоколаде</li>
<li>Конфеты</li>
<li>Шоколад</li>
<li>Медианты</li>
</ul>
</div>
</div>
<div class="bottom_sidebar">
<h0>8 800 700 34 21
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="page-admin.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
</div>
<script>
function checkMediaQuery() {
var sidebar = document.querySelector('.offcanvas');
var button = document.querySelector('.btn-primary');
if (window.matchMedia('(max-width: 1300px)').matches) {
sidebar.classList.remove('show');
button.setAttribute('aria-expanded', 'false');
} else {
sidebar.classList.add('show');
button.setAttribute('aria-expanded', 'true');
}
}
window.addEventListener('load', checkMediaQuery);
window.addEventListener('resize', checkMediaQuery);
</script>
<main class="container main_pannel">
<h1>Клубника в шоколаде</h1>
<div id="my-id-for-text" class="container table">
</div>
</main>
<div id="items-update" class="modal fade" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog">
<form id="items-form" class="needs-validation" novalidate>
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="items-update-title"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center">
<img id="image-preview" src="https://via.placeholder.com/200" class="rounded"
alt="placeholder">
</div>
<input id="items-line-id" type="number" hidden>
<div class="mb-2 ">
<label for="item" class="form-label">Название</label>
<select id="item" class="form-select" name="selected" required>
</select>
</div>
<div class="mb-2 ">
<label class="form-label" for="price">Цена</label>
<input id="price" name="price" class="form-control" type="number" placeholder="Цена" min="0"
step="100" required>
</div>
<div class="mb-2 ">
<label class="form-label" for="price">Количество</label>
<input id="count" name="count" class="form-control" type="number" placeholder="Количество"
min="0" step="1" required>
</div>
<div class=" mb-3 ">
<label class="form-label" for="image">Изображение</label>
<input id="image" type="file" name="image" class="form-control" accept="image/*" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
</div>
</div>
</form>
</div>
</div>
<script type="module">
import validation from "./js/validation";
import {linesFormOnIndex} from "./js/lines";
import {linesForm} from "./js/lines";
document.addEventListener('DOMContentLoaded', () => {
validation();
linesFormOnIndex();
linesForm();
});
</script>
</body>
</html>

View File

@ -0,0 +1,59 @@
// Модуль для работы с модальным окном
// импорт компонента Modal из bootstrap
import {Modal} from "bootstrap";
import {cntrls, imagePlaceholder} from "./lines-ui";
// поиск модального окна на странице
const modal = document.getElementById("items-update");
// если он найден, то создается экземпляр компонента Modal
// для программного управления модальным окном
const myModal = modal ? new Modal(modal, {}) : null;
// поиск тега с заголовком модального кона для его смены
const modalTitle = document.getElementById("items-update-title");
// обнуление значений модального окна, т. к.
// используется одно окно для всех операций
function resetValues() {
cntrls.lineId.value = "";
cntrls.itemsType.value = "";
cntrls.price.value = parseFloat(0).toFixed(2);
cntrls.count.value = 0;
cntrls.image.value = "";
cntrls.imagePreview.src = imagePlaceholder;
}
// функция для показа модального окна
// перед показом происходит заполнение формы для редактирования
// если объект item не пуст
export function showUpdateModal(item) {
modalTitle.innerHTML = item === null ? "Добавить" : "Изменить";
console.info(item);
if (item) {
cntrls.lineId.value = item.id;
cntrls.itemsType.value = item.itemsId;
cntrls.price.value = item.price;
cntrls.count.value = item.count;
// заполнение превью
// Если пользователь выбрал изображение, то оно загружается
// в тэг image с id image - preview
// иначе устанавливается заглушка, адрес которой указан в imagePlaceholder
cntrls.imagePreview.src = item.image ? item.image : imagePlaceholder;
} else {
resetValues();
}
myModal.show();
}
// функция для скрытия модального окна
export function hideUpdateModal() {
resetValues();
// удаление класса was-validated для скрытия результатов валидации
cntrls.form.classList.remove("was-validated");
myModal.hide();
}

View File

@ -0,0 +1,105 @@
// модуль для работы с REST API сервера
// адрес сервера
const serverUrl = "http://localhost:8081";
// функция возвращает объект нужной структуры для отправки на сервер
function createLineObject(item, price, count, image) {
return {
itemsId: item,
price: parseFloat(price).toFixed(2),
count,
image,
};
}
// обращение к серверу для получения всех типов товара (get)
export async function getAllItemTypes() {
const response = await fetch(`${serverUrl}/items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для получения всех записей (get)
export async function getAllLines() {
const response = await fetch(`${serverUrl}/lines?_expand=items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для получения записи по первичному ключу (id) (get)
// id передается в качестве части пути URL get-запроса
export async function getLine(id) {
const response = await fetch(`${serverUrl}/lines/${id}?_expand=items`);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для создания записи (post)
// объект отправляется в теле запроса (body)
export async function createLine(item, price, count, image) {
const itemObject = createLineObject(item, price, count, image);
const options = {
method: "POST",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines`, options);
if (!response.ok) {
throw response.statusText;
}
return response.json();
}
// обращение к серверу для обновления записи по id (put)
// объект отправляется в теле запроса (body)
// id передается в качестве части пути URL get-запроса
export async function updateLine(id, item, price, count, image) {
const itemObject = createLineObject(item, price, count, image);
const options = {
method: "PUT",
body: JSON.stringify(itemObject),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
await response.json();
location.reload();
}
// обращение к серверу для удаления записи по id (delete)
// id передается в качестве части пути URL get-запроса
export async function deleteLine(id) {
const options = {
method: "DELETE",
};
const response = await fetch(`${serverUrl}/lines/${id}`, options);
if (!response.ok) {
throw response.statusText;
}
await response.json();
location.reload();
}

View File

@ -0,0 +1,163 @@
// модуль для работы с элементами управления
// объект для удобного получения элементов
// при обращении к атрибуту объекта вызывается
// нужная функция для поиска элемента
export const cntrls = {
container: document.getElementById("my-id-for-text"),
button: document.getElementById("items-add"),
table: document.querySelector("#items-table tbody"),
form: document.getElementById("items-form"),
lineId: document.getElementById("items-line-id"),
itemsType: document.getElementById("item"),
name: document.getElementById("name"),
price: document.getElementById("price"),
count: document.getElementById("count"),
image: document.getElementById("image"),
imagePreview: document.getElementById("image-preview"),
};
// Дефолтное превью
export const imagePlaceholder = "https://via.placeholder.com/200";
// функция создает тег option для select
// <option value="" selected>name</option>
export function createItemsOption(name, value = "", isSelected = false) {
const option = document.createElement("option");
option.value = value || "";
option.selected = isSelected;
option.text = name;
return option;
}
// функция создает ссылку (a) для таблицы
// содержимое тега a заполняется необходимой иконкой (icon)
// при нажатии вызывается callback
// ссылка "оборачивается" тегом td
// <td><a href="#" onclick="callback()"><i class="fa-solid icon"></i></a></td>
function createTableAnchor(icon, callback) {
const i = document.createElement("i");
i.classList.add("fa-solid", icon);
const a = document.createElement("a");
a.href = "#";
a.appendChild(i);
a.onclick = (event) => {
// чтобы в URL не добавлялась решетка
event.preventDefault();
event.stopPropagation();
callback();
};
const td = document.createElement("td");
td.appendChild(a);
return td;
}
// функция создает колонку таблицы с текстом value
// <td>value</td>
function createTableColumn(value) {
const td = document.createElement("td");
td.textContent = value;
return td;
}
export function createTableRow(item, index, editCallback, editPageCallback, deleteCallback) {
const rowNumber = document.createElement("th");
rowNumber.scope = "row";
rowNumber.textContent = index + 1;
const row = document.createElement("tr");
row.id = `line-${item.id}`;
row.appendChild(rowNumber);
row.appendChild(createTableColumn(item.items.name));
row.appendChild(createTableColumn(parseFloat(item.price).toFixed(2)));
row.appendChild(createTableColumn(item.count));
// редактировать в модальном окне
row.appendChild(createTableAnchor("fa-pencil", editCallback));
// удаление
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
return row;
}
export function createTableRowOnIndex(item, index, editCallback, editPageCallback, deleteCallback) {
console.log(item)
const img = document.createElement("img");
img.classList.add("objects");
img.src = item.image;
img.alt = "object";
img.style.display = "block";
img.style.marginLeft = "auto";
img.style.marginRight = "auto";
const name = document.createElement("div");
name.classList.add("caption");
name.innerText = item.items.name
name.style.padding = "0px";
name.style.marginBottom = "-10px"
const count = document.createElement("div");
count.classList.add("caption_count");
count.innerText = `${item.count} ${item.count == 1 ? 'штука' : item.count > 1 && item.count < 5 ? 'штуки' : 'штук'}`;
count.style.padding = "0px";
count.style.marginBottom = "-10px";
const price = document.createElement("div");
price.classList.add("caption_2");
price.innerText = parseInt(item.price) + "₽";
price.style.padding = "0";
const a = document.createElement("a");
a.href = "page4.html"
a.style.textDecoration = "none"
a.appendChild(img);
a.appendChild(name);
a.appendChild(count);
a.appendChild(price);
const buttonsContainer = document.createElement("div");
buttonsContainer.style.display = "flex";
buttonsContainer.style.justifyContent = "center";
const editButton = createTableAnchor("fa-pencil", editCallback);
const deleteButton = createTableAnchor("fa-trash", deleteCallback);
deleteButton.style.marginLeft = "1.2vw"
buttonsContainer.appendChild(editButton);
buttonsContainer.appendChild(deleteButton);
buttonsContainer.style.marginTop = "-6px"
buttonsContainer.style.marginBottom = "10px"
a.appendChild(buttonsContainer);
const div = document.createElement("div");
div.classList.add("col");
div.classList.add("clear-float");
div.appendChild(a);
const uniqueId = `div-${index + 1}`;
div.id = uniqueId;
div.style.float = "left";
div.style.width = "33.33%";
div.style.boxSizing = "border-box";
return div;
}

View File

@ -0,0 +1,398 @@
// модуль с логикой
import {hideUpdateModal, showUpdateModal} from "./lines-modal";
import {createLine, deleteLine, getAllItemTypes, getAllLines, getLine, updateLine,} from "./lines-rest-api";
import {cntrls, createItemsOption, createTableRow, createTableRowOnIndex, imagePlaceholder,} from "./lines-ui";
async function drawItemsSelect() {
// вызов метода REST API для получения списка типов товаров
const data = await getAllItemTypes();
// очистка содержимого select
// удаляется все, что находится между тегами <select></select>
// но не атрибуты
cntrls.itemsType.innerHTML = "";
// пустое значение
cntrls.itemsType.appendChild(createItemsOption("Выберите значение", "", true));
// цикл по результату ответа от сервера
// используется лямбда-выражение
// (item) => {} аналогично function(item) {}
data.forEach((item) => {
cntrls.itemsType.appendChild(createItemsOption(item.name, item.id));
});
}
async function drawLinesTable() {
console.info("Try to load data");
if (!cntrls.table) {
return;
}
// вызов метода REST API для получения всех записей
const data = await getAllLines();
// очистка содержимого table
// удаляется все, что находится между тегами <table></table>
// но не атрибуты
cntrls.table.innerHTML = "";
// цикл по результату ответа от сервера
// используется лямбда-выражение
// (item, index) => {} аналогично function(item, index) {}
data.forEach((item, index) => {
cntrls.table.appendChild(
createTableRow(
item,
index,
// функции передаются в качестве параметра
// это очень удобно, так как аргументы функций доступны только
// в данном месте кода и не передаются в сервисные модули
() => showUpdateModal(item),
() => location.assign(`page-admin.html?id=${item.id}`),
() => removeLine(item.id),
),
);
});
}
async function drawLinesTableOnIndex() {
console.info("Try to load data On Index");
if (!cntrls.container) {
return;
}
// вызов метода REST API для получения всех записей
const data = await getAllLines();
// очистка содержимого table
// удаляется все, что находится между тегами <table></table>
// но не атрибуты
cntrls.container.innerHTML = "";
// цикл по результату ответа от сервера
// используется лямбда-выражение
// (item, index) => {} аналогично function(item, index) {}
data.forEach((item, index) => {
cntrls.container.appendChild(
createTableRowOnIndex(
item,
index,
// функции передаются в качестве параметра
// это очень удобно, так как аргументы функций доступны только
// в данном месте кода и не передаются в сервисные модули
() => showUpdateModal(item),
() => location.assign(`index.html?id=${item.id}`),
() => removeLine(item.id),
),
);
});
}
async function addLine(item, price, count, image) {
console.info("Try to add item");
// вызов метода REST API для добавления записи
const data = await createLine(item, price, count, image);
console.info("Added");
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
async function editLine(id, item, price, count, image) {
console.info("Try to update item");
// вызов метода REST API для обновления записи
const data = await updateLine(id, item, price, count, image);
console.info("Updated");
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
async function removeLine(id) {
if (!confirm("Вы точно хотите удалить этот товар?")) {
console.info("Canceled");
return;
}
console.info("Try to remove item");
// вызов метода REST API для удаления записи
const data = await deleteLine(id);
console.info(data);
// загрузка и заполнение table
drawLinesTable();
}
// функция для получения содержимого файла в виде base64 строки
// https://ru.wikipedia.org/wiki/Base64
async function readFile(file) {
const reader = new FileReader();
// создание Promise-объекта для использования функции
// с помощью await (асинхронно) без коллбэков (callback)
// https://learn.javascript.ru/promise
return new Promise((resolve, reject) => {
// 2. "Возвращаем" содержимое когда файл прочитан
// через вызов resolve
// Если не использовать Promise, то всю работу по взаимодействию
// с REST API пришлось бы делать в обработчике (callback) функции
// onloadend
reader.onloadend = () => {
const fileContent = reader.result;
// Здесь могла бы быть работа с REST API
// Чтение заканчивает выполняться здесь
resolve(fileContent);
};
// 3. Возвращаем ошибку
reader.onerror = () => {
// Или здесь в случае ошибки
reject(new Error("oops, something went wrong with the file reader."));
};
// Шаг 1. Сначала читаем файл
// Чтение начинает выполняться здесь
reader.readAsDataURL(file);
});
}
// функция для обновления блока с превью выбранного изображения
async function updateImagePreview() {
// получение выбранного файла
// возможен выбор нескольких файлов, поэтому необходимо получить только первый
const file = cntrls.image.files[0];
// чтение содержимого файла в виде base64 строки
const fileContent = await readFile(file);
console.info("base64 ", fileContent);
// обновление атрибута src для тега img с id image-preview
cntrls.imagePreview.src = fileContent;
}
// Функция для обработки создания и редактирования элементов таблицы через модальное окно
// Если хотите делать через страницу, то удалите эту функцию
export function linesForm() {
console.info("linesForm");
// загрузка и заполнение select со списком товаров
drawItemsSelect();
// загрузка и заполнение table
drawLinesTable();
// Вызов функции обновления превью изображения при возникновении
// события oncahnge в тэге input с id image
cntrls.image.addEventListener("change", () => updateImagePreview());
// обработчик события нажатия на кнопку для показа модального окна
cntrls.button.addEventListener("click", () => showUpdateModal(null));
// обработчик события отправки формы
// возникает при нажатии на кнопку (button) с типом submit
// кнопка должна находится внутри тега form
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
// Получение выбранного пользователем изображения в виде base64 строки
// Если пользователь ничего не выбрал, то не нужно сохранять в БД
// дефолтное изображение
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
// получение id строки для редактирования
// это значение содержится в скрытом input
const currentId = cntrls.lineId.value;
// если значение id не задано,
// то необходимо выполнить добавление записи
// иначе обновление записи
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
}
// после выполнения добавления/обновления модальное окно скрывается
hideUpdateModal();
});
}
export async function linesFormOnIndex() {
console.info("linesFormOnIndex");
await drawItemsSelect();
await drawLinesTableOnIndex();
// обработчик события отправки формы
// возникает при нажатии на кнопку (button) с типом submit
// кнопка должна находится внутри тега form
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
// Получение выбранного пользователем изображения в виде base64 строки
// Если пользователь ничего не выбрал, то не нужно сохранять в БД
// дефолтное изображение
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
// получение id строки для редактирования
// это значение содержится в скрытом input
const currentId = cntrls.lineId.value;
// если значение id не задано,
// то необходимо выполнить добавление записи
// иначе обновление записи
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
}
// после выполнения добавления/обновления модальное окно скрывается
hideUpdateModal();
});
}
// Функция для обработки создания и редактирования элементов таблицы через страницу page-admin.html
// Если хотите делать через модальное окно, то удалите эту функцию
export async function linesPageForm() {
console.info("linesPageForm");
// загрузка и заполнение select со списком товаров
drawItemsSelect();
// func1 = (id) => {} аналогично function func1(id) {}
const goBack = () => location.assign("/index.html");
// Вызов функции обновления превью изображения при возникновении
// события onchange в тэге input с id image
cntrls.image.addEventListener("change", () => updateImagePreview());
// получение параметров GET-запроса из URL
// параметры перечислены после символа ? (?id=1&color=black&...)
const urlParams = new URLSearchParams(location.search);
// получение значения конкретного параметра (id)
// указан только при редактировании
const currentId = urlParams.get("id");
// если id задан
if (currentId) {
try {
// вызов метода REST API для получения записи по первичному ключу(id)
const line = await getLine(currentId);
// заполнение формы для редактирования
cntrls.price.value = line.price;
cntrls.count.value = line.count;
// заполнение превью
// Если пользователь выбрал изображение, то оно загружается
// в тэг image с id image - preview
// иначе устанавливается заглушка, адрес которой указан в imagePlaceholder
cntrls.imagePreview.src = line.image ? line.image : imagePlaceholder;
} catch {
// в случае ошибки происходит возврат к index
goBack();
}
}
// обработчик события отправки формы
// возникает при нажатии на кнопку (button) с типом submit
// кнопка должна находится внутри тега form
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
// Получение выбранного пользователем изображения в виде base64 строки
// Если пользователь ничего не выбрал, то не нужно сохранять в БД
// дефолтное изображение
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
// если значение параметра запроса не задано,
// то необходимо выполнить добавление записи
// иначе обновление записи
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.price.value,
cntrls.count.value,
imageBase64,
);
}
// возврат к странице index
goBack();
});
}

View File

@ -0,0 +1,25 @@
// модуль используется для валидации форма на странице
function validation() {
// поиск всех форма с классом .needs-validation
const forms = document.querySelectorAll("form.needs-validation");
for (let i = 0; i < forms.length; i += 1) {
const form = forms[i];
// для каждой формы добавляется обработчик события отправки
form.addEventListener("submit", (event) => {
// если форма не прошла валидацию
// то выключить стандартное действие
if (!form.checkValidity()) {
event.preventDefault();
// предотвращает распространение preventDefault
// на другие объекты
event.stopPropagation();
}
// добавляет к форме класс was-validated
form.classList.add("was-validated");
});
}
}
export default validation;

View File

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

7950
3_laba_IP_project/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
{
"name": "int-prog",
"version": "1.0.0",
"type": "module",
"scripts": {
"vite": "vite",
"serve": "http-server -p 3000 ./dist/",
"build": "vite build",
"rest": "json-server --watch data.json -p 8081",
"dev": "npm-run-all --parallel rest vite",
"prod": "npm-run-all build --parallel serve rest"
},
"dependencies": {
"bootstrap": "5.3.2",
"@fortawesome/fontawesome-free": "6.4.2"
},
"devDependencies": {
"vite": "4.4.9",
"eslint": "8.50.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.28.1",
"http-server": "14.1.1",
"json-server": "0.17.4",
"npm-run-all": "4.1.5"
}
}

View File

@ -0,0 +1,68 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Добавить товар</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<main class="container-fluid p-2">
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="logo">
</a>
<form id="items-form" class="needs-validation" novalidate>
<div class="text-center add_object">
<h2>Добавить товар</h2>
<div class="text-center">
<img id="image-preview" src="https://via.placeholder.com/200" class="rounded"
alt="placeholder">
</div>
<div class="mb-2 width_add_object">
<!-- <label for="item" class="form-label">Название</label>-->
<select id="item" class="form-select" name="selected" required>
</select>
</div>
<div class="mb-2 width_add_object">
<!-- <label class="form-label" for="price">Цена</label>-->
<input id="price" name="price" class="form-control" type="number" placeholder="Цена" min="0" step="100"
required>
</div>
<div class="mb-2 width_add_object">
<!-- <label class="form-label" for="price">Количество</label>-->
<input id="count" name="count" class="form-control" type="number" placeholder="Количество" min="0"
step="1" required>
</div>
<div class=" mb-3 width_add_object">
<!-- <label class="form-label" for="image">Изображение</label>-->
<input id="image" type="file" name="image" class="form-control" accept="image/*" required>
</div>
<div class="text-center">
<button class="btn btn-primary add_object-button" type="submit">Добавить</button>
</div>
</div>
</form>
</main>
<script type="module">
import validation from "./js/validation";
import {linesPageForm} from "./js/lines"
document.addEventListener('DOMContentLoaded', () => {
validation();
linesPageForm();
});
</script>
</body>
</html>

View File

@ -0,0 +1,95 @@
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Моя страница</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="./css/style.css">
</head>
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="back_arrow">
</a>
<body class="h-100 d-flex flex-column">
<main class="container-fluid d-flex flex-column justify-content-center align-items-center" style="margin-top: 20vh">
<div class="btn-group" role="group">
<button id="items-add" class="btn btn-info">Добавить товар (диалог)</button>
<a class="btn btn-success" href="/page-admin.html">Добавить товар (страница)</a>
</div>
<div>
<table id="items-table" class="table table-striped">
<thead>
<th scope="col"></th>
<th scope="col" class="w-25">Товар</th>
<th scope="col" class="w-25">Цена</th>
<th scope="col" class="w-25">Количество</th>
</thead>
<tbody></tbody>
</table>
</div>
</main>
<div id="items-update" class="modal fade" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog ">
<form id="items-form" class="needs-validation" novalidate>
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="items-update-title"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center">
<img id="image-preview" src="https://via.placeholder.com/200" class="rounded rounded-circle"
alt="placeholder">
</div>
<input id="items-line-id" type="number" hidden>
<div class="mb-2">
<label for="item" class="form-label">Товары</label>
<select id="item" class="form-select" name="selected" required>
</select>
</div>
<div class="mb-2">
<label class="form-label" for="price">Цена</label>
<input id="price" name="price" class="form-control" type="number" value="0.00" min="1000.00"
step="0.50" required>
</div>
<div class="mb-2">
<label class="form-label" for="count">Количество</label>
<input id="count" name="count" class="form-control" type="number" value="0" min="1" step="1"
required>
</div>
<div class="mb-2">
<label class="form-label" for="image">Изображение</label>
<input id="image" type="file" name="image" class="form-control" accept="image/*">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
</div>
</div>
</form>
</div>
</div>
<script type="module">
import validation from "./js/validation";
import {linesForm} from "./js/lines";
document.addEventListener('DOMContentLoaded', () => {
validation();
linesForm();
});
</script>
</body>
</html>

View File

@ -0,0 +1,36 @@
<html lang="ru" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<title>Ульяновский кондитер</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<main class="container-fluid p-2">
<div class="text-center login_pannel">
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="back_arrow">
</a>
<img class="logo_sidebar" src="src/logo.png" alt="logo">
<h2>Войдите или зарегистрируйтесь</h2>
<div class="input-group flex-nowrap width_input_mail">
<span class="input-group-text" id="addon-wrapping">@</span>
<input type="text" class="form-control" placeholder="Введите почту" aria-label="Username"
aria-describedby="addon-wrapping">
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
<h2 class="h2_light">
Согласен на обработку <a href="./page2.html">персональных данных</a>
</h2>
</label>
</input>
</div>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,267 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Корзина</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<header>
<nav class="navbar navbar-expand-md navbar-white fixed-top">
<div class="btn_open_sidebar">
<button class="btn_open btn-primary" type="button" data-bs-toggle="offcanvas"
data-bs-target="#offcanvasScrolling" aria-controls="offcanvasScrolling"></button>
</div>
<div class="container-fluid top_pannel">
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="./inddex.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="./page3.html">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="index.html">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="list_sidebar">
<div class="list_font">
<ul>
<li>Клубника в шоколаде</li>
<li>Бананы в шоколаде</li>
<li>Конфеты</li>
<li>Шоколад</li>
<li>Медианты</li>
</ul>
</div>
</div>
<div class="bottom_sidebar">
<h0>8 800 700 34 21
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="page-admin.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
</div>
<script>
function checkMediaQuery() {
var sidebar = document.querySelector('.offcanvas');
var button = document.querySelector('.btn-primary');
if (window.matchMedia('(max-width: 1300px)').matches) {
sidebar.classList.remove('show');
button.setAttribute('aria-expanded', 'false');
} else {
sidebar.classList.add('show');
button.setAttribute('aria-expanded', 'true');
}
}
window.addEventListener('load', checkMediaQuery);
window.addEventListener('resize', checkMediaQuery);
</script>
<main class="container main_pannel">
<ul class="nav nav-pills mb-3 justify-content-center" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="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 class="nav-item" role="presentation">
<button class="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 class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab"
tabindex="0">
<div class="container table">
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<div class="caption_basket_price"> 3000₽</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Перейти к оплате</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<div class="caption_basket_price"> 3000₽</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Перейти к оплате</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_3.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<div class="caption_basket_price"> 3000₽</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Перейти к оплате</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<div class="caption_basket_price"> 3000₽</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Перейти к оплате</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<div class="caption_basket_price"> 3000₽</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Перейти к оплате</button>
</div>
</div>
</div>
<a href="index.html">
<img class="back_arrow_icon " src="src/back_arrow_icon.png" alt="logo">
</a>
</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">
<div class="container table">
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_2.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_1.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
</div>
</div>
<div class="row">
<div class="col">
<img class="objects_basket" src="src/object_3.png" alt="object">
</div>
<div class="col ">
<div class="caption_basket"> Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке
</div>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit" disabled>Доставлено
</button>
</div>
<div class="col">
<button class="btn btn-primary add_object-button w-100" type="submit">Оставить отзыв</button>
</div>
</div>
</div>
</div>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>(Название товара)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="h-100 d-flex flex-column">
<header>
<nav class="navbar navbar-expand-md navbar-white fixed-top">
<div class="btn_open_sidebar">
<button class="btn_open btn-primary" type="button" data-bs-toggle="offcanvas"
data-bs-target="#offcanvasScrolling" aria-controls="offcanvasScrolling"></button>
</div>
<div class="container-fluid top_pannel">
<div class="navbar-collapse collapse justify-content-start" id="navbarNav">
<div class="navbar-nav text_containter">
<div class="arrow_and_cities">
<img class="icon_top" src="src/arrow_icon.png" alt="arrow_icon">
<a class="nav-link " href="index.html" style=" color: black;">Ульяновск</a>
</div>
<a class="nav-link adress" href="page-edit.html" style="margin-left: 40px; color: black;">Адреса
магазинов</a>
</div>
</div>
<div class="navbar-collapse collapse justify-content-end " id="navbarNav1">
<div class="navbar-nav icon-container">
<a href="page2.html">
<img class="icon_top" src="src/acc_icon.png" alt="acc_icon">
</a>
<a href="page5.html">
<img class="icon_top" src="src/shop_icon.png" alt="shop_icon">
</a>
<a href="page2.html">
<img class="icon_top" src="src/search_icon.png" alt="search_icon">
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="offcanvas offcanvas-start show" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1"
id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
<div class="offcanvas-header">
<a href="index.html">
<img class="logo_sidebar" src="src/logo.png" alt="shop_icon">
</a>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="list_sidebar">
<div class="list_font">
<ul>
<li>Клубника в шоколаде</li>
<li>Бананы в шоколаде</li>
<li>Конфеты</li>
<li>Шоколад</li>
<li>Медианты</li>
</ul>
</div>
</div>
<div class="bottom_sidebar">
<h0>8 800 700 34 21
<div class="take_order" style="color: #25e000;">Сделать заказ</div>
</h0>
<div class="social_network">
<a href="page3.html" style="text-decoration: none;">
<img class="vk" src="src/whatsapp_icon.png" alt="vk">
</a>
<img class="whatsapp" src="src/vk_icon.png" alt="whatsapp">
</div>
</div>
</div>
</div>
<script>
function checkMediaQuery() {
var sidebar = document.querySelector('.offcanvas');
var button = document.querySelector('.btn-primary');
if (window.matchMedia('(max-width: 1300px)').matches) {
sidebar.classList.remove('show');
button.setAttribute('aria-expanded', 'false');
} else {
sidebar.classList.add('show');
button.setAttribute('aria-expanded', 'true');
}
}
window.addEventListener('load', checkMediaQuery);
window.addEventListener('resize', checkMediaQuery);
</script>
<main class="container main_pannel2">
<div class="container view_object d-flex flex-column flex-md-row">
<div class="left-cell">
<img class="objects" src="src/object_3.png" alt="object">
</div>
<div class="right-cell">
<h3>Букет из клубники 108. <br>Набор из клубники в шоколаде в коробке</h3>
<div>
<h3 style="font-size: 24px; color: #a2a2a2; ">Итого:</h3>
<h3 class="price_object">3000₽</h3>
<a href="page5.html">
<button type="button" class="btn btn-success btn-lg ">Добавить в корзину</button>
</a>
</div>
</div>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,21 @@
### Окружение
В VSCode необходимо установить плагин (расширение) ESLint:
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
ESLint уже настроен (см. конфиг .eslintrc.json), но для справки можно почитать материал по ссылке
https://www.digitalocean.com/community/tutorials/linting-and-formatting-with-eslint-in-vs-code
### Установка зависимостей
npm install
### Запуск в режиме разработки
npm run dev
### Запуск продуктовой версии (production)
npm run prod

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,18 @@
import {resolve} from "path";
// eslint-disable-next-line import/no-extraneous-dependencies
import {defineConfig} from "vite";
export default defineConfig({
build: {
sourcemap: true,
emptyOutDir: true,
rollupOptions: {
input: {
main: resolve(__dirname, "index.html"),
page2: resolve(__dirname, "page2.html"),
page3: resolve(__dirname, "page3.html"),
page4: resolve(__dirname, "page4.html"),
},
},
},
});

6
package-lock.json generated Normal file
View File

@ -0,0 +1,6 @@
{
"name": "IP_labs",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}