// Campaigns Grid Module // Displays public campaigns in a responsive grid on the homepage class CampaignsGrid { constructor() { this.campaigns = []; this.container = null; this.loading = false; this.error = null; } async init() { this.container = document.getElementById('campaigns-grid'); if (!this.container) { console.error('Campaigns grid container not found'); return; } await this.loadCampaigns(); } async loadCampaigns() { if (this.loading) return; this.loading = true; this.showLoading(); try { const response = await fetch('/api/public/campaigns'); const data = await response.json(); if (!data.success) { throw new Error(data.error || 'Failed to load campaigns'); } this.campaigns = data.campaigns || []; this.renderCampaigns(); // Show or hide the entire campaigns section based on availability const campaignsSection = document.getElementById('campaigns-section'); if (this.campaigns.length > 0) { campaignsSection.style.display = 'block'; } else { campaignsSection.style.display = 'none'; } } catch (error) { console.error('Error loading campaigns:', error); this.showError('Unable to load campaigns. Please try again later.'); } finally { this.loading = false; } } renderCampaigns() { if (!this.container) return; if (this.campaigns.length === 0) { this.container.innerHTML = `
No active campaigns at the moment. Check back soon!
${this.escapeHtml(truncatedDescription)}
${targetLevels ? `Loading campaigns...
⚠️ ${this.escapeHtml(message)}