1
This commit is contained in:
@@ -64,7 +64,7 @@ function initSocket() {
|
|||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
initAuth();
|
initAuth();
|
||||||
initReports();
|
initReports();
|
||||||
initSocket();
|
try { initSocket(); } catch(e) { console.warn('Socket.IO не подключен:', e.message); }
|
||||||
|
|
||||||
// Check if logged in
|
// Check if logged in
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
@@ -863,7 +863,7 @@ async function initCases() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
const res = await fetch('http://localhost:5000/api/ai/generate-complaint', {
|
const res = await fetch('/api/ai/generate-complaint', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -905,7 +905,7 @@ async function initCases() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
const res = await fetch('http://localhost:5000/api/ai/generate-reply', {
|
const res = await fetch('/api/ai/generate-reply', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -949,61 +949,7 @@ async function initReports() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadDashboard() {
|
// Дублирующий loadDashboard удалён — используется функция из строки ~149
|
||||||
// Update counters
|
|
||||||
document.getElementById('stat-cases').innerText = data.total_cases;
|
|
||||||
document.getElementById('stat-integrations').innerText = data.total_integrations;
|
|
||||||
document.getElementById('stat-sales').innerText = `${data.total_sales.toLocaleString()} ₽`;
|
|
||||||
|
|
||||||
// Update stores table (multi-account)
|
|
||||||
const storesTbody = document.querySelector('#stores-table tbody');
|
|
||||||
storesTbody.innerHTML = '';
|
|
||||||
data.stores.forEach(s => {
|
|
||||||
const tr = document.createElement('tr');
|
|
||||||
tr.innerHTML = `
|
|
||||||
<td><strong>${s.name}</strong></td>
|
|
||||||
<td><span style="text-transform: uppercase;">${s.platform}</span></td>
|
|
||||||
<td><span class="status-pill status-closed" style="background: rgba(16, 185, 129, 0.1); color: #34d399;">● Online</span></td>
|
|
||||||
<td>${s.daily_sales.toLocaleString()} ₽</td>
|
|
||||||
`;
|
|
||||||
storesTbody.appendChild(tr);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Activity Table
|
|
||||||
const tbody = document.querySelector('#recent-activity-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;
|
|
||||||
const statusClass = c.status === 'new' ? 'status-new' : (c.status === 'closed' ? 'status-closed' : '');
|
|
||||||
|
|
||||||
tr.innerHTML = `
|
|
||||||
<td>#${c.id}</td>
|
|
||||||
<td><strong>${pName}</strong></td>
|
|
||||||
<td><code>${c.violator_article}</code></td>
|
|
||||||
<td><span class="status-pill ${statusClass}">${c.status}</span></td>
|
|
||||||
<td>${new Date(c.created_at).toLocaleDateString()}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn-secondary" style="padding: 0.4rem 0.8rem; font-size: 0.8rem;" onclick="window.viewCase(${c.id})">Открыть</button>
|
|
||||||
<button class="btn-secondary" style="padding: 0.4rem 0.8rem; font-size: 0.8rem; color: var(--color-error);" onclick="window.deleteCase(${c.id})">Удалить</button>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
});
|
|
||||||
if (window.lucide) lucide.createIcons();
|
|
||||||
} catch (err) {
|
|
||||||
tbody.innerHTML = '<tr><td colspan="6">Ошибка сети</td></tr>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.viewCase = async function(id) {
|
window.viewCase = async function(id) {
|
||||||
currentViewCaseId = id;
|
currentViewCaseId = id;
|
||||||
@@ -1026,7 +972,7 @@ window.viewCase = async function(id) {
|
|||||||
if (files && files.length > 0) {
|
if (files && files.length > 0) {
|
||||||
html += `<h3>Файлы доказательств:</h3><div class="preview">`;
|
html += `<h3>Файлы доказательств:</h3><div class="preview">`;
|
||||||
files.forEach(f => {
|
files.forEach(f => {
|
||||||
const url = `http://localhost:5000/api/uploads/${f.path.split('/').pop()}`;
|
const url = `/api/uploads/${f.path.split('/').pop()}`;
|
||||||
html += `<a href="${url}" target="_blank"><img src="${url}" alt="Док" /></a>`;
|
html += `<a href="${url}" target="_blank"><img src="${url}" alt="Док" /></a>`;
|
||||||
});
|
});
|
||||||
html += `</div>`;
|
html += `</div>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user