Files
AutoMarket/frontend/index.html
Damir 641f9e1d8c modified: backend/app.py
modified:   frontend/index.html
	modified:   frontend/js/app.js
2026-05-15 19:02:24 +03:00

571 lines
33 KiB
HTML
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.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AutoMarket Универсальная панель управления</title>
<link rel="stylesheet" href="css/styles.css" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
</head>
<body>
<header class="header">
<div style="display: flex; justify-content: space-between; align-items: center; max-width: 1200px; margin: 0 auto;">
<div>
<h1><i data-lucide="shield-check" style="vertical-align: middle; margin-right: 0.5rem;"></i>AutoMarket</h1>
<p>Управление жалобами и интеграциями для 10 маркетплейсов</p>
</div>
<div id="user-info" class="hidden">
<span id="username-display" style="margin-right: 1rem;"></span>
<button id="logout-btn" class="btn-secondary">Выйти</button>
</div>
</div>
</header>
<!-- AUTH SECTION -->
<main id="auth-section" class="container">
<div class="auth-box">
<h2 id="auth-title">Вход в систему</h2>
<form id="auth-form">
<input type="text" id="auth-username" placeholder="Логин" required />
<input type="password" id="auth-password" placeholder="Пароль" required />
<button type="submit" id="auth-submit-btn" class="btn-primary" style="width: 100%; margin-top: 1rem;">Войти</button>
</form>
<p style="margin-top: 1rem; text-align: center;">
<a href="#" id="auth-toggle">Нет аккаунта? Зарегистрироваться</a>
</p>
</div>
</main>
<div id="main-app" class="hidden">
<div class="tabs-container">
<button class="tab-btn active" data-target="dashboard-section"><i data-lucide="layout-dashboard" class="icon-sm"></i> Дашборд</button>
<button class="tab-btn" data-target="cases-section"><i data-lucide="list" class="icon-sm"></i> Список жалоб</button>
<button class="tab-btn" data-target="integrations-section"><i data-lucide="settings" class="icon-sm"></i> Настройки</button>
<button class="tab-btn" data-target="billing-section"><i data-lucide="credit-card" class="icon-sm"></i> Тарифы</button>
<button class="tab-btn" data-target="logs-section"><i data-lucide="activity" class="icon-sm"></i> История</button>
<button class="tab-btn" data-target="reviews-section"><i data-lucide="message-square" class="icon-sm"></i> Отзывы</button>
<button class="tab-btn" data-target="seo-section"><i data-lucide="trending-up" class="icon-sm"></i> SEO</button>
<button class="tab-btn" data-target="content-section"><i data-lucide="image" class="icon-sm"></i> Контент</button>
<button class="tab-btn" data-target="finance-section"><i data-lucide="wallet" class="icon-sm"></i> Финансы</button>
<button class="tab-btn" data-target="generator-section"><i data-lucide="wand-2" class="icon-sm"></i> Генератор</button>
<button class="tab-btn" data-target="analytics-section"><i data-lucide="search-code" class="icon-sm"></i> Deep Insight</button>
<button class="tab-btn" data-target="repricer-section"><i data-lucide="tags" class="icon-sm"></i> Репрайзер</button>
</div>
<main class="container">
<!-- Dashboard Section -->
<section id="dashboard-section" class="section">
<h2>Сводная статистика</h2>
<div id="stats-grid" class="platforms-grid">
<div class="platform-card">
<p style="color: var(--color-text-dim); font-size: 0.9rem;">Всего кейсов</p>
<h3 id="stat-cases">0</h3>
</div>
<div class="platform-card">
<p style="color: var(--color-text-dim); font-size: 0.9rem;">Интеграций</p>
<h3 id="stat-integrations">0</h3>
</div>
<div class="platform-card">
<p style="color: var(--color-success); font-size: 0.9rem;">Выручка (всего сегодня)</p>
<h3 id="stat-sales">0 ₽</h3>
</div>
</div>
<div class="section" style="margin-top: 2rem; background: rgba(255,255,255,0.05); border-radius: 12px; padding: 1.5rem;">
<h3>Динамика кейсов</h3>
<canvas id="casesChart" style="max-height: 300px;"></canvas>
</div>
<div class="platforms-grid" style="margin-top: 1.5rem;">
<div class="platform-card" style="grid-column: 1 / -1;">
<h3>Состояние магазинов (Multi-account)</h3>
<table id="stores-table" class="table" style="margin-top: 1rem;">
<thead>
<tr>
<th>Магазин</th>
<th>Площадка</th>
<th>Статус API</th>
<th>Остатки (шт)</th>
<th>Дней до OOS</th>
<th>Продажи (сегодня)</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="platform-card" style="grid-column: 1 / -1;">
<h3>Динамика нарушений</h3>
<canvas id="caseTrendChart" height="100"></canvas>
</div>
</div>
<div class="section" style="margin-top: 2rem;">
<h3>Последняя активность</h3>
<table id="recent-activity-table" class="table">
<thead>
<tr>
<th>ID</th>
<th>Площадка</th>
<th>Артикул</th>
<th>Статус</th>
<th>Дата</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</section>
<!-- Billing / Subscription Section -->
<section id="billing-section" class="section hidden">
<h2>Ваш тариф: <span id="current-plan-display">Free</span></h2>
<div class="platforms-grid" style="margin-top: 2rem;">
<div class="platform-card">
<h3>Тариф FREE</h3>
<p class="status">Активен по умолчанию</p>
<ul>
<li>Подключение: Максимум 1 маркетплейс</li>
<li>Базовая поддержка</li>
</ul>
<button class="btn-secondary" disabled style="margin-top:1rem; width:100%;">Уже активирован</button>
</div>
<div class="platform-card" style="border-color: var(--color-primary);">
<h3 style="color: var(--color-primary);">Тариф PRO</h3>
<p class="status" style="color: var(--color-primary);">Рекомендуемый</p>
<ul>
<li>Подключение: До 10 маркетплейсов</li>
<li>Безлимитное создание жалоб</li>
<li>Приоритетная поддержка</li>
</ul>
<button id="upgrade-btn" class="btn-primary" style="margin-top:1rem; width:100%;">Купить за 990₽</button>
</div>
</div>
</section>
<!-- Audit Logs List -->
<section id="logs-section" class="section hidden">
<h2>История действий</h2>
<div class="table-container">
<table id="logs-table" class="table">
<thead>
<tr>
<th>Действие</th>
<th>Детали</th>
<th>Дата</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</section>
<!-- Reviews Section -->
<section id="reviews-section" class="section hidden">
<h2>ИИ-Ответчик на отзывы</h2>
<div class="platforms-grid">
<div class="platform-card" style="grid-column: 1 / -1;">
<p style="margin-bottom: 1.5rem; color: var(--color-text-dim);">
Введите текст отзыва покупателя и выберите оценку, чтобы ИИ подготовил идеальный ответ.
</p>
<div style="display: flex; flex-direction: column; gap: 1rem; max-width: 600px;">
<label>
Текст отзыва
<textarea id="review-text-input" rows="4" placeholder="Например: Товар пришел быстро, качество отличное!"></textarea>
</label>
<label>
Оценка (звезды)
<select id="review-rating-input">
<option value="5">⭐⭐⭐⭐⭐ (5)</option>
<option value="4">⭐⭐⭐⭐ (4)</option>
<option value="3">⭐⭐⭐ (3)</option>
<option value="2">⭐⭐ (2)</option>
<option value="1">⭐ (1)</option>
</select>
</label>
<button class="btn-primary" id="ai-review-btn">
<i data-lucide="sparkles" class="icon-sm"></i> Сгенерировать ответ
</button>
<div id="ai-reply-container" class="hidden" style="margin-top: 1.5rem; animation: fadeIn 0.3s;">
<label>
Предложенный ответ ИИ
<textarea id="ai-reply-output" rows="5"></textarea>
</label>
<button class="btn-secondary" onclick="copyReply()">
<i data-lucide="copy" class="icon-sm"></i> Копировать в буфер
</button>
</div>
</div>
</div>
</div>
</section>
<!-- SEO Section -->
<section id="seo-section" class="section hidden">
<h2>SEO Мониторинг позиций</h2>
<div class="platforms-grid">
<div class="platform-card" style="grid-column: 1 / 1;">
<h3>Добавить ключевое слово</h3>
<form id="add-seo-form" class="platform-form" style="margin-top: 1rem;">
<input type="text" name="keyword" placeholder="Ключевое слово (например: кофемолка)" required>
<input type="text" name="article" placeholder="Твой артикул" required>
<select name="platform">
<option value="ozon">Ozon</option>
<option value="wildberries">Wildberries</option>
</select>
<button type="submit" class="btn-primary">Начать отслеживание</button>
</form>
</div>
<div class="platform-card" style="grid-column: 2 / -1;">
<h3>Отслеживаемые ключи</h3>
<table id="seo-table" class="table" style="margin-top: 1rem;">
<thead>
<tr>
<th>Ключ</th>
<th>Артикул</th>
<th>Позиция</th>
<th>Действие</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div id="seo-chart-container" class="platform-card hidden" style="margin-top: 1.5rem;">
<h3 id="seo-chart-title">История позиции</h3>
<canvas id="seoChart" height="150"></canvas>
</div>
</section>
<!-- Content Protection Section -->
<section id="content-section" class="section hidden">
<h2>Защита визуального контента</h2>
<div class="platforms-grid">
<div class="platform-card">
<h3>Загрузить эталон (оригинал)</h3>
<form id="add-reference-form" class="platform-form" style="margin-top: 1rem;">
<input type="text" name="article" placeholder="Артикул товара" required>
<input type="file" name="file" accept="image/*" required style="border: none; padding: 0.5rem 0;">
<button type="submit" class="btn-primary">Сохранить эталон</button>
</form>
</div>
<div class="platform-card" style="grid-column: 2 / -1;">
<h3>Твои оригиналы</h3>
<div id="reference-list" class="platforms-grid" style="grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); margin-top: 1rem;">
<!-- Reference images here -->
</div>
</div>
</div>
<div id="clones-detected-container" class="section hidden" style="margin-top: 2rem; border-top: var(--glass-border); padding-top: 2rem;">
<h3><i data-lucide="alert-triangle" class="icon-sm" style="color: var(--color-error);"></i> Обнаружены клоны</h3>
<div id="clones-list" class="platforms-grid" style="margin-top: 1rem;">
<!-- Detected clones here -->
</div>
</div>
</section>
<!-- Finance Section -->
<section id="finance-section" class="section hidden">
<h2>Калькулятор чистой прибыли (Unit Economics)</h2>
<div class="platforms-grid">
<div class="platform-card" style="grid-column: 1 / 1;">
<h3>Параметры товара</h3>
<form id="pnl-form" class="platform-form" style="margin-top: 1rem; display: flex; flex-direction: column; gap: 0.8rem;">
<label>Цена продажи (₽)<input type="number" name="sale_price" value="1000" step="0.1" required></label>
<label>Закупка (₽)<input type="number" name="purchase_price" value="400" step="0.1" required></label>
<label>Логистика (₽)<input type="number" name="logistics" value="100" step="0.1" required></label>
<label>Комиссия (%)<input type="number" name="commission_pct" value="15" step="0.1" required></label>
<label>Налог (УСН %)<input type="number" name="tax_pct" value="6" step="0.1" required></label>
<label>Реклама на 1 шт (₽)<input type="number" name="adv_per_unit" value="50" step="0.1" required></label>
<button type="submit" class="btn-primary">Рассчитать прибыль</button>
</form>
</div>
<div id="pnl-results" class="platform-card hidden" style="grid-column: 2 / -1; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center;">
<h3 style="margin-bottom: 2rem;">Результаты расчета</h3>
<div style="display: flex; gap: 2rem; flex-wrap: wrap; justify-content: center;">
<div>
<div style="color: var(--color-text-dim); font-size: 0.9rem;">Чистая прибыль</div>
<div id="pnl-net-profit" style="font-size: 2.5rem; font-weight: 800; color: var(--color-success);">0 ₽</div>
</div>
<div>
<div style="color: var(--color-text-dim); font-size: 0.9rem;">Маржа</div>
<div id="pnl-margin" style="font-size: 2.5rem; font-weight: 800; color: var(--color-primary);">0 %</div>
</div>
<div>
<div style="color: var(--color-text-dim); font-size: 0.9rem;">ROI</div>
<div id="pnl-roi" style="font-size: 2.5rem; font-weight: 800; color: var(--color-warning);">0 %</div>
</div>
</div>
<div style="margin-top: 2rem; width: 100%; max-width: 400px; text-align: left; padding: 1rem; background: rgba(0,0,0,0.2); border-radius: 12px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>Комиссия МП:</span> <span id="pnl-comm-abs">0 ₽</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>Налоги:</span> <span id="pnl-tax-abs">0 ₽</span>
</div>
<div style="display: flex; justify-content: space-between; font-weight: bold; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 0.5rem;">
<span>Себестоимость полная:</span> <span id="pnl-total-costs">0 ₽</span>
</div>
</div>
</div>
</div>
</section>
<!-- Product Generator Section -->
<section id="generator-section" class="section hidden">
<h2>Умный генератор карточек товара</h2>
<div class="platforms-grid">
<div class="platform-card" style="grid-column: 1 / -1;">
<p style="margin-bottom: 1.5rem; color: var(--color-text-dim);">
Введите название товара, и ИИ подготовит описание, характеристики и промпты для генерации изображений.
</p>
<div style="display: flex; gap: 1rem; max-width: 800px;">
<input type="text" id="gen-title-input" placeholder="Например: Беспроводная кофемолка с керамическими жерновами" style="flex: 1;">
<button class="btn-primary" id="ai-gen-card-btn">
<i data-lucide="sparkles" class="icon-sm"></i> Создать карточку
</button>
</div>
</div>
</div>
<div id="gen-result-container" class="hidden" style="margin-top: 2rem; animation: fadeIn 0.4s;">
<div class="platforms-grid">
<!-- Description & SEO -->
<div class="platform-card" style="grid-column: 1 / 2;">
<h3>Продающее описание</h3>
<div id="gen-description" style="margin-top: 1rem; line-height: 1.6; color: var(--color-text-dim);"></div>
<h3 style="margin-top: 2rem;">SEO Теги</h3>
<div id="gen-tags" style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem;"></div>
</div>
<!-- Features & Image Prompts -->
<div class="platform-card" style="grid-column: 2 / -1;">
<h3>Технические характеристики</h3>
<table id="gen-features-table" class="table" style="margin-top: 1rem;">
<tbody></tbody>
</table>
<h3 style="margin-top: 2rem;">Промпты для ИИ-фото (DALL-E/Midjourney)</h3>
<div id="gen-image-prompts" style="margin-top: 1rem;"></div>
</div>
</div>
</div>
</section>
<!-- Deep Insight Section -->
<section id="analytics-section" class="section hidden">
<h2>AI Анализ конкурентов (Deep Insight)</h2>
<div class="platforms-grid">
<div class="platform-card">
<h3>Сравнение товаров</h3>
<p style="color: var(--color-text-dim); font-size: 0.9rem; margin-bottom: 1rem;">
Вставьте описание вашего товара и описание конкурента, чтобы ИИ нашел способ его победить.
</p>
<div style="display: flex; flex-direction: column; gap: 1rem;">
<label>Мое описание<textarea id="my-desc-input" rows="4" placeholder="Ваше описание..."></textarea></label>
<label>Описание конкурента<textarea id="comp-desc-input" rows="4" placeholder="Описание конкурента..."></textarea></label>
<button class="btn-primary" id="ai-analyze-comp-btn">
<i data-lucide="zap" class="icon-sm"></i> Запустить Deep Insight
</button>
</div>
</div>
<div id="insight-result" class="platform-card hidden" style="grid-column: 2 / -1;">
<div style="background: rgba(var(--color-primary-rgb), 0.1); border-left: 4px solid var(--color-primary); padding: 1rem; margin-bottom: 1.5rem;">
<h4 style="color: var(--color-primary);">Мощный слоган (Win Phrase):</h4>
<p id="insight-win-phrase" style="font-style: italic; font-size: 1.1rem; margin-top: 0.5rem;"></p>
</div>
<div class="platforms-grid" style="grid-template-columns: 1fr 1fr; gap: 1.5rem;">
<div>
<h4>Слабые места конкурента</h4>
<ul id="insight-weakness" style="margin-top: 0.5rem; color: var(--color-error); font-size: 0.9rem;"></ul>
</div>
<div>
<h4>Твои преимущества</h4>
<ul id="insight-advantages" style="margin-top: 0.5rem; color: var(--color-success); font-size: 0.9rem;"></ul>
</div>
</div>
<h4 style="margin-top: 1.5rem;">Стратегия захвата рынка</h4>
<p id="insight-strategy" style="margin-top: 0.5rem; line-height: 1.6; color: var(--color-text-dim);"></p>
</div>
</div>
</section>
<!-- Repricer Section -->
<section id="repricer-section" class="section hidden">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
<h2>Авто-репрайзер (Динамические цены)</h2>
<button class="btn-primary" id="run-repricer-btn">
<i data-lucide="refresh-cw" class="icon-sm"></i> Обновить цены сейчас
</button>
</div>
<div class="platforms-grid">
<div class="platform-card" style="grid-column: 1 / 1;">
<h3>Новое правило</h3>
<form id="repricer-form" class="platform-form" style="margin-top: 1rem; display: flex; flex-direction: column; gap: 0.8rem;">
<label>Товар<input type="text" name="product_name" placeholder="Название товара" required></label>
<label>SKU / Артикул<input type="text" name="sku" placeholder="Артикул" required></label>
<div style="display: flex; gap: 1rem;">
<label style="flex: 1;">Мин. цена (₽)<input type="number" name="min_price" required></label>
<label style="flex: 1;">Макс. цена (₽)<input type="number" name="max_price" required></label>
</div>
<label>Стратегия
<select name="strategy">
<option value="follow_competitor">На 1₽ дешевле конкурента</option>
<option value="match_lowest">Равняться на минимальную</option>
</select>
</label>
<button type="submit" class="btn-primary">Добавить правило</button>
</form>
</div>
<div class="platform-card" style="grid-column: 2 / -1;">
<h3>Активные правила</h3>
<table id="repricer-table" class="table" style="margin-top: 1rem;">
<thead>
<tr>
<th>Товар</th>
<th>Мин / Макс</th>
<th>Тек. цена</th>
<th>Последнее обновление</th>
<th>Статус</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</section>
<!-- Integrations List -->
<section id="integrations-section" class="section hidden">
<h2>Доступные маркетплейсы</h2>
<div id="platforms-grid" class="platforms-grid">
<!-- Dynamically populated -->
</div>
</section>
<!-- Cases list -->
<section id="cases-section" class="section">
<h2>Список кейсов</h2>
<div class="controls">
<input type="text" id="search-input" placeholder="Поиск по артикулу..." />
<select id="platform-filter">
<option value="">Все площадки</option>
<option value="ozon">Ozon</option>
<option value="wb">Wildberries</option>
<option value="ym">Yandex Market</option>
<option value="mm">Magnit Market</option>
<option value="mega">MegaMarket</option>
<option value="ae">AliExpress</option>
<option value="avito">Avito</option>
<option value="lamoda">Lamoda</option>
<option value="lemana">Lemana PRO</option>
<option value="flowwow">Flowwow</option>
</select>
<select id="status-filter">
<option value="">Все статусы</option>
<option value="new">Новый</option>
<option value="prepared">Подготовлен</option>
<option value="sent">Отправлен</option>
<option value="closed">Закрыт</option>
</select>
<button id="new-case-btn" class="btn-primary">+ Новый кейс</button>
<button id="export-csv-btn" class="btn-secondary">⬇ Экспорт CSV</button>
</div>
<table id="cases-table" class="table">
<thead>
<tr>
<th>ID</th>
<th>Площадка</th>
<th>Артикул</th>
<th>Статус</th>
<th>Создан</th>
<th>Действия</th>
</tr>
</thead>
<tbody></tbody>
</table>
</section>
<!-- Case form -->
<section id="case-form-section" class="section hidden">
<h2 id="form-title">Новый кейс</h2>
<form id="case-form">
<label>
Площадка
<select name="platform" id="case-platform" required>
<option value="ozon">Ozon</option>
<option value="wb">Wildberries</option>
<option value="ym">Yandex Market</option>
<option value="mm">Magnit Market</option>
<option value="mega">MegaMarket</option>
<option value="ae">AliExpress</option>
<option value="avito">Avito</option>
<option value="lamoda">Lamoda</option>
<option value="lemana">Lemana PRO</option>
<option value="flowwow">Flowwow</option>
</select>
</label>
<label>
Ссылка на карточку нарушителя
<input type="url" name="violator_url" required />
</label>
<label>
Артикул нарушителя
<input type="text" name="violator_article" required />
</label>
<label>
Мой артикул (опц.)
<input type="text" name="my_article" />
</label>
<label>
Комментарий / описание
<div style="display: flex; gap: 0.5rem; margin-top: 0.25rem;">
<textarea name="comment" id="case-comment" rows="4" style="flex: 1;"></textarea>
<button type="button" id="ai-gen-btn" class="btn-secondary" style="height: fit-content; white-space: nowrap;">
<i data-lucide="sparkles" class="icon-sm"></i> ИИ Помощник
</button>
</div>
</label>
<label>
Прикрепить доказательства
<input type="file" id="file-input" multiple accept="image/*,application/pdf" />
<div id="file-preview" class="preview"></div>
</label>
<div class="form-actions">
<button type="submit" class="btn-primary">Сохранить</button>
<button type="button" id="cancel-btn" class="btn-secondary">Отмена</button>
</div>
</form>
</section>
<!-- Case detail -->
<section id="case-detail-section" class="section hidden">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h2>Детали кейса</h2>
<button id="download-pdf-btn" class="btn-primary">📄 Скачать PDF-претензию</button>
</div>
<div id="case-detail"></div>
<button id="back-to-list" class="btn-secondary">← Назад к списку</button>
</section>
</main>
</div>
<script type="module" src="js/app.js"></script>
<!-- Toast Notification Container -->
<div id="toast-container" class="toast-container"></div>
</body>
</html>