fixes to my list w anilist

This commit is contained in:
2025-12-07 15:09:27 +01:00
parent 220bbed16a
commit b2f6b489aa
5 changed files with 132 additions and 41 deletions

View File

@@ -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()
});
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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');