начало положено

This commit is contained in:
a.puchkina 2024-06-04 23:38:20 +04:00
parent 1869d7ac60
commit efc468e209
80 changed files with 839 additions and 339 deletions

14
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"configurations": [
{
"type": "java",
"name": "Spring Boot-DemoApplication<PIbd-22_Puchkina_Internet_Programming_2>",
"request": "launch",
"cwd": "${workspaceFolder}",
"mainClass": "com.example.demo.DemoApplication",
"projectName": "PIbd-22_Puchkina_Internet_Programming_2",
"args": "",
"envFile": "${workspaceFolder}/.env"
}
]
}

Binary file not shown.

View File

@ -9,6 +9,16 @@
"projectName": "demo",
"args": "",
"envFile": "${workspaceFolder}/.env"
},
{
"type": "java",
"name": "Spring Boot-DemoApplication<lab4-5>",
"request": "launch",
"cwd": "${workspaceFolder}",
"mainClass": "com.example.demo.DemoApplication",
"projectName": "lab4-5",
"args": "",
"envFile": "${workspaceFolder}/.env"
}
]
}

View File

@ -51,9 +51,9 @@ td form {
}
.my-footer {
background-color: #2c2c2c;
background-color: #533908;
height: 32px;
color: rgba(255, 255, 255, 0.5);
color: white;
}
.cart-image {

View File

@ -29,7 +29,7 @@
<form action="#"
th:action="@{/cart/increase?type={type}&price={price}(type=${cartItem.type},price=${cartItem.price})}"
method="post">
<button type="submit" class="btn btn-primary">
<button type="submit" class="btn btn-secondary">
<i class="bi bi-plus-lg"></i>
</button>
</form>
@ -49,7 +49,7 @@
<div class="mb-2 col-12 col-md-8 col-lg-6 d-flex justify-content-center"
th:if="${not #lists.isEmpty(cart)}">
<form action="#" th:action="@{/cart/save}" method="post">
<button type="submit" class="btn btn-primary" onclick="return confirm('Вы уверены?')">
<button type="submit" class="btn btn-secondary" onclick="return confirm('Вы уверены?')">
Оформить заказ
</button>
</form>
@ -75,7 +75,7 @@
<input type="number" th:field="*{count}" id="count" class="form-control" value="0" step="1">
<div th:if="${#fields.hasErrors('count')}" th:errors="*{count}" class="invalid-feedback"></div>
</div>
<button type="submit" class="btn btn-primary">Добавить в корзину</button>
<button type="submit" class="btn btn-secondary">Добавить в корзину</button>
</form>
</div>
</main>

View File

@ -30,7 +30,7 @@
</li>
</th:block>
</ul>
<a class="btn btn-primary button-fixed-width" href="/">На главную</a>
<a class="btn btn-secondary button-fixed-width" href="/">На главную</a>
</main>
</body>

View File

@ -32,7 +32,7 @@
<label class="form-check-label" for="remember-me">Запомнить меня</label>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Войти</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Войти</button>
<a class="btn btn-secondary button-fixed-width" href="/signup">Регистрация</a>
</div>
</form>

View File

@ -16,7 +16,7 @@
</option>
</select>
</div>
<button type="submit" class="btn btn-primary col-sm-2">Показать</button>
<button type="submit" class="btn btn-secondary col-sm-2">Показать</button>
</form>
<table class="table mt-2">
<caption></caption>
@ -54,7 +54,7 @@
totalPages=${totalPages},
currentPage=${currentPage}) }" />
<div class="mt-2 d-flex justify-content-center">
<a class="btn btn-primary" href="/cart">Создать заказ</a>
<a class="btn btn-secondary" href="/cart">Создать заказ</a>
</div>
</th:block>
</th:block>

View File

