Update app.py
Browse files
app.py
CHANGED
|
@@ -287,6 +287,68 @@ BASE_STYLE = '''
|
|
| 287 |
box-shadow: var(--shadow);
|
| 288 |
transition: var(--transition);
|
| 289 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
@media (max-width: 768px) {
|
| 291 |
.sidebar {
|
| 292 |
transform: translateX(-100%);
|
|
@@ -310,6 +372,12 @@ BASE_STYLE = '''
|
|
| 310 |
font-size: 1em;
|
| 311 |
padding: 12px;
|
| 312 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
}
|
| 314 |
'''
|
| 315 |
|
|
@@ -774,12 +842,25 @@ def feed():
|
|
| 774 |
font-weight: 600;
|
| 775 |
color: var(--primary);
|
| 776 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 777 |
</style>
|
| 778 |
</head>
|
| 779 |
<body>
|
| 780 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 781 |
''' + NAV_HTML + '''
|
| 782 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 783 |
<div class="container">
|
| 784 |
<h1>Лента публикаций</h1>
|
| 785 |
<div class="search-container">
|
|
@@ -801,7 +882,8 @@ def feed():
|
|
| 801 |
<p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
|
| 802 |
<p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
|
| 803 |
<p class="stats">Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
|
| 804 |
-
{% if is_authenticated %}
|
|
|
|
| 805 |
<button class="btn cart-btn" onclick="addToCart('{{ post['id'] }}', '{{ post['title'] }}', '{{ post['price'] }}', '{{ post['currency'] }}', '{{ post['uploader'] }}')">В корзину</button>
|
| 806 |
{% endif %}
|
| 807 |
</div>
|
|
@@ -831,18 +913,81 @@ def feed():
|
|
| 831 |
document.getElementById('imageModal').style.display = 'none';
|
| 832 |
}
|
| 833 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 834 |
function addToCart(postId, title, price, currency, uploader) {
|
| 835 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
| 840 |
} else {
|
| 841 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 842 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 843 |
}
|
| 844 |
window.onload = () => {
|
| 845 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 846 |
const videos = document.querySelectorAll('.post-preview');
|
| 847 |
videos.forEach(video => {
|
| 848 |
video.addEventListener('loadedmetadata', () => {
|
|
@@ -879,6 +1024,7 @@ def post_page(post_id):
|
|
| 879 |
else:
|
| 880 |
post['likes'] = [user for user in post.get('likes', []) if user != username]
|
| 881 |
save_data(data)
|
|
|
|
| 882 |
elif 'comment' in request.form:
|
| 883 |
comment_text = request.form.get('comment')
|
| 884 |
if comment_text:
|
|
@@ -954,12 +1100,25 @@ def post_page(post_id):
|
|
| 954 |
font-weight: 600;
|
| 955 |
color: var(--primary);
|
| 956 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 957 |
</style>
|
| 958 |
</head>
|
| 959 |
<body>
|
| 960 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 961 |
''' + NAV_HTML + '''
|
| 962 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 963 |
<div class="container">
|
| 964 |
<h1>{{ post['title'] }}</h1>
|
| 965 |
<video controls>
|
|
@@ -975,7 +1134,10 @@ def post_page(post_id):
|
|
| 975 |
{% if username in post['likes'] %}Убрать лайк{% else %}Лайк{% endif %}
|
| 976 |
</button>
|
| 977 |
</form>
|
| 978 |
-
|
|
|
|
|
|
|
|
|
|
| 979 |
<form method="POST" class="comment-section">
|
| 980 |
<textarea name="comment" placeholder="Оставьте комментарий" rows="4"></textarea>
|
| 981 |
<button type="submit" class="btn">Отправить</button>
|
|
@@ -1000,18 +1162,81 @@ def post_page(post_id):
|
|
| 1000 |
document.body.classList.toggle('dark');
|
| 1001 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 1002 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1003 |
function addToCart(postId, title, price, currency, uploader) {
|
| 1004 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1005 |
-
|
| 1006 |
-
|
| 1007 |
-
|
| 1008 |
-
|
| 1009 |
} else {
|
| 1010 |
-
|
| 1011 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1012 |
}
|
| 1013 |
window.onload = () => {
|
| 1014 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 1015 |
};
|
| 1016 |
</script>
|
| 1017 |
</body>
|
|
@@ -1105,6 +1330,7 @@ def profile():
|
|
| 1105 |
'title': item['title'],
|
| 1106 |
'price': item['price'],
|
| 1107 |
'currency': item['currency'],
|
|
|
|
| 1108 |
'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
| 1109 |
'status': 'pending',
|
| 1110 |
'buyer_phone': phone,
|
|
@@ -1231,6 +1457,14 @@ def profile():
|
|
| 1231 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1232 |
''' + NAV_HTML + '''
|
| 1233 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1234 |
<div class="container">
|
| 1235 |
<div class="profile-header">
|
| 1236 |
{% if avatar %}
|
|
@@ -1277,6 +1511,7 @@ def profile():
|
|
| 1277 |
{% endif %}
|
| 1278 |
<h2>Корзина</h2>
|
| 1279 |
<div class="cart-grid" id="cartGrid"></div>
|
|
|
|
| 1280 |
<button class="btn" onclick="checkout()" style="margin-top: 20px;">Оформить заказ</button>
|
| 1281 |
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 1282 |
{% if messages %}
|
|
@@ -1323,26 +1558,43 @@ def profile():
|
|
| 1323 |
alert('Ссылка скопирована!');
|
| 1324 |
});
|
| 1325 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1326 |
function renderCart() {
|
| 1327 |
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
|
|
|
|
|
|
| 1328 |
const cartGrid = document.getElementById('cartGrid');
|
|
|
|
|
|
|
| 1329 |
cartGrid.innerHTML = '';
|
|
|
|
| 1330 |
cart.forEach(item => {
|
|
|
|
|
|
|
| 1331 |
const div = document.createElement('div');
|
| 1332 |
div.className = 'cart-item';
|
| 1333 |
div.innerHTML = `
|
| 1334 |
<h3>${item.title}</h3>
|
| 1335 |
-
<p
|
| 1336 |
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 1337 |
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 1338 |
`;
|
|
|
|
| 1339 |
cartGrid.appendChild(div);
|
| 1340 |
});
|
|
|
|
|
|
|
|
|
|
| 1341 |
}
|
| 1342 |
function removeFromCart(postId) {
|
| 1343 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1344 |
cart = cart.filter(item => item.postId !== postId);
|
| 1345 |
localStorage.setItem('cart', JSON.stringify(cart));
|
|
|
|
| 1346 |
renderCart();
|
| 1347 |
}
|
| 1348 |
function checkout() {
|
|
@@ -1367,9 +1619,12 @@ def profile():
|
|
| 1367 |
document.body.appendChild(form);
|
| 1368 |
form.submit();
|
| 1369 |
localStorage.removeItem('cart');
|
|
|
|
| 1370 |
}
|
| 1371 |
window.onload = () => {
|
| 1372 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 1373 |
renderCart();
|
| 1374 |
const videos = document.querySelectorAll('.post-preview');
|
| 1375 |
videos.forEach(video => {
|
|
@@ -1508,6 +1763,14 @@ def user_profile(username):
|
|
| 1508 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1509 |
''' + NAV_HTML + '''
|
| 1510 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1511 |
<div class="container">
|
| 1512 |
<div class="profile-header">
|
| 1513 |
{% if avatar %}
|
|
@@ -1566,8 +1829,68 @@ def user_profile(username):
|
|
| 1566 |
alert('Ссылка скопирована!');
|
| 1567 |
});
|
| 1568 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1569 |
window.onload = () => {
|
| 1570 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 1571 |
const videos = document.querySelectorAll('.post-preview');
|
| 1572 |
videos.forEach(video => {
|
| 1573 |
video.addEventListener('loadedmetadata', () => {
|
|
@@ -1719,6 +2042,14 @@ def upload():
|
|
| 1719 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1720 |
''' + NAV_HTML + '''
|
| 1721 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1722 |
<div class="container">
|
| 1723 |
<h1>Загрузить видео</h1>
|
| 1724 |
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
@@ -1756,6 +2087,64 @@ def upload():
|
|
| 1756 |
document.body.classList.toggle('dark');
|
| 1757 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 1758 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1759 |
document.getElementById('upload-form').onsubmit = async function(e) {
|
| 1760 |
e.preventDefault();
|
| 1761 |
const formData = new FormData(this);
|
|
@@ -1779,6 +2168,8 @@ def upload():
|
|
| 1779 |
};
|
| 1780 |
window.onload = () => {
|
| 1781 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 1782 |
};
|
| 1783 |
</script>
|
| 1784 |
</body>
|
|
@@ -1892,6 +2283,14 @@ def seller_orders():
|
|
| 1892 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1893 |
''' + NAV_HTML + '''
|
| 1894 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1895 |
<div class="container">
|
| 1896 |
<h1>Ваши заказы</h1>
|
| 1897 |
<div class="order-grid">
|
|
@@ -1899,7 +2298,7 @@ def seller_orders():
|
|
| 1899 |
{% for order in orders %}
|
| 1900 |
<div class="order-item">
|
| 1901 |
<h3>{{ order['title'] }}</h3>
|
| 1902 |
-
<p class="price">Цена: {{ order['price'] }} {{ order['currency'] }}</p>
|
| 1903 |
<p>Покупатель: <a href="{{ url_for('user_profile', username=order['buyer']) }}" class="username-link">{{ order['buyer'] }}</a></p>
|
| 1904 |
<p>Телефон покупателя: {{ order['buyer_phone'] }}</p>
|
| 1905 |
{% if order['buyer_address'] %}
|
|
@@ -1930,8 +2329,68 @@ def seller_orders():
|
|
| 1930 |
document.body.classList.toggle('dark');
|
| 1931 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 1932 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1933 |
window.onload = () => {
|
| 1934 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 1935 |
};
|
| 1936 |
</script>
|
| 1937 |
</body>
|
|
@@ -1977,8 +2436,7 @@ def user_orders():
|
|
| 1977 |
color: transparent;
|
| 1978 |
}
|
| 1979 |
.order-grid {
|
| 1980 |
-
display:
|
| 1981 |
-
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
| 1982 |
gap: 30px;
|
| 1983 |
}
|
| 1984 |
.order-item {
|
|
@@ -2021,6 +2479,14 @@ def user_orders():
|
|
| 2021 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2022 |
''' + NAV_HTML + '''
|
| 2023 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2024 |
<div class="container">
|
| 2025 |
<h1>Мои заказы</h1>
|
| 2026 |
<div class="order-grid">
|
|
@@ -2028,7 +2494,7 @@ def user_orders():
|
|
| 2028 |
{% for order in orders %}
|
| 2029 |
<div class="order-item">
|
| 2030 |
<h3>{{ order['title'] }}</h3>
|
| 2031 |
-
<p class="price">Цена: {{ order['price'] }} {{ order['currency'] }}</p>
|
| 2032 |
<p>Продавец: <a href="{{ url_for('user_profile', username=order['uploader']) }}" class="username-link">{{ order['uploader'] }}</a></p>
|
| 2033 |
<p>Дата: {{ order['date'] }}</p>
|
| 2034 |
<p>Статус: {{ 'В ожидании' if order['status'] == 'pending' else 'В обработке' if order['status'] == 'processing' else 'Завершено' }}</p>
|
|
@@ -2047,8 +2513,68 @@ def user_orders():
|
|
| 2047 |
document.body.classList.toggle('dark');
|
| 2048 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2049 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2050 |
window.onload = () => {
|
| 2051 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 2052 |
};
|
| 2053 |
</script>
|
| 2054 |
</body>
|
|
@@ -2213,6 +2739,14 @@ def admin_panel():
|
|
| 2213 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2214 |
''' + NAV_HTML + '''
|
| 2215 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2216 |
<div class="container">
|
| 2217 |
<h1>Админ-панель</h1>
|
| 2218 |
<h2>Организации на проверке</h2>
|
|
@@ -2275,8 +2809,68 @@ def admin_panel():
|
|
| 2275 |
document.body.classList.toggle('dark');
|
| 2276 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2277 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2278 |
window.onload = () => {
|
| 2279 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
|
|
|
|
|
|
| 2280 |
const videos = document.querySelectorAll('.post-preview');
|
| 2281 |
videos.forEach(video => {
|
| 2282 |
video.addEventListener('loadedmetadata', () => {
|
|
@@ -2293,4 +2887,4 @@ def admin_panel():
|
|
| 2293 |
if __name__ == '__main__':
|
| 2294 |
backup_thread = threading.Thread(target=periodic_backup, daemon=True)
|
| 2295 |
backup_thread.start()
|
| 2296 |
-
app.run(debug=True, host='0.0.0.0', port=7860)
|
|
|
|
| 287 |
box-shadow: var(--shadow);
|
| 288 |
transition: var(--transition);
|
| 289 |
}
|
| 290 |
+
.cart-float {
|
| 291 |
+
position: fixed;
|
| 292 |
+
bottom: 20px;
|
| 293 |
+
right: 20px;
|
| 294 |
+
background: var(--cart-btn);
|
| 295 |
+
color: white;
|
| 296 |
+
border-radius: 50%;
|
| 297 |
+
width: 60px;
|
| 298 |
+
height: 60px;
|
| 299 |
+
display: flex;
|
| 300 |
+
align-items: center;
|
| 301 |
+
justify-content: center;
|
| 302 |
+
box-shadow: var(--shadow);
|
| 303 |
+
cursor: pointer;
|
| 304 |
+
z-index: 1000;
|
| 305 |
+
transition: var(--transition);
|
| 306 |
+
}
|
| 307 |
+
.cart-float:hover {
|
| 308 |
+
transform: scale(1.1);
|
| 309 |
+
background: #0d9f6e;
|
| 310 |
+
}
|
| 311 |
+
.cart-modal {
|
| 312 |
+
display: none;
|
| 313 |
+
position: fixed;
|
| 314 |
+
top: 50%;
|
| 315 |
+
left: 50%;
|
| 316 |
+
transform: translate(-50%, -50%);
|
| 317 |
+
background: var(--card-bg-light);
|
| 318 |
+
padding: 30px;
|
| 319 |
+
border-radius: 25px;
|
| 320 |
+
box-shadow: var(--shadow);
|
| 321 |
+
z-index: 2000;
|
| 322 |
+
max-width: 500px;
|
| 323 |
+
width: 90%;
|
| 324 |
+
max-height: 80vh;
|
| 325 |
+
overflow-y: auto;
|
| 326 |
+
}
|
| 327 |
+
body.dark .cart-modal {
|
| 328 |
+
background: var(--card-bg-dark);
|
| 329 |
+
}
|
| 330 |
+
.cart-modal h2 {
|
| 331 |
+
font-size: 1.8em;
|
| 332 |
+
margin-bottom: 20px;
|
| 333 |
+
background: linear-gradient(45deg, var(--primary), var(--secondary));
|
| 334 |
+
-webkit-background-clip: text;
|
| 335 |
+
color: transparent;
|
| 336 |
+
}
|
| 337 |
+
.cart-item {
|
| 338 |
+
background: var(--glass-bg);
|
| 339 |
+
padding: 15px;
|
| 340 |
+
border-radius: 15px;
|
| 341 |
+
margin-bottom: 15px;
|
| 342 |
+
}
|
| 343 |
+
.cart-item h3 {
|
| 344 |
+
font-size: 1.2em;
|
| 345 |
+
margin-bottom: 10px;
|
| 346 |
+
}
|
| 347 |
+
.cart-total {
|
| 348 |
+
font-size: 1.2em;
|
| 349 |
+
font-weight: 600;
|
| 350 |
+
margin-top: 20px;
|
| 351 |
+
}
|
| 352 |
@media (max-width: 768px) {
|
| 353 |
.sidebar {
|
| 354 |
transform: translateX(-100%);
|
|
|
|
| 372 |
font-size: 1em;
|
| 373 |
padding: 12px;
|
| 374 |
}
|
| 375 |
+
.cart-float {
|
| 376 |
+
bottom: 15px;
|
| 377 |
+
right: 15px;
|
| 378 |
+
width: 50px;
|
| 379 |
+
height: 50px;
|
| 380 |
+
}
|
| 381 |
}
|
| 382 |
'''
|
| 383 |
|
|
|
|
| 842 |
font-weight: 600;
|
| 843 |
color: var(--primary);
|
| 844 |
}
|
| 845 |
+
.quantity-input {
|
| 846 |
+
width: 60px;
|
| 847 |
+
display: inline-block;
|
| 848 |
+
margin-right: 10px;
|
| 849 |
+
}
|
| 850 |
</style>
|
| 851 |
</head>
|
| 852 |
<body>
|
| 853 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 854 |
''' + NAV_HTML + '''
|
| 855 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 856 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 857 |
+
<div class="cart-modal" id="cartModal">
|
| 858 |
+
<h2>Корзина</h2>
|
| 859 |
+
<div id="cartItems"></div>
|
| 860 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 861 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 862 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 863 |
+
</div>
|
| 864 |
<div class="container">
|
| 865 |
<h1>Лента публикаций</h1>
|
| 866 |
<div class="search-container">
|
|
|
|
| 882 |
<p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
|
| 883 |
<p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
|
| 884 |
<p class="stats">Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
|
| 885 |
+
{% if is_authenticated and user_type == 'buyer' and verified %}
|
| 886 |
+
<input type="number" class="quantity-input" id="quantity_{{ post['id'] }}" min="1" value="1">
|
| 887 |
<button class="btn cart-btn" onclick="addToCart('{{ post['id'] }}', '{{ post['title'] }}', '{{ post['price'] }}', '{{ post['currency'] }}', '{{ post['uploader'] }}')">В корзину</button>
|
| 888 |
{% endif %}
|
| 889 |
</div>
|
|
|
|
| 913 |
document.getElementById('imageModal').style.display = 'none';
|
| 914 |
}
|
| 915 |
}
|
| 916 |
+
function toggleCart() {
|
| 917 |
+
const cartModal = document.getElementById('cartModal');
|
| 918 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 919 |
+
renderCart();
|
| 920 |
+
}
|
| 921 |
function addToCart(postId, title, price, currency, uploader) {
|
| 922 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 923 |
+
const quantity = parseInt(document.getElementById('quantity_' + postId).value) || 1;
|
| 924 |
+
const existingItem = cart.find(item => item.postId === postId);
|
| 925 |
+
if (existingItem) {
|
| 926 |
+
existingItem.quantity += quantity;
|
| 927 |
} else {
|
| 928 |
+
cart.push({ postId, title, price: parseFloat(price), currency, uploader, quantity });
|
| 929 |
+
}
|
| 930 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 931 |
+
document.getElementById('cartFloat').style.display = 'block';
|
| 932 |
+
alert('Добавлено в корзину!');
|
| 933 |
+
}
|
| 934 |
+
function renderCart() {
|
| 935 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 936 |
+
const cartItems = document.getElementById('cartItems');
|
| 937 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 938 |
+
cartItems.innerHTML = '';
|
| 939 |
+
let total = 0;
|
| 940 |
+
cart.forEach(item => {
|
| 941 |
+
const div = document.createElement('div');
|
| 942 |
+
div.className = 'cart-item';
|
| 943 |
+
const itemTotal = item.price * item.quantity;
|
| 944 |
+
total += itemTotal;
|
| 945 |
+
div.innerHTML = `
|
| 946 |
+
<h3>${item.title}</h3>
|
| 947 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 948 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 949 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 950 |
+
`;
|
| 951 |
+
cartItems.appendChild(div);
|
| 952 |
+
});
|
| 953 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 954 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 955 |
+
}
|
| 956 |
+
function removeFromCart(postId) {
|
| 957 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 958 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 959 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 960 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 961 |
+
renderCart();
|
| 962 |
+
}
|
| 963 |
+
function checkout() {
|
| 964 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 965 |
+
if (cart.length === 0) {
|
| 966 |
+
alert('Корзина пуста!');
|
| 967 |
+
return;
|
| 968 |
}
|
| 969 |
+
const form = document.createElement('form');
|
| 970 |
+
form.method = 'POST';
|
| 971 |
+
form.action = '/profile';
|
| 972 |
+
const input = document.createElement('input');
|
| 973 |
+
input.type = 'hidden';
|
| 974 |
+
input.name = 'checkout';
|
| 975 |
+
input.value = 'true';
|
| 976 |
+
const cartData = document.createElement('input');
|
| 977 |
+
cartData.type = 'hidden';
|
| 978 |
+
cartData.name = 'cart_data';
|
| 979 |
+
cartData.value = JSON.stringify(cart);
|
| 980 |
+
form.appendChild(input);
|
| 981 |
+
form.appendChild(cartData);
|
| 982 |
+
document.body.appendChild(form);
|
| 983 |
+
form.submit();
|
| 984 |
+
localStorage.removeItem('cart');
|
| 985 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 986 |
}
|
| 987 |
window.onload = () => {
|
| 988 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 989 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 990 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 991 |
const videos = document.querySelectorAll('.post-preview');
|
| 992 |
videos.forEach(video => {
|
| 993 |
video.addEventListener('loadedmetadata', () => {
|
|
|
|
| 1024 |
else:
|
| 1025 |
post['likes'] = [user for user in post.get('likes', []) if user != username]
|
| 1026 |
save_data(data)
|
| 1027 |
+
|
| 1028 |
elif 'comment' in request.form:
|
| 1029 |
comment_text = request.form.get('comment')
|
| 1030 |
if comment_text:
|
|
|
|
| 1100 |
font-weight: 600;
|
| 1101 |
color: var(--primary);
|
| 1102 |
}
|
| 1103 |
+
.quantity-input {
|
| 1104 |
+
width: 60px;
|
| 1105 |
+
display: inline-block;
|
| 1106 |
+
margin-right: 10px;
|
| 1107 |
+
}
|
| 1108 |
</style>
|
| 1109 |
</head>
|
| 1110 |
<body>
|
| 1111 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1112 |
''' + NAV_HTML + '''
|
| 1113 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 1114 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 1115 |
+
<div class="cart-modal" id="cartModal">
|
| 1116 |
+
<h2>Корзина</h2>
|
| 1117 |
+
<div id="cartItems"></div>
|
| 1118 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 1119 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 1120 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 1121 |
+
</div>
|
| 1122 |
<div class="container">
|
| 1123 |
<h1>{{ post['title'] }}</h1>
|
| 1124 |
<video controls>
|
|
|
|
| 1134 |
{% if username in post['likes'] %}Убрать лайк{% else %}Лайк{% endif %}
|
| 1135 |
</button>
|
| 1136 |
</form>
|
| 1137 |
+
{% if user_type == 'buyer' and verified %}
|
| 1138 |
+
<input type="number" class="quantity-input" id="quantity_{{ post['id'] }}" min="1" value="1">
|
| 1139 |
+
<button class="btn cart-btn" onclick="addToCart('{{ post['id'] }}', '{{ post['title'] }}', '{{ post['price'] }}', '{{ post['currency'] }}', '{{ post['uploader'] }}')">В корзину</button>
|
| 1140 |
+
{% endif %}
|
| 1141 |
<form method="POST" class="comment-section">
|
| 1142 |
<textarea name="comment" placeholder="Оставьте комментарий" rows="4"></textarea>
|
| 1143 |
<button type="submit" class="btn">Отправить</button>
|
|
|
|
| 1162 |
document.body.classList.toggle('dark');
|
| 1163 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 1164 |
}
|
| 1165 |
+
function toggleCart() {
|
| 1166 |
+
const cartModal = document.getElementById('cartModal');
|
| 1167 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 1168 |
+
renderCart();
|
| 1169 |
+
}
|
| 1170 |
function addToCart(postId, title, price, currency, uploader) {
|
| 1171 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1172 |
+
const quantity = parseInt(document.getElementById('quantity_' + postId).value) || 1;
|
| 1173 |
+
const existingItem = cart.find(item => item.postId === postId);
|
| 1174 |
+
if (existingItem) {
|
| 1175 |
+
existingItem.quantity += quantity;
|
| 1176 |
} else {
|
| 1177 |
+
cart.push({ postId, title, price: parseFloat(price), currency, uploader, quantity });
|
| 1178 |
}
|
| 1179 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 1180 |
+
document.getElementById('cartFloat').style.display = 'block';
|
| 1181 |
+
alert('Добавлено в корзину!');
|
| 1182 |
+
}
|
| 1183 |
+
function renderCart() {
|
| 1184 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1185 |
+
const cartItems = document.getElementById('cartItems');
|
| 1186 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 1187 |
+
cartItems.innerHTML = '';
|
| 1188 |
+
let total = 0;
|
| 1189 |
+
cart.forEach(item => {
|
| 1190 |
+
const div = document.createElement('div');
|
| 1191 |
+
div.className = 'cart-item';
|
| 1192 |
+
const itemTotal = item.price * item.quantity;
|
| 1193 |
+
total += itemTotal;
|
| 1194 |
+
div.innerHTML = `
|
| 1195 |
+
<h3>${item.title}</h3>
|
| 1196 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 1197 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 1198 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 1199 |
+
`;
|
| 1200 |
+
cartItems.appendChild(div);
|
| 1201 |
+
});
|
| 1202 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 1203 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 1204 |
+
}
|
| 1205 |
+
function removeFromCart(postId) {
|
| 1206 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1207 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 1208 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 1209 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 1210 |
+
renderCart();
|
| 1211 |
+
}
|
| 1212 |
+
function checkout() {
|
| 1213 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1214 |
+
if (cart.length === 0) {
|
| 1215 |
+
alert('Корзина пуста!');
|
| 1216 |
+
return;
|
| 1217 |
+
}
|
| 1218 |
+
const form = document.createElement('form');
|
| 1219 |
+
form.method = 'POST';
|
| 1220 |
+
form.action = '/profile';
|
| 1221 |
+
const input = document.createElement('input');
|
| 1222 |
+
input.type = 'hidden';
|
| 1223 |
+
input.name = 'checkout';
|
| 1224 |
+
input.value = 'true';
|
| 1225 |
+
const cartData = document.createElement('input');
|
| 1226 |
+
cartData.type = 'hidden';
|
| 1227 |
+
cartData.name = 'cart_data';
|
| 1228 |
+
cartData.value = JSON.stringify(cart);
|
| 1229 |
+
form.appendChild(input);
|
| 1230 |
+
form.appendChild(cartData);
|
| 1231 |
+
document.body.appendChild(form);
|
| 1232 |
+
form.submit();
|
| 1233 |
+
localStorage.removeItem('cart');
|
| 1234 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 1235 |
}
|
| 1236 |
window.onload = () => {
|
| 1237 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 1238 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1239 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 1240 |
};
|
| 1241 |
</script>
|
| 1242 |
</body>
|
|
|
|
| 1330 |
'title': item['title'],
|
| 1331 |
'price': item['price'],
|
| 1332 |
'currency': item['currency'],
|
| 1333 |
+
'quantity': item['quantity'],
|
| 1334 |
'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
| 1335 |
'status': 'pending',
|
| 1336 |
'buyer_phone': phone,
|
|
|
|
| 1457 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1458 |
''' + NAV_HTML + '''
|
| 1459 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 1460 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 1461 |
+
<div class="cart-modal" id="cartModal">
|
| 1462 |
+
<h2>Корзина</h2>
|
| 1463 |
+
<div id="cartItems"></div>
|
| 1464 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 1465 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 1466 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 1467 |
+
</div>
|
| 1468 |
<div class="container">
|
| 1469 |
<div class="profile-header">
|
| 1470 |
{% if avatar %}
|
|
|
|
| 1511 |
{% endif %}
|
| 1512 |
<h2>Корзина</h2>
|
| 1513 |
<div class="cart-grid" id="cartGrid"></div>
|
| 1514 |
+
<p class="cart-total" id="cartTotalProfile">Итого: 0</p>
|
| 1515 |
<button class="btn" onclick="checkout()" style="margin-top: 20px;">Оформить заказ</button>
|
| 1516 |
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 1517 |
{% if messages %}
|
|
|
|
| 1558 |
alert('Ссылка скопирована!');
|
| 1559 |
});
|
| 1560 |
}
|
| 1561 |
+
function toggleCart() {
|
| 1562 |
+
const cartModal = document.getElementById('cartModal');
|
| 1563 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 1564 |
+
renderCart();
|
| 1565 |
+
}
|
| 1566 |
function renderCart() {
|
| 1567 |
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1568 |
+
const cartItems = document.getElementById('cartItems');
|
| 1569 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 1570 |
const cartGrid = document.getElementById('cartGrid');
|
| 1571 |
+
const cartTotalProfile = document.getElementById('cartTotalProfile');
|
| 1572 |
+
cartItems.innerHTML = '';
|
| 1573 |
cartGrid.innerHTML = '';
|
| 1574 |
+
let total = 0;
|
| 1575 |
cart.forEach(item => {
|
| 1576 |
+
const itemTotal = item.price * item.quantity;
|
| 1577 |
+
total += itemTotal;
|
| 1578 |
const div = document.createElement('div');
|
| 1579 |
div.className = 'cart-item';
|
| 1580 |
div.innerHTML = `
|
| 1581 |
<h3>${item.title}</h3>
|
| 1582 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 1583 |
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 1584 |
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 1585 |
`;
|
| 1586 |
+
cartItems.appendChild(div.cloneNode(true));
|
| 1587 |
cartGrid.appendChild(div);
|
| 1588 |
});
|
| 1589 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 1590 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 1591 |
+
cartTotalProfile.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 1592 |
}
|
| 1593 |
function removeFromCart(postId) {
|
| 1594 |
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1595 |
cart = cart.filter(item => item.postId !== postId);
|
| 1596 |
localStorage.setItem('cart', JSON.stringify(cart));
|
| 1597 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 1598 |
renderCart();
|
| 1599 |
}
|
| 1600 |
function checkout() {
|
|
|
|
| 1619 |
document.body.appendChild(form);
|
| 1620 |
form.submit();
|
| 1621 |
localStorage.removeItem('cart');
|
| 1622 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 1623 |
}
|
| 1624 |
window.onload = () => {
|
| 1625 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 1626 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1627 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 1628 |
renderCart();
|
| 1629 |
const videos = document.querySelectorAll('.post-preview');
|
| 1630 |
videos.forEach(video => {
|
|
|
|
| 1763 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 1764 |
''' + NAV_HTML + '''
|
| 1765 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 1766 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 1767 |
+
<div class="cart-modal" id="cartModal">
|
| 1768 |
+
<h2>Корзина</h2>
|
| 1769 |
+
<div id="cartItems"></div>
|
| 1770 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 1771 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 1772 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 1773 |
+
</div>
|
| 1774 |
<div class="container">
|
| 1775 |
<div class="profile-header">
|
| 1776 |
{% if avatar %}
|
|
|
|
| 1829 |
alert('Ссылка скопирована!');
|
| 1830 |
});
|
| 1831 |
}
|
| 1832 |
+
function toggleCart() {
|
| 1833 |
+
const cartModal = document.getElementById('cartModal');
|
| 1834 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 1835 |
+
renderCart();
|
| 1836 |
+
}
|
| 1837 |
+
function renderCart() {
|
| 1838 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1839 |
+
const cartItems = document.getElementById('cartItems');
|
| 1840 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 1841 |
+
cartItems.innerHTML = '';
|
| 1842 |
+
let total = 0;
|
| 1843 |
+
cart.forEach(item => {
|
| 1844 |
+
const itemTotal = item.price * item.quantity;
|
| 1845 |
+
total += itemTotal;
|
| 1846 |
+
const div = document.createElement('div');
|
| 1847 |
+
div.className = 'cart-item';
|
| 1848 |
+
div.innerHTML = `
|
| 1849 |
+
<h3>${item.title}</h3>
|
| 1850 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 1851 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 1852 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 1853 |
+
`;
|
| 1854 |
+
cartItems.appendChild(div);
|
| 1855 |
+
});
|
| 1856 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 1857 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 1858 |
+
}
|
| 1859 |
+
function removeFromCart(postId) {
|
| 1860 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1861 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 1862 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 1863 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 1864 |
+
renderCart();
|
| 1865 |
+
}
|
| 1866 |
+
function checkout() {
|
| 1867 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1868 |
+
if (cart.length === 0) {
|
| 1869 |
+
alert('Корзина пуста!');
|
| 1870 |
+
return;
|
| 1871 |
+
}
|
| 1872 |
+
const form = document.createElement('form');
|
| 1873 |
+
form.method = 'POST';
|
| 1874 |
+
form.action = '/profile';
|
| 1875 |
+
const input = document.createElement('input');
|
| 1876 |
+
input.type = 'hidden';
|
| 1877 |
+
input.name = 'checkout';
|
| 1878 |
+
input.value = 'true';
|
| 1879 |
+
const cartData = document.createElement('input');
|
| 1880 |
+
cartData.type = 'hidden';
|
| 1881 |
+
cartData.name = 'cart_data';
|
| 1882 |
+
cartData.value = JSON.stringify(cart);
|
| 1883 |
+
form.appendChild(input);
|
| 1884 |
+
form.appendChild(cartData);
|
| 1885 |
+
document.body.appendChild(form);
|
| 1886 |
+
form.submit();
|
| 1887 |
+
localStorage.removeItem('cart');
|
| 1888 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 1889 |
+
}
|
| 1890 |
window.onload = () => {
|
| 1891 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 1892 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 1893 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 1894 |
const videos = document.querySelectorAll('.post-preview');
|
| 1895 |
videos.forEach(video => {
|
| 1896 |
video.addEventListener('loadedmetadata', () => {
|
|
|
|
| 2042 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2043 |
''' + NAV_HTML + '''
|
| 2044 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 2045 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 2046 |
+
<div class="cart-modal" id="cartModal">
|
| 2047 |
+
<h2>Корзина</h2>
|
| 2048 |
+
<div id="cartItems"></div>
|
| 2049 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 2050 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 2051 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 2052 |
+
</div>
|
| 2053 |
<div class="container">
|
| 2054 |
<h1>Загрузить видео</h1>
|
| 2055 |
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
|
|
| 2087 |
document.body.classList.toggle('dark');
|
| 2088 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2089 |
}
|
| 2090 |
+
function toggleCart() {
|
| 2091 |
+
const cartModal = document.getElementById('cartModal');
|
| 2092 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 2093 |
+
renderCart();
|
| 2094 |
+
}
|
| 2095 |
+
function renderCart() {
|
| 2096 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2097 |
+
const cartItems = document.getElementById('cartItems');
|
| 2098 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 2099 |
+
cartItems.innerHTML = '';
|
| 2100 |
+
let total = 0;
|
| 2101 |
+
cart.forEach(item => {
|
| 2102 |
+
const itemTotal = item.price * item.quantity;
|
| 2103 |
+
total += itemTotal;
|
| 2104 |
+
const div = document.createElement('div');
|
| 2105 |
+
div.className = 'cart-item';
|
| 2106 |
+
div.innerHTML = `
|
| 2107 |
+
<h3>${item.title}</h3>
|
| 2108 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 2109 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 2110 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 2111 |
+
`;
|
| 2112 |
+
cartItems.appendChild(div);
|
| 2113 |
+
});
|
| 2114 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 2115 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 2116 |
+
}
|
| 2117 |
+
function removeFromCart(postId) {
|
| 2118 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2119 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 2120 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 2121 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 2122 |
+
renderCart();
|
| 2123 |
+
}
|
| 2124 |
+
function checkout() {
|
| 2125 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2126 |
+
if (cart.length === 0) {
|
| 2127 |
+
alert('Корзина пуста!');
|
| 2128 |
+
return;
|
| 2129 |
+
}
|
| 2130 |
+
const form = document.createElement('form');
|
| 2131 |
+
form.method = 'POST';
|
| 2132 |
+
form.action = '/profile';
|
| 2133 |
+
const input = document.createElement('input');
|
| 2134 |
+
input.type = 'hidden';
|
| 2135 |
+
input.name = 'checkout';
|
| 2136 |
+
input.value = 'true';
|
| 2137 |
+
const cartData = document.createElement('input');
|
| 2138 |
+
cartData.type = 'hidden';
|
| 2139 |
+
cartData.name = 'cart_data';
|
| 2140 |
+
cartData.value = JSON.stringify(cart);
|
| 2141 |
+
form.appendChild(input);
|
| 2142 |
+
form.appendChild(cartData);
|
| 2143 |
+
document.body.appendChild(form);
|
| 2144 |
+
form.submit();
|
| 2145 |
+
localStorage.removeItem('cart');
|
| 2146 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 2147 |
+
}
|
| 2148 |
document.getElementById('upload-form').onsubmit = async function(e) {
|
| 2149 |
e.preventDefault();
|
| 2150 |
const formData = new FormData(this);
|
|
|
|
| 2168 |
};
|
| 2169 |
window.onload = () => {
|
| 2170 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 2171 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2172 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 2173 |
};
|
| 2174 |
</script>
|
| 2175 |
</body>
|
|
|
|
| 2283 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2284 |
''' + NAV_HTML + '''
|
| 2285 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 2286 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 2287 |
+
<div class="cart-modal" id="cartModal">
|
| 2288 |
+
<h2>Корзина</h2>
|
| 2289 |
+
<div id="cartItems"></div>
|
| 2290 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 2291 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 2292 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 2293 |
+
</div>
|
| 2294 |
<div class="container">
|
| 2295 |
<h1>Ваши заказы</h1>
|
| 2296 |
<div class="order-grid">
|
|
|
|
| 2298 |
{% for order in orders %}
|
| 2299 |
<div class="order-item">
|
| 2300 |
<h3>{{ order['title'] }}</h3>
|
| 2301 |
+
<p class="price">Цена: {{ order['price'] }} {{ order['currency'] }} x {{ order['quantity'] }} = {{ (order['price']|float * order['quantity'])|round(2) }} {{ order['currency'] }}</p>
|
| 2302 |
<p>Покупатель: <a href="{{ url_for('user_profile', username=order['buyer']) }}" class="username-link">{{ order['buyer'] }}</a></p>
|
| 2303 |
<p>Телефон покупателя: {{ order['buyer_phone'] }}</p>
|
| 2304 |
{% if order['buyer_address'] %}
|
|
|
|
| 2329 |
document.body.classList.toggle('dark');
|
| 2330 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2331 |
}
|
| 2332 |
+
function toggleCart() {
|
| 2333 |
+
const cartModal = document.getElementById('cartModal');
|
| 2334 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 2335 |
+
renderCart();
|
| 2336 |
+
}
|
| 2337 |
+
function renderCart() {
|
| 2338 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2339 |
+
const cartItems = document.getElementById('cartItems');
|
| 2340 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 2341 |
+
cartItems.innerHTML = '';
|
| 2342 |
+
let total = 0;
|
| 2343 |
+
cart.forEach(item => {
|
| 2344 |
+
const itemTotal = item.price * item.quantity;
|
| 2345 |
+
total += itemTotal;
|
| 2346 |
+
const div = document.createElement('div');
|
| 2347 |
+
div.className = 'cart-item';
|
| 2348 |
+
div.innerHTML = `
|
| 2349 |
+
<h3>${item.title}</h3>
|
| 2350 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 2351 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 2352 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 2353 |
+
`;
|
| 2354 |
+
cartItems.appendChild(div);
|
| 2355 |
+
});
|
| 2356 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 2357 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 2358 |
+
}
|
| 2359 |
+
function removeFromCart(postId) {
|
| 2360 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2361 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 2362 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 2363 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 2364 |
+
renderCart();
|
| 2365 |
+
}
|
| 2366 |
+
function checkout() {
|
| 2367 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2368 |
+
if (cart.length === 0) {
|
| 2369 |
+
alert('Корзина пуста!');
|
| 2370 |
+
return;
|
| 2371 |
+
}
|
| 2372 |
+
const form = document.createElement('form');
|
| 2373 |
+
form.method = 'POST';
|
| 2374 |
+
form.action = '/profile';
|
| 2375 |
+
const input = document.createElement('input');
|
| 2376 |
+
input.type = 'hidden';
|
| 2377 |
+
input.name = 'checkout';
|
| 2378 |
+
input.value = 'true';
|
| 2379 |
+
const cartData = document.createElement('input');
|
| 2380 |
+
cartData.type = 'hidden';
|
| 2381 |
+
cartData.name = 'cart_data';
|
| 2382 |
+
cartData.value = JSON.stringify(cart);
|
| 2383 |
+
form.appendChild(input);
|
| 2384 |
+
form.appendChild(cartData);
|
| 2385 |
+
document.body.appendChild(form);
|
| 2386 |
+
form.submit();
|
| 2387 |
+
localStorage.removeItem('cart');
|
| 2388 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 2389 |
+
}
|
| 2390 |
window.onload = () => {
|
| 2391 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 2392 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2393 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 2394 |
};
|
| 2395 |
</script>
|
| 2396 |
</body>
|
|
|
|
| 2436 |
color: transparent;
|
| 2437 |
}
|
| 2438 |
.order-grid {
|
| 2439 |
+
display grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
|
|
|
| 2440 |
gap: 30px;
|
| 2441 |
}
|
| 2442 |
.order-item {
|
|
|
|
| 2479 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2480 |
''' + NAV_HTML + '''
|
| 2481 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 2482 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 2483 |
+
<div class="cart-modal" id="cartModal">
|
| 2484 |
+
<h2>Корзина</h2>
|
| 2485 |
+
<div id="cartItems"></div>
|
| 2486 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 2487 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 2488 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 2489 |
+
</div>
|
| 2490 |
<div class="container">
|
| 2491 |
<h1>Мои заказы</h1>
|
| 2492 |
<div class="order-grid">
|
|
|
|
| 2494 |
{% for order in orders %}
|
| 2495 |
<div class="order-item">
|
| 2496 |
<h3>{{ order['title'] }}</h3>
|
| 2497 |
+
<p class="price">Цена: {{ order['price'] }} {{ order['currency'] }} x {{ order['quantity'] }} = {{ (order['price']|float * order['quantity'])|round(2) }} {{ order['currency'] }}</p>
|
| 2498 |
<p>Продавец: <a href="{{ url_for('user_profile', username=order['uploader']) }}" class="username-link">{{ order['uploader'] }}</a></p>
|
| 2499 |
<p>Дата: {{ order['date'] }}</p>
|
| 2500 |
<p>Статус: {{ 'В ожидании' if order['status'] == 'pending' else 'В обработке' if order['status'] == 'processing' else 'Завершено' }}</p>
|
|
|
|
| 2513 |
document.body.classList.toggle('dark');
|
| 2514 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2515 |
}
|
| 2516 |
+
function toggleCart() {
|
| 2517 |
+
const cartModal = document.getElementById('cartModal');
|
| 2518 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 2519 |
+
renderCart();
|
| 2520 |
+
}
|
| 2521 |
+
function renderCart() {
|
| 2522 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2523 |
+
const cartItems = document.getElementById('cartItems');
|
| 2524 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 2525 |
+
cartItems.innerHTML = '';
|
| 2526 |
+
let total = 0;
|
| 2527 |
+
cart.forEach(item => {
|
| 2528 |
+
const itemTotal = item.price * item.quantity;
|
| 2529 |
+
total += itemTotal;
|
| 2530 |
+
const div = document.createElement('div');
|
| 2531 |
+
div.className = 'cart-item';
|
| 2532 |
+
div.innerHTML = `
|
| 2533 |
+
<h3>${item.title}</h3>
|
| 2534 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 2535 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 2536 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 2537 |
+
`;
|
| 2538 |
+
cartItems.appendChild(div);
|
| 2539 |
+
});
|
| 2540 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 2541 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 2542 |
+
}
|
| 2543 |
+
function removeFromCart(postId) {
|
| 2544 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2545 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 2546 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 2547 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 2548 |
+
renderCart();
|
| 2549 |
+
}
|
| 2550 |
+
function checkout() {
|
| 2551 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2552 |
+
if (cart.length === 0) {
|
| 2553 |
+
alert('Корзина пуста!');
|
| 2554 |
+
return;
|
| 2555 |
+
}
|
| 2556 |
+
const form = document.createElement('form');
|
| 2557 |
+
form.method = 'POST';
|
| 2558 |
+
form.action = '/profile';
|
| 2559 |
+
const input = document.createElement('input');
|
| 2560 |
+
input.type = 'hidden';
|
| 2561 |
+
input.name = 'checkout';
|
| 2562 |
+
input.value = 'true';
|
| 2563 |
+
const cartData = document.createElement('input');
|
| 2564 |
+
cartData.type = 'hidden';
|
| 2565 |
+
cartData.name = 'cart_data';
|
| 2566 |
+
cartData.value = JSON.stringify(cart);
|
| 2567 |
+
form.appendChild(input);
|
| 2568 |
+
form.appendChild(cartData);
|
| 2569 |
+
document.body.appendChild(form);
|
| 2570 |
+
form.submit();
|
| 2571 |
+
localStorage.removeItem('cart');
|
| 2572 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 2573 |
+
}
|
| 2574 |
window.onload = () => {
|
| 2575 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 2576 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2577 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 2578 |
};
|
| 2579 |
</script>
|
| 2580 |
</body>
|
|
|
|
| 2739 |
<button class="menu-btn" onclick="toggleSidebar()">☰</button>
|
| 2740 |
''' + NAV_HTML + '''
|
| 2741 |
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
| 2742 |
+
<div class="cart-float" onclick="toggleCart()" style="display: none;" id="cartFloat">🛒</div>
|
| 2743 |
+
<div class="cart-modal" id="cartModal">
|
| 2744 |
+
<h2>Корзина</h2>
|
| 2745 |
+
<div id="cartItems"></div>
|
| 2746 |
+
<p class="cart-total" id="cartTotal">Итого: 0</p>
|
| 2747 |
+
<button class="btn" onclick="checkout()">Оформить заказ</button>
|
| 2748 |
+
<button class="btn" onclick="toggleCart()">Закрыть</button>
|
| 2749 |
+
</div>
|
| 2750 |
<div class="container">
|
| 2751 |
<h1>Админ-панель</h1>
|
| 2752 |
<h2>Организации на проверке</h2>
|
|
|
|
| 2809 |
document.body.classList.toggle('dark');
|
| 2810 |
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
|
| 2811 |
}
|
| 2812 |
+
function toggleCart() {
|
| 2813 |
+
const cartModal = document.getElementById('cartModal');
|
| 2814 |
+
cartModal.style.display = cartModal.style.display === 'block' ? 'none' : 'block';
|
| 2815 |
+
renderCart();
|
| 2816 |
+
}
|
| 2817 |
+
function renderCart() {
|
| 2818 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2819 |
+
const cartItems = document.getElementById('cartItems');
|
| 2820 |
+
const cartTotal = document.getElementById('cartTotal');
|
| 2821 |
+
cartItems.innerHTML = '';
|
| 2822 |
+
let total = 0;
|
| 2823 |
+
cart.forEach(item => {
|
| 2824 |
+
const itemTotal = item.price * item.quantity;
|
| 2825 |
+
total += itemTotal;
|
| 2826 |
+
const div = document.createElement('div');
|
| 2827 |
+
div.className = 'cart-item';
|
| 2828 |
+
div.innerHTML = `
|
| 2829 |
+
<h3>${item.title}</h3>
|
| 2830 |
+
<p>Цена: ${item.price} ${item.currency} x ${item.quantity} = ${itemTotal.toFixed(2)} ${item.currency}</p>
|
| 2831 |
+
<p>Продавец: <a href="/profile/${item.uploader}" class="username-link">${item.uploader}</a></p>
|
| 2832 |
+
<button class="btn remove-cart-btn" onclick="removeFromCart('${item.postId}')">Удалить</button>
|
| 2833 |
+
`;
|
| 2834 |
+
cartItems.appendChild(div);
|
| 2835 |
+
});
|
| 2836 |
+
const totalCurrency = cart.length > 0 ? cart[0].currency : '';
|
| 2837 |
+
cartTotal.textContent = `Итого: ${total.toFixed(2)} ${totalCurrency}`;
|
| 2838 |
+
}
|
| 2839 |
+
function removeFromCart(postId) {
|
| 2840 |
+
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2841 |
+
cart = cart.filter(item => item.postId !== postId);
|
| 2842 |
+
localStorage.setItem('cart', JSON.stringify(cart));
|
| 2843 |
+
if (cart.length === 0) document.getElementById('cartFloat').style.display = 'none';
|
| 2844 |
+
renderCart();
|
| 2845 |
+
}
|
| 2846 |
+
function checkout() {
|
| 2847 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2848 |
+
if (cart.length === 0) {
|
| 2849 |
+
alert('Корзина пуста!');
|
| 2850 |
+
return;
|
| 2851 |
+
}
|
| 2852 |
+
const form = document.createElement('form');
|
| 2853 |
+
form.method = 'POST';
|
| 2854 |
+
form.action = '/profile';
|
| 2855 |
+
const input = document.createElement('input');
|
| 2856 |
+
input.type = 'hidden';
|
| 2857 |
+
input.name = 'checkout';
|
| 2858 |
+
input.value = 'true';
|
| 2859 |
+
const cartData = document.createElement('input');
|
| 2860 |
+
cartData.type = 'hidden';
|
| 2861 |
+
cartData.name = 'cart_data';
|
| 2862 |
+
cartData.value = JSON.stringify(cart);
|
| 2863 |
+
form.appendChild(input);
|
| 2864 |
+
form.appendChild(cartData);
|
| 2865 |
+
document.body.appendChild(form);
|
| 2866 |
+
form.submit();
|
| 2867 |
+
localStorage.removeItem('cart');
|
| 2868 |
+
document.getElementById('cartFloat').style.display = 'none';
|
| 2869 |
+
}
|
| 2870 |
window.onload = () => {
|
| 2871 |
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
|
| 2872 |
+
const cart = JSON.parse(localStorage.getItem('cart') || '[]');
|
| 2873 |
+
if (cart.length > 0) document.getElementById('cartFloat').style.display = 'block';
|
| 2874 |
const videos = document.querySelectorAll('.post-preview');
|
| 2875 |
videos.forEach(video => {
|
| 2876 |
video.addEventListener('loadedmetadata', () => {
|
|
|
|
| 2887 |
if __name__ == '__main__':
|
| 2888 |
backup_thread = threading.Thread(target=periodic_backup, daemon=True)
|
| 2889 |
backup_thread.start()
|
| 2890 |
+
app.run(debug=True, host='0.0.0.0', port=7860)
|