// Variables globales let monsters = []; let quests = []; let announcements = []; // Éléments DOM pour les onglets const announcementsTab = document.getElementById('announcementsTab'); const monstersTab = document.getElementById('monstersTab'); const maintenanceTab = document.getElementById('maintenanceTab'); const sectionsEls = document.querySelectorAll('.admin-section'); // Éléments DOM pour les annonces const announcementsListEl = document.getElementById('announcementsList'); const emptyAnnouncementsMessageEl = document.getElementById('emptyAnnouncementsMessage'); const addAnnouncementBtn = document.getElementById('addAnnouncementBtn'); const announcementForm = document.getElementById('announcementForm'); const announcementIdEl = document.getElementById('announcementId'); const announcementTextEl = document.getElementById('announcementText'); const announcementActiveEl = document.getElementById('announcementActive'); const announcementModalTitleEl = document.getElementById('announcementModalTitle'); // Éléments DOM pour les monstres const monstersListEl = document.getElementById('monstersList'); const emptyMonstersMessageEl = document.getElementById('emptyMonstersMessage'); const addMonsterBtn = document.getElementById('addMonsterBtn'); const monsterForm = document.getElementById('monsterForm'); const monsterIdEl = document.getElementById('monsterId'); const monsterNameEl = document.getElementById('monsterName'); const monsterImageEl = document.getElementById('monsterImage'); const monsterModalTitleEl = document.getElementById('monsterModalTitle'); // Éléments DOM pour la maintenance const cleanOldQuestsBtn = document.getElementById('cleanOldQuestsBtn'); const cleanResultEl = document.getElementById('cleanResult'); const totalMonstersCountEl = document.getElementById('totalMonstersCount'); const totalQuestsCountEl = document.getElementById('totalQuestsCount'); const smallCrownQuestsCountEl = document.getElementById('smallCrownQuestsCount'); const largeCrownQuestsCountEl = document.getElementById('largeCrownQuestsCount'); // Éléments DOM pour la confirmation de suppression const confirmDeleteBtn = document.getElementById('confirmDeleteBtn'); const confirmDeleteMessageEl = document.getElementById('confirmDeleteMessage'); const confirmDeleteTitleEl = document.getElementById('confirmDeleteTitle'); // Modales Bootstrap const announcementModal = new bootstrap.Modal(document.getElementById('announcementModal')); const monsterModal = new bootstrap.Modal(document.getElementById('monsterModal')); const confirmDeleteModal = new bootstrap.Modal(document.getElementById('confirmDeleteModal')); // Variables pour la suppression let currentDeletionType = null; let currentDeletionId = null; // Vérifier l'authentification et rediriger si nécessaire function checkAuthentication() { if (localStorage.getItem('admin_authenticated') !== 'true') { window.location.href = 'login.html'; return false; } return true; } // Déconnexion function logout() { localStorage.removeItem('admin_authenticated'); window.location.href = 'login.html?logout=true'; } // Initialisation document.addEventListener('DOMContentLoaded', () => { // Vérifier l'authentification if (!checkAuthentication()) { return; } loadData(); // Événements pour les onglets announcementsTab.addEventListener('click', (e) => { e.preventDefault(); showSection('announcementsSection'); }); monstersTab.addEventListener('click', (e) => { e.preventDefault(); showSection('monstersSection'); }); maintenanceTab.addEventListener('click', (e) => { e.preventDefault(); showSection('maintenanceSection'); updateStatistics(); }); // Événements pour les annonces addAnnouncementBtn.addEventListener('click', () => { resetAnnouncementForm(); announcementModalTitleEl.textContent = 'Ajouter une annonce'; announcementModal.show(); }); announcementForm.addEventListener('submit', handleSaveAnnouncement); // Événements pour les monstres addMonsterBtn.addEventListener('click', () => { resetMonsterForm(); monsterModalTitleEl.textContent = 'Ajouter un monstre'; monsterModal.show(); }); monsterForm.addEventListener('submit', handleSaveMonster); // Événements pour la maintenance cleanOldQuestsBtn.addEventListener('click', handleCleanOldQuests); // Événement pour la confirmation de suppression confirmDeleteBtn.addEventListener('click', handleConfirmDelete); // Événement pour la déconnexion document.getElementById('logoutBtn').addEventListener('click', logout); }); // Fonctions de chargement et sauvegarde des données function loadData() { // Dans une implémentation réelle, ces données seraient chargées depuis des fichiers JSON ou une API // Pour l'instant, nous utilisons des données temporaires monsters = [ { id: 1, name: 'Chatacabra', image: 'img/Chatacabra.jpg' }, { id: 2, name: 'Quematrice', image: 'img/Quematrice.jpg' }, { id: 3, name: 'Lala Barina', image: 'img/Lala_Barina.jpg' }, { id: 4, name: 'Congalala', image: 'img/Congalala.jpg' }, { id: 5, name: 'Balahara', image: 'img/Balahara.jpg' }, { id: 6, name: 'Doshaguma', image: 'img/Doshaguma.jpg' }, { id: 7, name: 'Uth Duna', image: 'img/Uth_Duna.jpg' }, { id: 8, name: 'Rompopolo', image: 'img/Rompopolo.jpg' }, { id: 9, name: 'Rey Dau', image: 'img/Rey_Dau.jpg' }, { id: 10, name: 'Nerscylla', image: 'img/Nerscylla.jpg' }, { id: 11, name: 'Hirabami', image: 'img/Hirabami.jpg' }, { id: 12, name: 'Ajarakan', image: 'img/Ajarakan.jpg' }, { id: 13, name: 'Nu Udra', image: 'img/Nu_Udra.jpg' }, { id: 14, name: 'Doshaguma Gardien', image: 'img/Doshaguma_Gardien.jpg' }, { id: 15, name: 'Rathalos Gardien', image: 'img/Rathalos_Gardien.jpg' }, { id: 16, name: 'Jin Dahaad', image: 'img/Jin_Dahaad.jpg' }, { id: 17, name: 'Odogaron Désastre Gardien', image: 'img/Odogaron_Desastre_Gardien.jpg' }, { id: 18, name: 'Xu Wu', image: 'img/Xu_Wu.jpg' }, { id: 19, name: 'Arkveld Gardien', image: 'img/Arkveld_Gardien.jpg' }, { id: 20, name: 'Zoh Shia', image: 'img/Zoh_Shia.jpg' }, { id: 21, name: 'Yian Kut-Ku', image: 'img/Yian_Kut-Ku.jpg' }, { id: 22, name: 'Gypceros', image: 'img/Gypceros.jpg' }, { id: 23, name: 'Rathian', image: 'img/Rathian.jpg' }, { id: 24, name: 'Anjanath Tonnerre Gardien', image: 'img/Anjanath_Tonnerre_Gardien.jpg' }, { id: 25, name: 'Rathalos', image: 'img/Rathalos.jpg' }, { id: 26, name: 'Gravios', image: 'img/Gravios.jpg' }, { id: 27, name: 'Blangonga', image: 'img/Blangonga.jpg' }, { id: 28, name: 'Gore Malaga', image: 'img/Gore_Malaga.jpg' }, { id: 29, name: 'Arkveld', image: 'img/Arkveld.jpg' } ]; quests = [ { id: 1, monsterId: 1, crownType: 'small', playerName: 'Hunter123', playerId: 'MHW-1234', date: new Date().toISOString() }, { id: 2, monsterId: 1, crownType: 'large', playerName: 'DragonSlayer', playerId: 'MHW-5678', date: new Date().toISOString() }, { id: 3, monsterId: 2, crownType: 'small', playerName: 'ThunderLord', playerId: 'MHW-9012', date: new Date().toISOString() } ]; announcements = [ { id: 1, text: "Bienvenue sur le site de partage de quêtes à couronnes pour Monster Hunter Wilds!", active: true }, { id: 2, text: "De nouveaux monstres ont été ajoutés, consultez la liste!", active: false } ]; // Essayer de charger depuis localStorage s'il y a des données const storedMonsters = localStorage.getItem('mhw_monsters'); const storedQuests = localStorage.getItem('mhw_quests'); const storedAnnouncements = localStorage.getItem('mhw_announcements'); if (storedMonsters) monsters = JSON.parse(storedMonsters); if (storedQuests) quests = JSON.parse(storedQuests); if (storedAnnouncements) announcements = JSON.parse(storedAnnouncements); renderAnnouncementsList(); renderMonstersList(); } function saveData() { // Dans une implémentation réelle, ces données seraient sauvegardées via une API localStorage.setItem('mhw_monsters', JSON.stringify(monsters)); localStorage.setItem('mhw_quests', JSON.stringify(quests)); localStorage.setItem('mhw_announcements', JSON.stringify(announcements)); console.log('Données sauvegardées'); } // Fonctions pour la navigation entre les sections function showSection(sectionId) { // Désactiver tous les onglets et masquer toutes les sections document.querySelectorAll('.list-group-item').forEach(tab => { tab.classList.remove('active'); }); sectionsEls.forEach(section => { section.classList.add('d-none'); }); // Activer l'onglet sélectionné et afficher sa section document.getElementById(sectionId).classList.remove('d-none'); if (sectionId === 'announcementsSection') { announcementsTab.classList.add('active'); } else if (sectionId === 'monstersSection') { monstersTab.classList.add('active'); } else if (sectionId === 'maintenanceSection') { maintenanceTab.classList.add('active'); } } // ============ ANNONCES ============ // Rendu de la liste des annonces function renderAnnouncementsList() { if (announcements.length === 0) { announcementsListEl.innerHTML = ''; emptyAnnouncementsMessageEl.classList.remove('d-none'); return; } emptyAnnouncementsMessageEl.classList.add('d-none'); announcementsListEl.innerHTML = announcements.map(announcement => { const statusBadge = announcement.active ? 'Active' : 'Inactive'; return ` ${announcement.text} ${statusBadge}
`; }).join(''); // Ajouter les écouteurs d'événements pour les boutons document.querySelectorAll('.edit-announcement-btn').forEach(btn => { btn.addEventListener('click', () => { const announcementId = parseInt(btn.dataset.id); editAnnouncement(announcementId); }); }); document.querySelectorAll('.delete-announcement-btn').forEach(btn => { btn.addEventListener('click', () => { const announcementId = parseInt(btn.dataset.id); showDeleteConfirmation('announcement', announcementId); }); }); } // Réinitialiser le formulaire d'annonce function resetAnnouncementForm() { announcementIdEl.value = ''; announcementTextEl.value = ''; announcementActiveEl.checked = true; } // Éditer une annonce function editAnnouncement(announcementId) { const announcement = announcements.find(a => a.id === announcementId); if (!announcement) return; announcementIdEl.value = announcement.id; announcementTextEl.value = announcement.text; announcementActiveEl.checked = announcement.active; announcementModalTitleEl.textContent = 'Modifier l\'annonce'; announcementModal.show(); } // Gérer la sauvegarde d'une annonce function handleSaveAnnouncement(e) { e.preventDefault(); const announcementId = announcementIdEl.value.trim(); const announcementText = announcementTextEl.value.trim(); const announcementActive = announcementActiveEl.checked; if (!announcementText) { alert('Veuillez saisir le texte de l\'annonce'); return; } if (announcementId) { // Mode édition const index = announcements.findIndex(a => a.id === parseInt(announcementId)); if (index !== -1) { announcements[index].text = announcementText; announcements[index].active = announcementActive; } } else { // Mode ajout const newAnnouncementId = announcements.length > 0 ? Math.max(...announcements.map(a => a.id)) + 1 : 1; announcements.push({ id: newAnnouncementId, text: announcementText, active: announcementActive }); } saveData(); renderAnnouncementsList(); announcementModal.hide(); } // ============ MONSTRES ============ // Rendu de la liste des monstres function renderMonstersList() { if (monsters.length === 0) { monstersListEl.innerHTML = ''; emptyMonstersMessageEl.classList.remove('d-none'); return; } emptyMonstersMessageEl.classList.add('d-none'); monstersListEl.innerHTML = monsters.map(monster => { const questCount = quests.filter(q => q.monsterId === monster.id).length; return ` ${monster.name} ${monster.name} ${questCount}
`; }).join(''); // Ajouter les écouteurs d'événements pour les boutons document.querySelectorAll('.edit-monster-btn').forEach(btn => { btn.addEventListener('click', () => { const monsterId = parseInt(btn.dataset.id); editMonster(monsterId); }); }); document.querySelectorAll('.delete-monster-btn').forEach(btn => { btn.addEventListener('click', () => { const monsterId = parseInt(btn.dataset.id); showDeleteConfirmation('monster', monsterId); }); }); } // Réinitialiser le formulaire de monstre function resetMonsterForm() { monsterIdEl.value = ''; monsterNameEl.value = ''; monsterImageEl.value = ''; } // Éditer un monstre function editMonster(monsterId) { const monster = monsters.find(m => m.id === monsterId); if (!monster) return; monsterIdEl.value = monster.id; monsterNameEl.value = monster.name; // Retirer le préfixe 'img/' pour l'affichage dans le formulaire let imagePath = monster.image; if (imagePath.startsWith('img/')) { imagePath = imagePath.substring(4); } monsterImageEl.value = imagePath; monsterModalTitleEl.textContent = 'Modifier le monstre'; monsterModal.show(); } // Gérer la sauvegarde d'un monstre function handleSaveMonster(e) { e.preventDefault(); const monsterId = monsterIdEl.value.trim(); const monsterName = monsterNameEl.value.trim(); let monsterImage = monsterImageEl.value.trim(); // Ajouter le préfixe 'img/' si ce n'est pas déjà fait if (!monsterImage.startsWith('img/')) { monsterImage = 'img/' + monsterImage; } if (!monsterName || !monsterImage) { alert('Veuillez remplir tous les champs'); return; } if (monsterId) { // Mode édition const index = monsters.findIndex(m => m.id === parseInt(monsterId)); if (index !== -1) { monsters[index].name = monsterName; monsters[index].image = monsterImage; } } else { // Mode ajout const newMonsterId = monsters.length > 0 ? Math.max(...monsters.map(m => m.id)) + 1 : 1; monsters.push({ id: newMonsterId, name: monsterName, image: monsterImage }); } saveData(); renderMonstersList(); monsterModal.hide(); } // ============ MAINTENANCE ============ // Mettre à jour les statistiques function updateStatistics() { totalMonstersCountEl.textContent = monsters.length; totalQuestsCountEl.textContent = quests.length; smallCrownQuestsCountEl.textContent = quests.filter(q => q.crownType === 'small').length; largeCrownQuestsCountEl.textContent = quests.filter(q => q.crownType === 'large').length; } // Nettoyer les quêtes anciennes function handleCleanOldQuests() { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); const oldQuestsCount = quests.filter(q => new Date(q.date) < sevenDaysAgo).length; quests = quests.filter(q => new Date(q.date) >= sevenDaysAgo); saveData(); updateStatistics(); cleanResultEl.innerHTML = `${oldQuestsCount} quête(s) supprimée(s) avec succès.`; cleanResultEl.classList.remove('d-none'); // Masquer le message après 3 secondes setTimeout(() => { cleanResultEl.classList.add('d-none'); }, 3000); } // ============ SUPPRESSION ============ // Afficher la confirmation de suppression function showDeleteConfirmation(type, id) { currentDeletionType = type; currentDeletionId = id; if (type === 'announcement') { confirmDeleteTitleEl.textContent = 'Supprimer l\'annonce'; confirmDeleteMessageEl.textContent = 'Êtes-vous sûr de vouloir supprimer cette annonce ?'; } else if (type === 'monster') { const questCount = quests.filter(q => q.monsterId === id).length; confirmDeleteTitleEl.textContent = 'Supprimer le monstre'; confirmDeleteMessageEl.textContent = `Êtes-vous sûr de vouloir supprimer ce monstre ? Cette action supprimera également ${questCount} quête(s) associée(s).`; } confirmDeleteModal.show(); } // Gérer la confirmation de suppression function handleConfirmDelete() { if (currentDeletionType === 'announcement') { announcements = announcements.filter(a => a.id !== currentDeletionId); renderAnnouncementsList(); } else if (currentDeletionType === 'monster') { monsters = monsters.filter(m => m.id !== currentDeletionId); quests = quests.filter(q => q.monsterId !== currentDeletionId); renderMonstersList(); } saveData(); confirmDeleteModal.hide(); currentDeletionType = null; currentDeletionId = null; }