@ -7,6 +7,8 @@
<body>
<main layout:fragment="content">
<form action="#" th:action="@{/profile}" th:object="${user}" method="post">
<ul class="nav nav-pills justify-content-center" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="pill" href="#orders">Заказы</a>
@ -47,10 +49,11 @@
[[${subscription.name}]]
</label>
</div>
<button type="submit" class="btn btn-primary button-fixed-width">Сохранить</button>
<button type="submit" class="btn btn-secondary button-fixed-width">Сохранить</button>
</form>
</div>
</div>
</form>
</main>
</body>

View File

@ -25,7 +25,7 @@
class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Регистрация</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Регистрация</button>
<a class="btn btn-secondary button-fixed-width" href="/">Отмена</a>
</div>
</form>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/subscription">Отмена</a>
</div>
</form>

View File

@ -12,7 +12,7 @@
<th:block th:case="*">
<h2>Списки рассылки</h2>
<div>
<a href="/admin/subscription/edit/" class="btn btn-primary">Добавить список рассылки</a>
<a href="/admin/subscription/edit/" class="btn btn-secondary">Добавить список рассылки</a>
</div>
<table class="table">
<caption></caption>

View File

@ -18,7 +18,7 @@
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/type">Отмена</a>
</div>
</form>

View File

@ -12,7 +12,7 @@
<th:block th:case="*">
<h2>Типы заказов</h2>
<div>
<a href="/admin/type/edit/" class="btn btn-primary">Добавить тип заказа</a>
<a href="/admin/type/edit/" class="btn btn-secondary">Добавить тип заказа</a>
</div>
<table class="table">
<caption></caption>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('login')}" th:errors="*{login}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" th:href="@{/admin/user(page=${page})}">Отмена</a>
</div>
</form>

View File

@ -12,7 +12,7 @@
<th:block th:case="*">
<h2>Пользователи</h2>
<div>
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-primary">Добавить пользователя</a>
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-secondary">Добавить пользователя</a>
</div>
<table class="table">
<caption></caption>

View File

