2025-03-09 16:15:31 +01:00
// 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 ( ) {
2025-03-09 17:36:38 +01:00
// Vérifier si les données de jeu sont disponibles depuis data.js
if ( window . gameData ) {
// Charger les monstres depuis les données du jeu
monsters = [ ... window . gameData . monsters ] ;
// Charger les quêtes depuis localStorage ou utiliser les données par défaut
const storedQuests = localStorage . getItem ( 'mhw_quests' ) ;
quests = storedQuests ? JSON . parse ( storedQuests ) : [ ... window . gameData . initialQuests ] ;
// Charger les annonces depuis localStorage ou utiliser les données par défaut
const storedAnnouncements = localStorage . getItem ( 'mhw_announcements' ) ;
announcements = storedAnnouncements ? JSON . parse ( storedAnnouncements ) : [ ... window . gameData . initialAnnouncements ] ;
} else {
// Fallback au cas où data.js n'est pas chargé
console . warn ( "Données de jeu non disponibles. Utilisation des données locales de secours." ) ;
monsters = [ ] ;
// Essayer de charger depuis localStorage
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 ) ;
}
2025-03-09 16:15:31 +01:00
renderAnnouncementsList ( ) ;
renderMonstersList ( ) ;
}
function saveData ( ) {
2025-03-09 17:36:38 +01:00
// Sauvegarder dans le localStorage
2025-03-09 16:15:31 +01:00
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
? '<span class="badge bg-success">Active</span>'
: '<span class="badge bg-secondary">Inactive</span>' ;
return `
< tr >
< td > $ { announcement . text } < / t d >
< td > $ { statusBadge } < / t d >
< td >
< div class = "btn-group btn-group-sm" >
< button class = "btn btn-outline-primary edit-announcement-btn" data - id = "${announcement.id}" >
Éditer
< / b u t t o n >
< button class = "btn btn-outline-danger delete-announcement-btn" data - id = "${announcement.id}" >
Supprimer
< / b u t t o n >
< / d i v >
< / t d >
< / t r >
` ;
} ) . 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 `
< tr >
< td >
< img src = "${monster.image}" alt = "${monster.name}" class = "img-thumbnail" width = "80" >
< / t d >
< td > $ { monster . name } < / t d >
< td > $ { questCount } < / t d >
< td >
< div class = "btn-group btn-group-sm" >
< button class = "btn btn-outline-primary edit-monster-btn" data - id = "${monster.id}" >
Éditer
< / b u t t o n >
< button class = "btn btn-outline-danger delete-monster-btn" data - id = "${monster.id}" >
Supprimer
< / b u t t o n >
< / d i v >
< / t d >
< / t r >
` ;
} ) . 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 ;
}