document.addEventListener('DOMContentLoaded', function() { let currentChapterId = null; const storyId = document.querySelector('input[name="id"]')?.value; // Initialisation de l'éditeur Quill avec toutes les options const quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: [ [{ 'header': [1, 2, 3, false] }], ['bold', 'italic', 'underline', 'strike'], [{ 'color': [] }, { 'background': [] }], [{ 'font': [] }], [{ 'align': [] }], ['blockquote', 'code-block'], [{ 'list': 'ordered'}, { 'list': 'bullet' }], [{ 'script': 'sub'}, { 'script': 'super' }], [{ 'indent': '-1'}, { 'indent': '+1' }], [{ 'direction': 'rtl' }], ['link', 'image', 'video'], ['clean'] ], keyboard: { bindings: { tab: false, 'indent backwards': false } } }, placeholder: 'Commencez à écrire votre chapitre ici...', formats: [ 'header', 'bold', 'italic', 'underline', 'strike', 'color', 'background', 'font', 'align', 'blockquote', 'code-block', 'list', 'bullet', 'script', 'indent', 'direction', 'link', 'image', 'video' ] }); // Gestion des chapitres const modal = document.getElementById('chapterEditor'); const addChapterBtn = document.getElementById('addChapter'); const saveChapterBtn = document.getElementById('saveChapter'); const cancelEditBtn = document.getElementById('cancelEdit'); const chapterTitleInput = document.getElementById('chapterTitle'); const chaptersList = document.getElementById('chaptersList'); // Configuration de Sortable pour la réorganisation des chapitres if (chaptersList) { new Sortable(chaptersList, { animation: 150, handle: '.chapter-number', // Utiliser le numéro comme poignée de drag ghostClass: 'sortable-ghost', onEnd: async function(evt) { const chapters = Array.from(chaptersList.children).map((item, index) => ({ id: item.dataset.id, position: index })); try { const response = await fetch('api/reorder-chapters.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ storyId: storyId, chapters: chapters }) }); if (!response.ok) { throw new Error('Erreur lors de la réorganisation'); } // Mise à jour des numéros de chapitres chapters.forEach((chapter, index) => { const element = document.querySelector(`[data-id="${chapter.id}"] .chapter-number`); if (element) { element.textContent = index + 1; } }); } catch (error) { console.error('Erreur:', error); showNotification('Erreur lors de la réorganisation des chapitres', 'error'); } } }); } // Gestionnaires d'événements pour l'édition des chapitres if (addChapterBtn) { addChapterBtn.addEventListener('click', () => { currentChapterId = null; chapterTitleInput.value = ''; quill.setContents([]); modal.style.display = 'block'; }); } if (cancelEditBtn) { cancelEditBtn.addEventListener('click', () => { if (hasUnsavedChanges()) { if (!confirm('Des modifications non sauvegardées seront perdues. Voulez-vous vraiment fermer ?')) { return; } } modal.style.display = 'none'; }); } // Gestion des clics sur la liste des chapitres if (chaptersList) { chaptersList.addEventListener('click', async (e) => { const target = e.target; if (target.matches('.edit-chapter')) { const chapterItem = target.closest('.chapter-item'); currentChapterId = chapterItem.dataset.id; try { const response = await fetch(`api/get-chapter.php?storyId=${storyId}&chapterId=${currentChapterId}`); if (!response.ok) { throw new Error('Erreur réseau'); } const chapter = await response.json(); // Mise à jour du titre chapterTitleInput.value = chapter.title || ''; // Gestion du contenu if (chapter.html) { // Si on a du HTML, on le charge directement quill.root.innerHTML = chapter.html; } else if (chapter.content) { // Si on a du contenu au format Delta try { const content = typeof chapter.content === 'string' ? JSON.parse(chapter.content) : chapter.content; quill.setContents(content); } catch (contentError) { console.error('Erreur de parsing du contenu:', contentError); quill.setText(chapter.content || ''); } } else { // Contenu vide par défaut quill.setContents([]); } modal.style.display = 'block'; } catch (error) { console.error('Erreur détaillée:', error); showNotification('Erreur lors du chargement du chapitre. Veuillez réessayer.', 'error'); } } }); } // Système de notification function showNotification(message, type = 'success') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; document.body.appendChild(notification); // Animation d'entrée setTimeout(() => { notification.style.opacity = '1'; notification.style.transform = 'translateY(0)'; }, 10); // Auto-suppression après 3 secondes setTimeout(() => { notification.style.opacity = '0'; notification.style.transform = 'translateY(-100%)'; setTimeout(() => notification.remove(), 300); }, 3000); } // Vérification des changements non sauvegardés function hasUnsavedChanges() { if (!currentChapterId) { return chapterTitleInput.value !== '' || quill.getLength() > 1; } // Pour les chapitres existants, il faudrait comparer avec le contenu original return true; // Par défaut, on suppose qu'il y a des changements } // Sauvegarde d'un chapitre if (saveChapterBtn) { saveChapterBtn.addEventListener('click', async () => { const title = chapterTitleInput.value.trim(); if (!title) { showNotification('Le titre est requis', 'error'); return; } try { const response = await fetch('api/save-chapter.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ storyId: storyId, chapterId: currentChapterId, title: title, content: JSON.stringify(quill.getContents()) }) }); if (response.ok) { showNotification('Chapitre sauvegardé avec succès'); setTimeout(() => location.reload(), 500); } else { throw new Error('Erreur lors de la sauvegarde'); } } catch (error) { console.error('Erreur:', error); showNotification('Erreur lors de la sauvegarde du chapitre', 'error'); } }); } // Ajouter le style des notifications const style = document.createElement('style'); style.textContent = ` .notification { position: fixed; top: 20px; right: 20px; padding: 1rem 2rem; border-radius: var(--radius-sm); background: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); opacity: 0; transform: translateY(-100%); transition: opacity 0.3s ease, transform 0.3s ease; z-index: 1000; } .notification.success { background-color: var(--success-color); color: white; } .notification.error { background-color: var(--error-color); color: white; } `; document.head.appendChild(style); });