Your IP : 216.73.217.78


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

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

auth_check();

$id     = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$brand  = null;
$errors = [];
$selected_countries = [];

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

    $sc = db()->prepare("SELECT country_code FROM brand_countries WHERE brand_id = ?");
    $sc->execute([$id]);
    $selected_countries = array_column($sc->fetchAll(), 'country_code');
}

// Список стран для выбора (сгруппированных по регионам)
$country_groups = [
    'Crypto' => [
        'crypto' => 'Accepts Crypto',
    ],
    'Europe' => [
        'at'=>'Austria','be'=>'Belgium','ch'=>'Switzerland','cz'=>'Czech Republic',
        'de'=>'Germany','dk'=>'Denmark','ee'=>'Estonia','es'=>'Spain',
        'fi'=>'Finland','fr'=>'France','gr'=>'Greece','hr'=>'Croatia',
        'hu'=>'Hungary','ie'=>'Ireland','is'=>'Iceland','it'=>'Italy',
        'li'=>'Liechtenstein','lu'=>'Luxembourg','lv'=>'Latvia','md'=>'Moldova',
        'nl'=>'Netherlands','no'=>'Norway','pl'=>'Poland','pt'=>'Portugal',
        'ro'=>'Romania','se'=>'Sweden','si'=>'Slovenia','sk'=>'Slovakia',
        'ua'=>'Ukraine','uk'=>'United Kingdom',
    ],
    'Latam' => [
        'ar'=>'Argentina','bo'=>'Bolivia','br'=>'Brazil','cl'=>'Chile',
        'co'=>'Colombia','cr'=>'Costa Rica','ec'=>'Ecuador','gt'=>'Guatemala',
        'mx'=>'Mexico','pe'=>'Peru','uy'=>'Uruguay','ve'=>'Venezuela',
    ],
    'Asia' => [
        'bd'=>'Bangladesh','cn'=>'China','hk'=>'Hong Kong','id'=>'Indonesia',
        'in'=>'India','jp'=>'Japan','kh'=>'Cambodia','kr'=>'South Korea',
        'lk'=>'Sri Lanka','mo'=>'Macau','my'=>'Malaysia','ph'=>'Philippines',
        'pk'=>'Pakistan','sg'=>'Singapore','th'=>'Thailand','tw'=>'Taiwan',
        'vn'=>'Vietnam',
    ],
    'Africa' => [
        'bf'=>'Burkina Faso','bj'=>'Benin','cd'=>'DR Congo','ci'=>"Côte d'Ivoire",
        'cm'=>'Cameroon','dz'=>'Algeria','gh'=>'Ghana','ke'=>'Kenya',
        'ma'=>'Morocco','ne'=>'Niger','ng'=>'Nigeria','rw'=>'Rwanda',
        'sn'=>'Senegal','tg'=>'Togo','tz'=>'Tanzania','ug'=>'Uganda',
        'za'=>'South Africa','zm'=>'Zambia',
    ],
    'CIS / Caucasus' => [
        'am'=>'Armenia','az'=>'Azerbaijan','by'=>'Belarus','kg'=>'Kyrgyzstan',
        'kz'=>'Kazakhstan','ru'=>'Russia','tj'=>'Tajikistan','uz'=>'Uzbekistan',
    ],
    'MENA' => [
        'ae'=>'UAE','bh'=>'Bahrain','eg'=>'Egypt','il'=>'Israel',
        'kw'=>'Kuwait','om'=>'Oman','qa'=>'Qatar','sa'=>'Saudi Arabia','tr'=>'Turkey',
    ],
    'Oceania' => [
        'au'=>'Australia','nz'=>'New Zealand',
    ],
    'North America' => [
        'ca'=>'Canada','do'=>'Dominican Republic','pa'=>'Panama','us'=>'USA',
    ],
    'Global' => [
        'en'=>'Global / International',
    ],
];
$all_countries = array_merge(...array_values($country_groups));

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name         = trim($_POST['name'] ?? '');
    $slug         = trim($_POST['slug'] ?? '');
    $tracking_url = trim($_POST['tracking_url'] ?? '');
    $weight       = (int)($_POST['weight'] ?? 0);
    $is_featured      = isset($_POST['is_featured'])      ? 1 : 0;
    $postback_enabled = isset($_POST['postback_enabled']) ? 1 : 0;
    $badge        = trim($_POST['badge'] ?? '');
    $year_founded = (int)($_POST['year_founded'] ?? 0);
    $status       = $_POST['status'] ?? 'active';
    $countries    = $_POST['countries'] ?? [];
    $partner_id       = (int)($_POST['partner_id'] ?? 0) ?: null;
    $logo_bg          = trim($_POST['logo_bg'] ?? '');
    if ($logo_bg && !preg_match('/^#[0-9a-fA-F]{6}$/', $logo_bg)) $logo_bg = '';
    $payment_models   = $_POST['payment_models'] ?? [];
    $rate_cpa         = $_POST['rate_cpa'] !== '' ? (float)$_POST['rate_cpa'] : null;
    $rate_revshare    = $_POST['rate_revshare'] !== '' ? (float)$_POST['rate_revshare'] : null;
    $payment_models_json = !empty($payment_models) ? json_encode(array_values($payment_models)) : null;

    if (!$name)         $errors[] = 'Название обязательно.';
    if (!$tracking_url) $errors[] = 'Tracking URL обязателен.';
    if ($tracking_url && !filter_var($tracking_url, FILTER_VALIDATE_URL)) $errors[] = 'Tracking URL невалидный.';
    if (!in_array($status, ['active','inactive','draft'])) $status = 'active';

    if (!$slug) $slug = slugify($name);

    // Загрузка лого
    $logo = $brand['logo'] ?? '';
    if (!empty($_FILES['logo']['name'])) {
        try {
            $logo = upload_logo($_FILES['logo']);
        } catch (RuntimeException $e) {
            $errors[] = $e->getMessage();
        }
    }

    if (!$errors) {
        $db = db();
        if ($id) {
            $db->prepare("UPDATE brands SET name=?,slug=?,logo=?,tracking_url=?,weight=?,
                          is_featured=?,postback_enabled=?,badge=?,year_founded=?,status=?,
                          payment_models=?,rate_cpa=?,rate_revshare=?,partner_id=?,logo_bg=? WHERE id=?")
               ->execute([$name,$slug,$logo,$tracking_url,$weight,$is_featured,$postback_enabled,
                          $badge ?: null,$year_founded ?: null,$status,
                          $payment_models_json,$rate_cpa,$rate_revshare,$partner_id,$logo_bg ?: null,$id]);
        } else {
            $db->prepare("INSERT INTO brands (name,slug,logo,tracking_url,weight,is_featured,postback_enabled,badge,year_founded,status,
                          payment_models,rate_cpa,rate_revshare,partner_id,logo_bg)
                          VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
               ->execute([$name,$slug,$logo,$tracking_url,$weight,$is_featured,$postback_enabled,
                          $badge ?: null,$year_founded ?: null,$status,
                          $payment_models_json,$rate_cpa,$rate_revshare,$partner_id,$logo_bg ?: null]);
            $id = $db->lastInsertId();
        }

        // Страны
        $db->prepare("DELETE FROM brand_countries WHERE brand_id = ?")->execute([$id]);
        $stmt_c = $db->prepare("INSERT OR IGNORE INTO brand_countries (brand_id, country_code) VALUES (?,?)");
        foreach ($countries as $c) {
            $c = trim($c);
            if ($c) $stmt_c->execute([$id, $c]);
        }

        header('Location: /admin/brands.php?msg=' . urlencode('Бренд сохранён'));
        exit();
    }

    // Восстановить значения после ошибки
    $brand = array_merge($brand ?? [], compact('name','slug','tracking_url','weight','is_featured','badge','year_founded','status','rate_cpa','rate_revshare'));
    $brand['payment_models'] = $payment_models_json;
    $brand['partner_id'] = $partner_id;
    $selected_countries = $countries;
}

