loader image
Sélectionner une page
// Alternance de couleurs for (let i = 0; i < cityRows.length; i++) { const rowNumber = i + 2; const color = i % 2 === 0 ? "#f8f9fa" : "#ffffff"; sheet.getRange(rowNumber, 1, 1, headers.length).setBackground(color); } } // Ajuster la largeur des colonnes sheet.autoResizeColumns(1, headers.length); } /** * Créer/mettre à jour l'onglet de classement */ function updateRankingSheet(cityVotes) { const ss = SpreadsheetApp.getActiveSpreadsheet(); let rankingSheet = ss.getSheetByName("📊 Classement"); if (!rankingSheet) { rankingSheet = ss.insertSheet("📊 Classement", 0); } else { rankingSheet.clear(); } // Récupérer les votes si non fournis if (!cityVotes) { const mainSheet = ss.getSheetByName(MAIN_SHEET_NAME); const data = mainSheet.getDataRange().getValues(); const rows = data.slice(1); cityVotes = {}; rows.forEach(row => { const city = row[2]; if (city) { cityVotes[city] = (cityVotes[city] || 0) + 1; } }); } // Créer le classement const ranking = Object.entries(cityVotes) .map(([city, votes]) => ({ city, votes })) .sort((a, b) => b.votes - a.votes); // En-tête rankingSheet.getRange("A1").setValue("🎸 CLASSEMENT DES VILLES - THE SUNVIZORS TOURNÉE 2025"); rankingSheet.getRange("A1:F1").merge() .setBackground("#764ba2") .setFontColor("#FFFFFF") .setFontWeight("bold") .setHorizontalAlignment("center") .setFontSize(16); // Statistiques globales const totalVotes = ranking.reduce((sum, item) => sum + item.votes, 0); const validatedCities = ranking.filter(item => item.votes >= THRESHOLD).length; rankingSheet.getRange("A2").setValue("Total votes:"); rankingSheet.getRange("B2").setValue(totalVotes); rankingSheet.getRange("C2").setValue("Villes en course:"); rankingSheet.getRange("D2").setValue(ranking.length); rankingSheet.getRange("E2").setValue("Concerts validés:"); rankingSheet.getRange("F2").setValue(validatedCities); rankingSheet.getRange("A2:F2") .setBackground("#F8F9FA") .setFontWeight("bold") .setHorizontalAlignment("center"); // Ligne vide rankingSheet.getRange("A3:F3").setBackground("#FFFFFF"); // En-têtes du classement const headers = ["Position", "Ville", "Votes", "Progression", "Statut", "🔗 Lien feuille"]; rankingSheet.getRange(4, 1, 1, headers.length).setValues([headers]); rankingSheet.getRange(4, 1, 1, headers.length) .setBackground("#667eea") .setFontColor("#FFFFFF") .setFontWeight("bold") .setHorizontalAlignment("center"); // Remplir le classement ranking.forEach((item, index) => { const row = index + 5; const position = index + 1; const percentage = Math.min((item.votes / THRESHOLD) * 100, 100).toFixed(1) + "%"; const isValidated = item.votes >= THRESHOLD; const status = isValidated ? "✅ VALIDÉ" : `${THRESHOLD - item.votes} restants`; // Créer un lien vers la feuille de la ville const sheetLink = `=HYPERLINK("#gid=" & INDIRECT("'"&"${item.city}"&"'!A1";1); "📋 Voir détails")`; const rowData = [ position, item.city, item.votes, percentage, status, "" // Le lien sera ajouté séparément ]; rankingSheet.getRange(row, 1, 1, rowData.length).setValues([rowData]); // Ajouter le lien hypertexte try { rankingSheet.getRange(row, 6).setFormula(sheetLink); } catch (e) { rankingSheet.getRange(row, 6).setValue("Voir " + item.city); } // Couleurs selon position let bgColor = "#FFFFFF"; if (position === 1) bgColor = "#FFD700"; // Or else if (position === 2) bgColor = "#C0C0C0"; // Argent else if (position === 3) bgColor = "#CD7F32"; // Bronze else if (isValidated) bgColor = "#D1FAE5"; // Vert validé else if (index % 2 === 1) bgColor = "#F8F9FA"; // Alternance rankingSheet.getRange(row, 1, 1, 6).setBackground(bgColor); // Statut en couleur if (isValidated) { rankingSheet.getRange(row, 5) .setFontWeight("bold") .setFontColor("#10b981"); } }); // Figer les lignes d'en-tête rankingSheet.setFrozenRows(4); // Ajuster les colonnes rankingSheet.autoResizeColumns(1, headers.length); } /** * Fonction pour mise à jour manuelle */ function manualUpdate() { organizeData(); SpreadsheetApp.getUi().alert('✅ Classement mis à jour !'); } /** * Exporter le classement en JSON pour la carte */ function exportRankingJSON() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const mainSheet = ss.getSheetByName(MAIN_SHEET_NAME); const data = mainSheet.getDataRange().getValues(); const rows = data.slice(1); // Compter les votes par ville const cityVotes = {}; rows.forEach(row => { const city = row[2]; if (city) { cityVotes[city] = (cityVotes[city] || 0) + 1; } }); // Créer le JSON const json = JSON.stringify(cityVotes, null, 2); // Afficher dans un popup const ui = SpreadsheetApp.getUi(); ui.alert('Classement JSON', json, ui.ButtonSet.OK); return cityVotes; } /** * Créer un menu personnalisé */ function onOpen() { const ui = SpreadsheetApp.getUi(); ui.createMenu('🎸 The Sunvizors') .addItem('🔄 Mettre à jour le classement', 'manualUpdate') .addItem('📊 Exporter en JSON', 'exportRankingJSON') .addToUi(); } /** * Fonction pour nettoyer les données de test */ function clearTestData() { const ui = SpreadsheetApp.getUi(); const response = ui.alert( 'Confirmation', '⚠️ Voulez-vous vraiment supprimer TOUTES les données de test ?', ui.ButtonSet.YES_NO ); if (response == ui.Button.YES) { const ss = SpreadsheetApp.getActiveSpreadsheet(); const mainSheet = ss.getSheetByName(MAIN_SHEET_NAME); if (mainSheet && mainSheet.getLastRow() > 1) { mainSheet.getRange(2, 1, mainSheet.getLastRow() - 1, mainSheet.getLastColumn()).clearContent(); ui.alert('✅ Données effacées !'); } } }