Kgshop commited on
Commit
2a2ba1d
·
verified ·
1 Parent(s): b64f079

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -17
app.py CHANGED
@@ -384,7 +384,7 @@ def catalog():
384
  border-radius: 8px;
385
  margin-right: 15px;
386
  }
387
- .quantity-input, .color-select {
388
  width: 100%;
389
  max-width: 150px;
390
  padding: 8px;
@@ -458,13 +458,19 @@ def catalog():
458
  </div>
459
  </div>
460
 
461
- <!-- Quantity and Color Modal -->
462
  <div id="quantityModal" class="modal">
463
  <div class="modal-content">
464
  <span class="close" onclick="closeModal('quantityModal')">×</span>
465
- <h2>Укажите количество и цвет</h2>
 
466
  <input type="number" id="quantityInput" class="quantity-input" min="1" value="1">
 
467
  <select id="colorSelect" class="color-select"></select>
 
 
 
 
468
  <button class="product-button" onclick="confirmAddToCart()">Добавить</button>
469
  </div>
470
  </div>
@@ -539,6 +545,8 @@ def catalog():
539
  function openQuantityModal(index) {
540
  selectedProductIndex = index;
541
  const product = products[index];
 
 
542
  const colorSelect = document.getElementById('colorSelect');
543
  colorSelect.innerHTML = '';
544
  if (product.colors && product.colors.length > 0) {
@@ -554,6 +562,41 @@ def catalog():
554
  option.text = 'Нет цвета';
555
  colorSelect.appendChild(option);
556
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  document.getElementById('quantityModal').style.display = 'block';
558
  document.getElementById('quantityInput').value = 1;
559
  }
@@ -562,13 +605,17 @@ def catalog():
562
  if (selectedProductIndex === null) return;
563
  const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
564
  const color = document.getElementById('colorSelect').value;
 
 
 
565
  if (quantity <= 0) {
566
  alert("Укажите количество больше 0");
567
  return;
568
  }
 
569
  let cart = JSON.parse(localStorage.getItem('cart') || '[]');
570
  const product = products[selectedProductIndex];
571
- const cartItemId = `${product.name}-${color}`;
572
  const existingItem = cart.find(item => item.id === cartItemId);
573
 
574
  if (existingItem) {
@@ -580,7 +627,9 @@ def catalog():
580
  price: product.price,
581
  photo: product.photos && product.photos.length > 0 ? product.photos[0] : '',
582
  quantity: quantity,
583
- color: color
 
 
584
  });
585
  }
586
 
@@ -608,7 +657,7 @@ def catalog():
608
  ${item.photo ? `<img src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/photos/${item.photo}" alt="${item.name}">` : ''}
609
  <div>
610
  <strong>${item.name}</strong>
611
- <p>${item.price} с × ${item.quantity} (Цвет: ${item.color})</p>
612
  </div>
613
  </div>
614
  <span>${itemTotal} с</span>
@@ -631,7 +680,7 @@ def catalog():
631
  cart.forEach((item, index) => {
632
  const itemTotal = item.price * item.quantity;
633
  total += itemTotal;
634
- orderText += `${index + 1}. ${item.name} - ${item.price} с × ${item.quantity} (Цвет: ${item.color})%0A`;
635
  });
636
  orderText += `Итого: ${total} с`;
637
  window.open(`https://api.whatsapp.com/send?phone=996777888464&text=${orderText}`, '_blank');
@@ -713,6 +762,8 @@ def product_detail(index):
713
  <p><strong>Цена:</strong> {{ product['price'] }} с</p>
714
  <p><strong>Описание:</strong> {{ product['description'] }}</p>
715
  <p><strong>Доступные цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
 
 
716
  </div>
