first commit
This commit is contained in:
commit
9e4041cd0b
33 changed files with 1631162 additions and 0 deletions
174
frontend/main.css
Normal file
174
frontend/main.css
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
body {
|
||||
background-color: #1B2838;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
padding-top: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
background-color: #233B53;
|
||||
width: 950px;
|
||||
min-height: 555px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
flex-wrap: wrap;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
width: 635px;
|
||||
height: 360px;
|
||||
padding-top: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.image-container img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.details-container {
|
||||
width: 635px;
|
||||
height: auto;
|
||||
background-color: #19222C;
|
||||
border: 3px solid #35465E;
|
||||
box-sizing: border-box;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding: 10px 15px 10px 15px;
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 16px;
|
||||
font-family: Arial, sans-serif;
|
||||
color: #A1B0C7;
|
||||
margin-top: 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
width: 138px;
|
||||
height: 35px;
|
||||
background: linear-gradient(to bottom, #A4D007, #536904);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 19px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.download-btn:hover {
|
||||
background: linear-gradient(to bottom, #8DC50E, #475F2D);
|
||||
}
|
||||
|
||||
.game-mode {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 660px;
|
||||
font-size: 13px;
|
||||
color: #A1B0C7;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.dynamic-data {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tags {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 660px;
|
||||
font-size: 13px;
|
||||
color: #A1B0C7;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
position: absolute;
|
||||
top: 150px;
|
||||
left: 660px;
|
||||
font-size: 13px;
|
||||
color: #A1B0C7;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.file-size .dynamic-data {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
color: #A1B0C7;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.added-time {
|
||||
position: absolute;
|
||||
top: 170px;
|
||||
left: 660px;
|
||||
font-size: 13px;
|
||||
color: #A1B0C7;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.added-time .dynamic-data {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
color: #A1B0C7;
|
||||
margin-left: 45px;
|
||||
}
|
||||
|
||||
.youtube-container {
|
||||
margin-top: 15px;
|
||||
width: 265px;
|
||||
height: 150px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 210px;
|
||||
left: 660px;
|
||||
}
|
||||
64
frontend/main.html
Normal file
64
frontend/main.html
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Workshop</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main-container">
|
||||
<div class="image-wrapper">
|
||||
<div class="image-container">
|
||||
<img src="{{ image_url }}" alt="Map Image">
|
||||
</div>
|
||||
|
||||
<div class="details-container">
|
||||
<div class="card-title">{{ map_title }}</div>
|
||||
<div class="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<a href="{{ url_for('download_bsp', image_path=image_url) }}">
|
||||
<button class="download-btn">🡇 Скачать</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="game-mode">
|
||||
<span>Режим игры:</span>
|
||||
<span class="dynamic-data">{{ game_mode | default('Не указан') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="tags">
|
||||
<span>Метки:</span>
|
||||
<span class="dynamic-data">{{ tags | default('Не указаны') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="file-size">
|
||||
<span>Размер файла:</span>
|
||||
<span class="dynamic-data">{{ file_size | default('Не указан') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="added-time">
|
||||
<span>Добавлен:</span>
|
||||
<span class="dynamic-data">{{ added_time | default('Не указано') }}</span>
|
||||
</div>
|
||||
|
||||
{% if youtube_link %}
|
||||
<div class="youtube-container">
|
||||
<iframe
|
||||
width="265"
|
||||
height="150"
|
||||
src="{{ youtube_link | replace('watch?v=', 'embed/') }}"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
8
frontend/main.js
Normal file
8
frontend/main.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const cards = document.querySelectorAll('.card');
|
||||
cards.forEach(card => {
|
||||
card.addEventListener('click', () => {
|
||||
window.location.href = '/main';
|
||||
});
|
||||
});
|
||||
});
|
||||
487
frontend/workshop.css
Normal file
487
frontend/workshop.css
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
body {
|
||||
background-color: #1B2A3C;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
background-color: #171D25;
|
||||
width: 100%;
|
||||
height: 105px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
margin-top: 105px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 200px);
|
||||
grid-gap: 105px 20px;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.right-rectangle {
|
||||
width: 295px;
|
||||
height: 370px;
|
||||
background: linear-gradient(to left, #0E141C, #111A23, #15202C);
|
||||
margin-left: 20px;
|
||||
margin-top: 40px;
|
||||
border-radius: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.show-products-title {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.game-modes-title {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.game-modes {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.game-mode {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.game-mode input[type="checkbox"] {
|
||||
margin-right: 10px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
accent-color: blue;
|
||||
}
|
||||
|
||||
.game-mode:hover {
|
||||
background-color: #1B2A3C;
|
||||
}
|
||||
|
||||
.game-mode:hover::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 295px;
|
||||
height: 10px;
|
||||
background-color: #1B2A3C;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.stars {
|
||||
width: 81px;
|
||||
height: 14px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
margin-top: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.card img:not(.stars) {
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.description-popup {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
background-color: #61ABD7;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
z-index: 10;
|
||||
left: 220px;
|
||||
top: 0;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.description-popup::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: -20px;
|
||||
border-width: 10px;
|
||||
border-style: solid;
|
||||
border-color: transparent #61ABD7 transparent transparent;
|
||||
}
|
||||
|
||||
.description-popup strong {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.description-popup p {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card:hover .description-popup {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
bottom: 25px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagebtn {
|
||||
width: 40px;
|
||||
height: 16px;
|
||||
background-color: #2B475E;
|
||||
color: #63AFCD;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
border-radius: 2px;
|
||||
transition: background-color 0.3s, color 0.3s;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.pagebtn:hover {
|
||||
background-color: #66C0F4;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pagelink {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.pagination_space {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.pagebtn:hover, .pagelink:hover {
|
||||
background-color: #2A5B70;
|
||||
}
|
||||
|
||||
.sort-button-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 15px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.sort-button {
|
||||
width: 148px;
|
||||
height: 30px;
|
||||
background: linear-gradient(to top, #384A65, #57749E);
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.sort-button:hover {
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.sort-button:active {
|
||||
background: linear-gradient(to top, #2C3E55, #3D5B80);
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1001;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 530px;
|
||||
height: 315px;
|
||||
background: linear-gradient(to left, #333840, #333840);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: -15px;
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
color: #f1f1f1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal-content h2 {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.modal-rectangle {
|
||||
position: absolute;
|
||||
top: 105px;
|
||||
left: 25px;
|
||||
width: 480px;
|
||||
height: 42px;
|
||||
background-color: #292B2F;
|
||||
border-radius: 3px;
|
||||
z-index: 1002;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.modal-rectangle .text-left {
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.modal-rectangle .text-center {
|
||||
left: 240px;
|
||||
font-family: Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.date-input {
|
||||
background-color: #33363E;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
width: 205px;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
|
||||
z-index: 1003;
|
||||
}
|
||||
|
||||
.date-input::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.date-input:focus {
|
||||
outline: none;
|
||||
background-color: #4c4f58;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
position: absolute;
|
||||
bottom: -270px;
|
||||
right: 25px;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
background-color: #32363F;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-family: Arial, sans-serif;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.cancel-button:hover {
|
||||
background-color: #4A4F5A;
|
||||
box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.ok-button {
|
||||
position: absolute;
|
||||
bottom: -270px;
|
||||
right: 130px;
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
background-color: #6EA720;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-family: Arial, sans-serif;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.ok-button:hover {
|
||||
background-color: #A6FC30;
|
||||
box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-top: 420px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.search-input-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 250px;
|
||||
height: 40px;
|
||||
background-color: #2C3E55;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
padding-left: 10px;
|
||||
outline: none;
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
background-color: #3E4A61;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.search-button img {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.filter-stars {
|
||||
margin-top: 420px;
|
||||
margin-right: 260px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filter-stars {
|
||||
position: absolute;
|
||||
margin-top: 420px;
|
||||
margin-right: -660px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #2C3E55;
|
||||
width: 300px;
|
||||
height: 80px;
|
||||
border-radius: 3px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
margin-bottom: 10px;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.stars-filter {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stars-filter label {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stars-filter input[type="checkbox"] {
|
||||
margin-bottom: 5px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
accent-color: #63AFCD;
|
||||
}
|
||||
138
frontend/workshop.html
Normal file
138
frontend/workshop.html
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Workshop</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='workshop.css') }}">
|
||||
<script src="{{ url_for('static', filename='workshop.js') }}" defer></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-bar">
|
||||
<h1>Добро пожаловать в Workshop</h1>
|
||||
</div>
|
||||
|
||||
<div class="main-container">
|
||||
<div class="cards-container">
|
||||
{% for map in maps_data %}
|
||||
<div class="card">
|
||||
<a href="/main?image_url={{ get_image_path(map[0]) }}&map_title={{ map[1] }}&{{ filters }}">
|
||||
<img src="{{ get_image_path(map[0]) }}" alt="Map Image" width="200" height="110">
|
||||
</a>
|
||||
<img src="{{ get_star_image(map[2]) }}" alt="{{ map[2] }} stars" class="stars" width="81" height="14">
|
||||
<div class="card-title">{{ map[1] }}</div>
|
||||
<div class="description-popup">
|
||||
<strong>{{ map[1] }}</strong>
|
||||
<p>{{ map[3] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="right-rectangle">
|
||||
<div class="sort-button-container">
|
||||
<button class="sort-button">Сортировать по дате</button>
|
||||
</div>
|
||||
<div class="game-modes">
|
||||
<div class="show-products-title">
|
||||
Показать продукты, попадающие в каждую из выбранных категорий:
|
||||
</div>
|
||||
|
||||
<div class="game-modes-title">РЕЖИМ ИГРЫ</div>
|
||||
|
||||
{% for mode, label in {
|
||||
"Classic": "Классический",
|
||||
"Deathmatch": "Бой насмерть",
|
||||
"Demolition": "Уничтожение объекта",
|
||||
"Armsrace": "Гонка вооружений",
|
||||
"Custom": "Пользовательский",
|
||||
"Training": "Обучение",
|
||||
"Co-op Strike": "Совместный налёт",
|
||||
"Wingman": "Напарники",
|
||||
"Flying Scoutsman": "Перелётные снайперы"
|
||||
}.items() %}
|
||||
<label class="game-mode">
|
||||
<input type="checkbox" class="game-mode-checkbox" value="{{ mode }}" {% if mode in filters %}checked{% endif %}>
|
||||
{{ label }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<form method="get" action="/">
|
||||
<div class="search-input-container">
|
||||
<input type="text" id="search" class="search-input" name="search_title" placeholder="Поиск по названию" value="{{ request.args.get('search_title', '') }}">
|
||||
<button class="search-button" type="submit">
|
||||
<img src="/images/search-icon.png" alt="Поиск">
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="sortModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close-btn">×</span>
|
||||
<h2>Сортировать по дате</h2>
|
||||
<div class="modal-rectangle">
|
||||
<span class="text-left">С</span>
|
||||
<div class="first-rectangle">
|
||||
<input type="date" class="date-input" />
|
||||
</div>
|
||||
<span class="text-center">ПО</span>
|
||||
<div class="second-rectangle">
|
||||
<input type="date" class="date-input" />
|
||||
</div>
|
||||
</div>
|
||||
<button class="ok-button">ОК</button>
|
||||
<button class="cancel-button">Отмена</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-stars">
|
||||
<div class="filter-title">
|
||||
<label>Фильтр по количеству звезд:</label>
|
||||
</div>
|
||||
<div class="stars-filter">
|
||||
<label><input type="checkbox" name="stars" value="1" {% if 'stars' in request.args and '1' in request.args.getlist('stars') %}checked{% endif %}> 1</label>
|
||||
<label><input type="checkbox" name="stars" value="2" {% if 'stars' in request.args and '2' in request.args.getlist('stars') %}checked{% endif %}> 2</label>
|
||||
<label><input type="checkbox" name="stars" value="3" {% if 'stars' in request.args and '3' in request.args.getlist('stars') %}checked{% endif %}> 3</label>
|
||||
<label><input type="checkbox" name="stars" value="4" {% if 'stars' in request.args and '4' in request.args.getlist('stars') %}checked{% endif %}> 4</label>
|
||||
<label><input type="checkbox" name="stars" value="5" {% if 'stars' in request.args and '5' in request.args.getlist('stars') %}checked{% endif %}> 5</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
{% if page > 1 %}
|
||||
<a class="pagebtn" href="/?page={{ page - 1 }}&{{ filters }}"><</a>
|
||||
{% endif %}
|
||||
|
||||
{% if page > 3 %}
|
||||
<a class="pagelink" href="/?page=1&{{ filters }}">1</a>
|
||||
<span class="pagination_space">...</span>
|
||||
{% endif %}
|
||||
|
||||
{% for p in range(1, total_pages + 1) %}
|
||||
{% if p >= page - 1 and p <= page + 2 %}
|
||||
{% if p == page %}
|
||||
<span class="pagelink" style="color: #417A9B;">{{ p }}</span>
|
||||
{% else %}
|
||||
<a class="pagelink" href="/?page={{ p }}&{{ filters }}">{{ p }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if total_pages > 3 and page < total_pages - 2 %}
|
||||
<span class="pagination_space">...</span>
|
||||
<a class="pagelink" href="/?page={{ total_pages }}&{{ filters }}">{{ total_pages }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if page < total_pages %}
|
||||
<a class="pagebtn" href="/?page={{ page + 1 }}&{{ filters }}">></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
144
frontend/workshop.js
Normal file
144
frontend/workshop.js
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const sortButton = document.querySelector('.sort-button');
|
||||
const modal = document.getElementById('sortModal');
|
||||
const closeButton = document.querySelector('.close-btn');
|
||||
const cancelButton = document.querySelector('.cancel-button');
|
||||
const okButton = document.querySelector('.ok-button');
|
||||
const startDateInput = document.querySelector('.first-rectangle .date-input');
|
||||
const endDateInput = document.querySelector('.second-rectangle .date-input');
|
||||
const checkboxes = document.querySelectorAll('.game-mode-checkbox');
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
// Устанавливаем состояние чекбоксов при загрузке страницы
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = params.getAll('game_modes').includes(checkbox.value);
|
||||
});
|
||||
|
||||
// Открыть модальное окно при нажатии на кнопку
|
||||
sortButton.addEventListener('click', function () {
|
||||
modal.style.display = 'block';
|
||||
});
|
||||
|
||||
// Закрыть модальное окно при нажатии на крестик
|
||||
closeButton.addEventListener('click', function () {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
|
||||
// Закрыть модальное окно при нажатии на кнопку "Отмена"
|
||||
cancelButton.addEventListener('click', function () {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
|
||||
// Применить фильтры по дате и режимам игры при нажатии на кнопку "OK"
|
||||
okButton.addEventListener('click', function () {
|
||||
const startDate = startDateInput.value;
|
||||
const endDate = endDateInput.value;
|
||||
|
||||
// Фильтры по датам
|
||||
if (startDate) params.set('start_date', startDate);
|
||||
else params.delete('start_date');
|
||||
|
||||
if (endDate) params.set('end_date', endDate);
|
||||
else params.delete('end_date');
|
||||
|
||||
// Фильтры по режимам игры
|
||||
const selectedGameModes = Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked)
|
||||
.map(checkbox => checkbox.value);
|
||||
|
||||
// Обновляем параметры для выбранных режимов
|
||||
params.delete('game_modes'); // Удаляем старые значения
|
||||
selectedGameModes.forEach(mode => params.append('game_modes', mode));
|
||||
|
||||
params.set('page', 1); // Сбрасываем на первую страницу
|
||||
modal.style.display = 'none'; // Закрываем модальное окно
|
||||
window.location.search = params.toString(); // Перезагружаем страницу с новыми параметрами
|
||||
});
|
||||
|
||||
// Обновление параметров при изменении чекбоксов
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function () {
|
||||
const selectedGameModes = Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked)
|
||||
.map(checkbox => checkbox.value);
|
||||
|
||||
// Обновляем параметры URL
|
||||
params.delete('game_modes'); // Удаляем старые значения
|
||||
selectedGameModes.forEach(mode => params.append('game_modes', mode));
|
||||
|
||||
params.set('page', 1); // Сбрасываем на первую страницу
|
||||
window.location.search = params.toString(); // Перезагружаем страницу с новыми параметрами
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const searchInput = document.querySelector('.search-input');
|
||||
|
||||
// Функция для обработки поиска
|
||||
function performSearch() {
|
||||
const query = searchInput.value.toLowerCase();
|
||||
const cards = document.querySelectorAll('.card');
|
||||
|
||||
cards.forEach(card => {
|
||||
const title = card.querySelector('.card-title').textContent.toLowerCase();
|
||||
if (title.includes(query)) {
|
||||
card.style.display = 'block'; // Показываем карточку, если название соответствует запросу
|
||||
} else {
|
||||
card.style.display = 'none'; // Скрываем карточку, если название не соответствует запросу
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Поиск по нажатию клавиши Enter
|
||||
searchInput.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
performSearch();
|
||||
}
|
||||
});
|
||||
|
||||
// Поиск по клику на лупу (если такая кнопка добавлена)
|
||||
const searchButton = document.querySelector('.search-button');
|
||||
if (searchButton) {
|
||||
searchButton.addEventListener('click', performSearch);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const starsCheckboxes = document.querySelectorAll('input[name="stars"]');
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
// Устанавливаем состояние чекбоксов при загрузке страницы
|
||||
const selectedStars = params.get('stars');
|
||||
if (selectedStars) {
|
||||
starsCheckboxes.forEach(checkbox => {
|
||||
if (checkbox.value === selectedStars) {
|
||||
checkbox.checked = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Обновление параметров при изменении чекбоксов для звезд
|
||||
starsCheckboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function () {
|
||||
// Снимаем отметки с других чекбоксов
|
||||
starsCheckboxes.forEach(otherCheckbox => {
|
||||
if (otherCheckbox !== checkbox) {
|
||||
otherCheckbox.checked = false;
|
||||
}
|
||||
});
|
||||
|
||||
const selectedStar = checkbox.checked ? checkbox.value : null;
|
||||
|
||||
// Обновляем параметры URL
|
||||
params.delete('stars');
|
||||
if (selectedStar) {
|
||||
params.set('stars', selectedStar); // Устанавливаем выбранную звезду
|
||||
}
|
||||
|
||||
params.set('page', 1); // Сбрасываем на первую страницу
|
||||
window.location.search = params.toString(); // Перезагружаем страницу с новыми параметрами
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue