add movies details

This commit is contained in:
2026-04-13 02:31:16 +02:00
parent c0cbb0ddb2
commit 4b860af7fa
2 changed files with 130 additions and 24 deletions
+10
View File
@@ -111,6 +111,16 @@ switch ($action) {
]);
echo json_encode(['success' => $success]);
exit;
case 'getMovieDetails':
$id = $params['id'];
$type = $params['type']; // 'movie' ou 'tv'
// On demande les détails + les crédits (acteurs) en une seule fois
$url = "https://api.themoviedb.org/3/$type/$id?api_key=$apiKey&language=fr-FR&append_to_response=credits";
$response = file_get_contents($url);
echo $response;
exit;
default:
echo json_encode(['success' => false, 'error' => 'Action inconnue']);
+120 -24
View File
@@ -1,53 +1,141 @@
// Fonction principale pour parler au RequestHandler
// --- CONFIGURATION & UTILITAIRES ---
/**
* Fonction universelle pour parler à ton RequestHandler
* @param {string} action - L'action à exécuter (ex: 'searchTMDB')
* @param {object} params - Les données à envoyer
*/
async function apiRequest(action, params = {}) {
const response = await fetch('RequestHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json' // J'ai enlevé le ":" après Type
},
body: JSON.stringify({ action, params })
});
return await response.json();
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" };
}
}
// Action de recherche
// --- RECHERCHE ---
/**
* Lance la recherche TMDB et affiche les résultats sous forme de cartes
*/
async function performSearch() {
const query = document.getElementById('searchInput').value;
if (!query) return;
const grid = document.getElementById('resultsGrid');
grid.innerHTML = '<p class="col-span-full text-center">Recherche en cours...</p>';
grid.innerHTML = '<p class="col-span-full text-center py-10 opacity-50">Recherche de pépites en cours...</p>';
const data = await apiRequest('searchTMDB', { query: query });
grid.innerHTML = ''; // On vide le message de chargement
grid.innerHTML = ''; // On vide
if (data.results) {
if (data.results && data.results.length > 0) {
data.results.forEach(item => {
if (!item.poster_path) return;
// On ignore les résultats sans image ou qui ne sont pas film/série
if (!item.poster_path || (item.media_type !== 'movie' && item.media_type !== 'tv')) return;
const title = item.title || item.name;
const poster = `https://image.tmdb.org/t/p/w500${item.poster_path}`;
const type = item.media_type === 'tv' ? 'serie' : 'film';
const year = (item.release_date || item.first_air_date || "").substring(0, 4);
const card = document.createElement('div');
card.className = 'bg-slate-800 rounded-xl overflow-hidden border border-slate-700 hover:scale-105 transition-transform';
card.className = 'bg-slate-800 rounded-xl overflow-hidden border border-slate-700 hover:scale-105 transition-transform cursor-pointer group';
card.innerHTML = `
<img src="${poster}" class="w-full h-auto">
<div class="relative overflow-hidden" onclick="showDetails(${item.id}, '${item.media_type}')">
<img src="${poster}" class="w-full h-auto">
<div class="absolute inset-0 bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
<span class="bg-white text-black px-4 py-2 rounded-full font-bold text-xs uppercase tracking-wider">Voir la fiche</span>
</div>
</div>
<div class="p-3">
<h3 class="font-bold text-sm truncate">${title}</h3>
<button onclick="addMovie(${item.id}, '${title.replace(/'/g, "\\'")}', '${item.poster_path}', '${type}')"
class="mt-2 w-full bg-green-600 text-xs py-2 rounded font-bold hover:bg-green-500">
+ Ajouter
</button>
<div class="flex justify-between items-center mt-1">
<span class="text-[10px] text-gray-400 uppercase">${type}</span>
<span class="text-[10px] text-blue-400 font-bold">${year}</span>
</div>
</div>
`;
grid.appendChild(card);
});
} else {
grid.innerHTML = '<p class="col-span-full text-center py-10 text-gray-500">Aucun résultat trouvé pour cette recherche.</p>';
}
}
// Action d'ajout
// --- FICHE DÉTAILLÉE (MODAL) ---
/**
* Récupère les détails complets d'un film et ouvre la modal
*/
async function showDetails(id, type) {
// TMDB utilise 'movie' ou 'tv', on s'assure d'avoir le bon type
const mediaType = (type === 'serie') ? 'tv' : type;
const movie = await apiRequest('getMovieDetails', { id: id, type: mediaType });
if (!movie) return;
const modal = document.getElementById('movieModal');
// 1. Textes de base
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 pour le moment.";
document.getElementById('modalVote').innerText = movie.vote_average ? movie.vote_average.toFixed(1) : "N/A";
// 2. Images (Bannière)
const bannerUrl = movie.backdrop_path ? `https://image.tmdb.org/t/p/original${movie.backdrop_path}` : '';
document.getElementById('modalBanner').style.backgroundImage = `url(${bannerUrl})`;
// 3. Réalisateur
const director = movie.credits.crew.find(person => person.job === 'Director');
document.getElementById('modalDirector').innerText = director ? director.name : "Non renseigné";
// 4. Casting (Les 8 premiers)
const castContainer = document.getElementById('modalCast');
castContainer.innerHTML = movie.credits.cast.slice(0, 8).map(actor => `
<div class="min-w-[110px] text-center flex-shrink-0">
<img src="${actor.profile_path ? 'https://image.tmdb.org/t/p/w185' + actor.profile_path : 'https://via.placeholder.com/185x278?text=No+Image'}"
class="w-20 h-20 object-cover rounded-full mx-auto mb-2 border-2 border-slate-700 shadow-lg">
<p class="text-[10px] font-bold leading-tight text-white">${actor.name}</p>
<p class="text-[9px] text-gray-500 italic">${actor.character}</p>
</div>
`).join('');
// 5. Bouton Ajouter (on passe les infos pour la BDD)
const simplifiedType = (mediaType === 'tv') ? 'serie' : 'film';
document.getElementById('modalAddBtn').onclick = () => addMovie(movie.id, movie.title || movie.name, movie.poster_path, simplifiedType);
// Affichage
modal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
/**
* Ferme la modal
*/
function closeModal() {
document.getElementById('movieModal').classList.add('hidden');
document.body.style.overflow = 'auto';
}
// --- ACTIONS BDD ---
/**
* Ajoute un film dans la base de données MySQL
*/
async function addMovie(tmdbId, title, posterPath, type) {
const result = await apiRequest('addMovie', {
tmdb_id: tmdbId,
@@ -57,8 +145,16 @@ async function addMovie(tmdbId, title, posterPath, type) {
});
if (result.success) {
alert('Ajouté à la liste !');
alert(`"${title}" a été ajouté à votre liste ! 🍿`);
closeModal();
} else {
alert('Erreur lors de l\'ajout.');
alert('Erreur lors de l\'ajout. Vérifie si le film n\'est pas déjà présent.');
}
}
}
// Permettre la recherche avec la touche "Entrée"
document.getElementById('searchInput').addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
performSearch();
}
});