717
  '''
718
  return render_template_string(detail_html, product=product, repo_id=REPO_ID)
@@ -750,10 +801,12 @@ def admin():
750
  category = request.form.get('category')
751
  photos_files = request.files.getlist('photos')
752
  colors = request.form.getlist('colors')
 
 
753
  photos_list = []
754
 
755
  if photos_files:
756
- for photo in photos_files[:10]: # Ограничение до 10 фото
757
  if photo and photo.filename:
758
  photo_filename = secure_filename(photo.filename)
759
  uploads_dir = 'uploads'
@@ -783,7 +836,9 @@ def admin():
783
  'description': description,
784
  'category': category if category in categories else 'Без категории',
785
  'photos': photos_list,
786
- 'colors': colors if colors else []
 
 
787
  }
788
  products.append(new_product)
789
  save_data(data)
@@ -797,10 +852,12 @@ def admin():
797
  category = request.form.get('category')
798
  photos_files = request.files.getlist('photos')
799
  colors = request.form.getlist('colors')
 
 
800
 
801
  if photos_files and any(photo.filename for photo in photos_files):
802
  new_photos_list = []
803
- for photo in photos_files[:10]: # Ограничение до 10 фото
804
  if photo and photo.filename:
805
  photo_filename = secure_filename(photo.filename)
806
  uploads_dir = 'uploads'
@@ -826,6 +883,8 @@ def admin():
826
  products[index]['description'] = description
827
  products[index]['category'] = category if category in categories else 'Без категории'
828
  products[index]['colors'] = colors if colors else []
 
 
829
  save_data(data)
830
  return redirect(url_for('admin'))
831
 
@@ -942,15 +1001,15 @@ def admin():
942
  background: #f7fafc;
943
  border-radius: 10px;
944
  }
945
- .color-input-group {
946
  display: flex;
947
  gap: 10px;
948
  margin-top: 5px;
949
  }
950
- .add-color-btn {
951
  background-color: #10b981;
952
  }
953
- .add-color-btn:hover {
954
  background-color: #059669;
955
  }
956
  </style>
@@ -985,7 +1044,21 @@ def admin():
985
  <input type="text" name="colors" placeholder="Например: Красный">
986
  </div>
987
  </div>
988
- <button type="button" class="add-color-btn" onclick="addColorInput()">Добавить цвет</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
989
  <button type="submit">Добавить товар</button>
990
  </form>
991
 
@@ -1028,6 +1101,8 @@ def admin():
1028
  <p><strong>Цена:</strong> {{ product['price'] }} с</p>
1029
  <p><strong>Описание:</strong> {{ product['description'] }}</p>
1030
  <p><strong>Цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
 
 
1031
  {% if product.get('photos') and product['photos']|length > 0 %}
1032
  <div style="display: flex; flex-wrap: wrap; gap: 10px;">
1033
  {% for photo in product['photos'] %}
@@ -1066,6 +1141,24 @@ def admin():
1066
  {% endfor %}
1067
  </div>
1068
  <button type="button" class="add-color-btn" onclick="addColorInput('edit-color-inputs-{{ loop.index0 }}')">Добавить цвет</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1069
  <button type="submit">Сохранить</button>
1070
  </form>
1071
  </details>
@@ -1079,11 +1172,11 @@ def admin():
1079
  </div>
1080
  </div>
1081
  <script>
1082
- function addColorInput(containerId = 'color-inputs') {
1083
  const container = document.getElementById(containerId);
1084
  const newInput = document.createElement('div');
1085
- newInput.className = 'color-input-group';
1086
- newInput.innerHTML = '<input type="text" name="colors" placeholder="Например: Красный">';
1087
  container.appendChild(newInput);
1088
  }
1089
  </script>
 
384
  border-radius: 8px;
385
  margin-right: 15px;
386
  }
387
+ .quantity-input, .color-select, .size-select, .pattern-select {
388
  width: 100%;
389
  max-width: 150px;
390
  padding: 8px;
 
458
  </div>
459
  </div>
460
 
461
+ <!-- Quantity, Color, Size, Pattern Modal -->
462
  <div id="quantityModal" class="modal">
463
  <div class="modal-content">
464
  <span class="close" onclick="closeModal('quantityModal')">×</span>
465
+ <h2>Укажите параметры</h2>
466
+ <label>Количество:</label>
467
  <input type="number" id="quantityInput" class="quantity-input" min="1" value="1">
468
+ <label>Цвет:</label>
469
  <select id="colorSelect" class="color-select"></select>
470
+ <label>Размер:</label>
471
+ <select id="sizeSelect" class="size-select"></select>
472
+ <label>Узор:</label>
473
+ <select id="patternSelect" class="pattern-select"></select>
474
  <button class="product-button" onclick="confirmAddToCart()">Добавить</button>
475
  </div>
476
  </div>
 
545
  function openQuantityModal(index) {
546
  selectedProductIndex = index;
547
  const product = products[index];
548
+
549
+ // Цвета
550
  const colorSelect = document.getElementById('colorSelect');
551
  colorSelect.innerHTML = '';
552
  if (product.colors && product.colors.length > 0) {
 
562
  option.text = 'Нет цвета';
563
  colorSelect.appendChild(option);
564
  }
565
+
566
+ // Размеры
567
+ const sizeSelect = document.getElementById('sizeSelect');
568
+ sizeSelect.innerHTML = '';
569
+ if (product.sizes && product.sizes.length > 0) {
570
+ product.sizes.forEach(size => {
571
+ const option = document.createElement('option');
572
+ option.value = size;
573
+ option.text = size;
574
+ sizeSelect.appendChild(option);
575
+ });
576
+ } else {
577
+ const option = document.createElement('option');
578
+ option.value = 'Нет размера';
579
+ option.text = 'Нет размера';
580
+ sizeSelect.appendChild(option);
581
+ }
582
+
583
+ // Узоры
584
+ const patternSelect = document.getElementById('patternSelect');
585
+ patternSelect.innerHTML = '';
586
+ if (product.patterns && product.patterns.length > 0) {
587
+ product.patterns.forEach(pattern => {
588
+ const option = document.createElement('option');
589
+ option.value = pattern;
590
+ option.text = pattern;
591
+ patternSelect.appendChild(option);
592
+ });
593
+ } else {
594
+ const option = document.createElement('option');
595
+ option.value = 'Нет узора';
596
+ option.text = 'Нет узора';
597
+ patternSelect.appendChild(option);
598
+ }
599
+
600
  document.getElementById('quantityModal').style.display = 'block';
601
  document.getElementById('quantityInput').value = 1;
602
  }
 
605
  if (selectedProductIndex === null) return;
606
  const quantity = parseInt(document.getElementById('quantityInput').value) || 1;
607
  const color = document.getElementById('colorSelect').value;
608
+ const size = document.getElementById('sizeSelect').value;
609
+ const pattern = document.getElementById('patternSelect').value;
610
+
611
  if (quantity <= 0) {
612
  alert("Укажите количество больше 0");
613
  return;
614
  }
615
+
616
  let cart = JSON.parse(localStorage.getItem('cart') || '[]');
617
  const product = products[selectedProductIndex];
618
+ const cartItemId = `${product.name}-${color}-${size}-${pattern}`;
619
  const existingItem = cart.find(item => item.id === cartItemId);
620
 
621
  if (existingItem) {
 
627
  price: product.price,
628
  photo: product.photos && product.photos.length > 0 ? product.photos[0] : '',
629
  quantity: quantity,
630
+ color: color,
631
+ size: size,
632
+ pattern: pattern
633
  });
634
  }
635
 
 
657
  ${item.photo ? `<img src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/photos/${item.photo}" alt="${item.name}">` : ''}
658
  <div>
659
  <strong>${item.name}</strong>
660
+ <p>${item.price} с × ${item.quantity} (Цвет: ${item.color}, Размер: ${item.size}, Узор: ${item.pattern})</p>
661
  </div>
662
  </div>
663
  <span>${itemTotal} с</span>
 
680
  cart.forEach((item, index) => {
681
  const itemTotal = item.price * item.quantity;
682
  total += itemTotal;
683
+ orderText += `${index + 1}. ${item.name} - ${item.price} с × ${item.quantity} (Цвет: ${item.color}, Размер: ${item.size}, Узор: ${item.pattern})%0A`;
684
  });
685
  orderText += `Итого: ${total} с`;
686
  window.open(`https://api.whatsapp.com/send?phone=996777888464&text=${orderText}`, '_blank');
 
762
  <p><strong>Цена:</strong> {{ product['price'] }} с</p>
763
  <p><strong>Описание:</strong> {{ product['description'] }}</p>
764
  <p><strong>Доступные цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
765
+ <p><strong>Доступные размеры:</strong> {{ product.get('sizes', ['Нет размеров'])|join(', ') }}</p>
766
+ <p><strong>Доступные узоры:</strong> {{ product.get('patterns', ['Нет узоров'])|join(', ') }}</p>
767
  </div>
768
  '''