$title = $id ? 'Редактировать бренд' : 'Новый бренд';

// Список ПП для дропдауна
$all_partners = db()->query("SELECT id, name FROM partners ORDER BY name ASC")->fetchAll();

?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?= h($title) ?> — Admin</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<?= admin_nav('brands') ?>
<div class="container" style="max-width:800px">
    <h4 class="mb-4"><?= h($title) ?></h4>

    <?php foreach ($errors as $e): ?>
        <div class="alert alert-danger py-2"><?= h($e) ?></div>
    <?php endforeach ?>

    <form method="post" enctype="multipart/form-data">
        <div class="row g-3">
            <div class="col-md-8">
                <label class="form-label">Название *</label>
                <input type="text" name="name" class="form-control" required
                       value="<?= h($brand['name'] ?? '') ?>"
                       oninput="autoSlug(this.value)">
            </div>
            <div class="col-md-4">
                <label class="form-label">Slug</label>
                <input type="text" name="slug" id="slug" class="form-control"
                       value="<?= h($brand['slug'] ?? '') ?>" placeholder="авто из названия">
            </div>

            <div class="col-12">
                <label class="form-label">Tracking URL *</label>
                <input type="url" name="tracking_url" class="form-control" required
                       value="<?= h($brand['tracking_url'] ?? '') ?>" placeholder="https://...">
                <div class="form-text">
                    Макросы: <code>{subid}</code> — уникальный click ID &nbsp;·&nbsp;
                    <code>{landing_id}</code> — ID лендинга &nbsp;·&nbsp;
                    <code>{country}</code> — страна посетителя<br>
                    Пример: <code>https://brand.com/go?sub={subid}&dynamic={landing_id}&dynamic2={country}</code>
                </div>
            </div>

            <div class="col-md-4">
                <label class="form-label">Вес (weight)</label>
                <input type="number" name="weight" class="form-control" min="0"
                       value="<?= (int)($brand['weight'] ?? 0) ?>">
            </div>
            <div class="col-md-4">
                <label class="form-label">Badge</label>
                <select name="badge" class="form-select">
                    <option value="">— нет —</option>
                    <option value="best" <?= ($brand['badge'] ?? '') === 'best' ? 'selected' : '' ?>>⭐ Best</option>
                    <option value="new"  <?= ($brand['badge'] ?? '') === 'new'  ? 'selected' : '' ?>>🆕 New</option>
                    <option value="free" <?= ($brand['badge'] ?? '') === 'free' ? 'selected' : '' ?>>🎁 Free</option>
                </select>
            </div>
            <div class="col-md-4">
                <label class="form-label">Год основания</label>
                <input type="number" name="year_founded" class="form-control" min="1990" max="2099"
                       value="<?= (int)($brand['year_founded'] ?? 0) ?: '' ?>">
            </div>

            <div class="col-md-6">
                <label class="form-label">Статус</label>
                <select name="status" class="form-select">
                    <option value="active"   <?= ($brand['status'] ?? 'active') === 'active'   ? 'selected' : '' ?>>Активен</option>
                    <option value="inactive" <?= ($brand['status'] ?? '') === 'inactive' ? 'selected' : '' ?>>Неактивен</option>
                    <option value="draft"    <?= ($brand['status'] ?? '') === 'draft'    ? 'selected' : '' ?>>Черновик</option>
                </select>
            </div>
            <div class="col-md-6 d-flex align-items-end gap-4">
                <div class="form-check">
                    <input type="checkbox" name="is_featured" class="form-check-input" id="featured"
                           <?= !empty($brand['is_featured']) ? 'checked' : '' ?>>
                    <label class="form-check-label" for="featured">⭐ Featured (показывать первым)</label>
                </div>
                <div class="form-check">
                    <input type="checkbox" name="postback_enabled" class="form-check-input" id="postback_enabled"
                           <?= !empty($brand['postback_enabled']) ? 'checked' : '' ?>>
                    <label class="form-check-label" for="postback_enabled">📡 Постбеки включены</label>
                </div>
            </div>

            <div class="col-12">
                <label class="form-label">Логотип (PNG/JPG/WEBP, макс. 2MB)</label>
                <?php if (!empty($brand['logo'])): ?>
                    <div class="mb-2">
                        <img src="<?= h($brand['logo']) ?>" style="height:40px"> <small class="text-muted">текущий</small>
                    </div>
                <?php endif ?>
                <input type="file" name="logo" class="form-control" accept="image/png,image/jpeg,image/webp">
            </div>

            <div class="col-12">
                <label class="form-label">Цвет фона логотипа в виджете</label>
                <div class="d-flex align-items-center gap-2">
                    <div class="form-check mb-0">
                        <input type="checkbox" class="form-check-input" id="logo_bg_use"
                               <?= !empty($brand['logo_bg']) ? 'checked' : '' ?>>
                        <label class="form-check-label" for="logo_bg_use">Задать вручную</label>
                    </div>
                    <input type="color" name="logo_bg" id="logo_bg" class="form-control form-control-color"
                           style="width:48px"
                           value="<?= h($brand['logo_bg'] ?? '#2563eb') ?>"
                           <?= empty($brand['logo_bg']) ? 'disabled' : '' ?>>
                    <button type="button" class="btn btn-sm btn-outline-secondary" id="logo_bg_random">🎲 Random</button>
                    <span class="text-muted small" id="logo_bg_hint">
                        <?= !empty($brand['logo_bg']) ? 'Цвет задан вручную' : 'Авто — из палитры по ID бренда' ?>
                    </span>
                </div>
            </div>

            <div class="col-12"><hr class="my-1"><h6 class="text-muted mb-0">Условия работы</h6></div>

            <div class="col-12">
                <label class="form-label">Партнёрка (ПП)</label>
                <div class="d-flex gap-2 align-items-center">
                    <select name="partner_id" class="form-select">
                        <option value="0">— не привязан —</option>
                        <?php foreach ($all_partners as $pp): ?>
                            <option value="<?= $pp['id'] ?>"
                                <?= (int)($brand['partner_id'] ?? 0) === (int)$pp['id'] ? 'selected' : '' ?>>
                                <?= h($pp['name']) ?>
                            </option>
                        <?php endforeach ?>
                    </select>
                    <a href="/admin/partners.php" class="btn btn-outline-secondary btn-sm text-nowrap">Управление ПП →</a>
                </div>
            </div>

            <?php
                $active_models = json_decode($brand['payment_models'] ?? '[]', true) ?: [];
                $has_cpa       = in_array('cpa',      $active_models);
                $has_rs        = in_array('revshare', $active_models);
                $has_hyb       = in_array('hybrid',   $active_models);
            ?>
            <div class="col-12">
                <label class="form-label">Модель оплаты</label>
                <div class="d-flex gap-4">
                    <div class="form-check">
                        <input type="checkbox" name="payment_models[]" value="cpa"
                               class="form-check-input pm-check" id="pm_cpa"
                               <?= $has_cpa ? 'checked' : '' ?> onchange="syncRates()">
                        <label class="form-check-label" for="pm_cpa">CPA</label>
                    </div>
                    <div class="form-check">
                        <input type="checkbox" name="payment_models[]" value="revshare"
                               class="form-check-input pm-check" id="pm_revshare"
                               <?= $has_rs ? 'checked' : '' ?> onchange="syncRates()">
                        <label class="form-check-label" for="pm_revshare">RevShare</label>
                    </div>
                    <div class="form-check">
                        <input type="checkbox" name="payment_models[]" value="hybrid"
                               class="form-check-input pm-check" id="pm_hybrid"
                               <?= $has_hyb ? 'checked' : '' ?> onchange="syncRates()">
                        <label class="form-check-label" for="pm_hybrid">Hybrid</label>
                    </div>
                </div>
            </div>

            <div class="col-md-6" id="block_rate_cpa" style="display:<?= ($has_cpa || $has_hyb) ? 'block' : 'none' ?>">
                <label class="form-label">Ставка CPA</label>
                <input type="number" name="rate_cpa" class="form-control" min="0" step="0.01"
                       value="<?= ($brand['rate_cpa'] ?? '') !== '' && $brand['rate_cpa'] !== null ? h($brand['rate_cpa']) : '' ?>"
                       placeholder="50">
            </div>
            <div class="col-md-6" id="block_rate_rs" style="display:<?= ($has_rs || $has_hyb) ? 'block' : 'none' ?>">
                <label class="form-label">Ставка RevShare (%)</label>
                <input type="number" name="rate_revshare" class="form-control" min="0" max="100" step="0.1"
                       value="<?= ($brand['rate_revshare'] ?? '') !== '' && $brand['rate_revshare'] !== null ? h($brand['rate_revshare']) : '' ?>"
                       placeholder="25">
            </div>

            <div class="col-12"><hr class="my-1"></div>

            <div class="col-12">
                <label class="form-label">Страны (GEO)</label>
                <?php foreach ($country_groups as $region => $countries):
                    $region_key = preg_replace('/[^a-z0-9]/', '_', strtolower($region));
                    $all_checked = array_keys($countries) === array_values(array_intersect(array_keys($countries), $selected_countries))
                                   && count(array_intersect(array_keys($countries), $selected_countries)) === count($countries);
                ?>
                    <div class="card mb-2">
                        <div class="card-header py-1 px-3 d-flex align-items-center gap-2">
                            <div class="form-check mb-0">
                                <input type="checkbox" class="form-check-input region-toggle"
                                       id="rg_<?= $region_key ?>"
                                       data-region="<?= $region_key ?>"
                                       <?= $all_checked ? 'checked' : '' ?>
                                       onchange="toggleRegion('<?= $region_key ?>', this.checked)">
                                <label class="form-check-label fw-semibold small mb-0" for="rg_<?= $region_key ?>">
                                    <?= h($region) ?>
                                </label>
                            </div>
                            <small class="text-muted">(<?= count($countries) ?> countries)</small>
                        </div>
                        <div class="card-body py-2 px-3">
                            <div class="row row-cols-2 row-cols-md-4 row-cols-lg-5 g-1">
                                <?php foreach ($countries as $code => $cname): ?>
                                    <div class="col">
                                        <div class="form-check">
                                            <input type="checkbox" name="countries[]" value="<?= h($code) ?>"
                                                   class="form-check-input country-cb"
                                                   id="c_<?= h($code) ?>"
                                                   data-region="<?= $region_key ?>"
                                                   <?= in_array($code, $selected_countries) ? 'checked' : '' ?>
                                                   onchange="syncRegion('<?= $region_key ?>')">
                                            <label class="form-check-label small" for="c_<?= h($code) ?>">
                                                <?= h($cname) ?>
                                            </label>
                                        </div>
                                    </div>
                                <?php endforeach ?>
                            </div>
                        </div>
                    </div>
                <?php endforeach ?>
            </div>
        </div>

        <div class="mt-4 d-flex gap-2">
            <button type="submit" class="btn btn-primary">Сохранить</button>
            <a href="/admin/brands.php" class="btn btn-secondary">Отмена</a>
            <?php if ($id): ?>
                <a href="/admin/translations.php?brand_id=<?= $id ?>" class="btn btn-outline-info ms-auto">
                    Переводы →
                </a>
            <?php endif ?>
        </div>
    </form>
