Update app.py
Browse files
app.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
from flask import Flask, render_template_string, request, redirect, url_for, session, send_file, flash
|
| 2 |
import json
|
| 3 |
import os
|
|
@@ -438,6 +439,7 @@ def catalog():
|
|
| 438 |
const products = {{ products|tojson }};
|
| 439 |
const repoId = '{{ repo_id }}';
|
| 440 |
const currencyCode = '{{ currency_code }}';
|
|
|
|
| 441 |
const isAuthenticated = {{ is_authenticated|tojson }};
|
| 442 |
let selectedProductIndex = null;
|
| 443 |
let cart = JSON.parse(localStorage.getItem('soolaCart') || '[]');
|
|
@@ -702,35 +704,49 @@ def catalog():
|
|
| 702 |
alert("Корзина пуста! Добавьте товары перед заказом.");
|
| 703 |
return;
|
| 704 |
}
|
|
|
|
| 705 |
let total = 0;
|
| 706 |
-
let orderText = "Новый Заказ
|
|
|
|
|
|
|
| 707 |
cart.forEach((item, index) => {
|
| 708 |
const itemTotal = item.price * item.quantity;
|
| 709 |
total += itemTotal;
|
| 710 |
const colorText = item.color !== 'N/A' ? ` (Цвет: ${item.color})` : '';
|
| 711 |
-
orderText += `${index + 1}. ${item.name}${colorText}
|
|
|
|
|
|
|
|
|
|
| 712 |
});
|
| 713 |
-
|
|
|
|
|
|
|
|
|
|
| 714 |
|
| 715 |
const userInfo = {{ session.get('user_info', {})|tojson }};
|
| 716 |
if (userInfo && userInfo.login) {
|
| 717 |
-
orderText +=
|
| 718 |
-
orderText += `
|
| 719 |
-
orderText += `
|
| 720 |
-
orderText += `
|
|
|
|
|
|
|
| 721 |
} else {
|
| 722 |
-
orderText +=
|
| 723 |
}
|
| 724 |
|
| 725 |
const now = new Date();
|
| 726 |
-
const dateTimeString = now.toLocaleString('ru-RU');
|
| 727 |
-
orderText += `
|
|
|
|
| 728 |
|
| 729 |
-
const whatsappNumber = "996997703090";
|
| 730 |
const whatsappUrl = `https://api.whatsapp.com/send?phone=${whatsappNumber}&text=${encodeURIComponent(orderText)}`;
|
|
|
|
| 731 |
window.open(whatsappUrl, '_blank');
|
| 732 |
}
|
| 733 |
|
|
|
|
| 734 |
function filterProducts() {
|
| 735 |
const searchTerm = document.getElementById('search-input').value.toLowerCase().trim();
|
| 736 |
const activeCategoryButton = document.querySelector('.category-filter.active');
|
|
@@ -955,7 +971,8 @@ def login():
|
|
| 955 |
'first_name': user_info.get('first_name', ''),
|
| 956 |
'last_name': user_info.get('last_name', ''),
|
| 957 |
'country': user_info.get('country', ''),
|
| 958 |
-
'city': user_info.get('city', '')
|
|
|
|
| 959 |
}
|
| 960 |
logging.info(f"Пользователь {login} успешно вошел в систему.")
|
| 961 |
login_response_html = f'''
|
|
@@ -997,7 +1014,8 @@ def auto_login():
|
|
| 997 |
'first_name': user_info.get('first_name', ''),
|
| 998 |
'last_name': user_info.get('last_name', ''),
|
| 999 |
'country': user_info.get('country', ''),
|
| 1000 |
-
'city': user_info.get('city', '')
|
|
|
|
| 1001 |
}
|
| 1002 |
logging.info(f"Автоматический вход для пользователя {login} выполнен.")
|
| 1003 |
return "OK", 200
|
|
@@ -1043,7 +1061,7 @@ ADMIN_TEMPLATE = '''
|
|
| 1043 |
.section { margin-bottom: 30px; padding: 20px; background-color: #f8fcfb; border: 1px solid #d1e7dd; border-radius: 8px; }
|
| 1044 |
form { margin-bottom: 20px; }
|
| 1045 |
label { font-weight: 500; margin-top: 10px; display: block; color: #44524c; font-size: 0.9rem;}
|
| 1046 |
-
input[type="text"], input[type="number"], input[type="password"], textarea, select { width: 100%; padding: 10px 12px; margin-top: 5px; border: 1px solid #c4d9d1; border-radius: 6px; font-size: 0.95rem; box-sizing: border-box; transition: border-color 0.3s ease; }
|
| 1047 |
input:focus, textarea:focus, select:focus { border-color: #1C6758; outline: none; box-shadow: 0 0 0 2px rgba(28, 103, 88, 0.1); }
|
| 1048 |
textarea { min-height: 80px; resize: vertical; }
|
| 1049 |
input[type="file"] { padding: 8px; background-color: #f0f9f4; cursor: pointer; border: 1px solid #c4d9d1;}
|
|
@@ -1165,8 +1183,10 @@ ADMIN_TEMPLATE = '''
|
|
| 1165 |
<label for="login">Логин *:</label>
|
| 1166 |
<input type="text" id="login" name="login" required>
|
| 1167 |
<label for="password">Пароль *:</label>
|
| 1168 |
-
<input type="password" id="password" name="password" required title="Пароль будет сохранен в открытом виде.
|
| 1169 |
-
<
|
|
|
|
|
|
|
| 1170 |
<label for="first_name">Имя:</label>
|
| 1171 |
<input type="text" id="first_name" name="first_name">
|
| 1172 |
<label for="last_name">Фамилия:</label>
|
|
@@ -1187,6 +1207,7 @@ ADMIN_TEMPLATE = '''
|
|
| 1187 |
<div class="item">
|
| 1188 |
<p><strong>Логин:</strong> {{ login }}</p>
|
| 1189 |
<p><strong>Имя:</strong> {{ user_data.get('first_name', 'N/A') }} {{ user_data.get('last_name', '') }}</p>
|
|
|
|
| 1190 |
<p><strong>Локация:</strong> {{ user_data.get('city', 'N/A') }}, {{ user_data.get('country', 'N/A') }}</p>
|
| 1191 |
<div class="item-actions">
|
| 1192 |
<form method="POST" style="margin: 0;" onsubmit="return confirm('Вы уверены, что хотите удалить пользователя \'{{ login }}\'?');">
|
|
@@ -1630,6 +1651,7 @@ def admin():
|
|
| 1630 |
elif action == 'add_user':
|
| 1631 |
login = request.form.get('login', '').strip()
|
| 1632 |
password = request.form.get('password', '').strip()
|
|
|
|
| 1633 |
first_name = request.form.get('first_name', '').strip()
|
| 1634 |
last_name = request.form.get('last_name', '').strip()
|
| 1635 |
country = request.form.get('country', '').strip()
|
|
@@ -1644,6 +1666,7 @@ def admin():
|
|
| 1644 |
|
| 1645 |
users[login] = {
|
| 1646 |
'password': password,
|
|
|
|
| 1647 |
'first_name': first_name, 'last_name': last_name,
|
| 1648 |
'country': country, 'city': city
|
| 1649 |
}
|
|
@@ -1722,4 +1745,5 @@ if __name__ == '__main__':
|
|
| 1722 |
|
| 1723 |
port = int(os.environ.get('PORT', 7860))
|
| 1724 |
logging.info(f"Запуск Flask приложения на хосте 0.0.0.0 и порту {port}")
|
| 1725 |
-
app.run(debug=False, host='0.0.0.0', port=port)
|
|
|
|
|
|
| 1 |
+
|
| 2 |
from flask import Flask, render_template_string, request, redirect, url_for, session, send_file, flash
|
| 3 |
import json
|
| 4 |
import os
|
|
|
|
| 439 |
const products = {{ products|tojson }};
|
| 440 |
const repoId = '{{ repo_id }}';
|
| 441 |
const currencyCode = '{{ currency_code }}';
|
| 442 |
+
const storeAddress = '{{ store_address }}';
|
| 443 |
const isAuthenticated = {{ is_authenticated|tojson }};
|
| 444 |
let selectedProductIndex = null;
|
| 445 |
let cart = JSON.parse(localStorage.getItem('soolaCart') || '[]');
|
|
|
|
| 704 |
alert("Корзина пуста! Добавьте товары перед заказом.");
|
| 705 |
return;
|
| 706 |
}
|
| 707 |
+
|
| 708 |
let total = 0;
|
| 709 |
+
let orderText = "🛍️ *Новый Заказ Soola Cosmetics* 🛍️\n\n";
|
| 710 |
+
orderText += "🛒 *Товары:*\n";
|
| 711 |
+
|
| 712 |
cart.forEach((item, index) => {
|
| 713 |
const itemTotal = item.price * item.quantity;
|
| 714 |
total += itemTotal;
|
| 715 |
const colorText = item.color !== 'N/A' ? ` (Цвет: ${item.color})` : '';
|
| 716 |
+
orderText += `\n*${index + 1}. ${item.name}${colorText}*\n`;
|
| 717 |
+
orderText += ` Цена: ${item.price.toFixed(2)} ${currencyCode}\n`;
|
| 718 |
+
orderText += ` Кол-во: ${item.quantity}\n`;
|
| 719 |
+
orderText += ` Сумма: *${itemTotal.toFixed(2)} ${currencyCode}*\n`;
|
| 720 |
});
|
| 721 |
+
|
| 722 |
+
orderText += `\n--------------------\n`;
|
| 723 |
+
orderText += `💰 *Общая сумма: ${total.toFixed(2)} ${currencyCode}*\n`;
|
| 724 |
+
orderText += `--------------------\n\n`;
|
| 725 |
|
| 726 |
const userInfo = {{ session.get('user_info', {})|tojson }};
|
| 727 |
if (userInfo && userInfo.login) {
|
| 728 |
+
orderText += "👤 *Данные Заказчика:*\n";
|
| 729 |
+
orderText += `*Имя:* ${userInfo.first_name || ''} ${userInfo.last_name || ''}\n`;
|
| 730 |
+
orderText += `*Логин:* ${userInfo.login}\n`;
|
| 731 |
+
orderText += `*Телефон:* ${userInfo.phone_number || 'Не указан'}\n`;
|
| 732 |
+
orderText += `*Страна:* ${userInfo.country || 'Не указана'}\n`;
|
| 733 |
+
orderText += `*Город:* ${userInfo.city || 'Не указан'}\n`;
|
| 734 |
} else {
|
| 735 |
+
orderText += "👤 *Заказчик:* (Не авторизован)\n";
|
| 736 |
}
|
| 737 |
|
| 738 |
const now = new Date();
|
| 739 |
+
const dateTimeString = now.toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
| 740 |
+
orderText += `\n🕒 *Дата заказа:* ${dateTimeString}\n`;
|
| 741 |
+
orderText += `\n📍 *Адрес магазина:* ${storeAddress}`;
|
| 742 |
|
| 743 |
+
const whatsappNumber = "996997703090"; // Убедитесь, что номер правильный
|
| 744 |
const whatsappUrl = `https://api.whatsapp.com/send?phone=${whatsappNumber}&text=${encodeURIComponent(orderText)}`;
|
| 745 |
+
|
| 746 |
window.open(whatsappUrl, '_blank');
|
| 747 |
}
|
| 748 |
|
| 749 |
+
|
| 750 |
function filterProducts() {
|
| 751 |
const searchTerm = document.getElementById('search-input').value.toLowerCase().trim();
|
| 752 |
const activeCategoryButton = document.querySelector('.category-filter.active');
|
|
|
|
| 971 |
'first_name': user_info.get('first_name', ''),
|
| 972 |
'last_name': user_info.get('last_name', ''),
|
| 973 |
'country': user_info.get('country', ''),
|
| 974 |
+
'city': user_info.get('city', ''),
|
| 975 |
+
'phone_number': user_info.get('phone_number', '') # Added phone number
|
| 976 |
}
|
| 977 |
logging.info(f"Пользователь {login} успешно вошел в систему.")
|
| 978 |
login_response_html = f'''
|
|
|
|
| 1014 |
'first_name': user_info.get('first_name', ''),
|
| 1015 |
'last_name': user_info.get('last_name', ''),
|
| 1016 |
'country': user_info.get('country', ''),
|
| 1017 |
+
'city': user_info.get('city', ''),
|
| 1018 |
+
'phone_number': user_info.get('phone_number', '') # Added phone number
|
| 1019 |
}
|
| 1020 |
logging.info(f"Автоматический вход для пользователя {login} выполнен.")
|
| 1021 |
return "OK", 200
|
|
|
|
| 1061 |
.section { margin-bottom: 30px; padding: 20px; background-color: #f8fcfb; border: 1px solid #d1e7dd; border-radius: 8px; }
|
| 1062 |
form { margin-bottom: 20px; }
|
| 1063 |
label { font-weight: 500; margin-top: 10px; display: block; color: #44524c; font-size: 0.9rem;}
|
| 1064 |
+
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 #c4d9d1; border-radius: 6px; font-size: 0.95rem; box-sizing: border-box; transition: border-color 0.3s ease; }
|
| 1065 |
input:focus, textarea:focus, select:focus { border-color: #1C6758; outline: none; box-shadow: 0 0 0 2px rgba(28, 103, 88, 0.1); }
|
| 1066 |
textarea { min-height: 80px; resize: vertical; }
|
| 1067 |
input[type="file"] { padding: 8px; background-color: #f0f9f4; cursor: pointer; border: 1px solid #c4d9d1;}
|
|
|
|
| 1183 |
<label for="login">Логин *:</label>
|
| 1184 |
<input type="text" id="login" name="login" required>
|
| 1185 |
<label for="password">Пароль *:</label>
|
| 1186 |
+
<input type="password" id="password" name="password" required title="Пароль будет сохранен в открытом виде.">
|
| 1187 |
+
<label for="phone_number">Телефон:</label>
|
| 1188 |
+
<input type="tel" id="phone_number" name="phone_number">
|
| 1189 |
+
<p style="font-size: 0.8rem; color: #777;">Логин и пароль обязательны.</p>
|
| 1190 |
<label for="first_name">Имя:</label>
|
| 1191 |
<input type="text" id="first_name" name="first_name">
|
| 1192 |
<label for="last_name">Фамилия:</label>
|
|
|
|
| 1207 |
<div class="item">
|
| 1208 |
<p><strong>Логин:</strong> {{ login }}</p>
|
| 1209 |
<p><strong>Имя:</strong> {{ user_data.get('first_name', 'N/A') }} {{ user_data.get('last_name', '') }}</p>
|
| 1210 |
+
<p><strong>Телефон:</strong> {{ user_data.get('phone_number', 'N/A') }}</p>
|
| 1211 |
<p><strong>Локация:</strong> {{ user_data.get('city', 'N/A') }}, {{ user_data.get('country', 'N/A') }}</p>
|
| 1212 |
<div class="item-actions">
|
| 1213 |
<form method="POST" style="margin: 0;" onsubmit="return confirm('Вы уверены, что хотите удалить пользователя \'{{ login }}\'?');">
|
|
|
|
| 1651 |
elif action == 'add_user':
|
| 1652 |
login = request.form.get('login', '').strip()
|
| 1653 |
password = request.form.get('password', '').strip()
|
| 1654 |
+
phone_number = request.form.get('phone_number', '').strip() # Added phone number
|
| 1655 |
first_name = request.form.get('first_name', '').strip()
|
| 1656 |
last_name = request.form.get('last_name', '').strip()
|
| 1657 |
country = request.form.get('country', '').strip()
|
|
|
|
| 1666 |
|
| 1667 |
users[login] = {
|
| 1668 |
'password': password,
|
| 1669 |
+
'phone_number': phone_number, # Added phone number
|
| 1670 |
'first_name': first_name, 'last_name': last_name,
|
| 1671 |
'country': country, 'city': city
|
| 1672 |
}
|
|
|
|
| 1745 |
|
| 1746 |
port = int(os.environ.get('PORT', 7860))
|
| 1747 |
logging.info(f"Запуск Flask приложения на хосте 0.0.0.0 и порту {port}")
|
| 1748 |
+
app.run(debug=False, host='0.0.0.0', port=port)
|
| 1749 |
+
|