Kgshop commited on
Commit
aa625f8
·
verified ·
1 Parent(s): 8153dc8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -36
app.py CHANGED
@@ -398,23 +398,23 @@ CATALOG_TEMPLATE = '''
398
  .category-filter.active, .category-filter:hover { background-color: var(--primary-accent); color: var(--bg-color); border-color: var(--primary-accent); }
399
  .products-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; padding: 10px; }
400
  @media (min-width: 768px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); } }
401
- .product { background: var(--surface-color); border-radius: 15px; padding: 0; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); transition: transform 0.3s ease, box-shadow 0.3s ease; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; height: 100%; border: 1px solid var(--secondary-accent); position: relative; }
402
  .product:hover { transform: translateY(-8px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.5); }
403
- .product-image { width: 100%; aspect-ratio: 1 / 1.1; background-color: #fff; overflow: hidden; display: flex; justify-content: center; align-items: center; }
 
404
  .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
405
  .product:hover .product-image img { transform: scale(1.05); }
406
- .product-info { padding: 20px; flex-grow: 1; display: flex; flex-direction: column; justify-content: center; text-align: center; }
407
- .product h2 { font-size: 1.2rem; font-weight: 600; margin: 0 0 10px 0; color: var(--text-color); }
408
- .price-container { margin: 10px 0; }
409
- .product-price-line { font-size: 1.3rem; color: var(--primary-accent); font-weight: 700; display: block; }
410
- .product-price-piece { font-size: 0.9rem; color: var(--text-muted); display: block; }
411
- .product-description { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 15px; }
412
- .product-actions { padding: 0 20px 20px 20px; display: flex; flex-direction: column; gap: 10px; }
 
413
  .product-button { display: block; width: 100%; padding: 12px; border: none; border-radius: 8px; background-color: var(--primary-accent); color: var(--bg-color); font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; text-align: center; text-decoration: none; }
414
  .product-button:hover { background-color: var(--primary-accent-hover); }
415
  .product-button i { margin-right: 8px; }
416
- .details-button { background-color: transparent; border: 2px solid var(--primary-accent); color: var(--primary-accent); }
417
- .details-button:hover { background-color: var(--primary-accent); color: var(--bg-color); }
418
  #cart-button { position: fixed; bottom: 90px; right: 30px; background-color: var(--primary-accent); color: var(--bg-color); border: none; border-radius: 50%; width: 60px; height: 60px; font-size: 1.6rem; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 5px 20px rgba(217, 158, 203, 0.3); transition: all 0.3s ease; z-index: 1000; }
419
  #cart-button:hover { transform: scale(1.1); }
420
  #cart-button span { position: absolute; top: 0px; right: 0px; background-color: var(--secondary-accent); color: var(--text-color); border-radius: 50%; padding: 3px 7px; font-size: 0.8rem; font-weight: bold; }
@@ -447,7 +447,7 @@ CATALOG_TEMPLATE = '''
447
  .favorite-button.favorited { color: #e91e63; transform: scale(1.1); }
448
  .favorite-button:hover { transform: scale(1.2); }
449
  .bottom-nav { position: fixed; bottom: 0; left: 0; right: 0; background-color: var(--surface-color); display: flex; justify-content: space-around; align-items: center; padding: 10px 0; box-shadow: 0 -3px 15px rgba(0,0,0,0.3); z-index: 999; border-top: 1px solid var(--secondary-accent); }
450
- .nav-button { background: none; border: none; color: var(--text-muted); cursor: pointer; text-align: center; font-size: 0.8rem; transition: color 0.3s; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 5px 10px; }
451
  .nav-button:hover, .nav-button.active { color: var(--primary-accent); }
452
  .nav-button i { font-size: 1.5rem; }
453
  .address-list p { margin-bottom: 10px; }
@@ -490,29 +490,38 @@ CATALOG_TEMPLATE = '''
490
  {% if product.get('is_top', False) %}
491
  <span class="top-product-indicator"><i class="fas fa-star"></i> {{ _('top_product') }}</span>
492
  {% endif %}
493
- <div class="product-image">
494
- {% if product.get('photos') and product['photos']|length > 0 %}
495
- <img src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/photos/{{ product['photos'][0] }}"
496
- alt="{{ product['name'] }}"
497
- loading="lazy">
498
- {% else %}
499
- <img src="https://via.placeholder.com/300x330.png?text=No+Image" alt="No Image" loading="lazy">
500
- {% endif %}
501
- </div>
502
- <div class="product-info">
503
- <h2>{{ product['name'] }}</h2>
504
- <div class="price-container">
505
- <span class="product-price-line">{{ "%.2f"|format(product['price']) }} {{ currency_code }}</span>
506
- <span class="product-price-piece">
507
- {% if product.get('items_per_line', 0) > 0 %}
508
- {{ "%.2f"|format(product['price'] / product.get('items_per_line')) }} {{ currency_code }} / {{ _('price_per_piece') }}
509
- ({{ product.get('items_per_line') }} {{ _('items_in_line') }})
 
 
 
 
 
 
 
 
 
 
510
  {% endif %}
511
- </span>
512
  </div>
513
  </div>
514
  <div class="product-actions">
515
- <button class="product-button details-button" onclick="openModalByIndex({{ loop.index0 }})"><i class="fas fa-info-circle"></i> {{ _('details') }}</button>
516
  <button class="product-button add-to-cart" onclick="openQuantityModal({{ loop.index0 }})">
517
  <i class="fas fa-cart-plus"></i> {{ _('add_to_cart') }}
518
  </button>
@@ -780,7 +789,7 @@ CATALOG_TEMPLATE = '''
780
  ? `https://huggingface.co/datasets/${repoId}/resolve/main/photos/${item.photo}`
781
  : 'https://via.placeholder.com/70x70.png?text=N/A';
782
  const colorText = item.color !== 'N/A' ? ` (${item.color})` : '';
783
- const lineInfo = item.items_per_line ? ` (${item.items_per_line} ${t.items_in_line})` : '';
784
 
785
  return `
786
  <div class="cart-item">
@@ -918,6 +927,7 @@ CATALOG_TEMPLATE = '''
918
  }
919
 
920
  function toggleFavorite(productId, buttonElement) {
 
921
  const index = favorites.indexOf(productId);
922
  if (index > -1) {
923
  favorites.splice(index, 1);
@@ -944,6 +954,16 @@ CATALOG_TEMPLATE = '''
944
  });
945
  }
946
 
 
 
 
 
 
 
 
 
 
 
947
  function openFavoritesModal() {
948
  const favoritesContent = document.getElementById('favoritesContent');
949
  favoritesContent.innerHTML = '';
@@ -958,14 +978,14 @@ CATALOG_TEMPLATE = '''
958
  : 'https://via.placeholder.com/70x70.png?text=N/A';
959
 
960
  const itemHtml = `
961
- <div class="cart-item">
962
  <img src="${photoUrl}" alt="${item.name}">
963
  <div class="cart-item-details">
964
  <strong>${item.name}</strong>
965
  <p class="cart-item-price">${item.price.toFixed(2)} ${currencyCode}</p>
966
  </div>
967
  <span class="cart-item-total"></span>
968
- <button class="cart-item-remove" onclick="removeFromFavorites('${item.id}')" title="Удалить из избранного">×</button>
969
  </div>`;
970
  favoritesContent.innerHTML += itemHtml;
971
  });
@@ -974,7 +994,8 @@ CATALOG_TEMPLATE = '''
974
  openModal('favoritesModal');
975
  }
976
 
977
- function removeFromFavorites(productId) {
 
978
  const index = favorites.indexOf(productId);
979
  if (index > -1) {
980
  favorites.splice(index, 1);
@@ -1054,7 +1075,7 @@ PRODUCT_DETAIL_TEMPLATE = '''
1054
  <p style="font-size: 1.4rem; font-weight: bold; color: var(--primary-accent);">
1055
  <strong>{{ _('price') }}</strong> {{ "%.2f"|format(product['price']) }} {{ currency_code }}
1056
  </p>
1057
- {% if product.get('items_per_line', 0) > 0 %}
1058
  <p style="font-size: 1rem; color: var(--text-muted); margin-top: -10px; margin-bottom: 15px;">
1059
  {{ "%.2f"|format(product['price'] / product.get('items_per_line')) }} {{ currency_code }} / {{ _('price_per_piece') }} ({{ product.get('items_per_line') }} {{ _('items_in_line') }})
1060
  </p>
 
398
  .category-filter.active, .category-filter:hover { background-color: var(--primary-accent); color: var(--bg-color); border-color: var(--primary-accent); }
399
  .products-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; padding: 10px; }
400
  @media (min-width: 768px) { .products-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); } }
401
+ .product { background: var(--surface-color); border-radius: 15px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); transition: transform 0.3s ease, box-shadow 0.3s ease; overflow: hidden; display: flex; flex-direction: column; height: 100%; border: 1px solid var(--secondary-accent); position: relative; }
402
  .product:hover { transform: translateY(-8px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.5); }
403
+ .product-clickable-area { cursor: pointer; flex-grow: 1; display: flex; flex-direction: column; }
404
+ .product-image { width: 100%; aspect-ratio: 1 / 1; background-color: #fff; overflow: hidden; display: flex; justify-content: center; align-items: center; }
405
  .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
406
  .product:hover .product-image img { transform: scale(1.05); }
407
+ .product-info { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; justify-content: center; text-align: center; }
408
+ .product h2 { font-size: 1.1rem; font-weight: 600; margin: 0 0 8px 0; color: var(--text-color); }
409
+ .price-container { margin: 8px 0; }
410
+ .product-price-line { font-size: 1.2rem; color: var(--primary-accent); font-weight: 700; display: block; }
411
+ .product-price-piece { font-size: 0.85rem; color: var(--text-muted); display: block; }
412
+ .product-colors { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; margin-top: 10px; min-height: 24px; }
413
+ .color-tag { font-size: 0.75rem; background-color: var(--bg-color); color: var(--text-muted); padding: 3px 8px; border-radius: 10px; border: 1px solid var(--secondary-accent); }
414
+ .product-actions { padding: 0 15px 15px 15px; }
415
  .product-button { display: block; width: 100%; padding: 12px; border: none; border-radius: 8px; background-color: var(--primary-accent); color: var(--bg-color); font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; text-align: center; text-decoration: none; }
416
  .product-button:hover { background-color: var(--primary-accent-hover); }
417
  .product-button i { margin-right: 8px; }
 
 
418
  #cart-button { position: fixed; bottom: 90px; right: 30px; background-color: var(--primary-accent); color: var(--bg-color); border: none; border-radius: 50%; width: 60px; height: 60px; font-size: 1.6rem; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 5px 20px rgba(217, 158, 203, 0.3); transition: all 0.3s ease; z-index: 1000; }
419
  #cart-button:hover { transform: scale(1.1); }
420
  #cart-button span { position: absolute; top: 0px; right: 0px; background-color: var(--secondary-accent); color: var(--text-color); border-radius: 50%; padding: 3px 7px; font-size: 0.8rem; font-weight: bold; }
 
447
  .favorite-button.favorited { color: #e91e63; transform: scale(1.1); }
448
  .favorite-button:hover { transform: scale(1.2); }
449
  .bottom-nav { position: fixed; bottom: 0; left: 0; right: 0; background-color: var(--surface-color); display: flex; justify-content: space-around; align-items: center; padding: 10px 0; box-shadow: 0 -3px 15px rgba(0,0,0,0.3); z-index: 999; border-top: 1px solid var(--secondary-accent); }
450
+ .nav-button { background: none; border: none; color: var(--text-muted); cursor: pointer; text-align: center; font-size: 0.8rem; transition: color 0.3s; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 5px 10px; text-decoration: none; }
451
  .nav-button:hover, .nav-button.active { color: var(--primary-accent); }
452
  .nav-button i { font-size: 1.5rem; }
453
  .address-list p { margin-bottom: 10px; }
 
490
  {% if product.get('is_top', False) %}
491
  <span class="top-product-indicator"><i class="fas fa-star"></i> {{ _('top_product') }}</span>
492
  {% endif %}
493
+ <div class="product-clickable-area" onclick="openModalByIndex({{ loop.index0 }})">
494
+ <div class="product-image">
495
+ {% if product.get('photos') and product['photos']|length > 0 %}
496
+ <img src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/photos/{{ product['photos'][0] }}"
497
+ alt="{{ product['name'] }}"
498
+ loading="lazy">
499
+ {% else %}
500
+ <img src="https://via.placeholder.com/300x300.png?text=No+Image" alt="No Image" loading="lazy">
501
+ {% endif %}
502
+ </div>
503
+ <div class="product-info">
504
+ <h2>{{ product['name'] }}</h2>
505
+ <div class="price-container">
506
+ <span class="product-price-line">{{ "%.2f"|format(product['price']) }} {{ currency_code }}</span>
507
+ <span class="product-price-piece">
508
+ {% if product.get('items_per_line', 0) > 1 %}
509
+ {{ "%.2f"|format(product['price'] / product.get('items_per_line')) }} {{ currency_code }} / {{ _('price_per_piece') }}
510
+ ({{ product.get('items_per_line') }} {{ _('items_in_line') }})
511
+ {% endif %}
512
+ </span>
513
+ </div>
514
+ <div class="product-colors">
515
+ {% set colors = product.get('colors', [])|select('ne', '')|list %}
516
+ {% if colors %}
517
+ {% for color in colors %}
518
+ <span class="color-tag">{{ color }}</span>
519
+ {% endfor %}
520
  {% endif %}
521
+ </div>
522
  </div>
523
  </div>
524
  <div class="product-actions">
 
525
  <button class="product-button add-to-cart" onclick="openQuantityModal({{ loop.index0 }})">
526
  <i class="fas fa-cart-plus"></i> {{ _('add_to_cart') }}
527
  </button>
 
789
  ? `https://huggingface.co/datasets/${repoId}/resolve/main/photos/${item.photo}`
790
  : 'https://via.placeholder.com/70x70.png?text=N/A';
791
  const colorText = item.color !== 'N/A' ? ` (${item.color})` : '';
792
+ const lineInfo = item.items_per_line && item.items_per_line > 1 ? ` (${item.items_per_line} ${t.items_in_line})` : '';
793
 
794
  return `
795
  <div class="cart-item">
 
927
  }
928
 
929
  function toggleFavorite(productId, buttonElement) {
930
+ event.stopPropagation();
931
  const index = favorites.indexOf(productId);
932
  if (index > -1) {
933
  favorites.splice(index, 1);
 
954
  });
955
  }
956
 
957
+ function openFavoriteProductDetail(productId) {
958
+ const productIndex = products.findIndex(p => p.id === productId);
959
+ if (productIndex > -1) {
960
+ closeModal('favoritesModal');
961
+ setTimeout(() => {
962
+ openModalByIndex(productIndex);
963
+ }, 250);
964
+ }
965
+ }
966
+
967
  function openFavoritesModal() {
968
  const favoritesContent = document.getElementById('favoritesContent');
969
  favoritesContent.innerHTML = '';
 
978
  : 'https://via.placeholder.com/70x70.png?text=N/A';
979
 
980
  const itemHtml = `
981
+ <div class="cart-item" onclick="openFavoriteProductDetail('${item.id}')" style="cursor: pointer;">
982
  <img src="${photoUrl}" alt="${item.name}">
983
  <div class="cart-item-details">
984
  <strong>${item.name}</strong>
985
  <p class="cart-item-price">${item.price.toFixed(2)} ${currencyCode}</p>
986
  </div>
987
  <span class="cart-item-total"></span>
988
+ <button class="cart-item-remove" onclick="removeFromFavorites('${item.id}', event)" title="Удалить из избранного">×</button>
989
  </div>`;
990
  favoritesContent.innerHTML += itemHtml;
991
  });
 
994
  openModal('favoritesModal');
995
  }
996
 
997
+ function removeFromFavorites(productId, event) {
998
+ event.stopPropagation();
999
  const index = favorites.indexOf(productId);
1000
  if (index > -1) {
1001
  favorites.splice(index, 1);
 
1075
  <p style="font-size: 1.4rem; font-weight: bold; color: var(--primary-accent);">
1076
  <strong>{{ _('price') }}</strong> {{ "%.2f"|format(product['price']) }} {{ currency_code }}
1077
  </p>
1078
+ {% if product.get('items_per_line', 0) > 1 %}
1079
  <p style="font-size: 1rem; color: var(--text-muted); margin-top: -10px; margin-bottom: 15px;">
1080
  {{ "%.2f"|format(product['price'] / product.get('items_per_line')) }} {{ currency_code }} / {{ _('price_per_piece') }} ({{ product.get('items_per_line') }} {{ _('items_in_line') }})
1081
  </p>