diff --git a/src/api/anilist/anilist.service.ts b/src/api/anilist/anilist.service.ts index 670102b..32ca5d6 100644 --- a/src/api/anilist/anilist.service.ts +++ b/src/api/anilist/anilist.service.ts @@ -119,6 +119,8 @@ export async function getUserAniList(appUserId: number) { entries { media { id + type + format title { romaji english userPreferred } coverImage { extraLarge } chapters @@ -180,14 +182,22 @@ export async function getUserAniList(appUserId: number) { media?.chapters || (media?.volumes ? media.volumes * 10 : 0); + const resolvedType = + type === 'MANGA' && + (media?.format === 'LIGHT_NOVEL' || media?.format === 'NOVEL') + ? 'NOVEL' + : type; + + result.push({ user_id: appUserId, - // ✅ FIX CLAVE entry_id: media.id, - source: 'anilist', - entry_type: type, + + // ✅ AHORA TU FRONT RECIBE NOVEL + entry_type: resolvedType, + status: entry.status, progress: entry.progress || 0, score: entry.score || null, @@ -197,7 +207,6 @@ export async function getUserAniList(appUserId: number) { notes: entry.notes || null, is_private: entry.private ? 1 : 0, - // ✅ CAMPOS QUE EL FRONTEND NECESITA title: media?.title?.userPreferred || media?.title?.english || media?.title?.romaji @@ -206,10 +215,9 @@ export async function getUserAniList(appUserId: number) { poster: media?.coverImage?.extraLarge || 'https://placehold.co/400x600?text=No+Cover', - total_episodes: type === 'ANIME' ? totalEpisodes : undefined, - total_chapters: type === 'MANGA' ? totalChapters : undefined, + total_episodes: resolvedType === 'ANIME' ? totalEpisodes : undefined, + total_chapters: resolvedType !== 'ANIME' ? totalChapters : undefined, - // ✅ PARA ORDER BY EN EL FRONT updated_at: new Date().toISOString() }); } diff --git a/src/scripts/anime/anime.js b/src/scripts/anime/anime.js index be8ba87..50967b0 100644 --- a/src/scripts/anime/anime.js +++ b/src/scripts/anime/anime.js @@ -106,7 +106,11 @@ function openAddToListModal() { if (isInList && currentListEntry) { - statusEl.value = currentListEntry.status || 'PLANNING'; + const statusReverseMap = { + CURRENT: 'WATCHING' + }; + + statusEl.value = statusReverseMap[currentListEntry.status] || currentListEntry.status || 'PLANNING'; progressEl.value = currentListEntry.progress || 0; scoreEl.value = currentListEntry.score || ''; @@ -144,7 +148,18 @@ function closeAddToListModal() { // Función saveToList actualizada con todos los campos extendidos async function saveToList() { - const status = document.getElementById('entry-status').value; + const uiStatus = document.getElementById('entry-status').value; + + const anilistStatusMap = { + WATCHING: 'CURRENT', + COMPLETED: 'COMPLETED', + PLANNING: 'PLANNING', + PAUSED: 'PAUSED', + DROPPED: 'DROPPED', + REPEATING: 'REPEATING' + }; + + const status = anilistStatusMap[uiStatus]; const progress = parseInt(document.getElementById('entry-progress').value) || 0; const scoreValue = document.getElementById('entry-score').value; const score = scoreValue ? parseFloat(scoreValue) : null; diff --git a/src/scripts/books/book.js b/src/scripts/books/book.js index a722205..c77806e 100644 --- a/src/scripts/books/book.js +++ b/src/scripts/books/book.js @@ -188,7 +188,18 @@ function closeAddToListModal() { */ async function saveToList() { // Datos comunes - const status = document.getElementById('entry-status').value; + const uiStatus = document.getElementById('entry-status').value; + + const anilistStatusMap = { + WATCHING: 'CURRENT', + COMPLETED: 'COMPLETED', + PLANNING: 'PLANNING', + PAUSED: 'PAUSED', + DROPPED: 'DROPPED', + REPEATING: 'REPEATING' + }; + + const status = anilistStatusMap[uiStatus]; const progress = parseInt(document.getElementById('entry-progress').value) || 0; const scoreValue = document.getElementById('entry-score').value; const score = scoreValue ? parseFloat(scoreValue) : null; diff --git a/src/scripts/list.js b/src/scripts/list.js index a15fa23..bbad5a1 100644 --- a/src/scripts/list.js +++ b/src/scripts/list.js @@ -172,7 +172,7 @@ function applyFilters() { } if (typeFilter !== 'all') { - filtered = filtered.filter(item => (item.entry_type || 'ANIME') === typeFilter); + filtered = filtered.filter(item => item.entry_type === typeFilter); } switch (sortFilter) { @@ -226,7 +226,7 @@ function createListItem(item) { const score = item.score ? item.score.toFixed(1) : null; const repeatCount = item.repeat_count || 0; - const entryType = (item.entry_type || 'ANIME').toUpperCase(); + const entryType = (item.entry_type).toUpperCase(); let unitLabel = 'units'; if (entryType === 'ANIME') { unitLabel = 'episodes'; @@ -239,7 +239,7 @@ function createListItem(item) { const statusLabels = { 'WATCHING': entryType === 'ANIME' ? 'Watching' : 'Reading', 'COMPLETED': 'Completed', - 'PLANNING': entryType === 'ANIME' ? 'Plan to Watch' : 'Plan to Read', + 'PLANNING': 'Planning', 'PAUSED': 'Paused', 'DROPPED': 'Dropped' }; @@ -294,7 +294,14 @@ function openEditModal(item) { currentEditingEntry = item; // Campos existentes - document.getElementById('edit-status').value = item.status; + let modalStatus = item.status; + const type = item.entry_type?.toUpperCase(); + + if ((type === 'MANGA' || type === 'NOVEL') && item.status === 'READING') { + modalStatus = 'WATCHING'; // solo para mostrar correctamente + } + + document.getElementById('edit-status').value = modalStatus; document.getElementById('edit-progress').value = item.progress || 0; // Asegura que el score se muestre si existe. document.getElementById('edit-score').value = item.score !== null && item.score !== undefined ? item.score : ''; @@ -309,7 +316,7 @@ function openEditModal(item) { document.getElementById('edit-is-private').checked = item.is_private === 1 || item.is_private === true; - const entryType = (item.entry_type || 'ANIME').toUpperCase(); + const entryType = (item.entry_type).toUpperCase(); const progressLabel = document.querySelector('label[for="edit-progress"]'); if (progressLabel) { if (entryType === 'MANGA') { @@ -327,6 +334,17 @@ function openEditModal(item) { document.getElementById('edit-progress').max = totalUnits; document.getElementById('edit-modal').classList.add('active'); + const statusSelect = document.getElementById('edit-status'); + const type2 = item.entry_type?.toUpperCase(); + + [...statusSelect.options].forEach(opt => { + if (opt.value === 'WATCHING') { + opt.textContent = (type2 === 'MANGA' || type2 === 'NOVEL') + ? 'Reading' + : 'Watching'; + } + }); + } function closeEditModal() { @@ -338,14 +356,22 @@ function closeEditModal() { async function saveEntry() { if (!currentEditingEntry) return; - // Campos existentes - const status = document.getElementById('edit-status').value; + let status = document.getElementById('edit-status').value; + + const anilistStatusMap = { + WATCHING: 'CURRENT', + COMPLETED: 'COMPLETED', + PLANNING: 'PLANNING', + PAUSED: 'PAUSED', + DROPPED: 'DROPPED' + }; + + const anilistStatus = anilistStatusMap[status]; + const progress = parseInt(document.getElementById('edit-progress').value) || 0; - // Usar null si el score está vacío const scoreValue = document.getElementById('edit-score').value; const score = scoreValue ? parseFloat(scoreValue) : null; - // Nuevos campos const start_date = document.getElementById('edit-start-date').value || null; const end_date = document.getElementById('edit-end-date').value || null; const repeat_count = parseInt(document.getElementById('edit-repeat-count').value) || 0; @@ -360,32 +386,55 @@ async function saveEntry() { body: JSON.stringify({ entry_id: currentEditingEntry.entry_id, source: currentEditingEntry.source, - entry_type: currentEditingEntry.entry_type || 'ANIME', - status: status, - progress: progress, - score: score, - // Nuevos datos a enviar al backend - start_date: start_date, - end_date: end_date, - repeat_count: repeat_count, - notes: notes, - is_private: is_private + entry_type: currentEditingEntry.entry_type, + status: anilistStatus, + progress, + score, + start_date, + end_date, + repeat_count, + notes, + is_private }) }); - if (!response.ok) { - throw new Error('Failed to update entry'); + if (!response.ok) throw new Error('Failed to update entry'); + + // ✅ ACTUALIZAR EN MEMORIA + const index = currentList.findIndex(e => + e.entry_id === currentEditingEntry.entry_id && + e.source === currentEditingEntry.source + ); + + if (index !== -1) { + currentList[index] = { + ...currentList[index], + status, + progress, + score, + start_date, + end_date, + repeat_count, + notes, + is_private, + updated_at: new Date().toISOString() + }; } + filteredList = [...currentList]; + updateStats(); + applyFilters(); + closeEditModal(); - await loadList(); showNotification('Entry updated successfully!', 'success'); + } catch (error) { console.error('Error updating entry:', error); showNotification('Failed to update entry', 'error'); } } + async function deleteEntry() { if (!currentEditingEntry) return; @@ -402,13 +451,21 @@ async function deleteEntry() { } ); - if (!response.ok) { - throw new Error('Failed to delete entry'); - } + if (!response.ok) throw new Error('Failed to delete entry'); + + // ✅ ELIMINAR EN MEMORIA + currentList = currentList.filter(item => + !(item.entry_id === currentEditingEntry.entry_id && + item.source === currentEditingEntry.source) + ); + + filteredList = [...currentList]; + updateStats(); + applyFilters(); closeEditModal(); - await loadList(); showNotification('Entry removed from list', 'success'); + } catch (error) { console.error('Error deleting entry:', error); showNotification('Failed to remove entry', 'error'); diff --git a/views/list.html b/views/list.html index 82c5786..d8a817a 100644 --- a/views/list.html +++ b/views/list.html @@ -87,7 +87,7 @@
Start adding anime to track your progress
- +