ya-hochu-nachat-biznes-dazhe/index.html
2026-08-10 09:15:55 +00:00

490 lines
21 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Школьный магазинчик</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏪</text></svg>">
<style>
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7;--green:#25D366;--red:#FF4444}
*{box-sizing:border-box;margin:0;padding:0}
body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
.container{max-width:1140px;margin:0 auto;padding:80px 24px}
.hero{background:var(--ink);color:var(--white);padding:60px 24px}
.hero h1{font-size:48px;font-weight:800;line-height:1.05;margin-bottom:16px}
.hero p{font-size:20px;color:#9aa3b2;max-width:600px}
.section{padding:60px 24px}
.section h2{font-size:36px;font-weight:700;margin-bottom:32px;text-align:center}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:24px}
.card{background:var(--gray-100);border-radius:16px;overflow:hidden;transition:transform .2s}
.card:hover{transform:translateY(-4px)}
.card img{width:100%;height:200px;object-fit:cover}
.card-body{padding:20px}
.card-title{font-size:20px;font-weight:700;margin-bottom:8px}
.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}
.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:hover{opacity:0.9}
.btn-green{background:var(--green);color:#fff}
.btn-red{background:var(--red);color:#fff}
.nav{background:var(--ink);padding:16px 24px;position:sticky;top:0;z-index:100}
.nav-inner{max-width:1140px;margin:0 auto;display:flex;justify-content:space-between;align-items:center}
.nav a{color:var(--white);text-decoration:none;font-weight:600;margin-left:24px}
.nav a.active{color:var(--cyan)}
.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 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}
.filter-bar{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:32px;justify-content:center}
.filter-btn{padding:10px 20px;border:2px solid var(--gray-100);background:var(--white);border-radius:20px;cursor:pointer;font-weight:600}
.filter-btn.active{border-color:var(--cyan);background:var(--cyan-50)}
.empty{text-align:center;padding:60px 24px;color:var(--gray-500)}
.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:1000;align-items:center;justify-content:center}
.modal.on{display:flex}
.modal-content{background:var(--white);padding:32px;border-radius:16px;max-width:400px;width:90%}
.modal h3{margin-bottom:20px}
.password-input{margin-bottom:16px}
@media (max-width:640px){.hero h1{font-size:32px}.section h2{font-size:28px}.container{padding:40px 16px}}
</style>
</head>
<body>
<nav class="nav">
<div class="nav-inner">
<strong style="color:var(--white);font-size:20px;">🏪 Школьный магазин</strong>
<div>
<a href="#" id="nav-home" class="active">Товары</a>
<a href="#" id="nav-admin">Админка</a>
</div>
</div>
</nav>
<section class="hero">
<div class="container">
<h1>Добро пожаловать!</h1>
<p>Вкусные перекусы, школьные принадлежности и приятные мелочи по доступным ценам</p>
</div>
</section>
<section class="section" id="shop-section">
<div class="container">
<h2>🛒 Наши товары</h2>
<div class="filter-bar" id="filters">
<button class="filter-btn active" data-cat="all">Все</button>
<button class="filter-btn" data-cat="еда">🍫 Еда</button>
<button class="filter-btn" data-cat="напитки">🥤 Напитки</button>
<button class="filter-btn" data-cat="школа">✏️ Школа</button>
<button class="filter-btn" data-cat="разное">🎁 Разное</button>
</div>
<div class="grid" id="products-grid"></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>
</section>
<section class="section" id="admin-section" style="display:none">
<div class="container">
<h2>⚙️ Админка</h2>
<div class="admin-panel" id="admin-login">
<h3>🔐 Вход для владельца</h3>
<p style="margin-bottom:20px">Введите пароль для управления товарами</p>
<div class="form-group">
<input type="password" id="admin-password" class="password-input" placeholder="Пароль">
</div>
<button class="btn" onclick="checkPassword()">Войти</button>
</div>
<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">
<h3>➕ Добавить товар</h3>
<form id="add-form">
<div class="form-group">
<label>Название</label>
<input type="text" id="prod-name" placeholder="Например: Snickers" required>
</div>
<div class="form-group">
<label>Цена (₸)</label>
<input type="number" id="prod-price" placeholder="150" required>
</div>
<div class="form-group">
<label>Категория</label>
<select id="prod-cat">
<option value="еда">🍫 Еда</option>
<option value="напитки">🥤 Напитки</option>
<option value="школа">✏️ Школа</option>
<option value="разное">🎁 Разное</option>
</select>
</div>
<div class="form-group">
<label>Описание</label>
<textarea id="prod-desc" rows="3" placeholder="Короткое описание"></textarea>
</div>
<div class="form-group">
<label>Картинка (ссылка или оставь пустым)</label>
<input type="text" id="prod-img" placeholder="https://...">
</div>
<button type="submit" class="btn btn-green">Добавить товар</button>
</form>
</div>
<div class="admin-panel">
<h3>📊 История покупок</h3>
<div id="purchases-list" style="margin-top:16px"></div>
</div>
<h3>📦 Все товары</h3>
<div class="grid" id="admin-grid"></div>
</div>
</div>
</section>
<div class="modal" id="login-modal">
<div class="modal-content">
<h3>🔐 Введите пароль</h3>
<input type="password" id="modal-password" class="password-input" placeholder="Пароль" style="width:100%;padding:12px;border:1px solid #ddd;border-radius:8px;margin-bottom:16px">
<button class="btn" onclick="checkModalPassword()">Войти</button>
<button class="btn" style="background:var(--gray-100);margin-top:12px" onclick="closeModal()">Отмена</button>
</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>
// === Данные ===
const CATEGORIES = {еда:'🍫', напитки:'🥤', школа:'✏️', разное:'🎁'};
let products = [];
let parents = [];
let purchases = [];
let isAdmin = false;
const ADMIN_PASS = 'admin123'; // Поменяй на свой!
// === Загрузка/сохранение ===
function loadProducts() {
try {
products = localStorage.getItem('shop-products') ? JSON.parse(localStorage.getItem('shop-products')) : getDefaults();
parents = localStorage.getItem('shop-parents') ? JSON.parse(localStorage.getItem('shop-parents')) : [];
purchases = localStorage.getItem('shop-purchases') ? JSON.parse(localStorage.getItem('shop-purchases')) : [];
} catch {
products = getDefaults();
parents = [];
purchases = [];
}
}
function saveProducts() {
localStorage.setItem('shop-products', JSON.stringify(products));
localStorage.setItem('shop-parents', JSON.stringify(parents));
localStorage.setItem('shop-purchases', JSON.stringify(purchases));
}
function getDefaults() {
return [
{id:1, name:'Snickers', price:150, cat:'еда', desc:'Шоколадный батончик с нугой', img:'https://picsum.photos/seed/snickers/400/300'},
{id:2, name:'Coca-Cola', price:200, cat:'напитки', desc:'Газировка 0.5л', img:'https://picsum.photos/seed/coke/400/300'},
{id:3, name:'Тетрадь 12л', price:80, cat:'школа', desc:'В клетку, 12 листов', img:'https://picsum.photos/seed/notebook/400/300'},
{id:4, name:'Чипсы Lay\'s', price:350, cat:'еда', desc:'Вкус краба', img:'https://picsum.photos/seed/chips/400/300'},
{id:5, name:'Ручка синяя', price:120, cat:'школа', desc:'Шариковая, 0.7мм', img:'https://picsum.photos/seed/pen/400/300'},
{id:6, name:'Жвачка Love Is', price:50, cat:'еда', desc:'Клубничная', img:'https://picsum.photos/seed/gum/400/300'}
];
}
// === Рендер ===
function render(filter = 'all') {
const grid = document.getElementById('products-grid');
const adminGrid = document.getElementById('admin-grid');
const empty = document.getElementById('empty-msg');
const filtered = filter === 'all' ? products : products.filter(p => p.cat === filter);
if (filtered.length === 0) {
grid.innerHTML = '';
empty.style.display = 'block';
} else {
empty.style.display = 'none';
grid.innerHTML = filtered.map(p => `
<div class="card">
<img src="${p.img || 'https://picsum.photos/400/300'}" alt="${p.name}">
<div class="card-body">
<span class="card-cat">${CATEGORIES[p.cat]} ${p.cat}</span>
<div class="card-title">${p.name}</div>
<div class="card-price">${p.price} ₸</div>
<p style="color:var(--gray-500);font-size:14px">${p.desc || ''}</p>
<button class="btn" style="margin-top:12px;width:100%" onclick="buyProduct(${p.id})">Купить</button>
</div>
</div>
`).join('');
}
// Админка
if (adminGrid) {
adminGrid.innerHTML = products.map(p => `
<div class="card">
<img src="${p.img || 'https://picsum.photos/400/300'}" alt="${p.name}">
<div class="card-body">
<span class="card-cat">${CATEGORIES[p.cat]} ${p.cat}</span>
<div class="card-title">${p.name}</div>
<div class="card-price">${p.price} ₸</div>
<button class="btn btn-red" style="margin-top:12px;width:100%" onclick="deleteProduct(${p.id})">Удалить</button>
</div>
</div>
`).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);
}
// === Фильтры ===
document.getElementById('filters').addEventListener('click', (e) => {
if (e.target.classList.contains('filter-btn')) {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
render(e.target.dataset.cat);
}
});
// === Навигация ===
document.getElementById('nav-home').addEventListener('click', (e) => {
e.preventDefault();
showPage('home');
});
document.getElementById('nav-admin').addEventListener('click', (e) => {
e.preventDefault();
showPage('admin');
});
function showPage(page) {
document.getElementById('shop-section').style.display = page === 'home' ? 'block' : 'none';
document.getElementById('admin-section').style.display = page === 'admin' ? 'block' : 'none';
document.getElementById('nav-home').classList.toggle('active', page === 'home');
document.getElementById('nav-admin').classList.toggle('active', page === 'admin');
}
// === Админка ===
function checkPassword() {
const pass = document.getElementById('admin-password').value;
if (pass === ADMIN_PASS) {
isAdmin = true;
document.getElementById('admin-login').style.display = 'none';
document.getElementById('admin-content').style.display = 'block';
render();
} else {
alert('Неверный пароль!');
}
}
function checkModalPassword() {
const pass = document.getElementById('modal-password').value;
if (pass === ADMIN_PASS) {
isAdmin = true;
closeModal();
showPage('admin');
document.getElementById('admin-login').style.display = 'none';
document.getElementById('admin-content').style.display = 'block';
render();
} else {
alert('Неверный пароль!');
}
}
function closeModal() {
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) => {
e.preventDefault();
const product = {
id: Date.now(),
name: document.getElementById('prod-name').value,
price: Number(document.getElementById('prod-price').value),
cat: document.getElementById('prod-cat').value,
desc: document.getElementById('prod-desc').value,
img: document.getElementById('prod-img').value || 'https://picsum.photos/400/300'
};
products.push(product);
saveProducts();
render();
e.target.reset();
alert('✅ Товар добавлен!');
});
function deleteProduct(id) {
if (confirm('Удалить этот товар?')) {
products = products.filter(p => p.id !== id);
saveProducts();
render();
}
}
// === Старт ===
loadProducts();
render();
</script>
</body>
</html>