Files
AutoMarket/frontend/js/app.js

216 lines
8.4 KiB
JavaScript
Raw 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.
// frontend/js/app.js
import * as api from './api.js';
const PLATFORMS = [
{ id: 'ozon', name: 'Ozon' },
{ id: 'wb', name: 'Wildberries' },
{ id: 'ym', name: 'Yandex Market' },
{ id: 'mm', name: 'Magnit Market' },
{ id: 'mega', name: 'MegaMarket' },
{ id: 'ae', name: 'AliExpress' },
{ id: 'avito', name: 'Avito' },
{ id: 'lamoda', name: 'Lamoda' },
{ id: 'lemana', name: 'Lemana PRO' },
{ id: 'flowwow', name: 'Flowwow' }
];
document.addEventListener("DOMContentLoaded", () => {
initTabs();
initCases();
initIntegrations();
});
function initTabs() {
const btns = document.querySelectorAll('.tab-btn');
const sections = ['cases-section', 'integrations-section'];
btns.forEach(btn => {
btn.addEventListener('click', () => {
btns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const target = btn.dataset.target;
sections.forEach(s => {
document.getElementById(s).classList.add('hidden');
});
document.getElementById(target).classList.remove('hidden');
document.getElementById('case-form-section').classList.add('hidden');
document.getElementById('case-detail-section').classList.add('hidden');
if(target === 'cases-section') loadCases();
if(target === 'integrations-section') loadIntegrations();
});
});
}
// ---- INTEGRATIONS ----
async function loadIntegrations() {
const grid = document.getElementById('platforms-grid');
grid.innerHTML = 'Загрузка...';
try {
const configured = await api.getConfiguredPlatforms();
grid.innerHTML = '';
PLATFORMS.forEach(p => {
const isConfigured = configured.includes(p.id);
const card = document.createElement('div');
card.className = `platform-card ${isConfigured ? 'active-platform' : ''}`;
card.innerHTML = `
<h3>${p.name}</h3>
<p class="status">${isConfigured ? '✅ Подключено' : '❌ Не настроено'}</p>
<form class="platform-form" data-id="${p.id}">
<input type="text" name="api_key" placeholder="API Key / Token" />
<input type="text" name="client_id" placeholder="Client ID (если есть)" />
<input type="text" name="client_secret" placeholder="Client Secret (если есть)" />
<button type="submit" class="btn-primary">Сохранить</button>
</form>
`;
card.querySelector('form').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData);
await api.saveCredentials(p.id, data);
alert(`Настройки для ${p.name} сохранены!`);
loadIntegrations();
});
grid.appendChild(card);
});
} catch (e) {
grid.innerHTML = 'Ошибка загрузки интеграций.';
console.error(e);
}
}
// ---- CASES ----
async function initCases() {
document.getElementById('new-case-btn').addEventListener('click', () => {
document.getElementById('cases-section').classList.add('hidden');
document.getElementById('case-form-section').classList.remove('hidden');
document.getElementById('case-form').reset();
});
document.getElementById('cancel-btn').addEventListener('click', () => {
document.getElementById('case-form-section').classList.add('hidden');
document.getElementById('cases-section').classList.remove('hidden');
});
document.getElementById('back-to-list').addEventListener('click', () => {
document.getElementById('case-detail-section').classList.add('hidden');
document.getElementById('cases-section').classList.remove('hidden');
loadCases();
});
document.getElementById('search-input').addEventListener('input', debounce(loadCases, 500));
document.getElementById('status-filter').addEventListener('change', loadCases);
document.getElementById('platform-filter').addEventListener('change', loadCases);
document.getElementById('case-form').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData);
try {
const res = await api.createCase(data);
const fileInput = document.getElementById('file-input');
if (fileInput.files.length > 0) {
await api.uploadFiles(res.id, fileInput.files);
}
alert('Кейс успешно создан!');
document.getElementById('case-form-section').classList.add('hidden');
document.getElementById('cases-section').classList.remove('hidden');
loadCases();
} catch (err) {
console.error(err);
alert('Ошибка при сохранении');
}
});
loadCases();
}
async function loadCases() {
const article = document.getElementById('search-input').value;
const status = document.getElementById('status-filter').value;
const platform = document.getElementById('platform-filter').value;
const tbody = document.querySelector('#cases-table tbody');
tbody.innerHTML = '<tr><td colspan="6">Загрузка...</td></tr>';
try {
const cases = await api.fetchCases({ article, status, platform });
tbody.innerHTML = '';
if (cases.length === 0) {
tbody.innerHTML = '<tr><td colspan="6">Нет жалоб</td></tr>';
return;
}
cases.forEach(c => {
const tr = document.createElement('tr');
const pName = PLATFORMS.find(p => p.id === c.platform)?.name || c.platform;
tr.innerHTML = `
<td>${c.id}</td>
<td><strong>${pName}</strong></td>
<td>${c.violator_article}</td>
<td>${c.status}</td>
<td>${new Date(c.created_at).toLocaleString()}</td>
<td>
<button class="btn-secondary" onclick="window.viewCase(${c.id})">Просмотр</button>
<button class="btn-secondary" onclick="window.deleteCase(${c.id})">Удалить</button>
</td>
`;
tbody.appendChild(tr);
});
} catch (err) {
tbody.innerHTML = '<tr><td colspan="6">Ошибка сети</td></tr>';
}
}
window.viewCase = async function(id) {
document.getElementById('cases-section').classList.add('hidden');
const detailSection = document.getElementById('case-detail-section');
detailSection.classList.remove('hidden');
const caseObj = await api.getCase(id);
const files = await api.listFiles(id);
let html = `
<p><strong>Площадка:</strong> ${PLATFORMS.find(p => p.id === caseObj.platform)?.name || caseObj.platform}</p>
<p><strong>Артикул нарушителя:</strong> ${caseObj.violator_article}</p>
<p><strong>Ссылка:</strong> <a href="${caseObj.violator_url}" target="_blank">${caseObj.violator_url}</a></p>
<p><strong>Ваш артикул:</strong> ${caseObj.my_article || '-'}</p>
<p><strong>Комментарий:</strong> ${caseObj.comment || '-'}</p>
<p><strong>Статус:</strong> ${caseObj.status}</p>
`;
if (files && files.length > 0) {
html += `<h3>Файлы доказательств:</h3><div class="preview">`;
files.forEach(f => {
const url = `http://localhost:5000/api/uploads/${f.path.split('/').pop()}`;
html += `<a href="${url}" target="_blank"><img src="${url}" alt="Док" /></a>`;
});
html += `</div>`;
}
document.getElementById('case-detail').innerHTML = html;
};
window.deleteCase = async function(id) {
if(confirm('Удалить этот кейс?')) {
await api.deleteCase(id);
loadCases();
}
};
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}