769
  return render_template_string(detail_html, product=product, repo_id=REPO_ID)
 
801
  category = request.form.get('category')
802
  photos_files = request.files.getlist('photos')
803
  colors = request.form.getlist('colors')
804
+ sizes = request.form.getlist('sizes')
805
+ patterns = request.form.getlist('patterns')
806
  photos_list = []
807
 
808
  if photos_files:
809
+ for photo in photos_files[:10]:
810
  if photo and photo.filename:
811
  photo_filename = secure_filename(photo.filename)
812
  uploads_dir = 'uploads'
 
836
  'description': description,
837
  'category': category if category in categories else 'Без категории',
838
  'photos': photos_list,
839
+ 'colors': colors if colors else [],
840
+ 'sizes': sizes if sizes else [],
841
+ 'patterns': patterns if patterns else []
842
  }
843
  products.append(new_product)
844
  save_data(data)
 
852
  category = request.form.get('category')
853
  photos_files = request.files.getlist('photos')
854
  colors = request.form.getlist('colors')
855
+ sizes = request.form.getlist('sizes')
856
+ patterns = request.form.getlist('patterns')
857
 
858
  if photos_files and any(photo.filename for photo in photos_files):
859
  new_photos_list = []
860
+ for photo in photos_files[:10]:
861
  if photo and photo.filename:
862
  photo_filename = secure_filename(photo.filename)
863
  uploads_dir = 'uploads'
 
883
  products[index]['description'] = description
884
  products[index]['category'] = category if category in categories else 'Без категории'
