// 🏠 Dashboard JavaScript - Ana Sayfa İşlevleri class Dashboard { constructor() { this.user = null; this.socket = null; this.resources = { money: 50, wood: 0, grain: 0, business: 0 }; this.goals = { daily: { target: 100, current: 50 } }; this.isLoading = false; this.trustEarnedToday = 0; this.isMentorQueued = false; // yeni this.isMenteeWaiting = false; // yeni this.trustHistory = { recent: [], totals: { gained:0, lost:0 } }; // yeni this.activeMentorshipId = null; // yeni this.mentorshipRatings = { asMentor:{}, asMentee:{} }; // yeni this.lbMode = 'top'; // yeni: leaderboard modu this.lbCategory = 'trust'; // yeni: trust | mentor // Yeni: Trust rank & trend this.trustRank = null; this.trustTrend = []; this.mentorLbMinSessions = 3; // yeni dinamik filtre this.mentorLbLimit = 15; // yeni dinamik limit this.init(); } // Başlatma işlemleri async init() { try { console.log('🚀 Dashboard başlatılıyor...'); // İlk UI güncellemeleri - loading state'ini kaldır this.hideLoadingStates(); // Kullanıcı verilerini yükle (timeout ile) const loadUserPromise = this.loadUserData(); const timeoutPromise = new Promise((resolve) => setTimeout(() => { console.warn('⚠️ Dashboard: loadUserData timeout - varsayılan verilerle devam'); resolve(); }, 3000) ); await Promise.race([loadUserPromise, timeoutPromise]); // Diğer işlemler (hata olursa devam etsin) try { this.setupEventListeners(); } catch (error) { console.error('❌ Event listeners hatası:', error); } try { this.connectSocket(); } catch (error) { console.error('❌ Socket bağlantı hatası:', error); } try { this.updateGreeting(); this.startPeriodicUpdates(); this.setupNotifications(); } catch (error) { console.error('❌ UI güncellemeleri hatası:', error); } console.log('✅ Dashboard başlatıldı'); } catch (error) { console.error('❌ Dashboard başlatma hatası:', error); this.showError('Dashboard yüklenirken bir hata oluştu'); // En azından temel UI'yi göster this.hideLoadingStates(); } } // Kullanıcı verilerini yükle async loadUserData() { try { const token = localStorage.getItem('jwt_token'); if(!token){ window.location.href='/login.html'; return; } const r = await fetch('/api/user/bootstrap', { headers:{'Authorization':'Bearer '+token} }); if(r.ok){ const b = await r.json(); this.user = { id: b.user.id, displayName: b.user.username, trustScore: b.user.trust_score, bot_tutorial_state: b.user.bot_tutorial_state, resources:{ money:b.user.money, wood:b.user.wood, grain:b.user.grain, business:b.user.business } }; this.resources = this.user.resources; this.trustEarnedToday = b.dailyTrust.earned; this.trustCap = b.dailyTrust.cap; this.trustRemaining = b.dailyTrust.remaining; if(b.user.mentor_ready) this.isMentorQueued = true; if(b.user.mentee_waiting) this.isMenteeWaiting = true; if(b.mentorship.active){ this.user.bot_tutorial_state='DONE'; } this.trustHistory.recent = b.trust?.recent || []; this.trustHistory.totals = b.trust?.totals || { gained:0, lost:0 }; this.mentorshipRatings = b.mentorshipRatings || { asMentor:{}, asMentee:{} }; // Yeni: rank & trend this.trustRank = b.trustRank || null; this.trustTrend = (b.trustTrend && b.trustTrend.days) || []; this.updateUserDisplay(); this.updateResourcesDisplay(); this.updateMentorCard(); this.updateMentorReadyButton(); this.updateTrustEarningsDisplay(); this.renderTrustMiniHistory(); this.renderMentorRatingSummary(); this.renderTrustRank(); this.renderTrustTrend(); // Mentor self rank badge this.refreshMentorRankBadge(); } else { await this.legacyLoadUserData(); } } catch{ await this.legacyLoadUserData(); } } async legacyLoadUserData(){ const userData = localStorage.getItem('user'); const token = localStorage.getItem('jwt_token'); if (userData && token) { this.user = JSON.parse(userData); this.resources = this.user.resources || this.resources; this.updateUserDisplay(); this.updateResourcesDisplay(); await this.loadDailyTrustEarned(); this.fetchActiveMentorship(); } else { window.location.href='/login.html'; } } async loadDailyTrustEarned(force=false){ try { const token = localStorage.getItem('jwt_token'); const url = '/api/user/trust/daily-earned' + (force ? '?force=1' : ''); const r = await fetch(url,{headers:{'Authorization':'Bearer '+token}}); if(r.ok){ const j=await r.json(); this.trustEarnedToday = j.earned; this.trustCap = j.cap; this.trustRemaining = j.remaining; this.updateTrustEarningsDisplay(); } } catch(e){} } // API'den kullanıcı profilini getir (timeout ile) async fetchUserProfileWithTimeout() { try { console.log('🔄 Dashboard: API profil güncelleme deneniyor...'); const token = localStorage.getItem('jwt_token'); const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(); console.warn('⏰ Dashboard: API timeout - localStorage verisi kullanılıyor'); }, 3000); const response = await fetch('/api/user/profile', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, signal: controller.signal }); clearTimeout(timeoutId); if (response.ok) { const data = await response.json(); this.user = data.user; this.resources = data.user.resources; this.updateUserDisplay(); this.updateResourcesDisplay(); this.updateMentorCard(); // yeni console.log('✅ Dashboard: API den profil güncellendi'); } else if (response.status === 401) { localStorage.removeItem('jwt_token'); localStorage.removeItem('user'); window.location.href = '/login.html'; } } catch (error) { if (error.name === 'AbortError') { console.warn('⚠️ Dashboard: API timeout - localStorage verisi kullanılıyor'); } else { console.warn('⚠️ Dashboard: API hatası - localStorage verisi kullanılıyor:', error.message); } } } updateMentorCard() { const state = this.user?.bot_tutorial_state; const botSection = document.getElementById('bot-mentor'); const realSection = document.getElementById('real-mentor'); const mentorStatus = document.getElementById('mentor-status'); const reqBtn = document.getElementById('request-real-mentor'); const cancelBtn = document.getElementById('cancel-real-mentor'); const eligInfo = document.getElementById('mentor-eligibility-info'); if(!state || !botSection || !realSection || !mentorStatus) return; if(['INTRO','FIRST_CHAT','FIRST_CONTRACT','TRUST_LEARN'].includes(state)) { botSection.classList.remove('d-none'); realSection.classList.add('d-none'); mentorStatus.textContent = 'Bot'; mentorStatus.className = 'trust-badge trust-good'; if(reqBtn) { reqBtn.disabled=false; reqBtn.classList.remove('d-none'); } } else if(state === 'MENTOR_MATCH') { botSection.classList.remove('d-none'); realSection.classList.add('d-none'); mentorStatus.textContent = 'Eşleşme Aranıyor'; mentorStatus.className = 'trust-badge trust-medium'; if(reqBtn) reqBtn.disabled = true; if(cancelBtn) cancelBtn.classList.remove('d-none'); } else { if(cancelBtn) cancelBtn.classList.add('d-none'); } if(this.isMenteeWaiting && cancelBtn){ cancelBtn.classList.remove('d-none'); if(reqBtn) reqBtn.disabled = true; } if(eligInfo) this.loadMentorEligibility(); this.updateMentorQueues(); } async loadMentorEligibility(){ try { const r = await fetch('/api/mentor/mentor/eligibility', { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); const eligInfo = document.getElementById('mentor-eligibility-info'); const mentorSelf = document.getElementById('mentor-self-actions'); if(!eligInfo) return; if(j.eligible){ eligInfo.textContent = 'Mentor olabilirsin (Trust: '+j.trust+')'; eligInfo.className = 'mentor-eligibility ok'; if(mentorSelf) mentorSelf.classList.remove('d-none'); // Backend flag üzerinden hazır mı kontrolü this.fetchMentorFlags(); } else { if(j.reason==='low_trust') eligInfo.textContent = 'Mentor olmak için Trust '+j.trust+'/'+j.required; else if(j.reason==='already_active') eligInfo.textContent = 'Aktif mentorship var'; else eligInfo.textContent = 'Mentor olamazsın'; eligInfo.className = 'mentor-eligibility fail'; if(mentorSelf) mentorSelf.classList.add('d-none'); } } catch{} } async fetchMentorFlags(){ try { const r = await fetch('/api/user/me',{ headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); if(j.user){ this.isMentorQueued = j.user.mentor_ready === 1; this.isMenteeWaiting = j.user.mentee_waiting === 1; this.updateMentorReadyButton(); this.updateMentorCard(); } } catch{} } // API'den kullanıcı profilini getir (timeout ile) async fetchUserProfileWithTimeout() { try { console.log('🔄 Dashboard: API profil güncelleme deneniyor...'); const token = localStorage.getItem('jwt_token'); const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(); console.warn('⏰ Dashboard: API timeout - localStorage verisi kullanılıyor'); }, 3000); const response = await fetch('/api/user/profile', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, signal: controller.signal }); clearTimeout(timeoutId); if (response.ok) { const data = await response.json(); this.user = data.user; this.resources = data.user.resources; this.updateUserDisplay(); this.updateResourcesDisplay(); this.updateMentorCard(); // yeni console.log('✅ Dashboard: API den profil güncellendi'); } else if (response.status === 401) { localStorage.removeItem('jwt_token'); localStorage.removeItem('user'); window.location.href = '/login.html'; } } catch (error) { if (error.name === 'AbortError') { console.warn('⚠️ Dashboard: API timeout - localStorage verisi kullanılıyor'); } else { console.warn('⚠️ Dashboard: API hatası - localStorage verisi kullanılıyor:', error.message); } } } updateMentorCard() { const state = this.user?.bot_tutorial_state; const botSection = document.getElementById('bot-mentor'); const realSection = document.getElementById('real-mentor'); const mentorStatus = document.getElementById('mentor-status'); const reqBtn = document.getElementById('request-real-mentor'); const cancelBtn = document.getElementById('cancel-real-mentor'); const eligInfo = document.getElementById('mentor-eligibility-info'); if(!state || !botSection || !realSection || !mentorStatus) return; if(['INTRO','FIRST_CHAT','FIRST_CONTRACT','TRUST_LEARN'].includes(state)) { botSection.classList.remove('d-none'); realSection.classList.add('d-none'); mentorStatus.textContent = 'Bot'; mentorStatus.className = 'trust-badge trust-good'; if(reqBtn) { reqBtn.disabled=false; reqBtn.classList.remove('d-none'); } } else if(state === 'MENTOR_MATCH') { botSection.classList.remove('d-none'); realSection.classList.add('d-none'); mentorStatus.textContent = 'Eşleşme Aranıyor'; mentorStatus.className = 'trust-badge trust-medium'; if(reqBtn) reqBtn.disabled = true; if(cancelBtn) cancelBtn.classList.remove('d-none'); } else { if(cancelBtn) cancelBtn.classList.add('d-none'); } if(this.isMenteeWaiting && cancelBtn){ cancelBtn.classList.remove('d-none'); if(reqBtn) reqBtn.disabled = true; } if(eligInfo) this.loadMentorEligibility(); this.updateMentorQueues(); } async loadMentorEligibility(){ try { const r = await fetch('/api/mentor/mentor/eligibility', { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); const eligInfo = document.getElementById('mentor-eligibility-info'); const mentorSelf = document.getElementById('mentor-self-actions'); if(!eligInfo) return; if(j.eligible){ eligInfo.textContent = 'Mentor olabilirsin (Trust: '+j.trust+')'; eligInfo.className = 'mentor-eligibility ok'; if(mentorSelf) mentorSelf.classList.remove('d-none'); // Backend flag üzerinden hazır mı kontrolü this.fetchMentorFlags(); } else { if(j.reason==='low_trust') eligInfo.textContent = 'Mentor olmak için Trust '+j.trust+'/'+j.required; else if(j.reason==='already_active') eligInfo.textContent = 'Aktif mentorship var'; else eligInfo.textContent = 'Mentor olamazsın'; eligInfo.className = 'mentor-eligibility fail'; if(mentorSelf) mentorSelf.classList.add('d-none'); } } catch{} } async fetchMentorFlags(){ try { const r = await fetch('/api/user/me',{ headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); if(j.user){ this.isMentorQueued = j.user.mentor_ready === 1; this.isMenteeWaiting = j.user.mentee_waiting === 1; this.updateMentorReadyButton(); this.updateMentorCard(); } } catch{} } // Mentor rank fetch async fetchSelfMentorRank(minSessions=this.mentorLbMinSessions){ try { const r = await fetch(`/api/user/leaderboard?category=mentor&self=1&limit=0&minSessions=${encodeURIComponent(minSessions)}`, { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return null; const j = await r.json(); return j.selfRank || null; } catch { return null; } } openMentorRankModal(){ this.loadMentorRank(); const m=document.getElementById('mentor-rank-modal'); if(m) m.classList.remove('d-none'); } closeMentorRankModal(){ const m=document.getElementById('mentor-rank-modal'); if(m) m.classList.add('d-none'); } async loadMentorRank(){ const box = document.getElementById('mentor-rank-box'); if(box) box.textContent='Yükleniyor...'; const data = await this.fetchSelfMentorRank(); if(!box) return; if(!data){ box.textContent='Hata'; return; } if(!data.ranked){ if(data.reason==='min_sessions') box.innerHTML = `Henüz sıralamada değilsin. Minimum ${data.minSessions} oturum gerek. (Sen: ${data.sessions})`; else if(data.reason==='no_rating') box.innerHTML = 'Henüz rating verisi yok.'; else box.innerHTML = 'Sıralama verisi yok.'; this.updateMentorRankBadge(null); return; } box.innerHTML = `
Rank: #${data.rank} / ${data.total}
Percentile: %${data.percentile}
Oturum: ${data.sessions}
Ortalama Puan: ⭐ ${data.avg_rating}
Filtre: >=${data.minSessions} oturum
`; this.updateMentorRankBadge(data); } // Event listener'ları ayarla setupEventListeners() { // Action buttons const chopWoodBtn = document.getElementById('chop-wood'); const farmGrainBtn = document.getElementById('farm-grain'); if (chopWoodBtn) { chopWoodBtn.addEventListener('click', () => this.performAction('chop-wood')); } if (farmGrainBtn) { farmGrainBtn.addEventListener('click', () => this.performAction('farm')); } // Resource items - click for details const resourceItems = document.querySelectorAll('.resource-item'); resourceItems.forEach(item => { item.addEventListener('click', () => { const resourceType = item.dataset.resource; this.showResourceDetails(resourceType); }); }); // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key === 'c' && e.ctrlKey) { e.preventDefault(); window.location.href = '/chat.html'; } }); // Pull to refresh (mobile) let startY = 0; let currentY = 0; let isRefreshing = false; document.addEventListener('touchstart', (e) => { if (window.scrollY === 0) { startY = e.touches[0].clientY; } }); document.addEventListener('touchmove', (e) => { if (window.scrollY === 0 && !isRefreshing) { currentY = e.touches[0].clientY; const difference = currentY - startY; if (difference > 100) { isRefreshing = true; this.refreshData(); } } }); } // Socket bağlantısı kur connectSocket() { if (typeof io !== 'undefined') { try { this.socket = io({ timeout: 5000, transports: ['websocket', 'polling'] }); this.socket.on('connect', () => { console.log('🔌 Dashboard socket bağlandı'); this.socket.emit('join_chat', { userId: this.user?.id, token: localStorage.getItem('jwt_token') }); }); this.socket.on('disconnect', () => { console.log('🔌 Dashboard socket bağlantısı kesildi'); }); this.socket.on('connect_error', (error) => { console.warn('⚠️ Dashboard socket bağlantı hatası:', error); this.simulateSocketEvents(); }); this.socket.on('online_count_updated', (count) => { this.updateOnlineCount(count); }); this.socket.on('new_message', (message) => { this.handleNewMessage(message); }); this.socket.on('resource_updated', (data) => { if (data.userId === this.user?.id) { this.resources = data.resources; this.updateResourcesDisplay(); this.showSuccess('Kaynak güncellendi'); } }); // Yeni: trust güncelleme this.socket.on('trust_updated', (data) => { if (this.user && data.id === this.user.id) { this.user.trustScore = data.trust_score; this.updateUserDisplay(); this.showSuccess('Güven puanın güncellendi: ' + data.trust_score); } }); // Yeni: contract created this.socket.on('contract_created', (c) => { this.showContractToast('Yeni kontrat #' + c.id + ' (' + c.status + ')'); }); // Yeni: contract updated this.socket.on('contract_updated', (c) => { this.showContractToast('Kontrat #' + c.id + ' durum: ' + c.status); if(c.status==='COMPLETED'){ // Lokal tahmini + server force sync this.trustEarnedToday += 2; this.updateTrustEarningsDisplay(); this.genericToast('+2 İtibar (Kontrat)', 'contract'); this.loadDailyTrustEarned(true); // force senkron } }); // Yeni: tutorial ilerleme this.socket.on('tutorial_progress', (p) => { if (this.user && p.userId === this.user.id) { this.showTutorialToast('Tutorial ilerledi: ' + p.state); if (!this.user.bot_tutorial_state || this.user.bot_tutorial_state !== p.state) { this.user.bot_tutorial_state = p.state; this.updateMentorCard(); } } }); // Yeni: mentor atama this.socket.on('mentor_assigned', (data) => { if(this.user && (data.menteeId === this.user.id || data.mentorId === this.user.id)) { if(data.menteeId === this.user.id){ this.user.bot_tutorial_state = 'DONE'; this.isMenteeWaiting = false; // reset this.updateMentorCard(); const name = data.mentorUsername ? ('Mentor: '+data.mentorUsername) : ('Mentor #' + data.mentorId); this.genericToast('Mentor atandı! '+name,'mentor'); this.fetchActiveMentorship(); this.fetchMentorFlags(); } else if(data.mentorId === this.user.id){ this.isMentorQueued = false; // mentor artık aktif const name = data.menteeUsername ? ('Mentee: '+data.menteeUsername) : ('Mentee #' + data.menteeId); this.genericToast('Yeni mentee eşleşti! '+name,'mentor'); this.fetchActiveMentorship(); this.fetchMentorFlags(); } } }); // Yeni: mentorluk tamamlandı -> leaderboard & self rank refresh let _mentorLbRefreshTimer=null; const scheduleMentorLbRefresh = ()=>{ if(_mentorLbRefreshTimer) return; _mentorLbRefreshTimer = setTimeout(()=>{ _mentorLbRefreshTimer=null; try { if(this.lbCategory==='mentor') this.loadLeaderboard(); } catch{} try { this.fetchSelfMentorRank && this.fetchSelfMentorRank(); } catch{} }, 1200); }; this.socket.on('mentorship_completed', (m)=>{ if(!m) return; // Her iki taraf için güncelleme anlamlı if(this.user && (m.mentor_id===this.user.id || m.mentee_id===this.user.id)){ this.genericToast('Mentorluk tamamlandı (#'+m.id+')','mentor'); scheduleMentorLbRefresh(); this.refreshMentorRankBadge(); } }); // Timeout ekle - 5 saniye içinde bağlanamazsa simüle et setTimeout(() => { if (!this.socket.connected) { console.warn('⚠️ Dashboard socket timeout - simülasyon moduna geçiliyor'); this.simulateSocketEvents(); } }, 5000); } catch (error) { console.error('Dashboard socket hatası:', error); this.simulateSocketEvents(); } } else { console.warn('⚠️ Socket.io bulunamadı - simülasyon modu'); this.simulateSocketEvents(); } } // Socket olaylarını simüle et simulateSocketEvents() { console.log('🤖 Dashboard simülasyon modu aktif'); // Online count simülasyonu setInterval(() => { const count = 1100 + Math.floor(Math.random() * 200); this.updateOnlineCount(count); }, 30000); // Resource update simülasyonu setInterval(() => { this.resources.money += Math.floor(Math.random() * 10); this.updateResourcesDisplay(); }, 60000); } // Karşılama mesajını güncelle updateGreeting() { const hour = new Date().getHours(); let greeting = 'Merhaba'; if (hour < 6) greeting = 'İyi geceler'; else if (hour < 12) greeting = 'Günaydın'; else if (hour < 18) greeting = 'İyi günler'; else greeting = 'İyi akşamlar'; const greetingEl = document.getElementById('greeting'); if (greetingEl) { greetingEl.textContent = greeting; } // Welcome time message const welcomeTimeEl = document.getElementById('welcome-time'); if (welcomeTimeEl) { const messages = [ 'Bugün harika bir gün! Ticaret yapmaya hazır mısın?', 'Yeni fırsatlar seni bekliyor! Hadi başlayalım!', 'Mentorlardan tavsiye almayı unutma!', 'Chat\'te diğer oyuncularla sohbet edebilirsin!' ]; const randomMessage = messages[Math.floor(Math.random() * messages.length)]; welcomeTimeEl.textContent = randomMessage; } } // Kullanıcı bilgilerini göster updateUserDisplay() { console.log('👤 Dashboard: Kullanıcı bilgileri güncelleniyor:', this.user); const userNameEl = document.getElementById('user-name'); const userTrustEl = document.getElementById('user-trust'); if (userNameEl) { const displayName = this.user?.displayName || this.user?.name || 'Oyuncu'; userNameEl.textContent = displayName; console.log('✅ Dashboard: Kullanıcı adı güncellendi:', displayName); } if (userTrustEl) { const trustScore = this.user?.trustScore || 100; userTrustEl.textContent = trustScore; userTrustEl.className = `stat-value ${this.getTrustClass(trustScore)}`; console.log('✅ Dashboard: Trust score güncellendi:', trustScore); } // User initial for avatar const userInitial = document.getElementById('user-initial'); if (userInitial) { const name = this.user?.displayName || this.user?.name || 'O'; userInitial.textContent = name.charAt(0).toUpperCase(); console.log('✅ Dashboard: Avatar initial güncellendi:', name.charAt(0)); } this.updateTrustEarningsDisplay(); } // Kaynakları güncelle updateResourcesDisplay() { console.log('💰 Dashboard: Kaynaklar güncelleniyor:', this.resources); const moneyEl = document.getElementById('money'); const woodEl = document.getElementById('wood'); const grainEl = document.getElementById('grain'); const businessEl = document.getElementById('business'); if (moneyEl) { moneyEl.textContent = `${this.resources.money} TL`; console.log('✅ Dashboard: Para güncellendi:', this.resources.money); } if (woodEl) { woodEl.textContent = this.resources.wood; console.log('✅ Dashboard: Odun güncellendi:', this.resources.wood); } if (grainEl) { grainEl.textContent = this.resources.grain; console.log('✅ Dashboard: Buğday güncellendi:', this.resources.grain); } if (businessEl) { businessEl.textContent = this.resources.business; console.log('✅ Dashboard: İş güncellendi:', this.resources.business); } // Update daily goal progress this.updateGoalProgress(); } // Günlük hedef ilerlemesini güncelle updateGoalProgress() { const progressEl = document.getElementById('goal-progress'); const progressTextEl = document.getElementById('goal-progress-text'); const goalStatusEl = document.getElementById('goal-status'); if (progressEl && progressTextEl) { const current = this.resources.money; const target = this.goals.daily.target; const percentage = Math.min((current / target) * 100, 100); progressEl.style.width = `${percentage}%`; progressTextEl.textContent = `${current}/${target} TL (${Math.round(percentage)}%)`; if (goalStatusEl) { goalStatusEl.textContent = `${Math.round(percentage)}%`; goalStatusEl.className = `trust-badge ${this.getGoalClass(percentage)}`; } } } // Online kullanıcı sayısını güncelle updateOnlineCount(count) { const onlineCountEls = document.querySelectorAll('#online-count'); onlineCountEls.forEach(el => { el.textContent = `${count} kişi online`; }); } // Yeni mesaj geldiğinde handleNewMessage(message) { // Chat notification badge'ini güncelle const notificationEls = document.querySelectorAll('#chat-notification, #fab-chat-notification'); notificationEls.forEach(el => { el.classList.remove('d-none'); const currentCount = parseInt(el.textContent) || 0; el.textContent = currentCount + 1; }); // Sesli bildirim (eğer kullanıcı izin verdiyse) this.playNotificationSound(); } // Aktivite gerçekleştir async performAction(action) { if (this.isLoading) return; this.isLoading = true; this.showLoading(true); try { const token = localStorage.getItem('jwt_token'); const response = await fetch(`/api/activity/${action}`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); const data = await response.json(); if (data.success) { // Kaynakları güncelle this.resources = { ...this.resources, ...data.result }; this.updateResourcesDisplay(); // Başarı mesajı göster const messages = { 'chop-wood': `🪓 ${data.result.woodGained} odun kazandın!`, 'farm': `🌾 ${data.result.grainGained} tahıl kazandın!` }; this.showSuccess(messages[action] || 'İşlem başarılı!'); // Kaynak değişim animasyonu this.animateResourceChange(action, data.result); } else { this.showError(data.error || 'İşlem başarısız'); } } catch (error) { console.error('Aktivite hatası:', error); this.showError('Bağlantı hatası oluştu'); } finally { this.isLoading = false; this.showLoading(false); } } // Kaynak değişim animasyonu animateResourceChange(action, result) { const resourceType = action === 'chop-wood' ? 'wood' : 'grain'; const resourceEl = document.querySelector(`[data-resource="${resourceType}"]`); if (resourceEl) { resourceEl.classList.add('animate-bounce'); setTimeout(() => { resourceEl.classList.remove('animate-bounce'); }, 1000); } } // Verileri yenile async refreshData() { try { await this.fetchUserProfile(); this.showSuccess('Veriler güncellendi!'); } catch (error) { this.showError('Güncelleme başarısız'); } } // Periyodik güncellemeler startPeriodicUpdates() { // Her 30 saniyede bir online sayısını güncelle setInterval(() => { if (this.socket && this.socket.connected) { this.socket.emit('get_online_count'); } }, 30000); // Her 5 dakikada bir kullanıcı verilerini güncelle setInterval(() => { this.fetchUserProfile(); }, 300000); // Günlük reset kontrolü (her 60 sn) setInterval(()=>{ const now = new Date(); if(!this._lastDay){ this._lastDay = now.getDate(); } if(this._lastDay !== now.getDate()){ this._lastDay = now.getDate(); this.trustEarnedToday = 0; this.updateTrustEarningsDisplay(); this.loadDailyTrustEarned(); } },60000); // Günlük trust periyodik senkron (her 30sn cache hit, 5. dakikada force) let counter=0; setInterval(()=>{ counter++; const force = (counter % 10 === 0); // ~5 dakikada bir force (30s *10) this.loadDailyTrustEarned(force); },30000); // Mentor queue sayıları (her 40sn) setInterval(()=>{ this.updateMentorQueues(); }, 40000); } // Bildirimler ayarla setupNotifications() { // Tarayıcı bildirimi izni iste if ('Notification' in window && Notification.permission === 'default') { Notification.requestPermission(); } } // Bildirim sesi çal playNotificationSound() { try { const audio = new Audio('/assets/sounds/notification.mp3'); audio.volume = 0.3; audio.play().catch(() => { // Ses çalma başarısız (otomatik oynatma engeli) console.log('Bildirim sesi çalınamadı'); }); } catch (error) { console.log('Ses dosyası bulunamadı'); } } // Güven puanı sınıfını al getTrustClass(score) { if (score >= 180) return 'trust-excellent'; if (score >= 160) return 'trust-good'; if (score >= 140) return 'trust-medium'; if (score >= 120) return 'trust-low'; return 'trust-bad'; } // Hedef durumu sınıfını al getGoalClass(percentage) { if (percentage >= 100) return 'trust-excellent'; if (percentage >= 75) return 'trust-good'; if (percentage >= 50) return 'trust-medium'; if (percentage >= 25) return 'trust-low'; return 'trust-bad'; } // Loading state'lerini gizle (sayfa başlangıcında) hideLoadingStates() { console.log('🎯 Dashboard: Loading state\'leri gizleniyor...'); // Tüm loading elementlerini gizle const loadingElements = [ 'loading-overlay', 'page-loading', 'user-loading', 'resources-loading' ]; loadingElements.forEach(id => { const el = document.getElementById(id); if (el) { el.classList.add('d-none'); el.style.display = 'none'; console.log(`✅ Loading element gizlendi: ${id}`); } }); // Loading sınıflarını kaldır document.body.classList.remove('loading'); document.documentElement.classList.remove('loading'); // Ana içeriği göster const mainContent = document.querySelector('.main-content, .mobile-container, main'); if (mainContent) { mainContent.style.visibility = 'visible'; mainContent.style.opacity = '1'; console.log('✅ Ana içerik görünür yapıldı'); } } // Loading göster/gizle showLoading(show) { const loadingEl = document.getElementById('loading-overlay'); if (loadingEl) { loadingEl.classList.toggle('d-none', !show); } } // Başarı mesajı göster showSuccess(message) { const toastEl = document.getElementById('success-toast'); if (toastEl) { const messageEl = toastEl.querySelector('.toast-message'); if (messageEl) messageEl.textContent = message; toastEl.classList.remove('d-none'); setTimeout(() => { toastEl.classList.add('d-none'); }, 3000); } } // Hata mesajı göster showError(message) { const toastEl = document.getElementById('error-toast'); if (toastEl) { const messageEl = toastEl.querySelector('.toast-message'); if (messageEl) messageEl.textContent = message; toastEl.classList.remove('d-none'); setTimeout(() => { toastEl.classList.add('d-none'); }, 3000); } } // Kaynak detaylarını göster showResourceDetails(resourceType) { const details = { money: 'Para: Ticaret yapmak ve işletme kurmak için gerekli', wood: 'Odun: Odun kesme aktivitesi ile kazanabilirsin', grain: 'Tahıl: Çiftçilik aktivitesi ile kazanabilirsin', business: 'İşletme: Pasif gelir sağlayan yatırımlar' }; const message = details[resourceType] || 'Kaynak bilgisi bulunamadı'; alert(message); } showContractToast(text){ this.genericToast(text, 'contract'); } showTutorialToast(text){ this.genericToast(text, 'tutorial'); } genericToast(message, type='info'){ let container = document.getElementById('toast-container'); if(!container){ container = document.createElement('div'); container.id = 'toast-container'; container.style.position='fixed'; container.style.top='10px'; container.style.right='10px'; container.style.zIndex='9999'; document.body.appendChild(container); } const el = document.createElement('div'); el.textContent = message; el.style.background = type==='tutorial' ? '#4b6ef5' : (type==='contract' ? '#16a34a' : '#333'); el.style.color = '#fff'; el.style.padding = '8px 12px'; el.style.marginTop = '6px'; el.style.borderRadius = '6px'; el.style.fontSize = '14px'; el.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)'; el.style.opacity='0'; el.style.transition='opacity .3s'; container.appendChild(el); requestAnimationFrame(()=>{ el.style.opacity='1'; }); setTimeout(()=>{ el.style.opacity='0'; setTimeout(()=> el.remove(), 400); }, 4000); } updateTrustEarningsDisplay(){ const el = document.getElementById('trust-earned-today'); if(el){ const earned = this.trustEarnedToday||0; const cap = this.trustCap||40; el.textContent = '+'+earned; const ratio = earned / cap; el.classList.remove('trust-excellent','trust-good','trust-medium','trust-low','trust-bad'); if(ratio >= 1){ el.classList.add('trust-bad'); } else if(ratio >= 0.85){ el.classList.add('trust-low'); } else if(ratio >= 0.6){ el.classList.add('trust-medium'); } else if(ratio >= 0.3){ el.classList.add('trust-good'); } else { el.classList.add('trust-excellent'); } el.title = `Günlük ödül: ${earned}/${cap} (kalan ${Math.max(0, cap-earned)})`; } } async fetchActiveMentorship(){ try { const r = await fetch('/api/mentor/active', { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(r.ok){ const j = await r.json(); if(j.active){ const realSection = document.getElementById('real-mentor'); const botSection = document.getElementById('bot-mentor'); const mentorStatus = document.getElementById('mentor-status'); if(realSection && botSection && mentorStatus){ botSection.classList.add('d-none'); realSection.classList.remove('d-none'); mentorStatus.textContent = 'Aktif'; mentorStatus.className = 'trust-badge trust-excellent'; const nameEl = document.getElementById('mentor-name'); const descEl = document.getElementById('mentor-description'); if(nameEl) nameEl.textContent = j.mentorship.mentor_username || ('Mentor #' + j.mentorship.mentor_id); if(descEl) descEl.textContent = 'Mentor-ID: '+ j.mentorship.mentor_id + ' | Mentee-ID: ' + j.mentorship.mentee_id; } } } } catch(e){} } async updateMentorQueues(){ try { const r = await fetch('/api/mentor/queues',{ headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); const el = document.getElementById('mentor-queue-counts'); if(el){ el.textContent = 'Kuyruk: '+(j.counts?.mentors||0)+' mentor / '+(j.counts?.mentees||0)+' mentee'; } } catch{} } async toggleMentorReady(){ if(this.isMentorQueued){ try { const r = await fetch('/api/mentor/mentor/leave',{method:'POST', headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(r.ok){ this.isMentorQueued=false; this.genericToast('Mentor kuyruğundan çıktın','mentor'); this.updateMentorReadyButton(); } } catch{} } else { try { const r = await fetch('/api/mentor/mentor/ready',{method:'POST', headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); const j = await r.json().catch(()=>({})); if(r.ok && j.ok){ this.isMentorQueued=true; this.genericToast('Mentor olarak hazırsın','mentor'); this.updateMentorReadyButton(); } else { this.showError('Mentor olamadı: '+(j.reason||j.error||'hata')); } } catch{ this.showError('Bağlantı hatası'); } } } updateMentorReadyButton(){ const btn = document.getElementById('mentor-ready-btn'); if(!btn) return; if(this.isMentorQueued){ btn.textContent = '🛑 Mentor Modu Kapat'; btn.classList.remove('btn-outline'); btn.classList.add('btn-danger'); } else { btn.textContent = '✅ Mentor Modu Aç'; btn.classList.add('btn-outline'); btn.classList.remove('btn-danger'); } } async requestRealMentor(){ if(this.isMenteeWaiting){ return; } try { const r = await fetch('/api/mentor/mentor/request',{ method:'POST', headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(r.ok){ const j = await r.json(); if(j.queued){ this.isMenteeWaiting = true; this.genericToast('Gerçek mentor aranıyor...','mentor'); this.user.bot_tutorial_state='MENTOR_MATCH'; this.updateMentorCard(); } } else { const e = await r.json().catch(()=>({})); this.showError('Mentor isteği başarısız: '+(e.reason||e.error||'hata')); } } catch{ this.showError('Bağlantı hatası'); } } async cancelRealMentor(){ if(!this.isMenteeWaiting) return; try { const r = await fetch('/api/mentor/mentee/toggle',{ method:'POST', headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token'),'Content-Type':'application/json'}, body: JSON.stringify({ waiting:false }) }); if(r.ok){ this.isMenteeWaiting = false; this.genericToast('Mentor arama iptal edildi','mentor'); const cancelBtn=document.getElementById('cancel-real-mentor'); if(cancelBtn) cancelBtn.classList.add('d-none'); const reqBtn=document.getElementById('request-real-mentor'); if(reqBtn) { reqBtn.disabled=false; } } } catch{} } renderTrustMiniHistory(){ const wrapId = 'trust-mini-history'; let wrap = document.getElementById(wrapId); if(!wrap){ wrap = document.createElement('div'); wrap.id = wrapId; wrap.style.marginTop = '12px'; const statsCard = document.querySelector('.stats-grid')?.parentElement; if(statsCard){ statsCard.appendChild(wrap); } } if(!wrap) return; const gained = this.trustHistory.totals.gained||0; const lost = this.trustHistory.totals.lost||0; wrap.innerHTML = `
Trust Kazanç: +${gained} Trust Kayıp: -${lost} Son Olaylar: ${this.trustHistory.recent.map(r=>`${r.delta>0?'+':''}${r.delta} (${r.reason})`).join('') || 'kayıt yok'}
`; if(!wrap.querySelector('.trust-history-btn')){ const btn = document.createElement('button'); btn.textContent = 'Detaylı'; btn.className = 'trust-history-btn'; btn.style.cssText = 'margin-left:auto;background:#263238;border:1px solid #444;color:#fff;padding:4px 8px;border-radius:6px;font-size:11px;cursor:pointer;'; btn.onclick = ()=> this.openTrustHistory(); wrap.appendChild(btn); } } async openTrustHistory(){ if(!this._trustModal){ const m = document.createElement('div'); m.id='trust-modal'; m.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;z-index:9999;'; m.innerHTML=`

