| Current Path : /home/seto/888mirror.pm/admin/ |
| Current File : /home/seto/888mirror.pm/admin/widget-preview.php |
<?php
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/helpers.php';
auth_check();
$db = db();
$active_countries = $db->query("
SELECT DISTINCT bc.country_code FROM brand_countries bc
JOIN brands b ON b.id = bc.brand_id
WHERE b.status='active' AND bc.country_code NOT IN ('en','crypto')
ORDER BY bc.country_code
")->fetchAll(PDO::FETCH_COLUMN);
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Widget Preview — Admin</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.preview-toolbar {
position: sticky; top: 56px; z-index: 100;
background: var(--bs-body-bg);
border-bottom: 1px solid var(--bs-border-color);
padding: 10px 16px;
}
.width-btn.active { background: var(--bs-primary); color: #fff; border-color: var(--bs-primary); }
.preview-shell {
background: repeating-linear-gradient(
45deg,
rgba(0,0,0,.03),
rgba(0,0,0,.03) 10px,
transparent 10px,
transparent 20px
);
min-height: calc(100vh - 140px);
display: flex; flex-direction: column; align-items: center;
padding: 24px 16px 40px;
transition: background .2s;
}
.preview-shell.dark-bg {
background: #0e0e1a repeating-linear-gradient(
45deg,
rgba(255,255,255,.02),
rgba(255,255,255,.02) 10px,
transparent 10px,
transparent 20px
);
}
.device-frame {
width: 100%;
max-width: 100%;
transition: max-width .25s ease;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,.07), 0 12px 40px rgba(0,0,0,.12), 0 0 0 1px rgba(0,0,0,.08);
overflow: hidden;
position: relative;
}
.device-frame.dark-bg { background: #0e0e1a; }
.device-bar {
display: flex; align-items: center; gap: 6px;
padding: 8px 12px;
background: rgba(0,0,0,.04);
border-bottom: 1px solid rgba(0,0,0,.07);
font-size: 11px; color: #999;
flex-shrink: 0;
}
.device-bar.dark { background: rgba(255,255,255,.04); border-color: rgba(255,255,255,.06); color: #555; }
.device-dot { width: 8px; height: 8px; border-radius: 50%; }
.preview-iframe {
width: 100%;
border: none;
display: block;
min-height: 200px;
transition: height .1s;
}
.width-label {
font-size: 11px; color: #888; text-align: center;
margin-top: 8px; letter-spacing: .3px;
}
</style>
</head>
<body>
<?= admin_nav('widget') ?>
<div class="preview-toolbar">
<div class="d-flex align-items-center gap-3 flex-wrap">
<!-- Layout -->
<div class="d-flex align-items-center gap-1">
<span class="text-muted small me-1">Layout:</span>
<?php foreach (['table'=>'⊞ Table','cards'=>'▦ Cards','ranked'=>'☰ Ranked','liquid'=>'◈ Liquid'] as $lk=>$ll): ?>
<button class="btn btn-sm btn-outline-secondary layout-btn <?= $lk==='table'?'active':'' ?>"
data-layout="<?= $lk ?>"><?= $ll ?></button>
<?php endforeach ?>
</div>
<div class="vr"></div>
<!-- Width presets -->
<div class="d-flex align-items-center gap-1">
<span class="text-muted small me-1">Ширина:</span>
<?php
$widths = ['320'=>'📱 320','430'=>'📱 430','768'=>'📟 768','1024'=>'💻 1024','100%'=>'🖥 Full'];
foreach ($widths as $wv => $wl):
?>
<button class="btn btn-sm btn-outline-secondary width-btn <?= $wv==='100%'?'active':'' ?>"
data-width="<?= $wv ?>"><?= $wl ?></button>
<?php endforeach ?>
</div>
<div class="vr"></div>
<!-- GEO -->
<div class="d-flex align-items-center gap-2">
<span class="text-muted small">GEO:</span>
<select class="form-select form-select-sm" id="geoSel" style="width:160px">
<option value="">🌍 Global</option>
<?php foreach ($active_countries as $cc): ?>
<option value="<?= h($cc) ?>"><?= h(strtoupper($cc)) ?> — <?= h(country_name($cc)) ?></option>
<?php endforeach ?>
</select>
</div>
<div class="vr"></div>
<!-- Background -->
<div class="d-flex align-items-center gap-1">
<span class="text-muted small me-1">Фон:</span>
<button class="btn btn-sm btn-outline-secondary bg-btn active" data-bg="light">☀ Light</button>
<button class="btn btn-sm btn-outline-secondary bg-btn" data-bg="dark">🌙 Dark</button>
</div>
<div class="ms-auto">
<span class="text-muted small" id="currentWidth">100%</span>
</div>
</div>
</div>
<div class="preview-shell" id="previewShell">
<div class="device-frame" id="deviceFrame">
<div class="device-bar" id="deviceBar">
<span class="device-dot" style="background:#ff5f57"></span>
<span class="device-dot" style="background:#febc2e"></span>
<span class="device-dot" style="background:#28c840"></span>
<span style="margin-left:4px">888mirror.pm — Widget Preview</span>
</div>
<iframe
id="previewFrame"
class="preview-iframe"
style="height:600px"
></iframe>
</div>
<div class="width-label" id="widthLabel"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
(function () {
var frame = document.getElementById('previewFrame');
var device = document.getElementById('deviceFrame');
var shell = document.getElementById('previewShell');
var bar = document.getElementById('deviceBar');
var label = document.getElementById('widthLabel');
var curWLabel = document.getElementById('currentWidth');
var state = {
layout: localStorage.getItem('wp_layout') || 'table',
width: localStorage.getItem('wp_width') || '100%',
country: localStorage.getItem('wp_country') || '',
bg: localStorage.getItem('wp_bg') || 'light',
};
function buildSrc() {
var url = '/widget-test.php?embed=1&layout=' + encodeURIComponent(state.layout);
if (state.country) url += '&country=' + encodeURIComponent(state.country);
url += '&theme=' + (state.bg === 'dark' ? 'dark' : 'light');
return url;
}
function applyWidth() {
var w = state.width;
if (w === '100%') {
device.style.maxWidth = '100%';
label.textContent = '';
curWLabel.textContent = 'Full width';
} else {
device.style.maxWidth = w + 'px';
label.textContent = w + 'px';
curWLabel.textContent = w + 'px';
}
document.querySelectorAll('.width-btn').forEach(function (b) {
b.classList.toggle('active', b.dataset.width === w);
});
autoHeight();
}
function applyBg() {
var dark = state.bg === 'dark';
shell.classList.toggle('dark-bg', dark);
device.classList.toggle('dark-bg', dark);
bar.classList.toggle('dark', dark);
document.querySelectorAll('.bg-btn').forEach(function (b) {
b.classList.toggle('active', b.dataset.bg === state.bg);
});
}
function applyLayout() {
document.querySelectorAll('.layout-btn').forEach(function (b) {
b.classList.toggle('active', b.dataset.layout === state.layout);
});
}
function applyGeo() {
var sel = document.getElementById('geoSel');
sel.value = state.country;
}
function reload() {
frame.src = buildSrc();
}
function autoHeight() {
frame.onload = function () {
try {
var h = frame.contentDocument.body.scrollHeight;
if (h > 50) frame.style.height = (h + 16) + 'px';
} catch(e) {
frame.style.height = '700px';
}
};
}
// Width buttons
document.querySelectorAll('.width-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
state.width = btn.dataset.width;
localStorage.setItem('wp_width', state.width);
applyWidth();
});
});
// Layout buttons
document.querySelectorAll('.layout-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
state.layout = btn.dataset.layout;
localStorage.setItem('wp_layout', state.layout);
applyLayout();
reload();
});
});
// GEO
document.getElementById('geoSel').addEventListener('change', function () {
state.country = this.value;
localStorage.setItem('wp_country', state.country);
reload();
});
// Background
document.querySelectorAll('.bg-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
state.bg = btn.dataset.bg;
localStorage.setItem('wp_bg', state.bg);
applyBg();
reload();
});
});
// Init
applyLayout();
applyGeo();
applyBg();
applyWidth();
reload();
})();
</script>
</body>
</html>