Your IP : 216.73.217.78


Current Path : /home/seto/888mirror.pm/admin/
Upload File :
Current File : /home/seto/888mirror.pm/admin/translations.php

<?php
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/helpers.php';

auth_check();

$brand_id = (int)($_GET['brand_id'] ?? 0);
if (!$brand_id) { header('Location: /admin/brands.php'); exit(); }

$brand = db()->prepare("SELECT * FROM brands WHERE id = ?");
$brand->execute([$brand_id]);
$brand = $brand->fetch();
if (!$brand) { header('Location: /admin/brands.php'); exit(); }

$msg = '';

// Сохранение вручную
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_translations'])) {
    $langs  = $_POST['lang'] ?? [];
    $db     = db();
    $check  = $db->prepare("SELECT id FROM brand_translations WHERE brand_id=? AND language_code=?");
    $insert = $db->prepare("
        INSERT INTO brand_translations (brand_id, language_code, bonus, free_spins, games_count,
            advantages, license, payment_methods, payment_methods_count, min_withdraw, max_withdraw, currencies)
        VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
    ");
    $update = $db->prepare("
        UPDATE brand_translations SET bonus=?, free_spins=?, games_count=?, advantages=?,
            license=?, payment_methods=?, payment_methods_count=?, min_withdraw=?, max_withdraw=?, currencies=?
        WHERE brand_id=? AND language_code=?
    ");

    foreach ($langs as $lang_code => $values) {
        $bonus = $values['bonus'] ?? '';
        $spins = $values['free_spins'] ?? '';
        $games = $values['games_count'] ?? '';
        $adv   = $values['advantages'] ?? '';
        $lic   = $values['license'] ?? '';
        $pm    = $values['payment_methods'] ?? '';
        $pmc   = $values['payment_methods_count'] ?? '';
        $minw  = $values['min_withdraw'] ?? '';
        $maxw  = $values['max_withdraw'] ?? '';
        $curr  = $values['currencies'] ?? '';

        $check->execute([$brand_id, $lang_code]);
        if ($check->fetchColumn()) {
            $update->execute([$bonus,$spins,$games,$adv,$lic,$pm,$pmc,$minw,$maxw,$curr,$brand_id,$lang_code]);
        } else {
            $insert->execute([$brand_id,$lang_code,$bonus,$spins,$games,$adv,$lic,$pm,$pmc,$minw,$maxw,$curr]);
        }
    }
    $msg = 'Переводы сохранены.';
}

// Загрузить языки, отсортированные: EN → RU → по показам за 30 дней → алфавит
$since = date('Y-m-d H:i:s', strtotime('-30 days'));
$lang_stats = db()->prepare("
    SELECT language, COUNT(*) as cnt
    FROM stats
    WHERE event_type = 'impression' AND created_at >= ?
    GROUP BY language
");
$lang_stats->execute([$since]);
$stats_by_lang = array_column($lang_stats->fetchAll(), 'cnt', 'language');

$all_langs = db()->query("SELECT * FROM languages WHERE is_active = 1 ORDER BY code")->fetchAll();

$group_colors = [
    'Core Markets'  => 'primary',
    'Nordics'       => 'info',
    'Balkans & SEE' => 'warning',
    'Baltics'       => 'success',
    'Caucasus & CIS'=> 'secondary',
    'Asia Growth'   => 'danger',
];

usort($all_langs, function($a, $b) use ($stats_by_lang) {
    $priority = ['en' => 0, 'ru' => 1];
    $pa = $priority[$a['code']] ?? 2;
    $pb = $priority[$b['code']] ?? 2;
    if ($pa !== $pb) return $pa - $pb;
    $ca = $stats_by_lang[$a['code']] ?? 0;
    $cb = $stats_by_lang[$b['code']] ?? 0;
    if ($ca !== $cb) return $cb - $ca;
    return strcmp($a['code'], $b['code']);
});

$languages = $all_langs;

$trans_raw = db()->prepare("SELECT * FROM brand_translations WHERE brand_id = ?");
$trans_raw->execute([$brand_id]);
$translations = [];
foreach ($trans_raw->fetchAll() as $t) {
    $translations[$t['language_code']] = $t;
}

$openai_key = setting('openai_key');
$fields_labels = [
    'bonus'                 => 'Бонус',
    'free_spins'            => 'Фриспины',
    'games_count'           => 'Игр',
    'advantages'            => 'Преимущества (JSON или текст)',
    'license'               => 'Лицензия',
    'payment_methods'       => 'Способы оплаты (JSON или текст)',
    'payment_methods_count' => 'Кол-во способов',
    'min_withdraw'          => 'Мин. вывод',
    'max_withdraw'          => 'Макс. вывод',
    'currencies'            => 'Валюты',
];
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Переводы — <?= h($brand['name']) ?></title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .trans-table td, .trans-table th { vertical-align: middle; }
        .trans-table textarea { font-size: 12px; min-height: 36px; resize: vertical; }
        .lang-header { position: sticky; top: 0; background: #fff; z-index: 10; }
    </style>
</head>
<body>
<?= admin_nav('brands') ?>
<div class="container-fluid px-4">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <div>
            <h5 class="mb-0">Переводы: <strong><?= h($brand['name']) ?></strong></h5>
            <small class="text-muted">Slug: <?= h($brand['slug']) ?></small>
        </div>
        <div class="d-flex gap-2">
            <?php if ($openai_key): ?>
                <button class="btn btn-outline-info btn-sm" onclick="researchBrand()">
                    🔍 Исследовать бренд
                </button>
                <div class="dropdown">
                    <button class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown">
                        🤖 Сгенерировать через AI
                    </button>
                    <ul class="dropdown-menu">
                        <li><a class="dropdown-item" href="#" onclick="generateAll(); return false">Все языки (чанками по 6)</a></li>
                        <li><hr class="dropdown-divider"></li>
                        <?php foreach ($languages as $lang): ?>
                            <li>
                                <a class="dropdown-item" href="#"
                                   onclick="generateOne('<?= h($lang['code']) ?>','<?= h($lang['name']) ?>'); return false">
                                    <?= h($lang['name']) ?> (<?= h($lang['code']) ?>)
                                </a>
                            </li>
                        <?php endforeach ?>
                    </ul>
                </div>
            <?php else: ?>
                <a href="/admin/settings.php" class="btn btn-outline-secondary btn-sm">⚠ Добавьте OpenAI ключ</a>
            <?php endif ?>
            <a href="/admin/brands.php" class="btn btn-secondary btn-sm">← Назад</a>
        </div>
    </div>

    <?php if ($msg): ?>
        <div class="alert alert-success py-2"><?= h($msg) ?></div>
    <?php endif ?>

    <!-- Панель исследования бренда -->
    <div id="research-panel" class="card mb-3 d-none border-info">
        <div class="card-header bg-info bg-opacity-10 d-flex justify-content-between align-items-center py-2">
            <span class="fw-semibold">🔍 Найденные факты о бренде</span>
            <div class="d-flex gap-2">
                <button class="btn btn-success btn-sm" onclick="generateAll()">
                    🤖 Использовать факты + Генерировать все языки
                </button>
                <button class="btn btn-outline-secondary btn-sm" onclick="document.getElementById('research-panel').classList.add('d-none')">✕</button>
            </div>
        </div>
        <div class="card-body pb-2">
            <div class="text-muted small mb-1">Проверьте и при необходимости отредактируйте перед генерацией:</div>
            <textarea id="research-facts" class="form-control form-control-sm font-monospace" rows="10"></textarea>
        </div>
    </div>

    <!-- AI прогресс -->
    <div id="ai-progress" class="alert alert-info d-none">
        <div class="d-flex align-items-center gap-2">
            <div class="spinner-border spinner-border-sm"></div>
            <span id="ai-progress-text">Генерация...</span>
        </div>
    </div>
    <div id="ai-error" class="alert alert-danger d-none"></div>

    <form method="post">
        <div class="table-responsive">
            <table class="table table-bordered table-sm trans-table">
                <thead class="table-light lang-header">
                    <tr>
                        <th style="min-width:120px">Поле</th>
                        <?php foreach ($languages as $lang): ?>
                            <th style="min-width:140px">
                                <?= h($lang['name']) ?>
                                <br><small class="text-muted"><?= h($lang['code']) ?></small>
                                <br><span class="badge bg-<?= $group_colors[$lang['group_name'] ?? 'Core Markets'] ?? 'secondary' ?>" style="font-size:9px"><?= h($lang['group_name'] ?? '') ?></span>
                                <?php if (!empty($translations[$lang['code']]['generated_at'])): ?>
                                    <br><small class="text-success" title="Дата генерации">
                                        🤖 <?= substr($translations[$lang['code']]['generated_at'],0,10) ?>
                                    </small>
                                <?php endif ?>
                            </th>
                        <?php endforeach ?>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($fields_labels as $field => $label): ?>
                        <tr>
                            <td><strong><?= h($label) ?></strong></td>
                            <?php foreach ($languages as $lang): ?>
                                <td>
                                    <textarea name="lang[<?= h($lang['code']) ?>][<?= h($field) ?>]"
                                              class="form-control form-control-sm"
                                              id="f_<?= h($lang['code']) ?>_<?= h($field) ?>"
                                              rows="2"><?= h($translations[$lang['code']][$field] ?? '') ?></textarea>
                                </td>
                            <?php endforeach ?>
                        </tr>
                    <?php endforeach ?>
                </tbody>
            </table>
        </div>
        <div class="mt-3 mb-5">
            <button type="submit" name="save_translations" class="btn btn-primary">Сохранить переводы</button>
        </div>
    </form>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
const brandId   = <?= $brand_id ?>;
const allLangs  = <?= json_encode(array_column($languages, 'code')) ?>;
const fieldKeys = <?= json_encode(array_keys($fields_labels)) ?>;

function showProgress(text) {
    document.getElementById('ai-progress').classList.remove('d-none');
    document.getElementById('ai-progress-text').textContent = text;
    document.getElementById('ai-error').classList.add('d-none');
}
function hideProgress() {
    document.getElementById('ai-progress').classList.add('d-none');
}
function showError(msg) {
    hideProgress();
    var el = document.getElementById('ai-error');
    el.textContent = msg;
    el.classList.remove('d-none');
}

function fillFields(data) {
    for (var lang in data) {
        var vals = data[lang];
        for (var field in vals) {
            var el = document.getElementById('f_' + lang + '_' + field);
            if (el) {
                var val = vals[field];
                if (Array.isArray(val)) val = JSON.stringify(val, null, 2);
                el.value = val || '';
            }
        }
    }
}

async function researchBrand() {
    showProgress('🔍 Поиск информации о бренде в интернете...');
    try {
        const r = await fetch('/admin/generate.php', {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            body: 'brand_id=' + brandId + '&action=research'
        }).then(r => r.json());
        hideProgress();
        if (r.error) { showError(r.error); return; }
        document.getElementById('research-facts').value = r.facts;
        document.getElementById('research-panel').classList.remove('d-none');
        document.getElementById('research-panel').scrollIntoView({behavior:'smooth'});
    } catch(e) { showError('Ошибка: ' + e.message); }
}

function getContext() {
    var panel = document.getElementById('research-panel');
    if (panel && !panel.classList.contains('d-none')) {
        return document.getElementById('research-facts').value.trim();
    }
    return '';
}

async function generateAll() {
    const context   = getContext();
    const chunkSize = 6;
    const total     = allLangs.length;
    for (let i = 0; i < total; i += chunkSize) {
        const chunk = allLangs.slice(i, i + chunkSize);
        const from  = i + 1;
        const to    = Math.min(i + chunkSize, total);
        showProgress('🤖 Генерация языков ' + from + '–' + to + ' из ' + total + '...');
        try {
            const body = 'brand_id=' + brandId + '&langs=' + chunk.join(',')
                       + (context ? '&context=' + encodeURIComponent(context) : '');
            const r = await fetch('/admin/generate.php', {
                method: 'POST',
                headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                body: body
            }).then(r => r.json());
            if (r.error) { showError(r.error); return; }
            fillFields(r.data);
        } catch(e) { showError('Ошибка: ' + e.message); return; }
    }
    hideProgress();
    document.querySelector('button[name=save_translations]').click();
}

async function generateOne(lang, name) {
    const context = getContext();
    showProgress('🤖 Генерация: ' + name + '...');
    try {
        const body = 'brand_id=' + brandId + '&langs=' + lang
                   + (context ? '&context=' + encodeURIComponent(context) : '');
        const r = await fetch('/admin/generate.php', {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            body: body
        }).then(r => r.json());
        hideProgress();
        if (r.error) { showError(r.error); return; }
        fillFields(r.data);
        document.querySelector('button[name=save_translations]').click();
    } catch(e) { showError('Ошибка: ' + e.message); }
}
</script>
</body>
</html>