</div>

<script>
function autoSlug(val) {
    var slug = document.getElementById('slug');
    if (slug.dataset.manual) return;
    // простая транслитерация на JS
    var map = {'а':'a','б':'b','в':'v','г':'g','д':'d','е':'e','ё':'yo','ж':'zh','з':'z',
               'и':'i','й':'j','к':'k','л':'l','м':'m','н':'n','о':'o','п':'p','р':'r',
               'с':'s','т':'t','у':'u','ф':'f','х':'h','ц':'ts','ч':'ch','ш':'sh','щ':'sch',
               'ъ':'','ы':'y','ь':'','э':'e','ю':'yu','я':'ya'};
    var s = val.toLowerCase().split('').map(c => map[c] !== undefined ? map[c] : c).join('');
    slug.value = s.replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
}
document.getElementById('slug').addEventListener('input', function() {
    this.dataset.manual = '1';
});

function toggleRegion(region, checked) {
    document.querySelectorAll('.country-cb[data-region="' + region + '"]').forEach(function(cb) {
        cb.checked = checked;
    });
}

function syncRates() {
    var cpa = document.getElementById('pm_cpa').checked;
    var rs  = document.getElementById('pm_revshare').checked;
    var hyb = document.getElementById('pm_hybrid').checked;
    document.getElementById('block_rate_cpa').style.display = (cpa || hyb) ? 'block' : 'none';
    document.getElementById('block_rate_rs').style.display  = (rs  || hyb) ? 'block' : 'none';
}

