sozdat-sayt-magazin-zoloto/index.html

600 lines
18 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" 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>