Kgshop commited on
Commit
11c2347
·
verified ·
1 Parent(s): dca336a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -134
app.py CHANGED
@@ -16,7 +16,7 @@ import uuid
16
  load_dotenv()
17
 
18
  app = Flask(__name__)
19
- app.secret_key = 'your_unique_secret_key_aruuke_optomkz_99999_no_login'
20
  DATA_FILE = 'data.json'
21
 
22
 
@@ -211,97 +211,96 @@ CATALOG_TEMPLATE = '''
211
  <head>
212
  <meta charset="UTF-8">
213
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
214
- <title>Aruuke_optomKZ - Каталог</title>
215
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
216
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
217
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/10.2.0/swiper-bundle.min.css">
218
  <style>
219
  * { margin: 0; padding: 0; box-sizing: border-box; }
220
- body { font-family: 'Poppins', sans-serif; background: #FFF0F5; color: #4d333f; line-height: 1.6; transition: background 0.3s, color 0.3s; }
221
- body.dark-mode { background: #2c1a2b; color: #fce7f3; }
222
  .container { max-width: 1300px; margin: 0 auto; padding: 20px; }
223
- .header { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; border-bottom: 1px solid #FBCFE8; }
224
- body.dark-mode .header { border-bottom-color: #59344f; }
225
- .header h1 { font-size: 1.6rem; font-weight: 600; color: #F472B6; }
226
- .theme-toggle { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #d1a7b8; transition: color 0.3s ease; }
227
- .theme-toggle:hover { color: #DB2777; }
228
- body.dark-mode .theme-toggle { color: #fbcfe8; }
229
- body.dark-mode .theme-toggle:hover { color: #f9a8d4; }
230
- .store-address { padding: 15px; text-align: center; background-color: #ffffff; margin: 20px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); font-size: 1rem; color: #6b4d5d; }
231
- body.dark-mode .store-address { background-color: #412539; color: #fbcfe8; }
232
  .filters-container { margin: 20px 0; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
233
  .search-container { margin: 20px 0; text-align: center; }
234
- #search-input { width: 90%; max-width: 600px; padding: 12px 18px; font-size: 1rem; border: 1px solid #FBCFE8; border-radius: 25px; outline: none; box-shadow: 0 2px 5px rgba(0,0,0,0.05); transition: all 0.3s ease; }
235
- body.dark-mode #search-input { background-color: #412539; border-color: #59344f; color: #fce7f3; }
236
- #search-input:focus { border-color: #F472B6; box-shadow: 0 0 0 3px rgba(244, 114, 182, 0.2); }
237
- body.dark-mode #search-input:focus { border-color: #EC4899; box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.3); }
238
- .category-filter { padding: 8px 16px; border: 1px solid #FBCFE8; border-radius: 20px; background-color: #fff; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); font-size: 0.9rem; font-weight: 400; color: #DB2777; }
239
- body.dark-mode .category-filter { background-color: #412539; border-color: #59344f; color: #f9a8d4; }
240
- .category-filter.active, .category-filter:hover { background-color: #F472B6; color: white; border-color: #F472B6; box-shadow: 0 2px 10px rgba(244, 114, 182, 0.3); }
241
- body.dark-mode .category-filter.active, body.dark-mode .category-filter:hover { background-color: #EC4899; border-color: #EC4899; color: #2c1a2b; box-shadow: 0 2px 10px rgba(236, 72, 153, 0.4); }
242
  .products-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px; padding: 10px; }
243
  @media (min-width: 600px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } }
244
  @media (min-width: 900px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); } }
245
-
246
- .product { background: #fff; border-radius: 15px; padding: 0; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; height: 100%; border: 1px solid #FCE7F3;}
247
- body.dark-mode .product { background: #412539; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); border-color: #59344f; }
248
  .product:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); }
249
  body.dark-mode .product:hover { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); }
250
  .product-image { width: 100%; aspect-ratio: 1 / 1; background-color: #fff; border-radius: 10px 10px 0 0; overflow: hidden; display: flex; justify-content: center; align-items: center; margin-bottom: 0; }
251
  .product-image img { max-width: 100%; max-height: 100%; object-fit: contain; transition: transform 0.3s ease; }
252
  .product-info { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; justify-content: center; }
253
- .product h2 { font-size: 1.1rem; font-weight: 600; margin: 0 0 8px 0; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #4d333f; }
254
- body.dark-mode .product h2 { color: #fce7f3; }
255
- .product-price { font-size: 1.2rem; color: #DB2777; font-weight: 700; text-align: center; margin: 5px 0; }
256
- body.dark-mode .product-price { color: #f9a8d4; }
257
- .product-description { font-size: 0.85rem; color: #b88fa7; text-align: center; margin-bottom: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
258
- body.dark-mode .product-description { color: #fbcfe8; }
259
  .product-actions { padding: 0 15px 15px 15px; display: flex; flex-direction: column; gap: 8px; }
260
- .product-button { display: block; width: 100%; padding: 10px; border: none; border-radius: 8px; background-color: #F472B6; color: white; font-size: 0.9rem; font-weight: 500; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); text-align: center; text-decoration: none; }
261
- .product-button:hover { background-color: #DB2777; box-shadow: 0 4px 15px rgba(219, 39, 119, 0.4); transform: translateY(-2px); }
262
  .product-button i { margin-right: 5px; }
263
- .add-to-cart { background-color: #F472B6; }
264
- .add-to-cart:hover { background-color: #DB2777; box-shadow: 0 4px 15px rgba(219, 39, 119, 0.4); }
265
- #cart-button { position: fixed; bottom: 25px; right: 25px; background-color: #F472B6; color: white; border: none; border-radius: 50%; width: 55px; height: 55px; font-size: 1.5rem; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 4px 15px rgba(244, 114, 182, 0.4); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); z-index: 1000; }
266
  #cart-button .fa-shopping-cart { margin-right: 0; }
267
- #cart-button span { position: absolute; top: -5px; right: -5px; background-color: #DB2777; color: white; border-radius: 50%; padding: 2px 6px; font-size: 0.7rem; font-weight: bold; }
268
  .modal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.6); backdrop-filter: blur(5px); overflow-y: auto; }
269
  .modal-content { background: #ffffff; margin: 5% auto; padding: 25px; border-radius: 15px; width: 90%; max-width: 700px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); animation: slideIn 0.3s ease-out; position: relative; }
270
- body.dark-mode .modal-content { background: #412539; color: #fce7f3; }
271
  @keyframes slideIn { from { transform: translateY(-30px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
272
- .close { position: absolute; top: 15px; right: 15px; font-size: 1.8rem; color: #aaa; cursor: pointer; transition: color 0.3s; line-height: 1; }
273
- .close:hover { color: #333; }
274
- body.dark-mode .close { color: #fbcfe8; }
275
  body.dark-mode .close:hover { color: #ffffff; }
276
- .modal-content h2 { margin-top: 0; margin-bottom: 20px; color: #F472B6; display: flex; align-items: center; gap: 10px;}
277
- body.dark-mode .modal-content h2 { color: #f9a8d4; }
278
- .cart-item { display: grid; grid-template-columns: auto 1fr auto auto; gap: 15px; align-items: center; padding: 15px 0; border-bottom: 1px solid #FBCFE8; }
279
- body.dark-mode .cart-item { border-bottom-color: #59344f; }
280
  .cart-item:last-child { border-bottom: none; }
281
  .cart-item img { width: 60px; height: 60px; object-fit: contain; border-radius: 8px; background-color: #fff; padding: 5px; grid-column: 1; }
282
  .cart-item-details { grid-column: 2; }
283
  .cart-item-details strong { display: block; margin-bottom: 5px; font-size: 1rem; }
284
- .cart-item-price { font-size: 0.9rem; color: #6b4d5d; }
285
- body.dark-mode .cart-item-price { color: #fbcfe8; }
286
  .cart-item-total { font-weight: bold; text-align: right; grid-column: 3; font-size: 1rem;}
287
- .cart-item-remove { grid-column: 4; background:none; border:none; color:#f56565; cursor:pointer; font-size: 1.3em; padding: 5px; line-height: 1; }
288
- .cart-item-remove:hover { color: #c53030; }
289
- .quantity-input, .color-select { width: 100%; max-width: 180px; padding: 10px; border: 1px solid #FBCFE8; border-radius: 8px; font-size: 1rem; margin: 10px 0; box-sizing: border-box; }
290
- body.dark-mode .quantity-input, body.dark-mode .color-select { background-color: #2c1a2b; border-color: #59344f; color: #fce7f3; }
291
- .cart-summary { margin-top: 20px; text-align: right; border-top: 1px solid #FBCFE8; padding-top: 15px; }
292
- body.dark-mode .cart-summary { border-top-color: #59344f; }
293
  .cart-summary strong { font-size: 1.2rem; }
294
  .cart-actions { margin-top: 25px; display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
295
  .cart-actions .product-button { width: auto; flex-grow: 1; }
296
- .clear-cart { background-color: #a0aec0; }
297
- .clear-cart:hover { background-color: #718096; box-shadow: 0 4px 15px rgba(113, 128, 150, 0.4); }
298
- .formulate-order-button { background-color: #F472B6; }
299
- .formulate-order-button:hover { background-color: #DB2777; box-shadow: 0 4px 15px rgba(219, 39, 119, 0.4); }
300
- .notification { position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%); background-color: #F472B6; color: white; padding: 10px 20px; border-radius: 20px; box-shadow: 0 4px 10px rgba(0,0,0,0.2); z-index: 1002; opacity: 0; transition: opacity 0.5s ease; font-size: 0.9rem;}
301
  .notification.show { opacity: 1;}
302
- .no-results-message { grid-column: 1 / -1; text-align: center; padding: 40px; font-size: 1.1rem; color: #a0aec0; }
303
- body.dark-mode .no-results-message { color: #fbcfe8; }
304
- .top-product-indicator { position: absolute; top: 8px; right: 8px; background-color: rgba(255, 215, 0, 0.8); color: #333; padding: 2px 6px; font-size: 0.7rem; border-radius: 4px; font-weight: bold; z-index: 10; backdrop-filter: blur(2px); }
305
  .product { position: relative; }
306
  </style>
307
  </head>
@@ -309,8 +308,8 @@ CATALOG_TEMPLATE = '''
309
  <div class="container">
