let allMovies = []; // Stockage local de la liste entière
window.onload = () => {
loadList();
document.getElementById('sortOrder').addEventListener('change', renderList);
document.getElementById('filterType').addEventListener('change', renderList);
document.getElementById('filterStatus').addEventListener('change', renderList);
}
async function apiRequest(action, params = {}) {
try {
const response = await fetch('../RequestHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action, params })
});
return await response.json();
} catch (error) {
console.error("Erreur API:", error);
return { success: false, error: "Erreur de connexion au serveur" };
}
}
async function addMovie(tmdbId, title, posterPath, type) {
const result = await apiRequest('addMovie', {
tmdb_id: tmdbId,
titre: title,
affiche_path: posterPath,
type: type
});
if (result.success) {
alert(`"${title}" a été ajouté à votre liste ! 🍿`);
closeModal();
} else {
alert('Erreur lors de l\'ajout. Vérifie si le film n\'est pas déjà présent.');
}
}
async function loadList() {
const response = await fetch('../RequestHandler.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'getMyList' })
});
const data = await response.json();
if (data.success) {
allMovies = data.movies;
renderList();
}
}
function renderList() {
const grid = document.getElementById('myListGrid');
const sort = document.getElementById('sortOrder').value;
const type = document.getElementById('filterType').value;
const status = document.getElementById('filterStatus').value;
// 1. Filtrage
let filtered = allMovies.filter(m => {
const matchType = (type === 'all' || m.type === type);
const matchStatus = (status === 'all' || m.vu == status);
return matchType && matchStatus;
});
// 2. Tri
filtered.sort((a, b) => {
if (sort === 'titre_asc') return a.titre.localeCompare(b.titre);
if (sort === 'date_ajout_asc') return new Date(a.date_ajout) - new Date(b.date_ajout);
if (sort === 'date_ajout_desc') return new Date(b.date_ajout) - new Date(a.date_ajout);
});
// 3. Affichage
grid.innerHTML = '';
document.getElementById('movieCount').innerText = filtered.length;
filtered.forEach(m => {
const card = document.createElement('div');
// On ajoute 'flex flex-col' pour que le contenu s'empile proprement
card.className = `relative group bg-slate-800 rounded-xl overflow-hidden border ${m.vu == 1 ? 'border-green-500/50' : 'border-slate-700'} flex flex-col h-full`;
if (currentView === 'partner') {
card.innerHTML = `
${m.titre}
`;
} else if (currentView === 'common') {
card.innerHTML = `
${m.titre}
`;
} else {
card.innerHTML = `
`;
}
grid.appendChild(card);
});
}
// Actions rapides
async function toggleVu(id) {
const res = await fetch('../RequestHandler.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'toggleViewed', params: { movie_id: id } })
});
const data = await res.json();
if (data.success) {
// On met à jour localement pour ne pas recharger toute l'API
const movie = allMovies.find(m => m.id == id);
movie.vu = movie.vu == 1 ? 0 : 1;
renderList();
}
}
async function deleteMovie(id) {
if(!confirm("Supprimer ce film de ta liste ?")) return;
const res = await fetch('../RequestHandler.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'deleteMovie', params: { movie_id: id } })
});
const data = await res.json();
if (data.success) {
allMovies = allMovies.filter(m => m.id != id);
renderList();
}
}
let currentView = 'my'; // 'my', 'common', ou 'partner'
async function switchTab(view) {
currentView = view;
// Mise à jour visuelle des boutons
const tabs = ['my', 'common', 'partner'];
tabs.forEach(t => {
const btn = document.getElementById(`tab-${t}`);
if (t === view) {
btn.classList.replace('bg-slate-700/50', 'bg-slate-800');
btn.classList.replace('text-gray-400', 'text-white');
btn.classList.replace('border-transparent', 'border-blue-500');
} else {
btn.classList.replace('bg-slate-800', 'bg-slate-700/50');
btn.classList.replace('text-white', 'text-gray-400');
btn.classList.replace('border-blue-500', 'border-transparent');
}
});
// On recharge les données selon la vue
let action = 'getMyList';
if (view === 'common') action = 'getCommonList';
if (view === 'partner') action = 'getPartnerList'; // Il faudra créer cette action dans RequestHandler
const response = await apiRequest(action);
if (response.success) {
allMovies = response.movies || response.common_movies;
renderList();
}
}
async function showDetails(tmdbId, type, localId = null, isVu = 0) {
// 1. On récupère les détails complets via TMDB (comme dans search.js)
const mediaType = (type === 'serie') ? 'tv' : 'movie';
// On appelle ton RequestHandler pour avoir les détails + acteurs
const movie = await apiRequest('getMovieDetails', { id: tmdbId, type: mediaType });
if (!movie) return;
// 2. On remplit la modal avec les infos fraîches
document.getElementById('modalTitle').innerText = movie.title || movie.name;
const year = (movie.release_date || movie.first_air_date || "").substring(0, 4);
const duration = movie.runtime ? `${movie.runtime} min` : (movie.number_of_seasons ? `${movie.number_of_seasons} Saison(s)` : "");
const genres = movie.genres.map(g => g.name).join(', ');
document.getElementById('modalMeta').innerText = `${year} • ${genres} ${duration ? '• ' + duration : ''}`;
document.getElementById('modalOverview').innerText = movie.overview || "Aucun synopsis disponible.";
document.getElementById('modalVote').innerText = movie.vote_average ? movie.vote_average.toFixed(1) : "N/A";
// Image de bannière
const bannerUrl = movie.backdrop_path ? `https://image.tmdb.org/t/p/original${movie.backdrop_path}` : '';
document.getElementById('modalBanner').style.backgroundImage = `url(${bannerUrl})`;
// Réalisateur
const director = movie.credits.crew.find(person => person.job === 'Director');
document.getElementById('modalDirector').innerText = director ? director.name : "Non renseigné";
// Casting
const castContainer = document.getElementById('modalCast');
castContainer.innerHTML = movie.credits.cast.slice(0, 8).map(actor => `
${actor.name}
`).join('');
// 3. LOGIQUE DU BOUTON (Vu / Pas Vu)
const btn = document.getElementById('modalMainBtn');
const ratingZone = document.getElementById('ratingZone');
if (localId) {
ratingZone.classList.remove('hidden'); // On montre les étoiles
if (isVu == 1) {
btn.innerText = "NE PLUS MARQUER COMME VU";
btn.className = "w-full bg-slate-700 hover:bg-slate-600 text-white py-4 rounded-xl font-black transition-all";
} else {
btn.innerText = "MARQUER COMME VU";
btn.className = "w-full bg-green-600 hover:bg-green-500 text-white py-4 rounded-xl font-black transition-all";
}
btn.onclick = async () => {
await toggleVu(localId); // Ta fonction qui change le statut en BDD
closeModal();
};
}
// 4. LOGIQYUE DES ÉTOILES
// On récupère la note actuelle pour ce film (si elle existe)
apiRequest('getStarsRating', { movie_id: localId }).then(res => {
if (res.success) {
const currentRating = res.rating || 0;
setRating(currentRating); // On affiche la note actuelle
}
});
// Affichage final
document.getElementById('movieModal').classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
// Fonction pour les étoiles
function setRating(note) {
const currentMovieId = document.getElementById('modalMainBtn').onclick.toString().match(/toggleVu\((\d+)\)/)[1]; // Extraction de l'ID du film
const stars = document.querySelectorAll('#starContainer span');
stars.forEach((star, index) => {
if (index < note) {
star.classList.replace('text-gray-600', 'text-yellow-400');
} else {
star.classList.replace('text-yellow-400', 'text-gray-600');
}
});
apiRequest('setStarsRating', { movie_id: currentMovieId, rating: note }); // currentMovieId doit être défini lors de l'ouverture de la modal
}
function closeModal() {
document.getElementById('movieModal').classList.add('hidden');
document.body.style.overflow = 'auto';
}
loadList();