/* ═══════════════════════════════════════════════════════════ GAMEHUS — Core Engine Auth Guard · Tab System · Wallet · Toast · Counters ═══════════════════════════════════════════════════════════ */ 'use strict'; // ─── Fake Auth Store (will be replaced by Firebase Auth later) ─────────────── const TEST_USERS = [ { email: 'admin@gamehus.com', password: 'admin123', username: 'Admin', role: 'admin', vip: true, gold: 15000, silver: 8400 }, { email: 'vip@gamehus.com', password: 'vip123', username: 'VIP_Player', role: 'user', vip: true, gold: 5200, silver: 3100 }, { email: 'test@gamehus.com', password: 'test123', username: 'TestUser', role: 'user', vip: false, gold: 0, silver: 1200 }, { email: 'player1@gamehus.com', password: 'play123', username: 'ProShooter', role: 'user', vip: false, gold: 200, silver: 4500 }, { email: 'player2@gamehus.com', password: 'play456', username: 'ChessMaster', role: 'user', vip: true, gold: 800, silver: 6700 }, ]; const AUTH_KEY = 'gh_session'; const SESSION_TTL = 24 * 60 * 60 * 1000; // 24h // ─── AUTH MODULE ───────────────────────────────────────────────────────────── const Auth = (() => { function getSession() { try { const raw = sessionStorage.getItem(AUTH_KEY) || localStorage.getItem(AUTH_KEY); if (!raw) return null; const data = JSON.parse(raw); if (Date.now() - data.ts > SESSION_TTL) { clearSession(); return null; } return data.user; } catch { return null; } } function saveSession(user, remember = false) { const payload = JSON.stringify({ user, ts: Date.now() }); sessionStorage.setItem(AUTH_KEY, payload); if (remember) localStorage.setItem(AUTH_KEY, payload); } function clearSession() { sessionStorage.removeItem(AUTH_KEY); localStorage.removeItem(AUTH_KEY); } function login(identifier, password, remember = false) { const user = TEST_USERS.find(u => (u.email === identifier || u.username === identifier) && u.password === password ); if (!user) return { ok: false, msg: 'بيانات الدخول غير صحيحة' }; const { password: _, ...safeUser } = user; saveSession(safeUser, remember); return { ok: true, user: safeUser }; } function logout() { clearSession(); window.location.href = 'login.html'; } function requireAuth() { const user = getSession(); if (!user) { window.location.replace('login.html'); return null; } // reveal page document.querySelectorAll('.auth-guard').forEach(el => el.classList.add('revealed')); return user; } return { getSession, saveSession, clearSession, login, logout, requireAuth }; })(); // ─── TOAST MODULE ───────────────────────────────────────────────────────────── const Toast = (() => { let container; function getContainer() { if (!container) { container = document.createElement('div'); container.className = 'toast-container'; document.body.appendChild(container); } return container; } function show(msg, type = 'success', duration = 3000) { const icons = { success: '✅', gold: '🪙', error: '❌', info: 'ℹ️' }; const toast = document.createElement('div'); toast.className = `toast toast-${type}`; toast.innerHTML = `${icons[type] || '💬'}${msg}`; getContainer().appendChild(toast); setTimeout(() => { toast.style.opacity = '0'; toast.style.transform = 'translateX(20px)'; toast.style.transition = 'all 0.3s'; setTimeout(() => toast.remove(), 300); }, duration); } return { show }; })(); // ─── TAB SYSTEM ─────────────────────────────────────────────────────────────── const TabSystem = (() => { const instances = new Map(); // instanceId -> { tabs, activeId, container } function create(containerId, tabs, options = {}) { const container = document.getElementById(containerId); if (!container) return; const state = { tabs: [...tabs], activeId: tabs[0]?.id, container, options }; instances.set(containerId, state); render(containerId); return { activate: (id) => activate(containerId, id), addTab: (tab) => addTab(containerId, tab), removeTab: (id) => removeTab(containerId, id) }; } function render(cid) { const state = instances.get(cid); if (!state) return; const { tabs, activeId, container, options } = state; // Tab bar let barEl = container.querySelector('.tab-bar'); if (!barEl) { barEl = document.createElement('div'); barEl.className = 'tab-bar'; container.prepend(barEl); } barEl.innerHTML = tabs.map(tab => `
${tab.icon ? `${tab.icon}` : ''} ${tab.label} ${!tab.pinned ? `` : ''}
`).join('') + (options.addable ? `` : ''); // click events barEl.querySelectorAll('.tab-item').forEach(el => { el.addEventListener('click', (e) => { if (e.target.closest('.tab-close')) return; activate(cid, el.dataset.tid); }); }); barEl.querySelectorAll('.tab-close').forEach(btn => { btn.addEventListener('click', () => removeTab(cid, btn.dataset.close)); }); // panels let panelsEl = container.querySelector('.tab-panels'); if (!panelsEl) { panelsEl = document.createElement('div'); panelsEl.className = 'tab-panels'; container.appendChild(panelsEl); } tabs.forEach(tab => { let panel = panelsEl.querySelector(`[data-panel="${tab.id}"]`); if (!panel) { panel = document.createElement('div'); panel.className = 'tab-panel animate-in'; panel.dataset.panel = tab.id; panel.innerHTML = tab.content || ''; panelsEl.appendChild(panel); } panel.classList.toggle('active', tab.id === activeId); }); } function activate(cid, id) { const state = instances.get(cid); if (!state || !state.tabs.find(t => t.id === id)) return; state.activeId = id; render(cid); state.options.onActivate?.(id); } function addTab(cid, tab) { const state = instances.get(cid); if (!state) return; if (!state.tabs.find(t => t.id === tab.id)) state.tabs.push(tab); activate(cid, tab.id); } function removeTab(cid, id) { const state = instances.get(cid); if (!state) return; const idx = state.tabs.findIndex(t => t.id === id); if (idx === -1 || state.tabs[idx].pinned) return; state.tabs.splice(idx, 1); if (state.activeId === id) state.activeId = state.tabs[Math.max(0, idx - 1)]?.id; render(cid); } return { create, activate, addTab, removeTab }; })(); // ─── INNER TABS (simple, CSS-driven) ──────────────────────────────────────── function setupInnerTabs(containerEl) { const tabs = containerEl.querySelectorAll('.inner-tab'); const panels = containerEl.querySelectorAll('.inner-panel'); tabs.forEach(tab => { tab.addEventListener('click', () => { tabs.forEach(t => t.classList.remove('active')); panels.forEach(p => p.classList.remove('active')); tab.classList.add('active'); const target = containerEl.querySelector(`[data-inner-panel="${tab.dataset.innerTab}"]`); if (target) target.classList.add('active'); }); }); if (tabs[0]) tabs[0].click(); } // ─── TOPBAR BUILDER ───────────────────────────────────────────────────────── function buildTopbar(user) { const bar = document.getElementById('topbar'); if (!bar || !user) return; bar.innerHTML = `
💎 GAMEHUS
🪙 ${(user.gold||0).toLocaleString('ar')}
🔘 ${(user.silver||0).toLocaleString('ar')}
8,432 متصل
${(user.username||'?').substring(0,2).toUpperCase()}
${user.username}
${user.vip ? '
✨ VIP
' : ''}
`; // user menu dropdown document.getElementById('user-menu-btn')?.addEventListener('click', () => { const existing = document.getElementById('user-dropdown'); if (existing) { existing.remove(); return; } const dropdown = document.createElement('div'); dropdown.id = 'user-dropdown'; dropdown.style.cssText = `position:fixed;top:${65}px;left:16px;background:var(--bg-card);border:1px solid var(--border-gold);border-radius:12px;padding:8px;min-width:180px;z-index:100;box-shadow:var(--glow-gold);animation:fadeIn 0.2s ease;`; dropdown.innerHTML = `
${user.username}
${user.email}
👤 الملف الشخصي
🪙 شحن الذهب
🚪 تسجيل الخروج
`; document.body.appendChild(dropdown); setTimeout(() => document.addEventListener('click', function handler(e) { if (!dropdown.contains(e.target) && e.target.id !== 'user-menu-btn') { dropdown.remove(); document.removeEventListener('click', handler); } }), 10); }); // pulse online count const el = document.getElementById('online-count'); if (el) { const base = 8432; let tick = 0; setInterval(() => { tick++; el.textContent = (base + Math.round(Math.sin(tick/3)*18)).toLocaleString('ar'); }, 7000); } } // ─── SIDEBAR BUILDER ───────────────────────────────────────────────────────── function buildSidebar(user, activePage = '') { const sb = document.getElementById('sidebar'); if (!sb) return; const items = [ { id: 'dashboard', icon: '🏠', label: 'الرئيسية', href: 'index.html' }, { id: 'games', icon: '🎮', label: 'الألعاب', href: 'games.html' }, { id: 'rooms', icon: '🏠', label: 'الغرف', href: 'rooms.html' }, { id: 'top', icon: '🏆', label: 'المتصدرون', href: 'top.html' }, { id: 'chat', icon: '💬', label: 'الدردشة', href: 'chat.html', badge: '3' }, { divider: true }, { id: 'train', icon: '🚂', label: 'محطات الجوائز', href: 'train.html' }, { id: 'shop', icon: '🛍️', label: 'المتجر', href: 'shop.html' }, { id: 'tournaments',icon:'🥇', label: 'البطولات', href: 'tournaments.html' }, { divider: true }, { id: 'profile', icon: '👤', label: 'الملف الشخصي', href: 'profile.html' }, ...(user?.role === 'admin' ? [{ id: 'admin', icon: '⚙️', label: 'لوحة الإدارة', href: 'admin.html' }] : []), ]; sb.innerHTML = `
${user?.vip ? `
✨ VIP مفعّل
تذكرة القطار الذهبي نشطة
` : `
🚂 ترقية إلى VIP
جوائز أكبر في كل المحطات
اشترِ التذكرة `}
`; } // ─── COUNTERS ──────────────────────────────────────────────────────────────── function animateCounters() { document.querySelectorAll('[data-count]').forEach(el => { const target = parseInt(el.getAttribute('data-count') || '0', 10); if (!target) return; let cur = 0; const inc = target / 60; const t = setInterval(() => { cur += inc; if (cur >= target) { cur = target; clearInterval(t); } el.textContent = Math.floor(cur).toLocaleString('ar'); }, 16); }); } // ─── SHOP MODAL (quick open) ────────────────────────────────────────────────── function openShop() { const existing = document.getElementById('shop-modal'); if (existing) existing.remove(); const modal = document.createElement('div'); modal.id = 'shop-modal'; modal.className = 'modal-overlay'; modal.innerHTML = ` `; modal.addEventListener('click', e => { if (e.target === modal) modal.remove(); }); document.body.appendChild(modal); } // ─── PAGE INIT ──────────────────────────────────────────────────────────────── document.addEventListener('DOMContentLoaded', () => { const page = document.body.dataset.page || ''; const isAuthPage = ['login', 'register'].includes(page); if (!isAuthPage) { const user = Auth.requireAuth(); if (!user) return; buildTopbar(user); buildSidebar(user, page); animateCounters(); // setup any inner-tab containers on the page document.querySelectorAll('[data-inner-tabs]').forEach(el => setupInnerTabs(el)); } }); // expose globally window.Auth = Auth; window.Toast = Toast; window.TabSystem = TabSystem; window.openShop = openShop; window.setupInnerTabs = setupInnerTabs;