NoahsAPP / member-count.html
noah33565's picture
Upload member-count.html
823940b verified
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NoahsChat – Member Count</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap');
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0a0e14;
color: #e2e8f0;
font-family: Orbitron, monospace;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
text-align: center;
padding: 40px;
}
.title {
font-size: .7rem;
color: #4a5568;
letter-spacing: .3em;
margin-bottom: 30px;
}
.logo {
font-size: 1.6rem;
font-weight: 900;
color: #00d4ff;
letter-spacing: .2em;
margin-bottom: 40px;
}
.stats {
display: flex;
gap: 30px;
justify-content: center;
flex-wrap: wrap;
}
.stat-box {
background: #0d1117;
border: 1px solid #1e2a3a;
border-radius: 8px;
padding: 24px 36px;
min-width: 140px;
}
.stat-label {
font-size: .55rem;
color: #4a5568;
letter-spacing: .15em;
margin-bottom: 10px;
}
.stat-value {
font-size: 2.4rem;
font-weight: 700;
}
.stat-value.members { color: #00d4ff; }
.stat-value.online { color: #4eff91; }
.stat-value.visitors { color: #a855f7; }
.updated {
margin-top: 30px;
font-size: .55rem;
color: #2d3748;
letter-spacing: .1em;
}
</style>
</head>
<body>
<div class="container">
<div class="logo">NoahsChat</div>
<div class="title">SERVER STATISTIKEN</div>
<div class="stats">
<div class="stat-box">
<div class="stat-label">MITGLIEDER</div>
<div class="stat-value members" id="count-members">β€”</div>
</div>
<div class="stat-box">
<div class="stat-label">ONLINE</div>
<div class="stat-value online" id="count-online">β€”</div>
</div>
<div class="stat-box">
<div class="stat-label">UNIQUE BESUCHER</div>
<div class="stat-value visitors" id="count-visitors">β€”</div>
</div>
</div>
<div class="updated" id="last-updated">WIRD GELADEN...</div>
</div>
<script>
const JSONBIN_KEY = '$2a$10$Hurr28g4Cy7NWpA/Abd6YOzkBLuC8PdAOPQR34g4pEkA24LpXo7NK';
const JSONBIN_BIN = '69976e43ae596e708f382b97';
// Fingerprint
function getFingerprint() {
const s = navigator.userAgent + screen.width + screen.height + screen.colorDepth
+ (Intl.DateTimeFormat().resolvedOptions().timeZone || '') + navigator.language;
let h = 0;
for (let i = 0; i < s.length; i++) { h = ((h << 5) - h) + s.charCodeAt(i); h = h & h; }
return Math.abs(h).toString(36);
}
const MY_FP = getFingerprint();
async function loadAndTrack() {
try {
const r = await fetch(`https://api.jsonbin.io/v3/b/${JSONBIN_BIN}/latest`, {
headers: { 'X-Master-Key': JSONBIN_KEY, 'X-Bin-Meta': 'false' }
});
const DB = await r.json();
// Unique Visitor tracken
if (!DB.visitors) DB.visitors = {};
const isNew = !DB.visitors[MY_FP];
if (isNew) {
DB.visitors[MY_FP] = { ts: Date.now() };
await fetch(`https://api.jsonbin.io/v3/b/${JSONBIN_BIN}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-Master-Key': JSONBIN_KEY, 'X-Bin-Versioning': 'false' },
body: JSON.stringify(DB)
});
}
// Werte anzeigen
document.getElementById('count-members').textContent = Object.keys(DB.users || {}).length;
document.getElementById('count-visitors').textContent = Object.keys(DB.visitors || {}).length;
const now = Date.now();
const online = Object.values(DB.online || {}).filter(ts => now - ts < 12000).length;
document.getElementById('count-online').textContent = online;
const time = new Date().toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
document.getElementById('last-updated').textContent = 'ZULETZT AKTUALISIERT: ' + time;
} catch(e) {
document.getElementById('last-updated').textContent = 'FEHLER BEIM LADEN';
}
}
loadAndTrack();
setInterval(loadAndTrack, 10000); // alle 10 Sekunden aktualisieren
</script>
</body>
</html>