Trust Geçmişi

Yükleniyor...
`; document.body.appendChild(m); this._trustModal = m; m.addEventListener('click', e=>{ if(e.target===m) this.closeTrustHistory(); }); m.querySelector('#trust-close').onclick = ()=> this.closeTrustHistory(); m.querySelector('#trust-prev').onclick = ()=> { if(this._trustOffset>0){ this._trustOffset -= this._trustLimit; this.loadTrustHistory(); } }; m.querySelector('#trust-next').onclick = ()=> { if(this._trustOffset + this._trustLimit < (this._trustTotal||0)){ this._trustOffset += this._trustLimit; this.loadTrustHistory(); } }; this._trustLimit = 20; this._trustOffset = 0; this._trustTotal = 0; } this._trustModal.style.display='flex'; this.loadTrustHistory(); } closeTrustHistory(){ if(this._trustModal) this._trustModal.style.display='none'; } async loadTrustHistory(){ try { const list = document.getElementById('trust-history-list'); if(list) list.textContent='Yükleniyor...'; const r = await fetch(`/api/user/trust/history?limit=${this._trustLimit}&offset=${this._trustOffset}`, { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(r.ok){ const j = await r.json(); this._trustTotal = j.total; if(list){ if(!j.events.length){ list.innerHTML='Kayıt yok'; } else { list.innerHTML = j.events.map(ev=>`
${ev.delta>0?'+':''}${ev.delta} ${ev.reason} ${ev.created_at}
`).join(''); } } } else { if(list) list.textContent='Hata'; } } catch(e){ const list = document.getElementById('trust-history-list'); if(list) list.textContent='Hata'; } } openMentorshipCompleteModal(){ if(!this.activeMentorshipId) return; const m=document.getElementById('mentorship-complete-modal'); if(m) m.classList.remove('d-none'); } closeMentorshipCompleteModal(){ const m=document.getElementById('mentorship-complete-modal'); if(m) m.classList.add('d-none'); } async submitMentorshipCompletion(){ if(!this.activeMentorshipId) return; const body={}; const mrEl=document.getElementById('mentor-rating-input'); const meEl=document.getElementById('mentee-rating-input'); const mr=Number(mrEl?.value)||0; if(mr>=1&&mr<=5) body.mentor_rating=mr; const me=Number(meEl?.value)||0; if(me>=1&&me<=5) body.mentee_rating=me; try { const r=await fetch(`/api/mentor/mentorship/${this.activeMentorshipId}/complete`, { method:'POST', headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token'),'Content-Type':'application/json'}, body: JSON.stringify(body)}); const j=await r.json().catch(()=>({})); if(r.ok){ this.genericToast('Mentorluk tamamlandı','mentor'); this.closeMentorshipCompleteModal(); this.activeMentorshipId=null; const sess=document.getElementById('mentor-session-actions'); if(sess) sess.style.display='none'; this.fetchMentorFlags(); } else { this.showError('Tamamlama hata: '+(j.error||'bilinmeyen')); } } catch { this.showError('Bağlantı hatası'); } } renderMentorRatingSummary(){ const el = document.getElementById('mentor-rating-summary'); if(!el || !this.mentorshipRatings) return; const m = this.mentorshipRatings.asMentor || { count:0, avg_rating:null }; const me = this.mentorshipRatings.asMentee || { count:0, avg_rating:null }; el.textContent = `Mentor: ${m.count||0} oturum${m.avg_rating? ' (⭐'+m.avg_rating+')':''} • Mentee: ${me.count||0}${me.avg_rating? ' (⭐'+me.avg_rating+')':''}`; } // Mentorluk geçmişi modal openMentorshipHistory(){ this.mhOffset=0; this.loadMentorshipHistory(); const modal=document.getElementById('mentorship-history-modal'); if(modal) modal.classList.remove('d-none'); } closeMentorshipHistory(){ const modal=document.getElementById('mentorship-history-modal'); if(modal) modal.classList.add('d-none'); } async loadMentorshipHistory(){ try { const limit=10; const r=await fetch(`/api/user/mentorship/history?limit=${limit}&offset=${this.mhOffset||0}`, { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j=await r.json(); const list=document.getElementById('mentorship-history-list'); if(!list) return; list.innerHTML=''; if(!j.mentorships.length){ list.innerHTML='
Kayıt yok
'; } j.mentorships.forEach(m=>{ const div=document.createElement('div'); div.style.background='#26262b'; div.style.padding='8px 10px'; div.style.borderRadius='8px'; const youAre = m.role==='mentor' ? 'Mentor' : 'Mentee'; const otherId = m.role==='mentor' ? m.mentee_id : m.mentor_id; const rating = m.role==='mentor' ? (m.mentee_rating? '⭐'+m.mentee_rating : '-') : (m.mentor_rating? '⭐'+m.mentor_rating : '-'); div.innerHTML = `${youAre} • Diğer: #${otherId} • Puan: ${rating}
${m.created_at.split('T')[0]} → ${(m.ended_at||'').split('T')[0] || '—'}`; list.appendChild(div); }); const pageInfo=document.getElementById('mh-page-info'); const prev=document.getElementById('mh-prev'); const next=document.getElementById('mh-next'); const page = Math.floor((this.mhOffset||0)/limit)+1; const totalPages = Math.max(1, Math.ceil(j.total/limit)); if(pageInfo) pageInfo.textContent = page + '/' + totalPages; if(prev) prev.disabled = page<=1; if(next) next.disabled = page>=totalPages; prev&&prev.addEventListener('click', ()=>{ if(this.mhOffset>=limit){ this.mhOffset-=limit; this.loadMentorshipHistory(); } }); next&&next.addEventListener('click', ()=>{ if(this.mhOffset+limit=${this.mentorLbMinSessions} oturum)`; listEl.appendChild(info); } if(!(j.list||[]).length){ listEl.innerHTML+='
Kayıt yok
'; return; } j.list.forEach((u,i)=>{ const div=document.createElement('div'); div.style.background='#26262b'; div.style.padding='6px 10px'; div.style.borderRadius='8px'; div.style.display='flex'; div.style.justifyContent='space-between'; div.style.fontSize='13px'; div.innerHTML = `#${i+1} ${u.username||('U'+u.id)}${u.sessions} oturum⭐ ${u.avg_rating||'-'}`; listEl.appendChild(div); }); const rankEl=document.getElementById('leaderboard-user-rank'); if(rankEl) rankEl.textContent=''; return; } // trust leaderboard const around = this.lbMode==='around' ? '1':'0'; const r = await fetch(`/api/user/leaderboard?category=trust&limit=15&around=${around}&window=3`, { headers:{'Authorization':'Bearer '+localStorage.getItem('jwt_token')} }); if(!r.ok) return; const j = await r.json(); const rankEl = document.getElementById('leaderboard-user-rank'); if(!listEl) return; listEl.innerHTML=''; if(rankEl && !j.around){ rankEl.textContent = j.userRank ? ('SIRAN: #' + j.userRank) : ''; } if(j.around && rankEl){ rankEl.textContent = j.userRank ? ('Çevre Sıra: #' + j.userRank) : ''; } (j.list||[]).forEach((u,i)=>{ const div=document.createElement('div'); const rank = u.r || (i+1); // around modda r var const highlight = (u.id === this.user.id); div.style.background = highlight ? '#274054' : '#26262b'; div.style.padding='6px 10px'; div.style.borderRadius='8px'; div.style.display='flex'; div.style.justifyContent='space-between'; div.innerHTML = `#${rank} ${u.username}${u.trust_score}`; listEl.appendChild(div); }); } catch{} } // Yeni: Trust Rank gösterimi renderTrustRank(){ const line = document.getElementById('trust-rank-line'); if(!line || !this.trustRank) return; const { rank, total, percentile } = this.trustRank; line.textContent = `Sıra: #${rank}/${total} • Yüzdelik: ${percentile}%`; } // Yeni: Trust Trend sparkline renderTrustTrend(){ const wrap = document.getElementById('trust-trend-spark'); if(!wrap) return; const data = this.trustTrend || []; if(!data.length){ wrap.innerHTML = 'Trend yok'; return; } const values = data.map(d=>d.total); const min = Math.min(...values, 0); const max = Math.max(...values, 1); const W = Math.max(120, data.length * 18); const H = 28; const pad = 2; const scaleX = (i)=> pad + (i/(data.length-1))*(W-2*pad); const scaleY = (v)=> { if(max===min) return H/2; // flat line return H - pad - ((v - min)/(max - min))*(H-2*pad); }; let path = ''; data.forEach((d,i)=>{ const x = scaleX(i).toFixed(2); const y = scaleY(d.total).toFixed(2); path += (i===0?`M${x},${y}`:` L${x},${y}`); }); const areaPath = path + ` L${scaleX(data.length-1).toFixed(2)},${H-pad} L${scaleX(0).toFixed(2)},${H-pad} Z`; const last = data[data.length-1]; const diff = last.total - data[0].total; const color = diff>0 ? '#4CAF50' : (diff<0 ? '#F44336' : '#FFC107'); wrap.innerHTML = ` `; wrap.title = data.map(d=>`${d.day}: ${d.total}`).join('\n'); } } // Global fonksiyonlar (HTML'den çağrılabilir) window.dashboard = null; window.requestRealMentor = function(){ if(window.dashboard) window.dashboard.requestRealMentor(); }; window.toggleMentorReady = function(){ if(window.dashboard) window.dashboard.toggleMentorReady(); }; window.cancelRealMentor = function(){ if(window.dashboard) window.dashboard.cancelRealMentor(); }; window.openMentorshipCompleteModal=()=>window.dashboard&&window.dashboard.openMentorshipCompleteModal(); window.closeMentorshipCompleteModal=()=>window.dashboard&&window.dashboard.closeMentorshipCompleteModal(); window.submitMentorshipCompletion=()=>window.dashboard&&window.dashboard.submitMentorshipCompletion(); window.openMentorshipHistory=()=>window.dashboard&&window.dashboard.openMentorshipHistory(); window.closeMentorshipHistory=()=>window.dashboard&&window.dashboard.closeMentorshipHistory(); window.openLeaderboard=()=>window.dashboard&&window.dashboard.openLeaderboard(); window.closeLeaderboard=()=>window.dashboard&&window.dashboard.closeLeaderboard(); window.setLeaderboardMode=(m)=>window.dashboard&&window.dashboard.setLeaderboardMode(m); window.setLeaderboardCategory=(c)=>window.dashboard&&window.dashboard.setLeaderboardCategory(c); window.openMentorRankModal=()=>window.dashboard&&window.dashboard.openMentorRankModal(); window.closeMentorRankModal=()=>window.dashboard&&window.dashboard.closeMentorRankModal(); // Kaynakları yenile function refreshResources() { if (window.dashboard) { window.dashboard.refreshData(); } } // Aktivite gerçekleştir function performAction(action) { if (window.dashboard) { window.dashboard.performAction(action); } } // Chat'e git function goToChat() { window.location.href = '/chat.html'; } // Bot ile sohbet başlat function openChatWithBot() { localStorage.setItem('chat_target', 'bot'); window.location.href = '/chat.html'; } // Mentor ipuçlarını göster function showMentorTips() { const tips = [ '💡 İlk önce odun kesip para biriktir', '🤝 Güven puanı yüksek oyuncularla ticaret yap', '💬 Chat\'te aktif ol, fırsatları kaçırma', '📊 Günlük hedeflerini tamamlamaya odaklan', '👥 Mentor bul, deneyimli oyunculardan öğren' ]; const randomTip = tips[Math.floor(Math.random() * tips.length)]; alert(randomTip); } // Mentor ile iletişime geç function contactMentor() { window.location.href = '/chat.html?mentor=true'; } // Mentor profilini görüntüle function viewMentorProfile() { window.location.href = '/profile.html?view=mentor'; } // Detaylı istatistikleri göster function showDetailedStats() { window.location.href = '/stats.html'; } // Bildirimi kapat function dismissNotification(element) { const notificationCard = element.closest('.notification-card'); if (notificationCard) { notificationCard.style.animation = 'slideOutRight 0.3s ease'; setTimeout(() => { notificationCard.remove(); }, 300); } } // Sayfa yüklendiğinde dashboard'u başlat document.addEventListener('DOMContentLoaded', () => { window.dashboard = new Dashboard(); }); // Visibility change event - sayfa görünür olduğunda verileri güncelle document.addEventListener('visibilitychange', () => { if (!document.hidden && window.dashboard) { window.dashboard.refreshData(); } }); // Online/offline durumu window.addEventListener('online', () => { console.log('🌐 İnternet bağlantısı restore edildi'); if (window.dashboard) { window.dashboard.connectSocket(); } }); window.addEventListener('offline', () => { console.log('🌐 İnternet bağlantısı kesildi'); }); console.log('📱 Dashboard JavaScript yüklendi');