function syncRegion(region) {
    var cbs = document.querySelectorAll('.country-cb[data-region="' + region + '"]');
    var all = Array.from(cbs).every(function(cb) { return cb.checked; });
    var none = Array.from(cbs).every(function(cb) { return !cb.checked; });
    var toggle = document.getElementById('rg_' + region);
    if (toggle) {
        toggle.checked = all;
        toggle.indeterminate = !all && !none;
    }
}

var logoBgPalette = [
    '#3b82f6','#8b5cf6','#ec4899','#ef4444',
    '#f97316','#eab308','#22c55e','#06b6d4',
    '#6366f1','#a855f7','#14b8a6','#f43f5e',
    '#10b981','#84cc16','#0ea5e9','#d946ef'
];
document.getElementById('logo_bg_random').addEventListener('click', function() {
    var inp  = document.getElementById('logo_bg');
    var cb   = document.getElementById('logo_bg_use');
    var hint = document.getElementById('logo_bg_hint');
    inp.value    = logoBgPalette[Math.floor(Math.random() * logoBgPalette.length)];
    inp.disabled = false;
    inp.name     = 'logo_bg';
    cb.checked   = true;
    hint.textContent = 'Цвет задан вручную';
});
document.getElementById('logo_bg_use').addEventListener('change', function() {
    var inp  = document.getElementById('logo_bg');
    var hint = document.getElementById('logo_bg_hint');
    inp.disabled = !this.checked;
    inp.name     = this.checked ? 'logo_bg' : '';
    hint.textContent = this.checked ? 'Цвет задан вручную' : 'Авто — из палитры по ID бренда';
});

</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>