268 lines
8.2 KiB
JavaScript
268 lines
8.2 KiB
JavaScript
// ===================================
|
||
// ADMIN PANEL - JAVASCRIPT
|
||
// ===================================
|
||
|
||
const API = {
|
||
products: '/api/products',
|
||
adminProducts: '/api/admin/products',
|
||
announcements: '/api/announcements',
|
||
adminAnnouncements: '/api/admin/announcements',
|
||
settings: '/api/settings',
|
||
adminSettings: '/api/admin/settings'
|
||
};
|
||
|
||
// Initialize
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
loadSettings();
|
||
loadProducts();
|
||
loadAnnouncements();
|
||
setupForms();
|
||
});
|
||
|
||
// Setup forms
|
||
function setupForms() {
|
||
document.getElementById('settingsForm').addEventListener('submit', saveSettings);
|
||
document.getElementById('productForm').addEventListener('submit', addProduct);
|
||
document.getElementById('announcementForm').addEventListener('submit', addAnnouncement);
|
||
}
|
||
|
||
// ============ SETTINGS ============
|
||
async function loadSettings() {
|
||
try {
|
||
const res = await fetch(API.settings);
|
||
const json = await res.json();
|
||
if (json.ok && json.data) {
|
||
document.getElementById('heroTitle').value = json.data.heroTitle || '';
|
||
document.getElementById('heroSubtitle').value = json.data.heroSubtitle || '';
|
||
document.getElementById('theme').value = json.data.theme || 'dark';
|
||
}
|
||
} catch (e) {
|
||
console.error('Failed to load settings:', e);
|
||
}
|
||
}
|
||
|
||
async function saveSettings(e) {
|
||
e.preventDefault();
|
||
const data = {
|
||
heroTitle: document.getElementById('heroTitle').value,
|
||
heroSubtitle: document.getElementById('heroSubtitle').value,
|
||
theme: document.getElementById('theme').value
|
||
};
|
||
|
||
try {
|
||
const res = await fetch(API.adminSettings, {
|
||
method: 'PUT',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data)
|
||
});
|
||
const json = await res.json();
|
||
if (json.ok) {
|
||
alert('Настройки сохранены! ✅');
|
||
} else {
|
||
alert('Ошибка: ' + json.error);
|
||
}
|
||
} catch (e) {
|
||
alert('Ошибка сохранения: ' + e.message);
|
||
}
|
||
}
|
||
|
||
// ============ PRODUCTS ============
|
||
async function loadProducts() {
|
||
try {
|
||
const res = await fetch(API.products);
|
||
const json = await res.json();
|
||
const list = document.getElementById('productsList');
|
||
|
||
if (!json.ok || !json.data || json.data.length === 0) {
|
||
list.innerHTML = '<p style="color:#86868b;text-align:center;padding:40px">Нет продуктов</p>';
|
||
return;
|
||
}
|
||
|
||
list.innerHTML = json.data.map(p => `
|
||
<div class="list-item">
|
||
<div class="list-item-info">
|
||
<div class="list-item-title">${p.name}</div>
|
||
<div class="list-item-meta">
|
||
${p.tagline} • $${p.price} •
|
||
<span class="status-badge">${p.category}</span>
|
||
</div>
|
||
</div>
|
||
<div class="list-item-actions">
|
||
<button class="btn btn-secondary btn-small" onclick="editProduct(${p.id})">Изменить</button>
|
||
<button class="btn btn-danger btn-small" onclick="deleteProduct(${p.id})">Удалить</button>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
} catch (e) {
|
||
console.error('Failed to load products:', e);
|
||
}
|
||
}
|
||
|
||
function showAddProductForm() {
|
||
document.getElementById('addProductForm').style.display = 'block';
|
||
document.getElementById('productForm').reset();
|
||
}
|
||
|
||
function hideAddProductForm() {
|
||
document.getElementById('addProductForm').style.display = 'none';
|
||
}
|
||
|
||
async function addProduct(e) {
|
||
e.preventDefault();
|
||
|
||
const features = document.getElementById('productFeatures').value
|
||
.split(',')
|
||
.map(f => f.trim())
|
||
.filter(f => f);
|
||
|
||
const data = {
|
||
name: document.getElementById('productName').value,
|
||
tagline: document.getElementById('productTagline').value,
|
||
description: document.getElementById('productDescription').value,
|
||
price: parseFloat(document.getElementById('productPrice').value),
|
||
category: document.getElementById('productCategory').value,
|
||
image: document.getElementById('productImage').value || 'https://picsum.photos/800/600?random=' + Date.now(),
|
||
features: features
|
||
};
|
||
|
||
try {
|
||
const res = await fetch(API.adminProducts, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data)
|
||
});
|
||
const json = await res.json();
|
||
|
||
if (json.ok) {
|
||
alert('Продукт добавлен! ✅');
|
||
hideAddProductForm();
|
||
loadProducts();
|
||
} else {
|
||
alert('Ошибка: ' + json.error);
|
||
}
|
||
} catch (e) {
|
||
alert('Ошибка: ' + e.message);
|
||
}
|
||
}
|
||
|
||
async function editProduct(id) {
|
||
const res = await fetch(`${API.products}/${id}`);
|
||
const json = await res.json();
|
||
|
||
if (!json.ok) return alert('Продукт не найден');
|
||
|
||
const p = json.data;
|
||
if (confirm(`Редактировать "${p.name}"?\n\n(В полной версии откроется форма редактирования)`)) {
|
||
// В полной версии здесь открывается форма с заполненными данными
|
||
window.location.href = `edit-product.html?id=${id}`;
|
||
}
|
||
}
|
||
|
||
async function deleteProduct(id) {
|
||
if (!confirm('Вы уверены? Это действие нельзя отменить.')) return;
|
||
|
||
try {
|
||
const res = await fetch(`${API.adminProducts}/${id}`, { method: 'DELETE' });
|
||
const json = await res.json();
|
||
|
||
if (json.ok) {
|
||
alert('Продукт удалён');
|
||
loadProducts();
|
||
}
|
||
} catch (e) {
|
||
alert('Ошибка: ' + e.message);
|
||
}
|
||
}
|
||
|
||
// ============ ANNOUNCEMENTS ============
|
||
async function loadAnnouncements() {
|
||
try {
|
||
const res = await fetch(API.announcements);
|
||
const json = await res.json();
|
||
const list = document.getElementById('announcementsList');
|
||
|
||
if (!json.ok || !json.data || json.data.length === 0) {
|
||
list.innerHTML = '<p style="color:#86868b;text-align:center;padding:40px">Нет объявлений</p>';
|
||
return;
|
||
}
|
||
|
||
list.innerHTML = json.data.map(a => `
|
||
<div class="list-item">
|
||
<div class="list-item-info">
|
||
<div class="list-item-title">${a.title}</div>
|
||
<div class="list-item-meta">
|
||
${a.content} • ${a.date} •
|
||
<span class="status-badge">${a.active ? 'Активно' : 'Скрыто'}</span>
|
||
</div>
|
||
</div>
|
||
<div class="list-item-actions">
|
||
<button class="btn btn-secondary btn-small" onclick="editAnnouncement(${a.id})">Изменить</button>
|
||
<button class="btn btn-danger btn-small" onclick="deleteAnnouncement(${a.id})">Удалить</button>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
} catch (e) {
|
||
console.error('Failed to load announcements:', e);
|
||
}
|
||
}
|
||
|
||
function showAddAnnouncementForm() {
|
||
document.getElementById('addAnnouncementForm').style.display = 'block';
|
||
document.getElementById('announcementForm').reset();
|
||
}
|
||
|
||
function hideAddAnnouncementForm() {
|
||
document.getElementById('addAnnouncementForm').style.display = 'none';
|
||
}
|
||
|
||
async function addAnnouncement(e) {
|
||
e.preventDefault();
|
||
|
||
const data = {
|
||
title: document.getElementById('announcementTitle').value,
|
||
date: document.getElementById('announcementDate').value,
|
||
content: document.getElementById('announcementContent').value
|
||
};
|
||
|
||
try {
|
||
const res = await fetch(API.adminAnnouncements, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data)
|
||
});
|
||
const json = await res.json();
|
||
|
||
if (json.ok) {
|
||
alert('Объявление добавлено! ✅');
|
||
hideAddAnnouncementForm();
|
||
loadAnnouncements();
|
||
} else {
|
||
alert('Ошибка: ' + json.error);
|
||
}
|
||
} catch (e) {
|
||
alert('Ошибка: ' + e.message);
|
||
}
|
||
}
|
||
|
||
async function editAnnouncement(id) {
|
||
if (confirm(`Редактировать объявление #${id}?\n\n(В полной версии откроется форма)`)) {
|
||
window.location.href = `edit-announcement.html?id=${id}`;
|
||
}
|
||
}
|
||
|
||
async function deleteAnnouncement(id) {
|
||
if (!confirm('Удалить это объявление?')) return;
|
||
|
||
try {
|
||
const res = await fetch(`${API.adminAnnouncements}/${id}`, { method: 'DELETE' });
|
||
const json = await res.json();
|
||
|
||
if (json.ok) {
|
||
alert('Объявление удалено');
|
||
loadAnnouncements();
|
||
}
|
||
} catch (e) {
|
||
alert('Ошибка: ' + e.message);
|
||
}
|
||
}
|