310
  <div class="header">
311
  <div class="logo-title-container" style="display: flex; align-items: center; gap: 15px;">
312
- <img src="https://huggingface.co/spaces/Aruuke-almaty/admin/resolve/main/464856221_879152084357535_5878527617319379130_n.jpg" alt="Aruuke_optomKZ Logo" style="height: 50px; width: 50px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 8px rgba(244, 114, 182, 0.7), 0 0 15px rgba(219, 39, 119, 0.5);">
313
- <h1>Aruuke_optomKZ</h1>
314
  </div>
315
  <button class="theme-toggle" onclick="toggleTheme()" aria-label="Переключить тему">
316
  <i class="fas fa-moon"></i>
@@ -418,7 +417,7 @@ CATALOG_TEMPLATE = '''
418
  const repoId = '{{ repo_id }}';
419
  const currencyCode = '{{ currency_code }}';
420
  let selectedProductIndex = null;
421
- let cart = JSON.parse(localStorage.getItem('soolaCart') || '[]');
422
 
423
  function toggleTheme() {
424
  document.body.classList.toggle('dark-mode');
@@ -426,11 +425,11 @@ CATALOG_TEMPLATE = '''
426
  const isDarkMode = document.body.classList.contains('dark-mode');
427
  icon.classList.toggle('fa-moon', !isDarkMode);
428
  icon.classList.toggle('fa-sun', isDarkMode);
429
- localStorage.setItem('soolaTheme', isDarkMode ? 'dark' : 'light');
430
  }
431
 
432
  function applyInitialTheme() {
433
- const savedTheme = localStorage.getItem('soolaTheme');
434
  if (savedTheme === 'dark') {
435
  document.body.classList.add('dark-mode');
436
  const icon = document.querySelector('.theme-toggle i');
@@ -566,7 +565,7 @@ CATALOG_TEMPLATE = '''
566
  });
567
  }
568
 
569
- localStorage.setItem('soolaCart', JSON.stringify(cart));
570
  closeModal('quantityModal');
571
  updateCartButton();
572
  showNotification(`${product.name} добавлен в корзину!`);
@@ -631,7 +630,7 @@ CATALOG_TEMPLATE = '''
631
 
632
  function removeFromCart(itemId) {
633
  cart = cart.filter(item => item.id !== itemId);
634
- localStorage.setItem('soolaCart', JSON.stringify(cart));
635
  openCartModal();
636
  updateCartButton();
637
  }
@@ -639,7 +638,7 @@ CATALOG_TEMPLATE = '''
639
  function clearCart() {
640
  if (confirm("Вы уверены, что хотите очистить корзину?")) {
641
  cart = [];
642
- localStorage.removeItem('soolaCart');
643
  openCartModal();
644
  updateCartButton();
645
  }
@@ -673,7 +672,7 @@ CATALOG_TEMPLATE = '''
673
  })