@ -1,18 +1,116 @@
/* montserrat-alternates-200 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 200;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-200.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-300 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 300;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-300.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-regular - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 400;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-regular.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-500 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 500;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-500.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-600 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 600;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-600.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-700 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 700;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-700.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-800 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 800;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-800.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-900 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 900;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-900.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
html,
body {
font-family: "Montserrat Alternates", sans-serif;
height: 100%;
}
h1 {
font-size: 1.5em;
color:#533908
}
h2 {
font-size: 1.25em;
text-align: center;
color:#533908
}
.my-catalog-title{
font-size: 50px;
text-align: center;
}
h3 {
font-size: 1.1em;
color:#533908
}
td form {
@ -38,22 +136,29 @@ td form {
}
.my-navbar {
background-color: #3c3c3c !important;
border-bottom:#533908 solid 2px;
margin-bottom: 2em;
}
.my-navbar .link a:hover {
color:#533908;
text-decoration: underline;
}
.my-a{
color:#533908
}
.my-navbar .logo {
width: 26px;
height: 26px;
}
.my-footer {
background-color: #2c2c2c;
background-color: #533908;
height: 32px;
color: rgba(255, 255, 255, 0.5);
color: white;
}
.cart-image {
@ -65,3 +170,16 @@ td form {
.cart-item {
height: auto;
}
.button-secondary{
background-color: #533908;
border: 7px solid #533908;
color: white;
margin-top: 15px;
margin-bottom: 40px;
border-radius: 25px;
}
.form-select{
width: 35%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -29,7 +29,7 @@
<form action="#"
th:action="@{/cart/increase?type={type}&price={price}(type=${cartItem.type},price=${cartItem.price})}"
method="post">
<button type="submit" class="btn btn-primary">
<button type="submit" class="btn btn-secondary">
<i class="bi bi-plus-lg"></i>
</button>
</form>
@ -49,7 +49,7 @@
<div class="mb-2 col-12 col-md-8 col-lg-6 d-flex justify-content-center"
th:if="${not #lists.isEmpty(cart)}">
<form action="#" th:action="@{/cart/save}" method="post">
<button type="submit" class="btn btn-primary" onclick="return confirm('Вы уверены?')">
<button type="submit" class="btn btn-secondary" onclick="return confirm('Вы уверены?')">
Оформить заказ
</button>
</form>
@ -75,7 +75,7 @@
<input type="number" th:field="*{count}" id="count" class="form-control" value="0" step="1">
<div th:if="${#fields.hasErrors('count')}" th:errors="*{count}" class="invalid-feedback"></div>
</div>
<button type="submit" class="btn btn-primary">Добавить в корзину</button>
<button type="submit" class="btn btn-secondary">Добавить в корзину</button>
</form>
</div>
</main>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="ru" data-bs-theme="dark" xmlns:th="http://www.thymeleaf.org"
<html lang="ru" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
@ -7,7 +7,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">My shop</title>
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">ANNA</title>
<script type="text/javascript" src="/webjars/bootstrap/5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.3.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/webjars/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css" />
@ -15,11 +15,11 @@
</head>
<body class="h-100 d-flex flex-column">
<nav class="navbar navbar-expand-md my-navbar" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<nav class="navbar navbar-expand-md my-navbar" data-bs-theme="light">
<div class="container-fluid my-header-container">
<a class="navbar-brand my-a" href="/">
<i class="bi bi-cart2 d-inline-block align-top me-1 logo"></i>
MyShop
ANNA
</a>
<th:block sec:authorize="isAuthenticated()" th:with="userName=${#authentication.name}">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main-navbar"
@ -28,31 +28,33 @@
</button>
<div class="collapse navbar-collapse" id="main-navbar">
<ul class="navbar-nav me-auto link" th:with="activeLink=${#objects.nullSafe(servletPath, '')}">
<a class="nav-link my-a" href="/profile"
th:classappend="${activeLink.startsWith('/profile') ? 'active' : ''}">
Личный кабинет
</a>
<th:block sec:authorize="hasRole('ADMIN')">
<a class="nav-link" href="/admin/user"
<a class="nav-link my-a" href="/admin/user"
th:classappend="${activeLink.startsWith('/admin/user') ? 'active' : ''}">
Пользователи
</a>
<a class="nav-link" href="/admin/type"
<a class="nav-link my-a" href="/admin/type"
th:classappend="${activeLink.startsWith('/admin/type') ? 'active' : ''}">
Типы заказов
Типы товаров
</a>
<a class="nav-link" href="/admin/subscription"
<a class="nav-link my-a" href="/admin/subscription"
th:classappend="${activeLink.startsWith('/admin/subscription') ? 'active' : ''}">
Списки рассылки
Что это
</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
<a class="nav-link my-a" href="/h2-console/" target="_blank">Консоль H2</a>
</th:block>
<a class="nav-link" href="/123" target="_blank">Ошибка 1</a>
<a class="nav-link" href="/admin/123" target="_blank">Ошибка 2</a>
</ul>
<ul class="navbar-nav" th:if="${not #strings.isEmpty(userName)}">
<form th:action="@{/logout}" method="post">
<button type="submit" class="navbar-brand nav-link" onclick="return confirm('Вы уверены?')">
<button type="submit" class="navbar-brand nav-link my-a" onclick="return confirm('Вы уверены?')">
Выход ([[${userName}]])
</button>
</form>
<a class="navbar-brand" href="/cart">
<a class="navbar-brand my-a" href="/cart">
<i class="bi bi-cart2 d-inline-block align-top me-1 logo"></i>
[[${#numbers.formatDecimal(totalCart, 1, 2)}]] &#8381;
</a>
@ -64,7 +66,7 @@
<main class="container-fluid p-2" layout:fragment="content">
</main>
<footer class="my-footer mt-auto d-flex flex-shrink-0 justify-content-center align-items-center">
Автор, [[${#dates.year(#dates.createNow())}]]
Anna Puchkina, [[${#dates.year(#dates.createNow())}]]
</footer>
</body>

View File

@ -30,7 +30,7 @@
</li>
</th:block>
</ul>
<a class="btn btn-primary button-fixed-width" href="/">На главную</a>
<a class="btn btn-secondary button-fixed-width" href="/">На главную</a>
</main>
</body>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<head>
<title>Slay mama</title>
</head>
<body>
<main layout:fragment="content">
<h2 class="my-catalog-title">Каталог</h2>
</main>
</body>
</html>

View File

@ -32,7 +32,7 @@
<label class="form-check-label" for="remember-me">Запомнить меня</label>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Войти</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Войти</button>
<a class="btn btn-secondary button-fixed-width" href="/signup">Регистрация</a>
</div>
</form>

View File

@ -1,12 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<body>
<main layout:fragment="content">
<th:block th:fragment="orders (items, totalPages, currentPage)">
<th:block th:switch="${items.size()}">
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<form th:action="@{/}" method="get" class="row mt-2">
<form th:action="@{/orders}" method="get" class="row mt-2">
<div class="col-sm-10">
<input type="hidden" th:name="page" th:value="${page}">
<select th:name="typeId" id="typeId" class="form-select">
@ -16,14 +18,14 @@
</option>
</select>
</div>
<button type="submit" class="btn btn-primary col-sm-2">Показать</button>
<button type="submit" class="btn btn-secondary col-sm-2">Показать</button>
</form>
<table class="table mt-2">
<caption></caption>
<thead>
<tr>
<th scope="col" class="w-10">ID</th>
<th scope="col" class="w-auto">Тип заказа</th>
<th scope="col" class="w-auto">Тип товара</th>
<th scope="col" class="w-10">Цена</th>
<th scope="col" class="w-10">Количество</th>
<th scope="col" class="w-10">Сумма</th>
@ -54,11 +56,10 @@
totalPages=${totalPages},
currentPage=${currentPage}) }" />
<div class="mt-2 d-flex justify-content-center">
<a class="btn btn-primary" href="/cart">Создать заказ</a>
<a class="btn btn-secondary" href="/cart">Создать заказ</a>
</div>
</th:block>
</th:block>
</main>
</body>
</html>

View File

@ -7,7 +7,8 @@
<body>
<main layout:fragment="content">
<ul class="nav nav-pills justify-content-center" role="tablist">
<h2>Личный кабинет</h2>
<ul class="nav nav-underline justify-content-center" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="pill" href="#orders">Заказы</a>
</li>
@ -47,7 +48,7 @@
[[${subscription.name}]]
</label>
</div>
<button type="submit" class="btn btn-primary button-fixed-width">Сохранить</button>
<button type="submit" class="btn btn-secondary button-fixed-width">Сохранить</button>
</form>
</div>
</div>

View File

@ -25,7 +25,7 @@
class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Регистрация</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Регистрация</button>
<a class="btn btn-secondary button-fixed-width" href="/">Отмена</a>
</div>
</form>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/subscription">Отмена</a>
</div>
</form>

View File

@ -11,8 +11,8 @@
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Списки рассылки</h2>
<div>
<a href="/admin/subscription/edit/" class="btn btn-primary">Добавить список рассылки</a>
<div class="mt-2 d-flex justify-content-end">
<a href="/admin/subscription/edit/" class="btn btn-secondary">Добавить список рассылки</a>
</div>
<table class="table">
<caption></caption>

View File

@ -13,12 +13,12 @@
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
</div>
<div class="mb-3">
<label for="name" class="form-label">Тип заказа</label>
<label for="name" class="form-label">Тип товара</label>
<input type="text" th:field="*{name}" id="name" class="form-control">
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/type">Отмена</a>
</div>
</form>

View File

@ -2,7 +2,7 @@
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<head>
<title>Типы заказов</title>
<title>Типы товаров</title>
</head>
<body>
@ -10,16 +10,16 @@
<th:block th:switch="${items.size()}">
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Типы заказов</h2>
<div>
<a href="/admin/type/edit/" class="btn btn-primary">Добавить тип заказа</a>
<h2>Типы товаров</h2>
<div class="mt-2 d-flex justify-content-end">
<a href="/admin/type/edit/" class="btn btn-secondary">Добавить тип товара</a>
</div>
<table class="table">
<caption></caption>
<thead>
<tr>
<th scope="col" class="w-10">ID</th>
<th scope="col" class="w-auto">Тип заказа</th>
<th scope="col" class="w-auto">Тип товара</th>
<th scope="col" class="w-10"></th>
<th scope="col" class="w-10"></th>
</tr>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('login')}" th:errors="*{login}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" th:href="@{/admin/user(page=${page})}">Отмена</a>
</div>
</form>

View File

@ -11,8 +11,8 @@
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Пользователи</h2>
<div>
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-primary">Добавить пользователя</a>
<div class="mt-2 d-flex justify-content-end">
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-secondary">Добавить пользователя</a>
</div>
<table class="table">
<caption></caption>

Binary file not shown.

View File

@ -1072,3 +1072,202 @@ java.sql.SQLClientInfoException: Client info name 'ApplicationName' not supporte
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:77)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:115)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
2024-06-04 23:22:22.951527+04:00 database: flush
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]" [50000-224]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:407)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:122)
at org.h2.mvstore.MVStore.handleException(MVStore.java:1546)
at org.h2.mvstore.MVStore.panic(MVStore.java:371)
at org.h2.mvstore.MVStore.<init>(MVStore.java:291)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035)
at org.h2.mvstore.db.Store.<init>(Store.java:133)
at org.h2.engine.Database.<init>(Database.java:326)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.getConnectionUrl(H2ConsoleAutoConfiguration.java:94)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:86)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$h2Console$0(H2ConsoleAutoConfiguration.java:69)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.withThreadContextClassLoader(H2ConsoleAutoConfiguration.java:78)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:69)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1335)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1165)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:210)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:201)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:96)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:85)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:266)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:240)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:52)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4866)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:845)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:240)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:921)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:437)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:105)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:499)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:218)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:188)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:618)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
at com.example.demo.DemoApplication.main(DemoApplication.java:45)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]" [50000-224]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
... 103 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996)
at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143)
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117)
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81)
at org.h2.mvstore.MVStore.<init>(MVStore.java:286)
... 97 more
2024-06-04 23:22:24.576008+04:00 database: flush
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]" [50000-224]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:407)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:122)
at org.h2.mvstore.MVStore.handleException(MVStore.java:1546)
at org.h2.mvstore.MVStore.panic(MVStore.java:371)
at org.h2.mvstore.MVStore.<init>(MVStore.java:291)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035)
at org.h2.mvstore.db.Store.<init>(Store.java:133)
at org.h2.engine.Database.<init>(Database.java:326)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:428)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:61)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:276)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:107)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:223)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:170)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1432)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1503)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1234)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
at com.example.demo.DemoApplication.main(DemoApplication.java:45)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]" [50000-224]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
... 66 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/ip/web ANNA 2sem/PIbd-22_Puchkina_Internet_Programming_2/lab4-5/data.mv.db [2.2.224/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996)
at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143)
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117)
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81)
at org.h2.mvstore.MVStore.<init>(MVStore.java:286)
... 60 more

View File

@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@ -31,9 +32,10 @@ import com.example.demo.users.service.UserService;
import jakarta.validation.Valid;
@Controller
@RequestMapping(UserProfileController.URL)
public class UserProfileController {
public static final String URL = "/profile";
private static final String PROFILE_VIEW = "profile";
private static final String PAGE_ATTRIBUTE = "page";
private static final String TYPEID_ATTRIBUTE = "typeId";
private static final String PROFILE_ATTRIBUTE = "profile";
@ -114,7 +116,7 @@ public class UserProfileController {
profile.getSubscriptions().stream()
.map(this::toSubscriptionWithStatus)
.collect(Collectors.toSet()));
return Constants.REDIRECT_VIEW + "/";
return Constants.REDIRECT_VIEW + URL;
}
@PostMapping("/delete/{id}")
@ -127,6 +129,6 @@ public class UserProfileController {
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
redirectAttributes.addAttribute(TYPEID_ATTRIBUTE, typeId);
orderService.delete(principal.getId(), id);
return Constants.REDIRECT_VIEW + "/";
return Constants.REDIRECT_VIEW + URL;
}
}

View File

@ -1,18 +1,116 @@
/* montserrat-alternates-200 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 200;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-200.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-300 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 300;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-300.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-regular - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 400;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-regular.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-500 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 500;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-500.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-600 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 600;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-600.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-700 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 700;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-700.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-800 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 800;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-800.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* montserrat-alternates-900 - cyrillic_latin */
@font-face {
font-display: swap;
/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Montserrat Alternates";
font-style: normal;
font-weight: 900;
src: url("../fonts/montserrat-alternates-v17-cyrillic_latin-900.woff2") format("woff2");
/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
html,
body {
font-family: "Montserrat Alternates", sans-serif;
height: 100%;
}
h1 {
font-size: 1.5em;
color:#533908
}
h2 {
font-size: 1.25em;
text-align: center;
color:#533908
}
.my-catalog-title{
font-size: 50px;
text-align: center;
}
h3 {
font-size: 1.1em;
color:#533908
}
td form {
@ -38,22 +136,29 @@ td form {
}
.my-navbar {
background-color: #3c3c3c !important;
border-bottom:#533908 solid 2px;
margin-bottom: 2em;
}
.my-navbar .link a:hover {
color:#533908;
text-decoration: underline;
}
.my-a{
color:#533908
}
.my-navbar .logo {
width: 26px;
height: 26px;
}
.my-footer {
background-color: #2c2c2c;
background-color: #533908;
height: 32px;
color: rgba(255, 255, 255, 0.5);
color: white;
}
.cart-image {
@ -65,3 +170,16 @@ td form {
.cart-item {
height: auto;
}
.button-secondary{
background-color: #533908;
border: 7px solid #533908;
color: white;
margin-top: 15px;
margin-bottom: 40px;
border-radius: 25px;
}
.form-select{
width: 35%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -29,7 +29,7 @@
<form action="#"
th:action="@{/cart/increase?type={type}&price={price}(type=${cartItem.type},price=${cartItem.price})}"
method="post">
<button type="submit" class="btn btn-primary">
<button type="submit" class="btn btn-secondary">
<i class="bi bi-plus-lg"></i>
</button>
</form>
@ -49,7 +49,7 @@
<div class="mb-2 col-12 col-md-8 col-lg-6 d-flex justify-content-center"
th:if="${not #lists.isEmpty(cart)}">
<form action="#" th:action="@{/cart/save}" method="post">
<button type="submit" class="btn btn-primary" onclick="return confirm('Вы уверены?')">
<button type="submit" class="btn btn-secondary" onclick="return confirm('Вы уверены?')">
Оформить заказ
</button>
</form>
@ -75,7 +75,7 @@
<input type="number" th:field="*{count}" id="count" class="form-control" value="0" step="1">
<div th:if="${#fields.hasErrors('count')}" th:errors="*{count}" class="invalid-feedback"></div>
</div>
<button type="submit" class="btn btn-primary">Добавить в корзину</button>
<button type="submit" class="btn btn-secondary">Добавить в корзину</button>
</form>
</div>
</main>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="ru" data-bs-theme="dark" xmlns:th="http://www.thymeleaf.org"
<html lang="ru" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
@ -7,7 +7,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">My shop</title>
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">ANNA</title>
<script type="text/javascript" src="/webjars/bootstrap/5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.3.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/webjars/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css" />
@ -15,11 +15,11 @@
</head>
<body class="h-100 d-flex flex-column">
<nav class="navbar navbar-expand-md my-navbar" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<nav class="navbar navbar-expand-md my-navbar" data-bs-theme="light">
<div class="container-fluid my-header-container">
<a class="navbar-brand my-a" href="/">
<i class="bi bi-cart2 d-inline-block align-top me-1 logo"></i>
MyShop
ANNA
</a>
<th:block sec:authorize="isAuthenticated()" th:with="userName=${#authentication.name}">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main-navbar"
@ -28,31 +28,33 @@
</button>
<div class="collapse navbar-collapse" id="main-navbar">
<ul class="navbar-nav me-auto link" th:with="activeLink=${#objects.nullSafe(servletPath, '')}">
<a class="nav-link my-a" href="/profile"
th:classappend="${activeLink.startsWith('/profile') ? 'active' : ''}">
Личный кабинет
</a>
<th:block sec:authorize="hasRole('ADMIN')">
<a class="nav-link" href="/admin/user"
<a class="nav-link my-a" href="/admin/user"
th:classappend="${activeLink.startsWith('/admin/user') ? 'active' : ''}">
Пользователи
</a>
<a class="nav-link" href="/admin/type"
<a class="nav-link my-a" href="/admin/type"
th:classappend="${activeLink.startsWith('/admin/type') ? 'active' : ''}">
Типы заказов
Типы товаров
</a>
<a class="nav-link" href="/admin/subscription"
<a class="nav-link my-a" href="/admin/subscription"
th:classappend="${activeLink.startsWith('/admin/subscription') ? 'active' : ''}">
Списки рассылки
Что это
</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
<a class="nav-link my-a" href="/h2-console/" target="_blank">Консоль H2</a>
</th:block>
<a class="nav-link" href="/123" target="_blank">Ошибка 1</a>
<a class="nav-link" href="/admin/123" target="_blank">Ошибка 2</a>
</ul>
<ul class="navbar-nav" th:if="${not #strings.isEmpty(userName)}">
<form th:action="@{/logout}" method="post">
<button type="submit" class="navbar-brand nav-link" onclick="return confirm('Вы уверены?')">
<button type="submit" class="navbar-brand nav-link my-a" onclick="return confirm('Вы уверены?')">
Выход ([[${userName}]])
</button>
</form>
<a class="navbar-brand" href="/cart">
<a class="navbar-brand my-a" href="/cart">
<i class="bi bi-cart2 d-inline-block align-top me-1 logo"></i>
[[${#numbers.formatDecimal(totalCart, 1, 2)}]] &#8381;
</a>
@ -64,7 +66,7 @@
<main class="container-fluid p-2" layout:fragment="content">
</main>
<footer class="my-footer mt-auto d-flex flex-shrink-0 justify-content-center align-items-center">
Автор, [[${#dates.year(#dates.createNow())}]]
Anna Puchkina, [[${#dates.year(#dates.createNow())}]]
</footer>
</body>

View File

@ -30,7 +30,7 @@
</li>
</th:block>
</ul>
<a class="btn btn-primary button-fixed-width" href="/">На главную</a>
<a class="btn btn-secondary button-fixed-width" href="/">На главную</a>
</main>
</body>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<head>
<title>Slay mama</title>
</head>
<body>
<main layout:fragment="content">
<h2 class="my-catalog-title">Каталог</h2>
</main>
</body>
</html>

View File

@ -32,7 +32,7 @@
<label class="form-check-label" for="remember-me">Запомнить меня</label>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Войти</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Войти</button>
<a class="btn btn-secondary button-fixed-width" href="/signup">Регистрация</a>
</div>
</form>

View File

@ -1,12 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<body>
<main layout:fragment="content">
<th:block th:fragment="orders (items, totalPages, currentPage)">
<th:block th:switch="${items.size()}">
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<form th:action="@{/}" method="get" class="row mt-2">
<form th:action="@{/orders}" method="get" class="row mt-2">
<div class="col-sm-10">
<input type="hidden" th:name="page" th:value="${page}">
<select th:name="typeId" id="typeId" class="form-select">
@ -16,14 +18,14 @@
</option>
</select>
</div>
<button type="submit" class="btn btn-primary col-sm-2">Показать</button>
<button type="submit" class="btn btn-secondary col-sm-2">Показать</button>
</form>
<table class="table mt-2">
<caption></caption>
<thead>
<tr>
<th scope="col" class="w-10">ID</th>
<th scope="col" class="w-auto">Тип заказа</th>
<th scope="col" class="w-auto">Тип товара</th>
<th scope="col" class="w-10">Цена</th>
<th scope="col" class="w-10">Количество</th>
<th scope="col" class="w-10">Сумма</th>
@ -54,11 +56,10 @@
totalPages=${totalPages},
currentPage=${currentPage}) }" />
<div class="mt-2 d-flex justify-content-center">
<a class="btn btn-primary" href="/cart">Создать заказ</a>
<a class="btn btn-secondary" href="/cart">Создать заказ</a>
</div>
</th:block>
</th:block>
</main>
</body>
</html>

View File

@ -7,7 +7,8 @@
<body>
<main layout:fragment="content">
<ul class="nav nav-pills justify-content-center" role="tablist">
<h2>Личный кабинет</h2>
<ul class="nav nav-underline justify-content-center" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="pill" href="#orders">Заказы</a>
</li>
@ -47,7 +48,7 @@
[[${subscription.name}]]
</label>
</div>
<button type="submit" class="btn btn-primary button-fixed-width">Сохранить</button>
<button type="submit" class="btn btn-secondary button-fixed-width">Сохранить</button>
</form>
</div>
</div>

View File

@ -25,7 +25,7 @@
class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Регистрация</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Регистрация</button>
<a class="btn btn-secondary button-fixed-width" href="/">Отмена</a>
</div>
</form>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/subscription">Отмена</a>
</div>
</form>

View File

@ -11,8 +11,8 @@
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Списки рассылки</h2>
<div>
<a href="/admin/subscription/edit/" class="btn btn-primary">Добавить список рассылки</a>
<div class="mt-2 d-flex justify-content-end">
<a href="/admin/subscription/edit/" class="btn btn-secondary">Добавить список рассылки</a>
</div>
<table class="table">
<caption></caption>

View File

@ -13,12 +13,12 @@
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
</div>
<div class="mb-3">
<label for="name" class="form-label">Тип заказа</label>
<label for="name" class="form-label">Тип товара</label>
<input type="text" th:field="*{name}" id="name" class="form-control">
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/type">Отмена</a>
</div>
</form>

View File

@ -2,7 +2,7 @@
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<head>
<title>Типы заказов</title>
<title>Типы товаров</title>
</head>
<body>
@ -10,16 +10,16 @@
<th:block th:switch="${items.size()}">
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Типы заказов</h2>
<div>
<a href="/admin/type/edit/" class="btn btn-primary">Добавить тип заказа</a>
<h2>Типы товаров</h2>
<div class="mt-2 d-flex justify-content-end">
<a href="/admin/type/edit/" class="btn btn-secondary">Добавить тип товара</a>
</div>
<table class="table">
<caption></caption>
<thead>
<tr>
<th scope="col" class="w-10">ID</th>
<th scope="col" class="w-auto">Тип заказа</th>
<th scope="col" class="w-auto">Тип товара</th>
<th scope="col" class="w-10"></th>
<th scope="col" class="w-10"></th>
</tr>

View File

@ -19,7 +19,7 @@
<div th:if="${#fields.hasErrors('login')}" th:errors="*{login}" class="invalid-feedback"></div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<button class="btn btn-secondary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" th:href="@{/admin/user(page=${page})}">Отмена</a>
</div>
</form>

View File

@ -11,8 +11,8 @@
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
<h2>Пользователи</h2>
<div>
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-primary">Добавить пользователя</a>
<div class="mt-2 d-flex justify-content-end">
<a th:href="@{/admin/user/edit/(page=${page})}" class="btn btn-secondary">Добавить пользователя</a>
</div>
<table class="table">
<caption></caption>