LineUp-Bot / premium.html
Brozy123's picture
Update premium.html
ae11d5e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FriendlyBot — Premium</title>
<link rel="icon" href="/logo.png" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
<style>
:root {
--bg: #0a0a1a; --surface: #12122a; --border: rgba(255,255,255,0.08);
--text: #fff; --text-dim: rgba(255,255,255,0.6); --gold: #FFD700;
--accent: #5865F2; --radius: 16px;
}
* { box-sizing: border-box; margin:0; padding:0; }
body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; padding: 40px 20px; }
header { max-width: 1000px; margin: 0 auto 40px; display: flex; justify-content: space-between; align-items: center; }
h1 { font-size: 28px; font-weight: 700; }
.btn {
display: inline-block; padding: 10px 20px; background: var(--accent);
color: #fff; text-decoration: none; border-radius: 8px; font-weight: 600; font-size: 14px;
}
.container { max-width: 1000px; margin: 0 auto; }
.hero {
background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
color: #000; padding: 40px; border-radius: var(--radius); margin-bottom: 30px; text-align: center;
}
.hero h2 { font-size: 28px; font-weight: 800; margin-bottom: 10px; }
.hero p { font-size: 16px; opacity: 0.8; }
.features { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; margin-bottom: 30px; }
.card {
background: rgba(18,18,42,0.85); backdrop-filter: blur(8px);
border: 1px solid var(--border); border-radius: var(--radius);
padding: 24px; transition: all 0.25s;
}
.card:hover { border-color: var(--gold); transform: translateY(-3px); }
.card .icon { font-size: 32px; margin-bottom: 12px; }
.card h3 { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.card p { font-size: 14px; color: var(--text-dim); line-height: 1.6; }
.status {
background: rgba(18,18,42,0.85); backdrop-filter: blur(8px);
border: 1px solid var(--border); border-radius: var(--radius);
padding: 24px; margin-bottom: 30px; display: flex; align-items: center; gap: 16px;
}
.status .badge {
padding: 8px 20px; border-radius: 100px; font-weight: 700; font-size: 14px;
}
.badge.active { background: rgba(255,215,0,0.2); color: var(--gold); border: 1px solid var(--gold); }
.badge.inactive { background: rgba(255,255,255,0.05); color: var(--text-dim); border: 1px solid var(--border); }
.user-row { display: flex; align-items: center; gap: 12px; }
.user-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; color: white; }
.user-avatar img { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
th, td { text-align: left; padding: 12px; border-bottom: 1px solid var(--border); }
th { color: var(--text-dim); font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }
@media (max-width: 700px) { .features { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<header>
<h1>⭐ Premium</h1>
<a href="/" class="btn">Back to Dashboard</a>
</header>
<div class="container">
<div class="hero">
<h2>⭐ FriendlyBot Premium</h2>
<p>Unlock exclusive features by winning a league match. Premium is granted automatically when you record a win with <code>!win</code>.</p>
</div>
<div class="status" id="status">
<div class="badge inactive" id="premium-badge">Checking...</div>
<span id="premium-text">Loading your premium status...</span>
</div>
<div class="features" id="features">
<div class="card locked" data-feature="0">
<div class="icon">📊</div>
<h3>Advanced Stats & Analytics</h3>
<p>Track goals, assists, clean sheets, and weekly leaderboards for every player.</p>
</div>
<div class="card locked" data-feature="1">
<div class="icon">📅</div>
<h3>Match Scheduling & Reminders</h3>
<p>Auto-post scheduled matches with DM reminders 60 minutes before kickoff.</p>
</div>
<div class="card locked" data-feature="2">
<div class="icon">🎴</div>
<h3>Player Profile Cards</h3>
<p>Advanced <code>profileimage</code> with extra stats and custom backgrounds.</p>
</div>
<div class="card locked" data-feature="3">
<div class="icon">🔧</div>
<h3>Custom Command Aliases</h3>
<p>Rename bot commands to fit your server (e.g. <code>!ff</code> for <code>!friendly</code>).</p>
</div>
</div>
<div class="card" style="padding:24px">
<h3>🏆 Premium Users</h3>
<table>
<thead><tr><th>User</th><th>Since</th><th>Reason</th></tr></thead>
<tbody id="premium-list"><tr><td colspan="3">Loading...</td></tr></tbody>
</table>
</div>
</div>
<script>
async function fetchUser(userId) {
try {
const r = await fetch(`https://cdn.discordapp.com/embed/avatars/0.png`); // placeholder — we use ID
return null; // We use a fallback below
} catch(e) { return null; }
}
async function load() {
const statusEl = document.getElementById('premium-badge');
const textEl = document.getElementById('premium-text');
const listEl = document.getElementById('premium-list');
const cards = document.querySelectorAll('#features .card');
try {
// Check login status first to show user-specific premium status
let userPremium = false;
try {
const authR = await fetch('/api/me');
const authData = await authR.json();
if (authData.loggedIn) {
const premiumR = await fetch('/api/premium');
const premiumData = await premiumR.json();
userPremium = premiumData.premium;
}
} catch (e) { /* not logged in, that's fine */ }
if (userPremium) {
statusEl.className = 'badge active';
statusEl.textContent = '⭐ ACTIVE';
textEl.textContent = 'You have Premium access! Enjoy all features.';
cards.forEach(c => { c.style.borderColor = 'var(--gold)'; c.style.opacity = '1'; c.classList.remove('locked'); });
} else {
statusEl.className = 'badge inactive';
statusEl.textContent = '— LOCKED';
textEl.textContent = 'Log in to the dashboard and win a league match with !win to unlock Premium.';
cards.forEach(c => { c.style.borderColor = 'var(--border)'; c.style.opacity = '0.55'; c.classList.add('locked'); });
}
// Load public premium list
const listR = await fetch('/api/premium/list');
const listData = await listR.json();
if (listData.list && listData.list.length > 0) {
listEl.innerHTML = listData.list.map(u => {
const date = new Date(u.grantedAt).toLocaleDateString();
const avatarUrl = u.avatarUrl || '';
const displayName = u.userTag || u.userId;
const initial = (displayName || '?')[0].toUpperCase();
const avatarHtml = avatarUrl
? `<img src="${avatarUrl}" onerror="this.parentElement.textContent='${initial}'" alt="">`
: `<span style="font-size:14px;font-weight:700">${initial}</span>`;
return `<tr><td><div class="user-row"><div class="user-avatar">${avatarHtml}</div><span style="font-size:13px;font-weight:500">${displayName}</span></div></td><td style="font-size:13px">${date}</td><td style="font-size:13px;color:var(--text-dim)">${u.reason || 'manual'}</td></tr>`;
}).join('');
} else {
listEl.innerHTML = '<tr><td colspan="3" style="text-align:center;color:var(--text-dim);padding:24px">No premium users yet. Win a league match to be the first!</td></tr>';
}
} catch (e) {
statusEl.className = 'badge inactive';
statusEl.textContent = '❌ ERROR';
textEl.textContent = 'Could not load premium data.';
listEl.innerHTML = '<tr><td colspan="3" style="text-align:center;color:var(--red)">Failed to load.</td></tr>';
}
}
load();
</script>
</body>
</html>