885
  products[index]['colors'] = colors if colors else []
886
+ products[index]['sizes'] = sizes if sizes else []
887
+ products[index]['patterns'] = patterns if patterns else []
888
  save_data(data)
889
  return redirect(url_for('admin'))
890
 
 
1001
  background: #f7fafc;
1002
  border-radius: 10px;
1003
  }
1004
+ .color-input-group, .size-input-group, .pattern-input-group {
1005
  display: flex;
1006
  gap: 10px;
1007
  margin-top: 5px;
1008
  }
1009
+ .add-color-btn, .add-size-btn, .add-pattern-btn {
1010
  background-color: #10b981;
1011
  }
1012
+ .add-color-btn:hover, .add-size-btn:hover, .add-pattern-btn:hover {
1013
  background-color: #059669;
1014
  }
1015
  </style>
 
1044
  <input type="text" name="colors" placeholder="Например: Красный">
1045
  </div>
1046
  </div>
1047
+ <button type="button" class="add-color-btn" onclick="addColorInput('color-inputs')">Добавить цвет</button>
1048
+ <label>Размеры:</label>
1049
+ <div id="size-inputs">
1050
+ <div class="size-input-group">
1051
+ <input type="text" name="sizes" placeholder="Например: M">
1052
+ </div>
1053
+ </div>
1054
+ <button type="button" class="add-size-btn" onclick="addColorInput('size-inputs', 'sizes')">Добавить размер</button>
1055
+ <label>Узоры:</label>
1056
+ <div id="pattern-inputs">
1057
+ <div class="pattern-input-group">
1058
+ <input type="text" name="patterns" placeholder="Например: Полоска">
1059
+ </div>
1060
+ </div>
1061
+ <button type="button" class="add-pattern-btn" onclick="addColorInput('pattern-inputs', 'patterns')">Добавить узор</button>
1062
  <button type="submit">Добавить товар</button>
1063
  </form>
1064
 
 
1101
  <p><strong>Цена:</strong> {{ product['price'] }} с</p>
1102
  <p><strong>Описание:</strong> {{ product['description'] }}</p>
1103
  <p><strong>Цвета:</strong> {{ product.get('colors', ['Нет цветов'])|join(', ') }}</p>
1104
+ <p><strong>Размеры:</strong> {{ product.get('sizes', ['Нет размеров'])|join(', ') }}</p>
1105
+ <p><strong>Узоры:</strong> {{ product.get('patterns', ['Нет узоров'])|join(', ') }}</p>
1106
  {% if product.get('photos') and product['photos']|length > 0 %}
1107
  <div style="display: flex; flex-wrap: wrap; gap: 10px;">
1108
  {% for photo in product['photos'] %}
 
1141
  {% endfor %}
1142
  </div>
1143
  <button type="button" class="add-color-btn" onclick="addColorInput('edit-color-inputs-{{ loop.index0 }}')">Добавить цвет</button>
1144
+ <label>Размеры:</label>
1145
+ <div id="edit-size-inputs-{{ loop.index0 }}">
1146
+ {% for size in product.get('sizes', []) %}
1147
+ <div class="size-input-group">
1148
+ <input type="text" name="sizes" value="{{ size }}">
1149
+ </div>
1150
+ {% endfor %}
1151
+ </div>
1152
+ <button type="button" class="add-size-btn" onclick="addColorInput('edit-size-inputs-{{ loop.index0 }}', 'sizes')">Добавить размер</button>
1153
+ <label>Узоры:</label>
1154
+ <div id="edit-pattern-inputs-{{ loop.index0 }}">
1155
+ {% for pattern in product.get('patterns', []) %}
1156
+ <div class="pattern-input-group">
1157
+ <input type="text" name="patterns" value="{{ pattern }}">
1158
+ </div>
1159
+ {% endfor %}
1160
+ </div>
1161
+ <button type="button" class="add-pattern-btn" onclick="addColorInput('edit-pattern-inputs-{{ loop.index0 }}', 'patterns')">Добавить узор</button>
1162
  <button type="submit">Сохранить</button>
1163
  </form>
1164
  </details>
 
1172
  </div>
1173
  </div>
1174
  <script>
1175
+ function addColorInput(containerId, name = 'colors') {
1176
  const container = document.getElementById(containerId);
1177
  const newInput = document.createElement('div');
1178
+ newInput.className = name === 'colors' ? 'color-input-group' : name === 'sizes' ? 'size-input-group' : 'pattern-input-group';
1179
+ newInput.innerHTML = `<input type="text" name="${name}" placeholder="Например: ${name === 'colors' ? 'Красный' : name === 'sizes' ? 'M' : 'Полоска'}">`;
1180
  container.appendChild(newInput);
1181
  }
1182
  </script>