← Kapat
progress-tracker.js
// Progress Tracker JavaScript
class ProgressTracker {
constructor() {
this.tracker = null;
this.collapsed = false;
this.updateInterval = null;
this.lastProgress = null;
this.stalledCounter = 0;
this.init();
}
init() {
this.createTracker();
this.loadProgressState();
this.bindEvents();
}
createTracker() {
// CSS dosyasını yükle
if (!document.querySelector('link[href*="floating-tracker.css"]')) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'floating-tracker.css';
document.head.appendChild(link);
}
// Tracker HTML'ini oluştur
this.tracker = document.createElement('div');
this.tracker.className = 'floating-tracker';
this.tracker.id = 'progressTracker';
this.tracker.style.display = 'none'; // Başlangıçta gizli
this.tracker.innerHTML = `
<div class="tracker-icon">⟳</div>
<div class="tracker-content">
<div class="tracker-header">
<span class="tracker-title">Veri Güncelleme</span>
<button class="tracker-toggle" onclick="progressTracker.toggleCollapse()">−</button>
</div>
<div class="tracker-progress">
<div class="tracker-progress-fill" id="progressFill"></div>
</div>
<div class="tracker-stats">
<span id="progressText">0/0</span>
<span id="progressPercent">0%</span>
</div>
<div class="tracker-current" id="currentTeam">Bekliyor...</div>
<div class="tracker-actions" id="trackerActions" style="display: none;">
<button class="tracker-continue-btn" id="continueBtn" onclick="progressTracker.continueRefresh()">
🔄 Devam Ettir
</button>
</div>
</div>
`;
document.body.appendChild(this.tracker);
}
bindEvents() {
// Sayfa değişimlerinde tracker'ı koru
window.addEventListener('beforeunload', () => {
this.saveProgressState();
});
// Tracker'a tıklama olayı (collapsed durumda)
this.tracker.addEventListener('click', (e) => {
if (this.collapsed && e.target === this.tracker) {
this.toggleCollapse();
}
});
}
show() {
this.tracker.style.display = 'block';
this.startProgressMonitoring();
}
hide() {
this.tracker.style.display = 'none';
this.stopProgressMonitoring();
}
toggleCollapse() {
this.collapsed = !this.collapsed;
this.tracker.classList.toggle('collapsed', this.collapsed);
const toggleBtn = this.tracker.querySelector('.tracker-toggle');
toggleBtn.textContent = this.collapsed ? '+' : '−';
this.saveProgressState();
}
updateProgress(data) {
if (!data) return;
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
const progressPercent = document.getElementById('progressPercent');
const currentTeam = document.getElementById('currentTeam');
const trackerActions = document.getElementById('trackerActions');
if (progressFill) progressFill.style.width = `${data.yuzde}%`;
if (progressText) progressText.textContent = `${data.tamamlanan}/${data.toplam}`;
if (progressPercent) progressPercent.textContent = `${data.yuzde}%`;
// Stalled durumunu kontrol et
const progressKey = `${data.tamamlanan}-${data.toplam}`;
if (this.lastProgress === progressKey && data.status === 'processing') {
this.stalledCounter++;
} else {
this.stalledCounter = 0;
}
this.lastProgress = progressKey;
if (currentTeam) {
if (data.status === 'completed') {
currentTeam.textContent = 'Tamamlandı!';
if (trackerActions) trackerActions.style.display = 'none';
} else if (data.status === 'error') {
currentTeam.textContent = 'Hata oluştu';
if (trackerActions) trackerActions.style.display = 'block';
} else if (this.stalledCounter > 5) { // 5 saniye durmuşsa
currentTeam.textContent = `Durdu: ${data.current_team || 'Bilinmiyor'} - Devam ettirin`;
if (trackerActions) trackerActions.style.display = 'block';
} else if (data.current_team) {
currentTeam.textContent = `İşleniyor: ${data.current_team}`;
if (trackerActions) trackerActions.style.display = 'none';
} else {
currentTeam.textContent = 'Hazırlanıyor...';
if (trackerActions) trackerActions.style.display = 'none';
}
}
// Status'a göre görünümü ayarla
const icon = this.tracker.querySelector('.tracker-icon');
if (data.status === 'completed') {
icon.style.animation = 'none';
icon.textContent = '✓';
// 5 saniye sonra tracker'ı gizle
setTimeout(() => this.hide(), 5000);
} else if (data.status === 'error') {
icon.style.animation = 'none';
icon.textContent = '✗';
} else if (this.stalledCounter > 5) {
icon.style.animation = 'none';
icon.textContent = '⏸';
} else if (data.status === 'running' || data.status === 'processing') {
icon.style.animation = 'spin 2s linear infinite';
icon.textContent = '⟳';
}
}
startProgressMonitoring() {
this.stopProgressMonitoring(); // Önce varolan interval'ı temizle
this.updateInterval = setInterval(() => {
fetch('get_progress.php')
.then(response => response.json())
.then(data => {
this.updateProgress(data);
// Eğer işlem tamamlandıysa monitoring'i durdur
if (data.status === 'completed' || data.status === 'error') {
setTimeout(() => {
this.stopProgressMonitoring();
}, 10000); // 10 saniye sonra durdur
}
})
.catch(error => {
console.error('Progress monitoring error:', error);
});
}, 1000); // Her saniye güncelle
}
stopProgressMonitoring() {
if (this.updateInterval) {
clearInterval(this.updateInterval);
this.updateInterval = null;
}
}
saveProgressState() {
const state = {
collapsed: this.collapsed,
visible: this.tracker.style.display !== 'none'
};
localStorage.setItem('progressTrackerState', JSON.stringify(state));
}
loadProgressState() {
const saved = localStorage.getItem('progressTrackerState');
if (saved) {
try {
const state = JSON.parse(saved);
this.collapsed = state.collapsed || false;
if (this.collapsed) {
this.tracker.classList.add('collapsed');
const toggleBtn = this.tracker.querySelector('.tracker-toggle');
if (toggleBtn) toggleBtn.textContent = '+';
}
// Eğer daha önce görünürse ve hala aktif bir işlem varsa göster
if (state.visible) {
fetch('get_progress.php')
.then(response => response.json())
.then(data => {
if (data.status === 'running' || data.status === 'processing' || data.status === 'starting') {
this.show();
}
})
.catch(() => {
// Hata durumunda gizle
this.hide();
});
}
} catch (e) {
console.error('Error loading progress state:', e);
}
}
}
// Public methods for external use
continueRefresh() {
// Devam ettir butonuna basıldığında
const continueBtn = document.getElementById('continueBtn');
if (continueBtn) {
continueBtn.disabled = true;
continueBtn.textContent = '🔄 Devam Ediyor...';
}
// Mevcut progress'i kontrol et
fetch('get_progress.php')
.then(response => response.json())
.then(data => {
if (data.toplam > 0 && data.tamamlanan < data.toplam) {
// Kaldığı yerden devam ettir
this.stalledCounter = 0; // Stalled counter'ı sıfırla
this.lastProgress = null;
// Yenileme işlemini tetikle
fetch('refresh_and_scrape.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `action=refresh&continue_from=${data.tamamlanan}`
})
.then(response => response.json())
.then(result => {
if (result.success) {
console.log('Devam ettirme başarılı');
} else {
console.error('Devam ettirme hatası:', result.message);
}
})
.catch(error => {
console.error('Devam ettirme isteği hatası:', error);
});
// Actions'ı gizle
const trackerActions = document.getElementById('trackerActions');
if (trackerActions) trackerActions.style.display = 'none';
} else {
console.log('Devam ettirilecek işlem yok');
}
})
.catch(error => {
console.error('Progress kontrol hatası:', error);
})
.finally(() => {
// Button'u eski haline getir
if (continueBtn) {
continueBtn.disabled = false;
continueBtn.textContent = '🔄 Devam Ettir';
}
});
}
startRefresh() {
this.show();
this.updateProgress({
toplam: 0,
tamamlanan: 0,
yuzde: 0,
current_team: '',
status: 'starting'
});
}
}
// Export for use in other scripts
window.ProgressTracker = ProgressTracker;
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', function() {
if (!window.progressTracker) {
window.progressTracker = new ProgressTracker();
}
});
window.progressTracker = progressTracker;