UNPKG

ihrz

Version:
626 lines (569 loc) 13.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style> :root { --primary: #5865F2; --primary-light: #7983f5; --secondary: #EB459E; --secondary-light: #f16db6; --bg-dark: #1E1F22; --bg-medium: #2B2D31; --bg-light: #313338; --text-bright: #FFFFFF; --text-muted: #B5BAC1; --success: #3BA55C; --warning: #FAA61A; --danger: #ED4245; --border-radius: 12px; --box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { font-family: 'Inter', 'Poppins', sans-serif; background: var(--bg-dark); color: var(--text-bright); width: 1920px; margin: 0; padding: 0; overflow: hidden; } .card { background: var(--bg-medium); border-radius: var(--border-radius); width: 1920px; height: 1200px; box-shadow: var(--box-shadow); position: relative; box-sizing: border-box; overflow: hidden; display: grid; grid-template-rows: auto auto 1fr; grid-template-areas: "header" "sections" "chart"; } .card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, var(--primary), var(--secondary)); } .header { grid-area: header; display: flex; align-items: center; padding: 15px; background: var(--bg-light); border-bottom: 1px solid rgba(255, 255, 255, 0.05); position: relative; width: 100%; box-sizing: border-box; } .avatar-container { position: relative; margin-right: 24px; } .avatar { width: 90px; height: 90px; border-radius: 50%; object-fit: cover; border: 4px solid var(--primary); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); transition: var(--transition); } .avatar:hover { transform: scale(1.05); } .header-info { display: flex; flex-direction: column; } .username { font-size: 32px; font-weight: 700; margin-bottom: 5px; background: linear-gradient(90deg, var(--primary), var(--secondary)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } .rank { color: var(--text-muted); font-size: 20px; font-weight: 500; display: flex; align-items: center; } .rank::before { content: ''; display: inline-block; width: 8px; height: 8px; background-color: var(--success); border-radius: 50%; margin-right: 8px; } .stats-overview { display: flex; justify-content: space-between; padding: 20px 30px; background: var(--bg-light); border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .stat-item { text-align: center; flex: 1; padding: 0 15px; position: relative; } .stat-item:not(:last-child)::after { content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%); height: 70%; width: 1px; background: rgba(255, 255, 255, 0.1); } .stat-value { font-size: 24px; font-weight: 700; color: var(--text-bright); margin-bottom: 5px; } .stat-label { font-size: 14px; color: var(--text-muted); font-weight: 500; } .sections { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; padding: 15px; width: 100%; box-sizing: border-box; } .section { background: var(--bg-light); border-radius: var(--border-radius); padding: 15px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); position: relative; overflow: hidden; transition: var(--transition); height: auto; min-height: 180px; } .section::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: var(--primary); } .section:nth-child(2n)::before { background: var(--secondary); } .section-title { font-size: 20px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; color: var(--text-bright); } .section-title .icon { margin-right: 10px; font-size: 20px; } .section-content { font-size: 16px; color: var(--text-muted); line-height: 1.5; } .rank-item { display: flex; align-items: center; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .rank-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .rank-position { font-weight: 700; margin-right: 10px; color: var(--text-bright); background: var(--primary); width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; } .rank-item:nth-child(2) .rank-position { background: var(--secondary); } .rank-item:nth-child(3) .rank-position { background: var(--warning); } .rank-name { flex: 1; font-weight: 500; color: var(--text-bright); } .rank-value { font-weight: 600; color: var(--primary-light); } .time-stat { display: flex; align-items: center; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .time-stat:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .time-period { flex: 1; font-weight: 500; color: var(--text-bright); } .time-value { font-weight: 600; color: var(--primary-light); } .chart-container { grid-area: chart; background: var(--bg-light); border-radius: var(--border-radius); margin: 0 20px 20px; padding: 15px 15px 25px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); width: calc(100% - 40px); box-sizing: border-box; display: flex; flex-direction: column; height: 550px; align-self: stretch; } .chart-title { font-size: 22px; font-weight: 600; font-weight: 600; margin-bottom: 5px; color: var(--text-bright); text-align: center; } @media (max-width: 350px) { .card { width: 350px; max-width: 350px; min-width: 350px; } .sections { grid-template-columns: 1fr; } .stats-overview { flex-direction: column; gap: 15px; } .stat-item:not(:last-child)::after { display: none; } } </style> </head> <body> <div class="card"> <!-- Header with user info --> <div class="header"> <div class="avatar-container"> <img src="{author_pfp}" alt="Avatar" class="avatar"> </div> <div class="header-info"> <div class="username">{username}</div> <div class="rank">{guild_name}</div> </div> </div> <!-- Stats overview --> <div class="stats-overview"> <div class="stat-item"> <div class="stat-value">{message_monthly}</div> <div class="stat-label">{messages_word}</div> </div> <div class="stat-item"> <div class="stat-value">{voice_monthly}</div> <div class="stat-label">{voice_activity}</div> </div> </div> <!-- Main sections --> <div class="sections"> <!-- Top voice channels --> <div class="section"> <div class="section-title"> <span class="icon">🏆</span> {top_voice} </div> <div class="section-content"> <div class="rank-item"> <div class="rank-position">1</div> <div class="rank-name">#{voice_top1}</div> <div class="rank-value">{voice_top1_2}</div> </div> <div class="rank-item"> <div class="rank-position">2</div> <div class="rank-name">#{voice_top2}</div> <div class="rank-value">{voice_top2_2}</div> </div> <div class="rank-item"> <div class="rank-position">3</div> <div class="rank-name">#{voice_top3}</div> <div class="rank-value">{voice_top3_2}</div> </div> </div> </div> <!-- Top message channels --> <div class="section"> <div class="section-title"> <span class="icon">📊</span> {top_message} </div> <div class="section-content"> <div class="rank-item"> <div class="rank-position">1</div> <div class="rank-name">#{messages_top1}</div> <div class="rank-value">{messages_top1_2} {messages_word}</div> </div> <div class="rank-item"> <div class="rank-position">2</div> <div class="rank-name">#{messages_top2}</div> <div class="rank-value">{messages_top2_2} {messages_word}</div> </div> <div class="rank-item"> <div class="rank-position">3</div> <div class="rank-name">#{messages_top3}</div> <div class="rank-value">{messages_top3_2} {messages_word}</div> </div> </div> </div> <!-- Voice activity --> <div class="section"> <div class="section-title"> <span class="icon">🔊</span> {voice_activity} </div> <div class="section-content"> <div class="time-stat"> <div class="time-period">{var_1d}</div> <div class="time-value">{voice_daily}</div> </div> <div class="time-stat"> <div class="time-period">{var_7d}</div> <div class="time-value">{voice_weekly}</div> </div> <div class="time-stat"> <div class="time-period">{var_14d}</div> <div class="time-value">{voice_monthly}</div> </div> </div> </div> <!-- Message activity --> <div class="section"> <div class="section-title"> <span class="icon">📨</span> {messages_word} </div> <div class="section-content"> <div class="time-stat"> <div class="time-period">{var_1d}</div> <div class="time-value">{message_daily} {messages_word}</div> </div> <div class="time-stat"> <div class="time-period">{var_7d}</div> <div class="time-value">{message_weekly} {messages_word}</div> </div> <div class="time-stat"> <div class="time-period">{var_14d}</div> <div class="time-value">{message_monthly} {messages_word}</div> </div> </div> </div> </div> <!-- Activity chart --> <div class="chart-container"> <div class="chart-title">{chart_title}</div> <canvas id="statsChart"></canvas> </div> </div> <script> const messageData = { messageData }; const voiceData = { voiceData }; const labels = { timeLabels }; const ctx = document.getElementById('statsChart').getContext('2d'); // Create gradient for message data const messageGradient = ctx.createLinearGradient(0, 0, 0, 600); messageGradient.addColorStop(0, 'rgba(88, 101, 242, 0.8)'); messageGradient.addColorStop(1, 'rgba(88, 101, 242, 0.1)'); // Create gradient for voice data const voiceGradient = ctx.createLinearGradient(0, 0, 0, 600); voiceGradient.addColorStop(0, 'rgba(235, 69, 158, 0.8)'); voiceGradient.addColorStop(1, 'rgba(235, 69, 158, 0.1)'); new Chart(ctx, { type: 'line', data: { labels: labels, datasets: [ { label: '{messages_word}', data: messageData, borderColor: 'rgba(88, 101, 242, 1)', backgroundColor: messageGradient, fill: true, tension: 0.4, borderWidth: 3, pointBackgroundColor: 'rgba(88, 101, 242, 1)', pointBorderColor: '#fff', pointRadius: 3, pointHoverRadius: 5 }, { label: '{voice_activity}', data: voiceData, borderColor: 'rgba(235, 69, 158, 1)', backgroundColor: voiceGradient, fill: true, tension: 0.4, borderWidth: 3, pointBackgroundColor: 'rgba(235, 69, 158, 1)', pointBorderColor: '#fff', pointRadius: 3, pointHoverRadius: 5 } ] }, options: { responsive: true, maintainAspectRatio: false, animation: false, interaction: { mode: 'index', intersect: false, }, layout: { padding: { left: 10, right: 10, top: 20, bottom: 30 } }, plugins: { legend: { position: 'top', labels: { boxWidth: 12, usePointStyle: true, padding: 10, color: 'rgba(255, 255, 255, 1)', font: { family: 'Inter, sans-serif', size: 14, weight: 600 } } }, tooltip: { enabled: true, mode: 'index', intersect: false, backgroundColor: 'rgba(30, 31, 34, 0.9)', titleFont: { family: 'Inter, sans-serif', size: 15, weight: 700 }, bodyFont: { family: 'Inter, sans-serif', size: 14, weight: 500 } } }, scales: { x: { grid: { color: 'rgba(255, 255, 255, 0.05)', drawBorder: false }, ticks: { color: 'rgba(255, 255, 255, 0.9)', font: { family: 'Inter, sans-serif', size: 14, weight: 600 }, maxRotation: 45, minRotation: 45, autoSkip: true, maxTicksLimit: 15 } }, y: { beginAtZero: true, grid: { color: 'rgba(255, 255, 255, 0.05)', drawBorder: false }, max: function (context) { const maxValue = Math.max(...messageData, ...voiceData); return maxValue + (maxValue * 0.2); }, ticks: { color: 'rgba(255, 255, 255, 0.9)', font: { family: 'Inter, sans-serif', size: 14, weight: 600 } } } } } }); </script> </body> </html>