- Full gg.deals-style UI: deal feed with filters, game pages with price history charts, rankings, vouchers, news, prepaids, subscriptions, bundles, franchises, wishlist, API docs - Real data crawlers: * gg:crawl (Steam Store API + GOG Catalog + Epic free games) * gg:catalog (252K game slugs from gg.deals sitemaps) * gg:ggdeals (per-game prices via FlareSolverr session, JSON-LD parsing) * gg:seed / gg:crawl-covers (demo seed + Steam CDN cover art) - 24/7 self-updating scheduler (scripts/scheduler_loop.php, lockfile-protected) - Tailwind v4 dark/light theme, Alpine.js, Chart.js
133 lines
7.1 KiB
PHP
133 lines
7.1 KiB
PHP
<?= $this->extend('layout') ?>
|
|
<?= $this->section('content') ?>
|
|
|
|
<?php
|
|
$dealSections = [
|
|
'popular' => ['Most Popular Games', 'popular', '/deals'],
|
|
'newDeals' => ['New deals', 'new', '/deals/new-deals'],
|
|
'bestDeals' => ['Best deals', 'hot', '/deals/hot-new-deals'],
|
|
'histLows' => ['Historical lows', 'hl', '/deals/historical-lows'],
|
|
'endingSoon' => ['Ending Soon', 'ending', '/deals/ending-soon'],
|
|
];
|
|
?>
|
|
|
|
<!-- ======= stats strip ======= -->
|
|
<div class="bg-panel border border-line rounded-2xl px-5 py-4 mb-8 flex flex-wrap items-center gap-x-8 gap-y-3">
|
|
<div>
|
|
<div class="text-2xl font-extrabold text-white"><?= number_format($stats['games']) ?></div>
|
|
<div class="text-[11px] uppercase tracking-wider text-muted">Games tracked</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-extrabold text-white"><?= number_format($stats['deals']) ?></div>
|
|
<div class="text-[11px] uppercase tracking-wider text-muted">Deals today</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-extrabold text-white"><?= $stats['stores'] ?></div>
|
|
<div class="text-[11px] uppercase tracking-wider text-muted">Stores</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-extrabold text-accent"><?= $stats['hl_now'] ?></div>
|
|
<div class="text-[11px] uppercase tracking-wider text-muted">All-time lows now</div>
|
|
</div>
|
|
<div class="ml-auto text-xs text-muted">
|
|
Compare prices of video games from <span class="text-zinc-200 font-semibold"><?= $stats['stores'] ?> stores</span>,
|
|
find the best game deals online. CD keys for PC games at the best price!
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ======= deal sections ======= -->
|
|
<?php foreach ($dealSections as $key => [$title, $mode, $link]): ?>
|
|
<?php if (${$key} !== []): ?>
|
|
<section class="mb-8">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h2 class="text-sm font-bold text-zinc-200 uppercase tracking-wider"><?= $title ?></h2>
|
|
<a href="<?= $link ?>" class="text-xs font-bold text-accent hover:underline">See all →</a>
|
|
</div>
|
|
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-2.5">
|
|
<?php foreach (${$key} as $d): ?>
|
|
<?= view('partials/dash_deal', ['d' => $d, 'stores' => $stores]) ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
|
|
<!-- ======= game lists: most wanted / new releases / upcoming ======= -->
|
|
<div class="grid lg:grid-cols-3 gap-6 mb-8">
|
|
<?php
|
|
$gameSections = [
|
|
'mostWanted' => ['🔥 Most Wanted', 'wanted'],
|
|
'newReleases' => ['🆕 New releases', 'releases'],
|
|
'upcoming' => ['📅 Upcoming games', 'upcoming'],
|
|
];
|
|
foreach ($gameSections as $key => [$title, $mode]): ?>
|
|
<div class="bg-panel border border-line rounded-2xl overflow-hidden">
|
|
<div class="px-4 py-3 border-b border-line flex items-center justify-between">
|
|
<h2 class="text-sm font-bold text-zinc-200 uppercase tracking-wider"><?= $title ?></h2>
|
|
<a href="/games" class="text-xs font-bold text-accent hover:underline">See all</a>
|
|
</div>
|
|
<div class="divide-y divide-line/60">
|
|
<?php foreach (${$key} as $i => $g): ?>
|
|
<a href="/game/<?= $g['slug'] ?>" class="flex items-center gap-3 px-4 py-2.5 hover:bg-elev/50 transition-colors group">
|
|
<span class="w-6 text-center font-extrabold <?= $i < 3 ? 'text-accent' : 'text-muted' ?>"><?= $i + 1 ?></span>
|
|
<img src="<?= esc($g['cover']['file']) ?>" alt="" class="w-[84px] h-[39px] object-cover rounded ring-1 ring-line shrink-0" loading="lazy">
|
|
<div class="min-w-0 flex-1">
|
|
<div class="text-[13px] font-semibold text-zinc-100 truncate group-hover:text-accent"><?= esc($g['title']) ?></div>
|
|
<div class="text-[11px] text-muted">
|
|
<span class="text-accent font-bold"><?= money(min($g['best_official']['price'], $g['best_keyshop']['price'])) ?></span>
|
|
<span class="line-through ml-1"><?= money($g['base_price']) ?></span>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- ======= news + prepaids ======= -->
|
|
<div class="grid lg:grid-cols-3 gap-6">
|
|
<!-- news feed -->
|
|
<div class="lg:col-span-2 bg-panel border border-line rounded-2xl overflow-hidden">
|
|
<div class="px-4 py-3 border-b border-line flex items-center justify-between">
|
|
<h2 class="text-sm font-bold text-zinc-200 uppercase tracking-wider">📰 News</h2>
|
|
<a href="/news" class="text-xs font-bold text-accent hover:underline">All news →</a>
|
|
</div>
|
|
<div class="divide-y divide-line/60">
|
|
<?php foreach ($news as $p): ?>
|
|
<a href="/news" class="flex items-start gap-3 px-4 py-3 hover:bg-elev/50 transition-colors group">
|
|
<span class="kind-tag mt-0.5 <?= $p['category'] === 'freebies' ? 'kind-keyshop' : 'kind-official' ?> shrink-0"><?= esc($p['category']) ?></span>
|
|
<div class="min-w-0">
|
|
<div class="text-sm font-semibold text-zinc-100 group-hover:text-accent leading-snug"><?= esc($p['title']) ?></div>
|
|
<div class="text-[11px] text-muted mt-1"><?= time_ago($p['date']) ?></div>
|
|
</div>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- prepaids -->
|
|
<div class="bg-panel border border-line rounded-2xl overflow-hidden">
|
|
<div class="px-4 py-3 border-b border-line flex items-center justify-between">
|
|
<h2 class="text-sm font-bold text-zinc-200 uppercase tracking-wider">🎁 Prepaids</h2>
|
|
<a href="/prepaids" class="text-xs font-bold text-accent hover:underline">All →</a>
|
|
</div>
|
|
<div class="p-3 space-y-2">
|
|
<?php foreach ($prepaids as $g): ?>
|
|
<a href="/prepaids" class="flex items-center justify-between px-3 py-2 rounded-lg bg-card border border-line hover:border-accent/40 transition-colors group">
|
|
<div class="flex items-center gap-2.5 min-w-0">
|
|
<span class="w-7 h-7 rounded-md flex items-center justify-center text-[10px] font-extrabold text-white shrink-0"
|
|
style="background: linear-gradient(135deg, <?= esc($g['color'][0]) ?>, <?= esc($g['color'][1]) ?>)">
|
|
<?= store_initials($g['name']) ?>
|
|
</span>
|
|
<span class="text-[13px] font-semibold text-zinc-100 truncate group-hover:text-accent"><?= esc($g['name']) ?></span>
|
|
</div>
|
|
<span class="text-xs text-accent font-bold shrink-0">from <?= money((float) $g['offers'][0]['price']) ?></span>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?= $this->endSection() ?>
|