shop with parent control

This commit is contained in:
Zholdas 2026-08-10 09:15:55 +00:00
parent 1c84803dc1
commit 4d2cba24bc

View File

@ -24,7 +24,6 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
.card-price{font-size:24px;font-weight:800;color:var(--ink);margin-bottom:12px} .card-price{font-size:24px;font-weight:800;color:var(--ink);margin-bottom:12px}
.card-cat{display:inline-block;background:var(--cyan-50);color:var(--ink);padding:4px 12px;border-radius:20px;font-size:14px;font-weight:600;margin-bottom:12px} .card-cat{display:inline-block;background:var(--cyan-50);color:var(--ink);padding:4px 12px;border-radius:20px;font-size:14px;font-weight:600;margin-bottom:12px}
.btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:14px 28px;border-radius:8px;font-weight:700;text-decoration:none;border:none;cursor:pointer} .btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:14px 28px;border-radius:8px;font-weight:700;text-decoration:none;border:none;cursor:pointer}
.btn-buy{width:100%;margin-top:12px}
.btn:hover{opacity:0.9} .btn:hover{opacity:0.9}
.btn-green{background:var(--green);color:#fff} .btn-green{background:var(--green);color:#fff}
.btn-red{background:var(--red);color:#fff} .btn-red{background:var(--red);color:#fff}
@ -33,6 +32,7 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
.nav a{color:var(--white);text-decoration:none;font-weight:600;margin-left:24px} .nav a{color:var(--white);text-decoration:none;font-weight:600;margin-left:24px}
.nav a.active{color:var(--cyan)} .nav a.active{color:var(--cyan)}
.admin-panel{background:var(--cyan-50);padding:32px;border-radius:16px;margin-bottom:40px} .admin-panel{background:var(--cyan-50);padding:32px;border-radius:16px;margin-bottom:40px}
.code-display{background:var(--ink);color:var(--cyan);padding:24px;border-radius:12px;text-align:center;font-size:32px;font-weight:800;letter-spacing:4px;margin:20px 0}
.form-group{margin-bottom:20px} .form-group{margin-bottom:20px}
.form-group label{display:block;font-weight:600;margin-bottom:8px} .form-group label{display:block;font-weight:600;margin-bottom:8px}
.form-group input,.form-group select,.form-group textarea{width:100%;padding:12px;border:1px solid #ddd;border-radius:8px;font-size:16px} .form-group input,.form-group select,.form-group textarea{width:100%;padding:12px;border:1px solid #ddd;border-radius:8px;font-size:16px}
@ -81,6 +81,10 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
<div class="grid" id="products-grid"></div> <div class="grid" id="products-grid"></div>
<div class="empty" id="empty-msg" style="display:none">Товаров пока нет 😔</div> <div class="empty" id="empty-msg" style="display:none">Товаров пока нет 😔</div>
<div style="text-align:center;margin-top:40px">
<button class="btn" onclick="openParentCodeModal()" style="background:var(--green);color:#fff">👨‍👩‍👧 Получить код родителя</button>
</div>
</div> </div>
</section> </section>
@ -98,6 +102,30 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
</div> </div>
<div id="admin-content" style="display:none"> <div id="admin-content" style="display:none">
<div class="admin-panel">
<h3>👨‍👩‍👧 Родительский контроль</h3>
<p style="margin-bottom:20px">Дети покупают только с кодом от родителей</p>
<form id="parent-form" style="margin-bottom:32px">
<div class="form-group">
<label>Имя родителя</label>
<input type="text" id="parent-name" placeholder="Иванова Мария" required>
</div>
<div class="form-group">
<label>Телефон</label>
<input type="tel" id="parent-phone" placeholder="+7 777 123 45 67" required>
</div>
<div class="form-group">
<label>Лимит на день (₸)</label>
<input type="number" id="parent-limit" placeholder="1000" required>
</div>
<button type="submit" class="btn btn-green">Зарегистрировать родителя</button>
</form>
<h4 style="margin-bottom:16px">Зарегистрированные родители:</h4>
<div id="parents-list" style="margin-bottom:32px"></div>
</div>
<div class="admin-panel"> <div class="admin-panel">
<h3>➕ Добавить товар</h3> <h3>➕ Добавить товар</h3>
<form id="add-form"> <form id="add-form">
@ -130,6 +158,11 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
</form> </form>
</div> </div>
<div class="admin-panel">
<h3>📊 История покупок</h3>
<div id="purchases-list" style="margin-top:16px"></div>
</div>
<h3>📦 Все товары</h3> <h3>📦 Все товары</h3>
<div class="grid" id="admin-grid"></div> <div class="grid" id="admin-grid"></div>
</div> </div>
@ -145,23 +178,53 @@ body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
</div> </div>
</div> </div>
<div class="modal" id="parent-code-modal">
<div class="modal-content">
<h3>👨‍👩‍👧 Родительский контроль</h3>
<p style="margin-bottom:16px">Для покупки нужен код от родителя</p>
<input type="text" id="parent-code-input" placeholder="Введите код" style="width:100%;padding:12px;border:1px solid #ddd;border-radius:8px;margin-bottom:16px;font-size:18px;text-align:center">
<button class="btn" onclick="verifyParentCode()">Подтвердить</button>
<button class="btn" style="background:var(--gray-100);margin-top:12px" onclick="closeParentModal()">Отмена</button>
<p style="margin-top:20px;font-size:14px;color:var(--gray-500)">Нет кода? Попроси родителей зарегистрироваться в админке</p>
</div>
</div>
<div class="modal" id="success-modal">
<div class="modal-content" style="text-align:center">
<h3>✅ Покупка разрешена!</h3>
<p id="success-message" style="margin:20px 0"></p>
<div id="success-code" class="code-display"></div>
<p style="font-size:14px;color:var(--gray-500);margin-bottom:20px">Покажи этот код на кассе</p>
<button class="btn" onclick="document.getElementById('success-modal').classList.remove('on')">OK</button>
</div>
</div>
<script> <script>
// === Данные === // === Данные ===
const CATEGORIES = {еда:'🍫', напитки:'🥤', школа:'✏️', разное:'🎁'}; const CATEGORIES = {еда:'🍫', напитки:'🥤', школа:'✏️', разное:'🎁'};
let products = []; let products = [];
let parents = [];
let purchases = [];
let isAdmin = false; let isAdmin = false;
const ADMIN_PASS = 'admin123'; // Поменяй на свой! const ADMIN_PASS = 'admin123'; // Поменяй на свой!
// === Загрузка/сохранение === // === Загрузка/сохранение ===
function loadProducts() { function loadProducts() {
try { try {
const saved = localStorage.getItem('shop-products'); products = localStorage.getItem('shop-products') ? JSON.parse(localStorage.getItem('shop-products')) : getDefaults();
products = saved ? JSON.parse(saved) : getDefaults(); parents = localStorage.getItem('shop-parents') ? JSON.parse(localStorage.getItem('shop-parents')) : [];
} catch { products = getDefaults(); } purchases = localStorage.getItem('shop-purchases') ? JSON.parse(localStorage.getItem('shop-purchases')) : [];
} catch {
products = getDefaults();
parents = [];
purchases = [];
}
} }
function saveProducts() { function saveProducts() {
localStorage.setItem('shop-products', JSON.stringify(products)); localStorage.setItem('shop-products', JSON.stringify(products));
localStorage.setItem('shop-parents', JSON.stringify(parents));
localStorage.setItem('shop-purchases', JSON.stringify(purchases));
} }
function getDefaults() { function getDefaults() {
@ -196,7 +259,7 @@ function render(filter = 'all') {
<div class="card-title">${p.name}</div> <div class="card-title">${p.name}</div>
<div class="card-price">${p.price} ₸</div> <div class="card-price">${p.price} ₸</div>
<p style="color:var(--gray-500);font-size:14px">${p.desc || ''}</p> <p style="color:var(--gray-500);font-size:14px">${p.desc || ''}</p>
<button class="btn btn-buy" onclick="askParent('${p.name}', ${p.price})">👨‍👩‍👧‍👦 Попросить родителя</button> <button class="btn" style="margin-top:12px;width:100%" onclick="buyProduct(${p.id})">Купить</button>
</div> </div>
</div> </div>
`).join(''); `).join('');
@ -216,6 +279,41 @@ function render(filter = 'all') {
</div> </div>
`).join(''); `).join('');
} }
// Родители
const parentsList = document.getElementById('parents-list');
if (parentsList) {
parentsList.innerHTML = parents.length === 0 ? '<p style="color:var(--gray-500)">Пока нет зарегистрированных родителей</p>' :
parents.map(par => `
<div class="card" style="margin-bottom:16px;padding:16px">
<strong>${par.name}</strong> (${par.phone})<br>
<span style="color:var(--gray-500)">Код: <strong style="color:var(--cyan)">${par.code}</strong></span> |
Лимит: <strong>${par.limit} ₸</strong> |
Потрачено сегодня: <strong>${getSpentToday(par.id)} ₸</strong> |
<button class="btn btn-red" style="margin-left:12px;padding:6px 12px;font-size:14px" onclick="deleteParent(${par.id})">Удалить</button>
</div>
`).join('');
}
// Покупки
const purchasesList = document.getElementById('purchases-list');
if (purchasesList) {
purchasesList.innerHTML = purchases.length === 0 ? '<p style="color:var(--gray-500)">Покупок пока нет</p>' :
purchases.slice(-10).reverse().map(p => `
<div style="padding:12px;border-bottom:1px solid var(--gray-100)">
<strong>${p.product}</strong> — ${p.price} ₸ |
Родитель: <strong>${p.parentName}</strong> |
${new Date(p.date).toLocaleString('ru-RU')}
</div>
`).join('');
}
}
function getSpentToday(parentId) {
const today = new Date().toDateString();
return purchases
.filter(p => p.parentId === parentId && new Date(p.date).toDateString() === today)
.reduce((sum, p) => sum + p.price, 0);
} }
// === Фильтры === // === Фильтры ===
@ -275,6 +373,88 @@ function closeModal() {
document.getElementById('login-modal').classList.remove('on'); document.getElementById('login-modal').classList.remove('on');
} }
// === Покупки ===
let currentProduct = null;
function buyProduct(id) {
currentProduct = products.find(p => p.id === id);
openParentCodeModal();
}
function openParentCodeModal() {
document.getElementById('parent-code-input').value = '';
document.getElementById('parent-code-modal').classList.add('on');
}
function closeParentModal() {
document.getElementById('parent-code-modal').classList.remove('on');
}
function verifyParentCode() {
const code = document.getElementById('parent-code-input').value.trim();
const parent = parents.find(p => p.code === code);
if (!parent) {
alert('❌ Неверный код! Попроси родителя ввести код.');
return;
}
const spentToday = getSpentToday(parent.id);
const productPrice = currentProduct ? currentProduct.price : 0;
if (spentToday + productPrice > parent.limit) {
alert(`⚠️ Превышен лимит! Сегодня потрачено: ${spentToday} ₸ из ${parent.limit} ₸`);
return;
}
// Успешная покупка
if (currentProduct) {
purchases.push({
parentId: parent.id,
parentName: parent.name,
productId: currentProduct.id,
product: currentProduct.name,
price: currentProduct.price,
date: new Date().toISOString()
});
saveProducts();
document.getElementById('success-message').textContent = `${parent.name}, ваш ребёнок покупает: ${currentProduct.name} за ${currentProduct.price} ₸`;
document.getElementById('success-code').textContent = code;
document.getElementById('parent-code-modal').classList.remove('on');
document.getElementById('success-modal').classList.add('on');
}
}
// === Родители ===
document.getElementById('parent-form').addEventListener('submit', (e) => {
e.preventDefault();
const parent = {
id: Date.now(),
name: document.getElementById('parent-name').value,
phone: document.getElementById('parent-phone').value,
limit: Number(document.getElementById('parent-limit').value),
code: generateCode()
};
parents.push(parent);
saveProducts();
render();
e.target.reset();
alert(`✅ Родитель зарегистрирован! Код: ${parent.code}`);
});
function generateCode() {
return Math.floor(1000 + Math.random() * 9000).toString();
}
function deleteParent(id) {
if (confirm('Удалить этого родителя?')) {
parents = parents.filter(p => p.id !== id);
saveProducts();
render();
}
}
// === Добавление/удаление === // === Добавление/удаление ===
document.getElementById('add-form').addEventListener('submit', (e) => { document.getElementById('add-form').addEventListener('submit', (e) => {
e.preventDefault(); e.preventDefault();
@ -301,19 +481,6 @@ function deleteProduct(id) {
} }
} }
// === Запрос родителю ===
function askParent(name, price) {
const parentPhone = prompt(
`Товар: ${name}\nЦена: ${price} ₸\n\nВведите номер телефона родителя (WhatsApp):`,
'77771234567'
);
if (parentPhone) {
const msg = `Здравствуйте! Я хочу купить ${name} за ${price} ₸. Можно?`;
const url = `https://wa.me/${parentPhone}?text=${encodeURIComponent(msg)}`;
window.open(url, '_blank');
}
}
// === Старт === // === Старт ===
loadProducts(); loadProducts();
render(); render();