674
  .then(data => {
675
  if (data.order_id) {
676
- localStorage.removeItem('soolaCart');
677
  cart = [];
678
  updateCartButton();
679
  closeModal('cartModal');
@@ -802,7 +801,7 @@ CATALOG_TEMPLATE = '''
802
 
803
  PRODUCT_DETAIL_TEMPLATE = '''
804
  <div style="padding: 10px;">
805
- <h2 style="font-size: 1.6rem; font-weight: 600; margin-bottom: 15px; text-align: center; color: #F472B6;">{{ product['name'] }}</h2>
806
  <div class="swiper-container" style="max-width: 450px; margin: 0 auto 20px; border-radius: 10px; overflow: hidden; background-color: #fff;">
807
  <div class="swiper-wrapper">
808
  {% if product.get('photos') and product['photos']|length > 0 %}
@@ -823,14 +822,14 @@ PRODUCT_DETAIL_TEMPLATE = '''
823
  </div>
824
  {% if product.get('photos') and product['photos']|length > 1 %}
825
  <div class="swiper-pagination" style="position: relative; bottom: 5px;"></div>
826
- <div class="swiper-button-next" style="color: #F472B6;"></div>
827
- <div class="swiper-button-prev" style="color: #F472B6;"></div>
828
  {% endif %}
829
  </div>
830
 
831
  <div style="margin-top: 20px; font-size: 1rem; line-height: 1.7;">
832
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
833
- <p style="font-size: 1.2rem; font-weight: bold; color: #DB2777;"><strong>Цена:</strong> {{ "%.2f"|format(product['price']) }} {{ currency_code }}</p>
834
  <p><strong>Описание:</strong><br> {{ product.get('description', 'Описание отсутствует.')|replace('\\n', '<br>')|safe }}</p>
835
  {% set colors = product.get('colors', []) %}
836
  {% if colors and colors|select('ne', '')|list|length > 0 %}
@@ -846,33 +845,33 @@ ORDER_TEMPLATE = '''
846
  <head>
847
  <meta charset="UTF-8">
848
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
849
- <title>Заказ №{{ order.id }} - Aruuke_optomKZ</title>
850
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
851
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
852
  <style>
853
- body { font-family: 'Poppins', sans-serif; background: #FFF0F5; color: #4d333f; padding: 20px; }
854
- .container { max-width: 800px; margin: 20px auto; padding: 30px; background: #fff; border-radius: 15px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); border: 1px solid #FBCFE8; }
855
- h1 { text-align: center; color: #F472B6; margin-bottom: 25px; font-size: 1.8rem; font-weight: 600; }
856
- h2 { color: #DB2777; margin-top: 30px; margin-bottom: 15px; font-size: 1.4rem; border-bottom: 1px solid #FBCFE8; padding-bottom: 8px;}
857
- .order-meta { font-size: 0.9rem; color: #a0aec0; margin-bottom: 20px; text-align: center; }
858
- .order-item { display: grid; grid-template-columns: 60px 1fr auto; gap: 15px; align-items: center; padding: 15px 0; border-bottom: 1px solid #FCE7F3; }
859
  .order-item:last-child { border-bottom: none; }
860
- .order-item img { width: 60px; height: 60px; object-fit: contain; border-radius: 8px; background-color: #fff; padding: 5px; border: 1px solid #FCE7F3;}
861
- .item-details strong { display: block; margin-bottom: 5px; font-size: 1.05rem; color: #4d333f;}
862
- .item-details span { font-size: 0.9rem; color: #6b4d5d; display: block;}
863
- .item-total { font-weight: bold; text-align: right; font-size: 1rem; color: #DB2777;}
864
- .order-summary { margin-top: 30px; padding-top: 20px; border-top: 2px solid #F472B6; text-align: right; }
865
  .order-summary p { margin-bottom: 10px; font-size: 1.1rem; }
866
- .order-summary strong { font-size: 1.3rem; color: #F472B6; }
867
- .customer-info { margin-top: 30px; background-color: #fff7fa; padding: 20px; border-radius: 8px; border: 1px solid #FCE7F3;}
868
  .customer-info p { margin-bottom: 8px; font-size: 0.95rem; }
869
- .customer-info strong { color: #DB2777; }
870
  .actions { margin-top: 30px; text-align: center; }
871
- .button { padding: 12px 25px; border: none; border-radius: 8px; background-color: #F472B6; color: white; font-weight: 600; cursor: pointer; transition: background-color 0.3s ease, transform 0.1s ease; font-size: 1rem; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
872
- .button:hover { background-color: #DB2777; }
873
  .button:active { transform: scale(0.98); }
874
  .button i { font-size: 1.2rem; }
875
- .catalog-link { display: block; text-align: center; margin-top: 25px; color: #EC4899; text-decoration: none; font-size: 0.9rem; }
876
  .catalog-link:hover { text-decoration: underline; }
877
  .not-found { text-align: center; color: #c53030; font-size: 1.2rem; padding: 40px 0;}
878
  </style>
@@ -920,9 +919,9 @@ ORDER_TEMPLATE = '''
920
  function sendOrderViaWhatsApp() {
921
  const orderId = '{{ order.id }}';
922
  const orderUrl = `{{ request.url }}`;
923
- const whatsappNumber = "+77089276224";
924
 
925
- let message = `Здравствуйте! Хочу подтвердить свой заказ на Aruuke_optomKZ:%0A%0A`;
926
  message += `*Номер заказа:* ${orderId}%0A`;
927
  message += `*Ссылка на заказ:* ${encodeURIComponent(orderUrl)}%0A%0A`;
928
  message += `Пожалуйста, свяжитесь со мной для уточнения деталей оплаты и доставки.`;
@@ -948,60 +947,60 @@ ADMIN_TEMPLATE = '''
948
  <head>
949
  <meta charset="UTF-8">
950
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
951
- <title>Админ-панель - Aruuke_optomKZ</title>
952
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
953
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
954
  <style>
955
- body { font-family: 'Poppins', sans-serif; background-color: #fff7fa; color: #4d333f; padding: 20px; line-height: 1.6; }
956
  .container { max-width: 1200px; margin: 0 auto; background-color: #fff; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.05); }
957
- .header { padding-bottom: 15px; margin-bottom: 25px; border-bottom: 1px solid #FBCFE8; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;}
958
- h1, h2, h3 { font-weight: 600; color: #F472B6; margin-bottom: 15px; }
959
  h1 { font-size: 1.6rem; }
960
  h2 { font-size: 1.5rem; margin-top: 30px; display: flex; align-items: center; gap: 8px; }
961
- h3 { font-size: 1.2rem; color: #DB2777; margin-top: 20px; }
962
- .section { margin-bottom: 30px; padding: 20px; background-color: #fff7fa; border: 1px solid #FBCFE8; border-radius: 8px; }
963
  form { margin-bottom: 20px; }
964
- label { font-weight: 500; margin-top: 10px; display: block; color: #6b4d5d; font-size: 0.9rem;}
965
- input[type="text"], input[type="number"], input[type="password"], input[type="tel"], textarea, select { width: 100%; padding: 10px 12px; margin-top: 5px; border: 1px solid #fbcfe8; border-radius: 6px; font-size: 0.95rem; box-sizing: border-box; transition: border-color 0.3s ease; background-color: #fff; }
966
- input:focus, textarea:focus, select:focus { border-color: #F472B6; outline: none; box-shadow: 0 0 0 2px rgba(244, 114, 182, 0.1); }
967
  textarea { min-height: 80px; resize: vertical; }
968
- input[type="file"] { padding: 8px; background-color: #fff0f5; cursor: pointer; border: 1px solid #fbcfe8;}
969
- input[type="file"]::file-selector-button { padding: 5px 10px; border-radius: 4px; background-color: #fce7f3; border: 1px solid #fbcfe8; cursor: pointer; margin-right: 10px;}
970
  input[type="checkbox"] { margin-right: 5px; vertical-align: middle; }
971
  label.inline-label { display: inline-block; margin-top: 10px; font-weight: normal; }
972
- button, .button { padding: 10px 18px; border: none; border-radius: 6px; background-color: #F472B6; color: white; font-weight: 500; cursor: pointer; transition: background-color 0.3s ease, transform 0.1s ease; margin-top: 15px; font-size: 0.95rem; display: inline-flex; align-items: center; gap: 5px; text-decoration: none; line-height: 1.2;}
973
- button:hover, .button:hover { background-color: #DB2777; }
974
  button:active, .button:active { transform: scale(0.98); }
975
  button[type="submit"] { min-width: 120px; justify-content: center; }
976
- .delete-button { background-color: #f56565; }
977
- .delete-button:hover { background-color: #e53e3e; }
978
- .add-button { background-color: #F472B6; }
979
- .add-button:hover { background-color: #DB2777; }
980
  .item-list { display: grid; gap: 20px; }
981
- .item { background: #fff; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.07); border: 1px solid #FCE7F3; }
982
- .item p { margin: 5px 0; font-size: 0.9rem; color: #6b4d5d; }
983
- .item strong { color: #4d333f; }
984
- .item .description { font-size: 0.85rem; color: #a0aec0; max-height: 60px; overflow: hidden; text-overflow: ellipsis; }
985
  .item-actions { margin-top: 15px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
986
- .item-actions button:not(.delete-button) { background-color: #F472B6; }
987
- .item-actions button:not(.delete-button):hover { background-color: #DB2777; }
988
- .edit-form-container { margin-top: 15px; padding: 20px; background: #fff0f5; border: 1px dashed #fbcfe8; border-radius: 6px; display: none; }
989
- details { background-color: #fff7fa; border: 1px solid #FBCFE8; border-radius: 8px; margin-bottom: 20px; }
990
- details > summary { cursor: pointer; font-weight: 600; color: #DB2777; display: block; padding: 15px; border-bottom: 1px solid #FBCFE8; list-style: none; position: relative; }
991
- details > summary::after { content: '\\f078'; font-family: 'Font Awesome 6 Free'; font-weight: 900; position: absolute; right: 20px; top: 50%; transform: translateY(-50%); transition: transform 0.2s ease; color: #F472B6; }
992
  details[open] > summary::after { transform: translateY(-50%) rotate(180deg); }
993
- details[open] > summary { border-bottom: 1px solid #FBCFE8; }
994
  details .form-content { padding: 20px; }
995
  .color-input-group { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
996
  .color-input-group input { flex-grow: 1; margin: 0; }
997
- .remove-color-btn { background-color: #f56565; padding: 6px 10px; font-size: 0.8rem; margin-top: 0; line-height: 1; }
998
- .remove-color-btn:hover { background-color: #e53e3e; }
999
- .add-color-btn { background-color: #f9a8d4; color: #DB2777; }
1000
- .add-color-btn:hover { background-color: #fbcfe8; }
1001
- .photo-preview img { max-width: 70px; max-height: 70px; border-radius: 5px; margin: 5px 5px 0 0; border: 1px solid #FBCFE8; object-fit: cover;}
1002
  .sync-buttons { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
1003
- .download-hf-button { background-color: #a0aec0; }
1004
- .download-hf-button:hover { background-color: #718096; }
1005
  .flex-container { display: flex; flex-wrap: wrap; gap: 20px; }
1006
  .flex-item { flex: 1; min-width: 350px; }
1007
  .message { padding: 10px 15px; border-radius: 6px; margin-bottom: 15px; font-size: 0.9rem;}
@@ -1018,10 +1017,10 @@ ADMIN_TEMPLATE = '''
1018
  <div class="container">
1019
  <div class="header">
1020
  <div class="logo-title-container" style="display: flex; align-items: center; gap: 15px;">
1021
- <img src="https://huggingface.co/spaces/Aruuke-almaty/admin/resolve/main/464856221_879152084357535_5878527617319379130_n.jpg" alt="Aruuke_optomKZ Logo" style="height: 50px; width: 50px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 8px rgba(244, 114, 182, 0.7), 0 0 15px rgba(219, 39, 119, 0.5);">
1022
- <h1><i class="fas fa-tools"></i> Админ-панель Aruuke_optomKZ</h1>
1023
  </div>
1024
- <a href="{{ url_for('catalog') }}" class="button" style="background-color: #EC4899;"><i class="fas fa-store"></i> Перейти в каталог</a>
1025
  </div>
1026
 
1027
 
@@ -1116,7 +1115,7 @@ ADMIN_TEMPLATE = '''
1116
  <label>Цвета/Варианты (оставьте пустым, если нет):</label>
1117
  <div id="add-color-inputs">
1118
  <div class="color-input-group">
1119
- <input type="text" name="colors" placeholder="Например: Розовый">
1120
  <button type="button" class="remove-color-btn" onclick="removeColorInput(this)"><i class="fas fa-times"></i></button>
1121
  </div>
1122
  </div>
@@ -1152,7 +1151,7 @@ ADMIN_TEMPLATE = '''
1152
  {% endif %}
1153
  </div>
1154
  <div style="flex-grow: 1;">
1155
- <h3 style="margin-top: 0; margin-bottom: 5px; color: #4d333f;">
1156
  {{ product['name'] }}
1157
  {% if product.get('in_stock', True) %}
1158
  <span class="status-indicator in-stock">В наличии</span>
@@ -1225,7 +1224,7 @@ ADMIN_TEMPLATE = '''
1225
  {% endfor %}
1226
  {% else %}
1227
  <div class="color-input-group">
1228
- <input type="text" name="colors" placeholder="Например: Красный">
1229
  <button type="button" class="remove-color-btn" onclick="removeColorInput(this)"><i class="fas fa-times"></i></button>
1230
  </div>
1231
  {% endif %}
 
16
  load_dotenv()
17
 
18
  app = Flask(__name__)
19
+ app.secret_key = 'desert_storm_secret_key_no_login'
20
  DATA_FILE = 'data.json'
21
 
22
 
 
211
  <head>
212
  <meta charset="UTF-8">
213
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
214
+ <title>desert storm - Каталог</title>
215
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
216
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
217
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/10.2.0/swiper-bundle.min.css">
218
  <style>
219
  * { margin: 0; padding: 0; box-sizing: border-box; }
220
+ body { font-family: 'Poppins', sans-serif; background: #f5f0e1; color: #3d3522; line-height: 1.6; transition: background 0.3s, color 0.3s; }
221
+ body.dark-mode { background: #2c2a26; color: #e0dace; }
222
  .container { max-width: 1300px; margin: 0 auto; padding: 20px; }
223
+ .header { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; border-bottom: 1px solid #dcd3b8; }
224
+ body.dark-mode .header { border-bottom-color: #424039; }
225
+ .header h1 { font-size: 1.6rem; font-weight: 600; color: #556b2f; }
226
+ .theme-toggle { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #8b8577; transition: color 0.3s ease; }
227
+ .theme-toggle:hover { color: #556b2f; }
228
+ body.dark-mode .theme-toggle { color: #dcd3b8; }
229
+ body.dark-mode .theme-toggle:hover { color: #b2c2a1; }
230
+ .store-address { padding: 15px; text-align: center; background-color: #ffffff; margin: 20px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); font-size: 1rem; color: #6f6a5b; }
231
+ body.dark-mode .store-address { background-color: #424039; color: #dcd3b8; }
232
  .filters-container { margin: 20px 0; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
233
  .search-container { margin: 20px 0; text-align: center; }
234
+ #search-input { width: 90%; max-width: 600px; padding: 12px 18px; font-size: 1rem; border: 1px solid #dcd3b8; border-radius: 25px; outline: none; box-shadow: 0 2px 5px rgba(0,0,0,0.05); transition: all 0.3s ease; background-color: #fff; }
235
+ body.dark-mode #search-input { background-color: #424039; border-color: #5a5a54; color: #e0dace; }
236
+ #search-input:focus { border-color: #556b2f; box-shadow: 0 0 0 3px rgba(85, 107, 47, 0.2); }
237
+ body.dark-mode #search-input:focus { border-color: #6b8e23; box-shadow: 0 0 0 3px rgba(107, 142, 35, 0.3); }
238
+ .category-filter { padding: 8px 16px; border: 1px solid #dcd3b8; border-radius: 20px; background-color: #fff; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); font-size: 0.9rem; font-weight: 400; color: #556b2f; }
239
+ body.dark-mode .category-filter { background-color: #424039; border-color: #5a5a54; color: #b2c2a1; }
240
+ .category-filter.active, .category-filter:hover { background-color: #556b2f; color: white; border-color: #556b2f; box-shadow: 0 2px 10px rgba(85, 107, 47, 0.3); }
241
+ body.dark-mode .category-filter.active, body.dark-mode .category-filter:hover { background-color: #6b8e23; border-color: #6b8e23; color: #2c2a26; box-shadow: 0 2px 10px rgba(107, 142, 35, 0.4); }
242
  .products-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px; padding: 10px; }
243
  @media (min-width: 600px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } }
244
  @media (min-width: 900px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); } }
245
+ .product { background: #fff; border-radius: 15px; padding: 0; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; height: 100%; border: 1px solid #e5d9b7;}
246
+ body.dark-mode .product { background: #424039; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); border-color: #5a5a54; }
 
247
  .product:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); }
248
  body.dark-mode .product:hover { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); }
249
  .product-image { width: 100%; aspect-ratio: 1 / 1; background-color: #fff; border-radius: 10px 10px 0 0; overflow: hidden; display: flex; justify-content: center; align-items: center; margin-bottom: 0; }
250
  .product-image img { max-width: 100%; max-height: 100%; object-fit: contain; transition: transform 0.3s ease; }
251
  .product-info { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; justify-content: center; }
252
+ .product h2 { font-size: 1.1rem; font-weight: 600; margin: 0 0 8px 0; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #3d3522; }
253
+ body.dark-mode .product h2 { color: #e0dace; }
254
+ .product-price { font-size: 1.2rem; color: #8b4513; font-weight: 700; text-align: center; margin: 5px 0; }
255
+ body.dark-mode .product-price { color: #d2b48c; }
256
+ .product-description { font-size: 0.85rem; color: #6f6a5b; text-align: center; margin-bottom: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
257
+ body.dark-mode .product-description { color: #dcd3b8; }
258
  .product-actions { padding: 0 15px 15px 15px; display: flex; flex-direction: column; gap: 8px; }
259
+ .product-button { display: block; width: 100%; padding: 10px; border: none; border-radius: 8px; background-color: #556b2f; color: white; font-size: 0.9rem; font-weight: 500; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); text-align: center; text-decoration: none; }
260
+ .product-button:hover { background-color: #6b8e23; box-shadow: 0 4px 15px rgba(107, 142, 35, 0.4); transform: translateY(-2px); }
261
  .product-button i { margin-right: 5px; }
262
+ .add-to-cart { background-color: #556b2f; }
263
+ .add-to-cart:hover { background-color: #6b8e23; box-shadow: 0 4px 15px rgba(107, 142, 35, 0.4); }
264
+ #cart-button { position: fixed; bottom: 25px; right: 25px; background-color: #556b2f; color: white; border: none; border-radius: 50%; width: 55px; height: 55px; font-size: 1.5rem; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 4px 15px rgba(85, 107, 47, 0.4); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); z-index: 1000; }
265
  #cart-button .fa-shopping-cart { margin-right: 0; }
266
+ #cart-button span { position: absolute; top: -5px; right: -5px; background-color: #8b4513; color: white; border-radius: 50%; padding: 2px 6px; font-size: 0.7rem; font-weight: bold; }
267
  .modal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.6); backdrop-filter: blur(5px); overflow-y: auto; }
268
  .modal-content { background: #ffffff; margin: 5% auto; padding: 25px; border-radius: 15px; width: 90%; max-width: 700px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); animation: slideIn 0.3s ease-out; position: relative; }
269
+ body.dark-mode .modal-content { background: #424039; color: #e0dace; }
270
  @keyframes slideIn { from { transform: translateY(-30px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
271
+ .close { position: absolute; top: 15px; right: 15px; font-size: 1.8rem; color: #8b8577; cursor: pointer; transition: color 0.3s; line-height: 1; }
272
+ .close:hover { color: #3d3522; }
273
+ body.dark-mode .close { color: #dcd3b8; }
274
  body.dark-mode .close:hover { color: #ffffff; }
275
+ .modal-content h2 { margin-top: 0; margin-bottom: 20px; color: #556b2f; display: flex; align-items: center; gap: 10px;}
276
+ body.dark-mode .modal-content h2 { color: #b2c2a1; }
277
+ .cart-item { display: grid; grid-template-columns: auto 1fr auto auto; gap: 15px; align-items: center; padding: 15px 0; border-bottom: 1px solid #dcd3b8; }
278
+ body.dark-mode .cart-item { border-bottom-color: #5a5a54; }
279
  .cart-item:last-child { border-bottom: none; }
280
  .cart-item img { width: 60px; height: 60px; object-fit: contain; border-radius: 8px; background-color: #fff; padding: 5px; grid-column: 1; }
281
  .cart-item-details { grid-column: 2; }
282
  .cart-item-details strong { display: block; margin-bottom: 5px; font-size: 1rem; }
283
+ .cart-item-price { font-size: 0.9rem; color: #6f6a5b; }
284
+ body.dark-mode .cart-item-price { color: #dcd3b8; }
285
  .cart-item-total { font-weight: bold; text-align: right; grid-column: 3; font-size: 1rem;}
286
+ .cart-item-remove { grid-column: 4; background:none; border:none; color:#c04c4c; cursor:pointer; font-size: 1.3em; padding: 5px; line-height: 1; }
287
+ .cart-item-remove:hover { color: #a03c3c; }
288
+ .quantity-input, .color-select { width: 100%; max-width: 180px; padding: 10px; border: 1px solid #dcd3b8; border-radius: 8px; font-size: 1rem; margin: 10px 0; box-sizing: border-box; }
289
+ body.dark-mode .quantity-input, body.dark-mode .color-select { background-color: #2c2a26; border-color: #5a5a54; color: #e0dace; }
290
+ .cart-summary { margin-top: 20px; text-align: right; border-top: 1px solid #dcd3b8; padding-top: 15px; }
291
+ body.dark-mode .cart-summary { border-top-color: #5a5a54; }
292
  .cart-summary strong { font-size: 1.2rem; }
293
  .cart-actions { margin-top: 25px; display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
294
  .cart-actions .product-button { width: auto; flex-grow: 1; }
295
+ .clear-cart { background-color: #8b8577; }
296
+ .clear-cart:hover { background-color: #6f6a5b; box-shadow: 0 4px 15px rgba(113, 128, 150, 0.4); }
297
+ .formulate-order-button { background-color: #556b2f; }
298
+ .formulate-order-button:hover { background-color: #6b8e23; box-shadow: 0 4px 15px rgba(107, 142, 35, 0.4); }
299
+ .notification { position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%); background-color: #556b2f; color: white; padding: 10px 20px; border-radius: 20px; box-shadow: 0 4px 10px rgba(0,0,0,0.2); z-index: 1002; opacity: 0; transition: opacity 0.5s ease; font-size: 0.9rem;}
300
  .notification.show { opacity: 1;}
301
+ .no-results-message { grid-column: 1 / -1; text-align: center; padding: 40px; font-size: 1.1rem; color: #8b8577; }
302
+ body.dark-mode .no-results-message { color: #dcd3b8; }
303
+ .top-product-indicator { position: absolute; top: 8px; right: 8px; background-color: rgba(210, 180, 140, 0.8); color: #3d3522; padding: 2px 6px; font-size: 0.7rem; border-radius: 4px; font-weight: bold; z-index: 10; backdrop-filter: blur(2px); }
304
  .product { position: relative; }
305
  </style>
306
  </head>
 
308
  <div class="container">
309
  <div class="header">
310
  <div class="logo-title-container" style="display: flex; align-items: center; gap: 15px;">
311
+ <i class="fas fa-wind" style="font-size: 36px; color: #556b2f;"></i>
312
+ <h1>desert storm</h1>
313
  </div>
314
  <button class="theme-toggle" onclick="toggleTheme()" aria-label="Переключить тему">
315
  <i class="fas fa-moon"></i>
 
417
  const repoId = '{{ repo_id }}';
418
  const currencyCode = '{{ currency_code }}';
419
  let selectedProductIndex = null;
420
+ let cart = JSON.parse(localStorage.getItem('desertStormCart') || '[]');
421
 
422
  function toggleTheme() {
423
  document.body.classList.toggle('dark-mode');
 
425
  const isDarkMode = document.body.classList.contains('dark-mode');
426
  icon.classList.toggle('fa-moon', !isDarkMode);
427
  icon.classList.toggle('fa-sun', isDarkMode);
428
+ localStorage.setItem('desertStormTheme', isDarkMode ? 'dark' : 'light');
429
  }
430
 
431
  function applyInitialTheme() {
432
+ const savedTheme = localStorage.getItem('desertStormTheme');
433
  if (savedTheme === 'dark') {
434
  document.body.classList.add('dark-mode');
435
  const icon = document.querySelector('.theme-toggle i');
 
565
  });
566
  }
567
 
568
+ localStorage.setItem('desertStormCart', JSON.stringify(cart));
569
  closeModal('quantityModal');
570
  updateCartButton();
571
  showNotification(`${product.name} добавлен в корзину!`);
 
630
 
631
  function removeFromCart(itemId) {
632
  cart = cart.filter(item => item.id !== itemId);
633
+ localStorage.setItem('desertStormCart', JSON.stringify(cart));
634
  openCartModal();
635
  updateCartButton();
636
  }
 
638
  function clearCart() {
639
  if (confirm("Вы уверены, что хотите очистить корзину?")) {
640
  cart = [];
641
+ localStorage.removeItem('desertStormCart');
642
  openCartModal();
643
  updateCartButton();
644
  }
 
672
  })
673
  .then(data => {
674
  if (data.order_id) {
675
+ localStorage.removeItem('desertStormCart');
676
  cart = [];
677
  updateCartButton();
678
  closeModal('cartModal');
 
801
 
802
  PRODUCT_DETAIL_TEMPLATE = '''
803
  <div style="padding: 10px;">
804
+ <h2 style="font-size: 1.6rem; font-weight: 600; margin-bottom: 15px; text-align: center; color: #556b2f;">{{ product['name'] }}</h2>
805
  <div class="swiper-container" style="max-width: 450px; margin: 0 auto 20px; border-radius: 10px; overflow: hidden; background-color: #fff;">
806
  <div class="swiper-wrapper">
807
  {% if product.get('photos') and product['photos']|length > 0 %}
 
822
  </div>
823
  {% if product.get('photos') and product['photos']|length > 1 %}
824
  <div class="swiper-pagination" style="position: relative; bottom: 5px;"></div>
825
+ <div class="swiper-button-next" style="color: #556b2f;"></div>
826
+ <div class="swiper-button-prev" style="color: #556b2f;"></div>
827
  {% endif %}
828
  </div>
829
 
830
  <div style="margin-top: 20px; font-size: 1rem; line-height: 1.7;">
831
  <p><strong>Категория:</strong> {{ product.get('category', 'Без категории') }}</p>
832
+ <p style="font-size: 1.2rem; font-weight: bold; color: #8b4513;"><strong>Цена:</strong> {{ "%.2f"|format(product['price']) }} {{ currency_code }}</p>
833
  <p><strong>Описание:</strong><br> {{ product.get('description', 'Описание отсутствует.')|replace('\\n', '<br>')|safe }}</p>
834
  {% set colors = product.get('colors', []) %}
835
  {% if colors and colors|select('ne', '')|list|length > 0 %}
 
845
  <head>
846
  <meta charset="UTF-8">
847
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
848
+ <title>Заказ №{{ order.id }} - desert storm</title>
849
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
850
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
851
  <style>
852
+ body { font-family: 'Poppins', sans-serif; background: #f5f0e1; color: #3d3522; padding: 20px; }
853
+ .container { max-width: 800px; margin: 20px auto; padding: 30px; background: #fff; border-radius: 15px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); border: 1px solid #dcd3b8; }
854
+ h1 { text-align: center; color: #556b2f; margin-bottom: 25px; font-size: 1.8rem; font-weight: 600; }
855
+ h2 { color: #8b4513; margin-top: 30px; margin-bottom: 15px; font-size: 1.4rem; border-bottom: 1px solid #dcd3b8; padding-bottom: 8px;}
856
+ .order-meta { font-size: 0.9rem; color: #8b8577; margin-bottom: 20px; text-align: center; }
857
+ .order-item { display: grid; grid-template-columns: 60px 1fr auto; gap: 15px; align-items: center; padding: 15px 0; border-bottom: 1px solid #e5d9b7; }
858
  .order-item:last-child { border-bottom: none; }
859
+ .order-item img { width: 60px; height: 60px; object-fit: contain; border-radius: 8px; background-color: #fff; padding: 5px; border: 1px solid #e5d9b7;}
860
+ .item-details strong { display: block; margin-bottom: 5px; font-size: 1.05rem; color: #3d3522;}
861
+ .item-details span { font-size: 0.9rem; color: #6f6a5b; display: block;}
862
+ .item-total { font-weight: bold; text-align: right; font-size: 1rem; color: #8b4513;}
863
+ .order-summary { margin-top: 30px; padding-top: 20px; border-top: 2px solid #556b2f; text-align: right; }
864
  .order-summary p { margin-bottom: 10px; font-size: 1.1rem; }
865
+ .order-summary strong { font-size: 1.3rem; color: #556b2f; }
866
+ .customer-info { margin-top: 30px; background-color: #fcfaf5; padding: 20px; border-radius: 8px; border: 1px solid #e5d9b7;}
867
  .customer-info p { margin-bottom: 8px; font-size: 0.95rem; }
868
+ .customer-info strong { color: #8b4513; }
869
  .actions { margin-top: 30px; text-align: center; }
870
+ .button { padding: 12px 25px; border: none; border-radius: 8px; background-color: #556b2f; color: white; font-weight: 600; cursor: pointer; transition: background-color 0.3s ease, transform 0.1s ease; font-size: 1rem; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
871
+ .button:hover { background-color: #6b8e23; }
872
  .button:active { transform: scale(0.98); }
873
  .button i { font-size: 1.2rem; }
874
+ .catalog-link { display: block; text-align: center; margin-top: 25px; color: #556b2f; text-decoration: none; font-size: 0.9rem; }
875
  .catalog-link:hover { text-decoration: underline; }
876
  .not-found { text-align: center; color: #c53030; font-size: 1.2rem; padding: 40px 0;}
877
  </style>
 
919
  function sendOrderViaWhatsApp() {
920
  const orderId = '{{ order.id }}';
921
  const orderUrl = `{{ request.url }}`;
922
+ const whatsappNumber = "+77013127373";
923
 
924
+ let message = `Здравствуйте! Хочу подтвердить свой заказ на desert storm:%0A%0A`;
925
  message += `*Номер заказа:* ${orderId}%0A`;
926
  message += `*Ссылка на заказ:* ${encodeURIComponent(orderUrl)}%0A%0A`;
927
  message += `Пожалуйста, свяжитесь со мной для уточнения деталей оплаты и доставки.`;
 
947
  <head>
948
  <meta charset="UTF-8">
949
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
950
+ <title>Админ-панель - desert storm</title>
951
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
952
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
953
  <style>
954
+ body { font-family: 'Poppins', sans-serif; background-color: #f0f2f5; color: #3d3522; padding: 20px; line-height: 1.6; }
955
  .container { max-width: 1200px; margin: 0 auto; background-color: #fff; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.05); }
956
+ .header { padding-bottom: 15px; margin-bottom: 25px; border-bottom: 1px solid #dcd3b8; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;}
957
+ h1, h2, h3 { font-weight: 600; color: #556b2f; margin-bottom: 15px; }
958
  h1 { font-size: 1.6rem; }
959
  h2 { font-size: 1.5rem; margin-top: 30px; display: flex; align-items: center; gap: 8px; }
960
+ h3 { font-size: 1.2rem; color: #8b4513; margin-top: 20px; }
961
+ .section { margin-bottom: 30px; padding: 20px; background-color: #fcfaf5; border: 1px solid #dcd3b8; border-radius: 8px; }
962
  form { margin-bottom: 20px; }
963
+ label { font-weight: 500; margin-top: 10px; display: block; color: #6f6a5b; font-size: 0.9rem;}
964
+ input[type="text"], input[type="number"], input[type="password"], input[type="tel"], textarea, select { width: 100%; padding: 10px 12px; margin-top: 5px; border: 1px solid #dcd3b8; border-radius: 6px; font-size: 0.95rem; box-sizing: border-box; transition: border-color 0.3s ease; background-color: #fff; }
965
+ input:focus, textarea:focus, select:focus { border-color: #556b2f; outline: none; box-shadow: 0 0 0 2px rgba(85, 107, 47, 0.1); }
966
  textarea { min-height: 80px; resize: vertical; }
967
+ input[type="file"] { padding: 8px; background-color: #f5f0e1; cursor: pointer; border: 1px solid #dcd3b8;}
968
+ input[type="file"]::file-selector-button { padding: 5px 10px; border-radius: 4px; background-color: #e0dace; border: 1px solid #dcd3b8; cursor: pointer; margin-right: 10px;}
969
  input[type="checkbox"] { margin-right: 5px; vertical-align: middle; }
970
  label.inline-label { display: inline-block; margin-top: 10px; font-weight: normal; }
971
+ button, .button { padding: 10px 18px; border: none; border-radius: 6px; background-color: #556b2f; color: white; font-weight: 500; cursor: pointer; transition: background-color 0.3s ease, transform 0.1s ease; margin-top: 15px; font-size: 0.95rem; display: inline-flex; align-items: center; gap: 5px; text-decoration: none; line-height: 1.2;}
972
+ button:hover, .button:hover { background-color: #6b8e23; }
973
  button:active, .button:active { transform: scale(0.98); }
974
  button[type="submit"] { min-width: 120px; justify-content: center; }
975
+ .delete-button { background-color: #c04c4c; }
976
+ .delete-button:hover { background-color: #a03c3c; }
977
+ .add-button { background-color: #556b2f; }
978
+ .add-button:hover { background-color: #6b8e23; }
979
  .item-list { display: grid; gap: 20px; }
980
+ .item { background: #fff; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.07); border: 1px solid #e5d9b7; }
981
+ .item p { margin: 5px 0; font-size: 0.9rem; color: #6f6a5b; }
982
+ .item strong { color: #3d3522; }
983
+ .item .description { font-size: 0.85rem; color: #8b8577; max-height: 60px; overflow: hidden; text-overflow: ellipsis; }
984
  .item-actions { margin-top: 15px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
985
+ .item-actions button:not(.delete-button) { background-color: #556b2f; }
986
+ .item-actions button:not(.delete-button):hover { background-color: #6b8e23; }
987
+ .edit-form-container { margin-top: 15px; padding: 20px; background: #f5f0e1; border: 1px dashed #dcd3b8; border-radius: 6px; display: none; }
988
+ details { background-color: #fcfaf5; border: 1px solid #dcd3b8; border-radius: 8px; margin-bottom: 20px; }
989
+ details > summary { cursor: pointer; font-weight: 600; color: #8b4513; display: block; padding: 15px; border-bottom: 1px solid #dcd3b8; list-style: none; position: relative; }
990
+ details > summary::after { content: '\\f078'; font-family: 'Font Awesome 6 Free'; font-weight: 900; position: absolute; right: 20px; top: 50%; transform: translateY(-50%); transition: transform 0.2s ease; color: #556b2f; }
991
  details[open] > summary::after { transform: translateY(-50%) rotate(180deg); }
992
+ details[open] > summary { border-bottom: 1px solid #dcd3b8; }
993
  details .form-content { padding: 20px; }
994
  .color-input-group { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
995
  .color-input-group input { flex-grow: 1; margin: 0; }
996
+ .remove-color-btn { background-color: #c04c4c; padding: 6px 10px; font-size: 0.8rem; margin-top: 0; line-height: 1; }
997
+ .remove-color-btn:hover { background-color: #a03c3c; }
998
+ .add-color-btn { background-color: #b2c2a1; color: #3d3522; }
999
+ .add-color-btn:hover { background-color: #dcd3b8; }
1000
+ .photo-preview img { max-width: 70px; max-height: 70px; border-radius: 5px; margin: 5px 5px 0 0; border: 1px solid #dcd3b8; object-fit: cover;}
1001
  .sync-buttons { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
1002
+ .download-hf-button { background-color: #8b8577; }
1003
+ .download-hf-button:hover { background-color: #6f6a5b; }
1004
  .flex-container { display: flex; flex-wrap: wrap; gap: 20px; }
1005
  .flex-item { flex: 1; min-width: 350px; }
1006
  .message { padding: 10px 15px; border-radius: 6px; margin-bottom: 15px; font-size: 0.9rem;}
 
1017
  <div class="container">
1018
  <div class="header">
1019
  <div class="logo-title-container" style="display: flex; align-items: center; gap: 15px;">
1020
+ <i class="fas fa-wind" style="font-size: 36px; color: #556b2f;"></i>
1021
+ <h1><i class="fas fa-tools"></i> Админ-панель desert storm</h1>
1022
  </div>
1023
+ <a href="{{ url_for('catalog') }}" class="button" style="background-color: #6b8e23;"><i class="fas fa-store"></i> Перейти в каталог</a>
1024
  </div>
1025
 
1026
 
 
1115
  <label>Цвета/Варианты (оставьте пустым, если нет):</label>
1116
  <div id="add-color-inputs">
1117
  <div class="color-input-group">
1118
+ <input type="text" name="colors" placeholder="Например: Хаки">
1119
  <button type="button" class="remove-color-btn" onclick="removeColorInput(this)"><i class="fas fa-times"></i></button>
1120
  </div>
1121
  </div>
 
1151
  {% endif %}
1152
  </div>
1153
  <div style="flex-grow: 1;">
1154
+ <h3 style="margin-top: 0; margin-bottom: 5px; color: #3d3522;">
1155
  {{ product['name'] }}
1156
  {% if product.get('in_stock', True) %}
1157
  <span class="status-indicator in-stock">В наличии</span>
 
1224
  {% endfor %}
1225
  {% else %}
1226
  <div class="color-input-group">
1227
+ <input type="text" name="colors" placeholder="Например: Койот">
1228
  <button type="button" class="remove-color-btn" onclick="removeColorInput(this)"><i class="fas fa-times"></i></button>
1229
  </div>
1230
  {% endif %}