600 lines
18 KiB
HTML
600 lines
18 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" data-theme="auto">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>ЗОЛОТО — Магазин ювелирных изделий</title>
|
||
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-components.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-page.css">
|
||
<link rel="icon" href="design-system/brand/kt-ai-logo.png">
|
||
<style>
|
||
a.kt-ai-btn { text-decoration: none; }
|
||
.shop-header {
|
||
background: var(--kt-ai-card-bg);
|
||
border-bottom: 1px solid var(--kt-ai-border);
|
||
padding: var(--kt-ai-space-4) 0;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
}
|
||
.shop-header-in {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--kt-ai-space-4);
|
||
}
|
||
.shop-logo {
|
||
font-size: var(--kt-ai-text-xl);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
color: var(--kt-ai-fg);
|
||
}
|
||
.cart-btn-wrapper {
|
||
position: relative;
|
||
}
|
||
.cart-badge {
|
||
position: absolute;
|
||
top: -8px;
|
||
right: -8px;
|
||
background: var(--kt-ai-primary);
|
||
color: white;
|
||
font-size: var(--kt-ai-text-xs);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
min-width: 20px;
|
||
height: 20px;
|
||
border-radius: var(--kt-ai-radius-full);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 6px;
|
||
}
|
||
.category-filter {
|
||
display: flex;
|
||
gap: var(--kt-ai-space-2);
|
||
flex-wrap: wrap;
|
||
margin-bottom: var(--kt-ai-space-6);
|
||
}
|
||
.products-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||
gap: var(--kt-ai-space-5);
|
||
margin-bottom: var(--kt-ai-space-8);
|
||
}
|
||
.product-card {
|
||
background: var(--kt-ai-card-bg);
|
||
border: 1px solid var(--kt-ai-card-border);
|
||
border-radius: var(--kt-ai-radius-2xl);
|
||
overflow: hidden;
|
||
transition: transform 0.2s, box-shadow 0.2s;
|
||
}
|
||
.product-card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: 0 12px 24px rgba(0,0,0,0.1);
|
||
}
|
||
.product-image {
|
||
width: 100%;
|
||
height: 280px;
|
||
object-fit: cover;
|
||
background: var(--kt-ai-bg-soft);
|
||
}
|
||
.product-info {
|
||
padding: var(--kt-ai-space-4);
|
||
}
|
||
.product-name {
|
||
font-size: var(--kt-ai-text-lg);
|
||
font-weight: var(--kt-ai-weight-semibold);
|
||
margin-bottom: var(--kt-ai-space-2);
|
||
color: var(--kt-ai-fg);
|
||
}
|
||
.product-desc {
|
||
font-size: var(--kt-ai-text-sm);
|
||
color: var(--kt-ai-fg-muted);
|
||
margin-bottom: var(--kt-ai-space-3);
|
||
line-height: 1.4;
|
||
}
|
||
.product-meta {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: var(--kt-ai-space-3);
|
||
font-size: var(--kt-ai-text-sm);
|
||
color: var(--kt-ai-fg-muted);
|
||
}
|
||
.product-price {
|
||
font-size: var(--kt-ai-text-xl);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
color: var(--kt-ai-primary);
|
||
}
|
||
.add-to-cart {
|
||
width: 100%;
|
||
}
|
||
.cart-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
right: 0;
|
||
width: 100%;
|
||
max-width: 480px;
|
||
height: 100vh;
|
||
background: var(--kt-ai-card-bg);
|
||
border-left: 1px solid var(--kt-ai-border);
|
||
z-index: 1000;
|
||
display: flex;
|
||
flex-direction: column;
|
||
transform: translateX(100%);
|
||
transition: transform 0.3s ease;
|
||
}
|
||
.cart-modal.open {
|
||
transform: translateX(0);
|
||
}
|
||
.cart-header {
|
||
padding: var(--kt-ai-space-5);
|
||
border-bottom: 1px solid var(--kt-ai-border);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
.cart-title {
|
||
font-size: var(--kt-ai-text-xl);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
}
|
||
.cart-items {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: var(--kt-ai-space-4);
|
||
}
|
||
.cart-item {
|
||
display: flex;
|
||
gap: var(--kt-ai-space-3);
|
||
padding: var(--kt-ai-space-3);
|
||
background: var(--kt-ai-bg-soft);
|
||
border-radius: var(--kt-ai-radius-xl);
|
||
margin-bottom: var(--kt-ai-space-3);
|
||
}
|
||
.cart-item-img {
|
||
width: 80px;
|
||
height: 80px;
|
||
object-fit: cover;
|
||
border-radius: var(--kt-ai-radius-lg);
|
||
}
|
||
.cart-item-info {
|
||
flex: 1;
|
||
}
|
||
.cart-item-name {
|
||
font-weight: var(--kt-ai-weight-semibold);
|
||
margin-bottom: var(--kt-ai-space-1);
|
||
}
|
||
.cart-item-price {
|
||
color: var(--kt-ai-primary);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
}
|
||
.cart-item-qty {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--kt-ai-space-2);
|
||
margin-top: var(--kt-ai-space-2);
|
||
}
|
||
.qty-btn {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: var(--kt-ai-radius-md);
|
||
border: 1px solid var(--kt-ai-border);
|
||
background: var(--kt-ai-card-bg);
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.cart-footer {
|
||
padding: var(--kt-ai-space-5);
|
||
border-top: 1px solid var(--kt-ai-border);
|
||
background: var(--kt-ai-bg-soft);
|
||
}
|
||
.cart-total {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: var(--kt-ai-space-4);
|
||
font-size: var(--kt-ai-text-lg);
|
||
}
|
||
.total-amount {
|
||
font-size: var(--kt-ai-text-2xl);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
color: var(--kt-ai-primary);
|
||
}
|
||
.checkout-btn {
|
||
width: 100%;
|
||
margin-bottom: var(--kt-ai-space-3);
|
||
}
|
||
.overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0,0,0,0.5);
|
||
z-index: 999;
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
transition: opacity 0.3s;
|
||
}
|
||
.overlay.open {
|
||
opacity: 1;
|
||
pointer-events: auto;
|
||
}
|
||
.checkout-modal {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%) scale(0.9);
|
||
background: var(--kt-ai-card-bg);
|
||
border-radius: var(--kt-ai-radius-3xl);
|
||
padding: var(--kt-ai-space-6);
|
||
max-width: 500px;
|
||
width: 90%;
|
||
max-height: 90vh;
|
||
overflow-y: auto;
|
||
z-index: 1001;
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
transition: all 0.3s;
|
||
}
|
||
.checkout-modal.open {
|
||
transform: translate(-50%, -50%) scale(1);
|
||
opacity: 1;
|
||
pointer-events: auto;
|
||
}
|
||
.checkout-title {
|
||
font-size: var(--kt-ai-text-2xl);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
margin-bottom: var(--kt-ai-space-4);
|
||
}
|
||
.order-summary {
|
||
background: var(--kt-ai-bg-soft);
|
||
padding: var(--kt-ai-space-4);
|
||
border-radius: var(--kt-ai-radius-xl);
|
||
margin-bottom: var(--kt-ai-space-5);
|
||
}
|
||
.summary-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: var(--kt-ai-space-2);
|
||
font-size: var(--kt-ai-text-sm);
|
||
}
|
||
.summary-total {
|
||
border-top: 1px solid var(--kt-ai-border);
|
||
padding-top: var(--kt-ai-space-2);
|
||
margin-top: var(--kt-ai-space-2);
|
||
font-weight: var(--kt-ai-weight-bold);
|
||
font-size: var(--kt-ai-text-lg);
|
||
}
|
||
.empty-cart {
|
||
text-align: center;
|
||
padding: var(--kt-ai-space-8);
|
||
color: var(--kt-ai-fg-muted);
|
||
}
|
||
.close-btn {
|
||
background: none;
|
||
border: none;
|
||
font-size: var(--kt-ai-text-2xl);
|
||
cursor: pointer;
|
||
color: var(--kt-ai-fg-muted);
|
||
padding: 0;
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.success-message {
|
||
text-align: center;
|
||
padding: var(--kt-ai-space-6);
|
||
}
|
||
.success-icon {
|
||
font-size: 64px;
|
||
margin-bottom: var(--kt-ai-space-4);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<header class="shop-header">
|
||
<div class="kt-ai-wrap shop-header-in">
|
||
<div class="shop-logo">✨ ЗОЛОТО</div>
|
||
<div class="cart-btn-wrapper">
|
||
<button class="kt-ai-btn" data-variant="primary" onclick="toggleCart()">
|
||
Корзина
|
||
</button>
|
||
<span class="cart-badge" id="cartBadge">0</span>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="kt-ai-section">
|
||
<div class="kt-ai-wrap">
|
||
<div class="kt-ai-section-head">
|
||
<h1>Каталог украшений</h1>
|
||
<p>Выбирайте изящные изделия из золота — от классики до современных дизайнов</p>
|
||
</div>
|
||
|
||
<div class="category-filter" id="categoryFilter">
|
||
<button class="kt-ai-btn" data-variant="primary" onclick="filterCategory('all')">Все</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('rings')">Кольца</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('earrings')">Серьги</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('chains')">Цепочки</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('bracelets')">Браслеты</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('necklaces')">Колье</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" onclick="filterCategory('sets')">Комплекты</button>
|
||
</div>
|
||
|
||
<div class="products-grid" id="productsGrid"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="overlay" id="overlay" onclick="toggleCart()"></div>
|
||
|
||
<div class="cart-modal" id="cartModal">
|
||
<div class="cart-header">
|
||
<h2 class="cart-title">Корзина</h2>
|
||
<button class="close-btn" onclick="toggleCart()">×</button>
|
||
</div>
|
||
<div class="cart-items" id="cartItems"></div>
|
||
<div class="cart-footer">
|
||
<div class="cart-total">
|
||
<span>Итого:</span>
|
||
<span class="total-amount" id="cartTotal">0 ₸</span>
|
||
</div>
|
||
<button class="kt-ai-btn checkout-btn" data-variant="primary" data-size="lg" onclick="openCheckout()">
|
||
Оформить заказ
|
||
</button>
|
||
<button class="kt-ai-btn checkout-btn" onclick="toggleCart()">
|
||
Продолжить покупки
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="overlay" id="checkoutOverlay" onclick="closeCheckout()"></div>
|
||
|
||
<div class="checkout-modal" id="checkoutModal">
|
||
<h2 class="checkout-title">Оформление заказа</h2>
|
||
<div class="order-summary" id="orderSummary"></div>
|
||
|
||
<form id="orderForm" onsubmit="submitOrder(event)">
|
||
<div class="kt-ai-field" style="margin-bottom: var(--kt-ai-space-4);">
|
||
<label style="display:block; margin-bottom: var(--kt-ai-space-2); font-weight: var(--kt-ai-weight-medium);">Ваше имя</label>
|
||
<input class="kt-ai-input" type="text" name="name" required placeholder="Иван Иванов">
|
||
</div>
|
||
<div class="kt-ai-field" style="margin-bottom: var(--kt-ai-space-4);">
|
||
<label style="display:block; margin-bottom: var(--kt-ai-space-2); font-weight: var(--kt-ai-weight-medium);">Телефон</label>
|
||
<input class="kt-ai-input" type="tel" name="phone" required placeholder="+7 777 123 45 67">
|
||
</div>
|
||
<div class="kt-ai-field" style="margin-bottom: var(--kt-ai-space-4);">
|
||
<label style="display:block; margin-bottom: var(--kt-ai-space-2); font-weight: var(--kt-ai-weight-medium);">Адрес доставки</label>
|
||
<input class="kt-ai-input" type="text" name="address" required placeholder="г. Алматы, ул. Абая 10">
|
||
</div>
|
||
<div class="kt-ai-field" style="margin-bottom: var(--kt-ai-space-5);">
|
||
<label style="display:block; margin-bottom: var(--kt-ai-space-2); font-weight: var(--kt-ai-weight-medium);">Комментарий</label>
|
||
<textarea class="kt-ai-textarea" name="comment" rows="3" placeholder="Пожелания к заказу"></textarea>
|
||
</div>
|
||
<button class="kt-ai-btn" data-variant="primary" data-size="lg" type="submit" style="width: 100%;">
|
||
Подтвердить заказ
|
||
</button>
|
||
<button class="kt-ai-btn" type="button" onclick="closeCheckout()" style="width: 100%; margin-top: var(--kt-ai-space-2);">
|
||
Назад
|
||
</button>
|
||
</form>
|
||
|
||
<div class="success-message" id="successMessage" style="display: none;">
|
||
<div class="success-icon">🎉</div>
|
||
<h3>Заказ оформлен!</h3>
|
||
<p style="color: var(--kt-ai-fg-muted); margin: var(--kt-ai-space-3) 0;">
|
||
Спасибо за покупку! Мы свяжемся с вами в ближайшее время.
|
||
</p>
|
||
<button class="kt-ai-btn" data-variant="primary" onclick="closeCheckout()">
|
||
Вернуться в магазин
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
let products = [];
|
||
let cart = [];
|
||
let currentCategory = 'all';
|
||
|
||
async function loadProducts() {
|
||
try {
|
||
const res = await fetch('api/products');
|
||
products = await res.json();
|
||
renderProducts();
|
||
} catch (e) {
|
||
console.error('Ошибка загрузки товаров:', e);
|
||
}
|
||
}
|
||
|
||
function renderProducts() {
|
||
const grid = document.getElementById('productsGrid');
|
||
const filtered = currentCategory === 'all'
|
||
? products
|
||
: products.filter(p => p.category === currentCategory);
|
||
|
||
grid.innerHTML = filtered.map(p => `
|
||
<div class="product-card">
|
||
<img class="product-image" src="${p.image}" alt="${p.name}" loading="lazy">
|
||
<div class="product-info">
|
||
<h3 class="product-name">${p.name}</h3>
|
||
<p class="product-desc">${p.description}</p>
|
||
<div class="product-meta">
|
||
<span>${p.material}, ${p.weight}</span>
|
||
</div>
|
||
<div class="product-price">${formatPrice(p.price)}</div>
|
||
<button class="kt-ai-btn add-to-cart" data-variant="primary" style="margin-top: var(--kt-ai-space-3);" onclick="addToCart(${p.id})">
|
||
В корзину
|
||
</button>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
function filterCategory(cat) {
|
||
currentCategory = cat;
|
||
const buttons = document.querySelectorAll('.category-filter .kt-ai-btn');
|
||
buttons.forEach((btn, i) => {
|
||
if (i === 0 && cat === 'all') btn.setAttribute('data-variant', 'primary');
|
||
else if (btn.textContent.toLowerCase().includes(getCatName(cat))) btn.setAttribute('data-variant', 'primary');
|
||
else btn.setAttribute('data-variant', 'ghost');
|
||
});
|
||
renderProducts();
|
||
}
|
||
|
||
function getCatName(cat) {
|
||
const names = { all: 'все', rings: 'кольца', earrings: 'серьги', chains: 'цепочки', bracelets: 'браслеты', necklaces: 'колье', sets: 'комплекты' };
|
||
return names[cat] || cat;
|
||
}
|
||
|
||
function addToCart(id) {
|
||
const product = products.find(p => p.id === id);
|
||
const existing = cart.find(item => item.id === id);
|
||
if (existing) {
|
||
existing.qty++;
|
||
} else {
|
||
cart.push({ ...product, qty: 1 });
|
||
}
|
||
updateCart();
|
||
showAddedAnimation(id);
|
||
}
|
||
|
||
function showAddedAnimation(id) {
|
||
const btn = event.target;
|
||
const originalText = btn.textContent;
|
||
btn.textContent = '✓ Добавлено';
|
||
setTimeout(() => { btn.textContent = originalText; }, 1000);
|
||
}
|
||
|
||
function removeFromCart(id) {
|
||
cart = cart.filter(item => item.id !== id);
|
||
updateCart();
|
||
}
|
||
|
||
function changeQty(id, delta) {
|
||
const item = cart.find(i => i.id === id);
|
||
if (item) {
|
||
item.qty += delta;
|
||
if (item.qty <= 0) removeFromCart(id);
|
||
else updateCart();
|
||
}
|
||
}
|
||
|
||
function updateCart() {
|
||
const badge = document.getElementById('cartBadge');
|
||
const itemsContainer = document.getElementById('cartItems');
|
||
const totalEl = document.getElementById('cartTotal');
|
||
|
||
const totalQty = cart.reduce((sum, item) => sum + item.qty, 0);
|
||
const totalPrice = cart.reduce((sum, item) => sum + item.price * item.qty, 0);
|
||
|
||
badge.textContent = totalQty;
|
||
badge.style.display = totalQty > 0 ? 'flex' : 'none';
|
||
|
||
if (cart.length === 0) {
|
||
itemsContainer.innerHTML = '<div class="empty-cart"><p>Корзина пуста</p><p style="margin-top: var(--kt-ai-space-2);">Добавьте товары из каталога</p></div>';
|
||
} else {
|
||
itemsContainer.innerHTML = cart.map(item => `
|
||
<div class="cart-item">
|
||
<img class="cart-item-img" src="${item.image}" alt="${item.name}">
|
||
<div class="cart-item-info">
|
||
<div class="cart-item-name">${item.name}</div>
|
||
<div class="cart-item-price">${formatPrice(item.price)}</div>
|
||
<div class="cart-item-qty">
|
||
<button class="qty-btn" onclick="changeQty(${item.id}, -1)">−</button>
|
||
<span>${item.qty}</span>
|
||
<button class="qty-btn" onclick="changeQty(${item.id}, 1)">+</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
totalEl.textContent = formatPrice(totalPrice);
|
||
}
|
||
|
||
function toggleCart() {
|
||
const modal = document.getElementById('cartModal');
|
||
const overlay = document.getElementById('overlay');
|
||
modal.classList.toggle('open');
|
||
overlay.classList.toggle('open');
|
||
}
|
||
|
||
function openCheckout() {
|
||
if (cart.length === 0) {
|
||
alert('Корзина пуста');
|
||
return;
|
||
}
|
||
toggleCart();
|
||
|
||
const summary = document.getElementById('orderSummary');
|
||
const total = cart.reduce((sum, item) => sum + item.price * item.qty, 0);
|
||
|
||
summary.innerHTML = `
|
||
<div class="summary-row"><span>Товаров:</span><span>${cart.reduce((s, i) => s + i.qty, 0)} шт.</span></div>
|
||
<div class="summary-row"><span>Сумма:</span><span>${formatPrice(total)}</span></div>
|
||
<div class="summary-total"><span>К оплате:</span><span>${formatPrice(total)}</span></div>
|
||
`;
|
||
|
||
document.getElementById('checkoutModal').classList.add('open');
|
||
document.getElementById('checkoutOverlay').classList.add('open');
|
||
document.getElementById('orderForm').style.display = 'block';
|
||
document.getElementById('successMessage').style.display = 'none';
|
||
}
|
||
|
||
function closeCheckout() {
|
||
document.getElementById('checkoutModal').classList.remove('open');
|
||
document.getElementById('checkoutOverlay').classList.remove('open');
|
||
}
|
||
|
||
async function submitOrder(e) {
|
||
e.preventDefault();
|
||
|
||
const form = e.target;
|
||
const formData = new FormData(form);
|
||
|
||
const order = {
|
||
name: formData.get('name'),
|
||
phone: formData.get('phone'),
|
||
address: formData.get('address'),
|
||
comment: formData.get('comment'),
|
||
items: cart,
|
||
total: cart.reduce((sum, item) => sum + item.price * item.qty, 0)
|
||
};
|
||
|
||
try {
|
||
const res = await fetch('api/orders', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(order)
|
||
});
|
||
|
||
if (res.ok) {
|
||
cart = [];
|
||
updateCart();
|
||
form.style.display = 'none';
|
||
document.getElementById('successMessage').style.display = 'block';
|
||
} else {
|
||
alert('Ошибка оформления заказа. Попробуйте ещё раз.');
|
||
}
|
||
} catch (err) {
|
||
console.error(err);
|
||
alert('Ошибка соединения. Попробуйте ещё раз.');
|
||
}
|
||
}
|
||
|
||
function formatPrice(price) {
|
||
return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ') + ' ₸';
|
||
}
|
||
|
||
loadProducts();
|
||
updateCart();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|