aa
This commit is contained in:
@@ -55,16 +55,24 @@ switch ($action) {
|
|||||||
|
|
||||||
// --- GESTION DES FILMS ---
|
// --- GESTION DES FILMS ---
|
||||||
case 'addMovie':
|
case 'addMovie':
|
||||||
$stmt = $pdo->prepare("INSERT INTO movies (tmdb_id, titre, affiche_path, type, user_id, vu) VALUES (?, ?, ?, ?, ?, 0)");
|
// On cherche si le film existe déjà pour cet utilisateur
|
||||||
$success = $stmt->execute([
|
$stmt = $pdo->prepare("SELECT id FROM movies WHERE tmdb_id = ? AND user_id = ?");
|
||||||
$params['tmdb_id'],
|
$stmt->execute([$params['tmdb_id'], $current_user_id]);
|
||||||
$params['titre'],
|
if ($stmt->fetch()) {
|
||||||
$params['affiche_path'],
|
echo json_encode(['success' => false, 'error' => 'Film déjà dans la liste']);
|
||||||
$params['type'], // 'film' ou 'serie'
|
exit;
|
||||||
$current_user_id
|
} else {
|
||||||
]);
|
$stmt = $pdo->prepare("INSERT INTO movies (tmdb_id, titre, affiche_path, type, user_id, vu) VALUES (?, ?, ?, ?, ?, 0)");
|
||||||
echo json_encode(['success' => $success]);
|
$success = $stmt->execute([
|
||||||
exit;
|
$params['tmdb_id'],
|
||||||
|
$params['titre'],
|
||||||
|
$params['affiche_path'],
|
||||||
|
$params['type'], // 'film' ou 'serie'
|
||||||
|
$current_user_id
|
||||||
|
]);
|
||||||
|
echo json_encode(['success' => $success]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
case 'getMyList':
|
case 'getMyList':
|
||||||
// Récupère les films ajoutés par l'utilisateur
|
// Récupère les films ajoutés par l'utilisateur
|
||||||
@@ -86,12 +94,19 @@ switch ($action) {
|
|||||||
$stmt->execute([$current_user_id, $partner_id]);
|
$stmt->execute([$current_user_id, $partner_id]);
|
||||||
echo json_encode(['success' => true, 'common_movies' => $stmt->fetchAll()]);
|
echo json_encode(['success' => true, 'common_movies' => $stmt->fetchAll()]);
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
case 'getPartnerList':
|
||||||
|
$partner_id = ($current_user_id == 1) ? 2 : 1;
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM movies WHERE user_id = ? ORDER BY date_ajout DESC");
|
||||||
|
$stmt->execute([$partner_id]);
|
||||||
|
echo json_encode(['success' => true, 'movies' => $stmt->fetchAll()]);
|
||||||
|
exit;
|
||||||
|
|
||||||
// --- ACTIONS SUR LE FILM ---
|
// --- ACTIONS SUR LE FILM ---
|
||||||
case 'toggleViewed':
|
case 'toggleViewed':
|
||||||
// Alterne entre vu (1) et non vu (0)
|
// Alterne entre vu (1) et non vu (0)
|
||||||
$stmt = $pdo->prepare("UPDATE movies SET vu = !vu WHERE id = ? AND user_id = ?");
|
$stmt = $pdo->prepare("UPDATE movies SET vu = !vu WHERE id = ?");
|
||||||
$success = $stmt->execute([(int)$params['movie_id'], $current_user_id]);
|
$success = $stmt->execute([(int)$params['movie_id']]);
|
||||||
echo json_encode(['success' => $success]);
|
echo json_encode(['success' => $success]);
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
@@ -112,6 +127,16 @@ switch ($action) {
|
|||||||
echo json_encode(['success' => $success]);
|
echo json_encode(['success' => $success]);
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
case 'getComments':
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT c.*, u.pseudo FROM commentaires c
|
||||||
|
JOIN users u ON c.user_id = u.id
|
||||||
|
WHERE c.movie_id = ? ORDER BY c.date_ajout DESC
|
||||||
|
");
|
||||||
|
$stmt->execute([(int)$params['movie_id']]);
|
||||||
|
echo json_encode(['success' => true, 'comments' => $stmt->fetchAll()]);
|
||||||
|
exit;
|
||||||
|
|
||||||
case 'getMovieDetails':
|
case 'getMovieDetails':
|
||||||
$id = $params['id'];
|
$id = $params['id'];
|
||||||
$type = $params['type']; // 'movie' ou 'tv'
|
$type = $params['type']; // 'movie' ou 'tv'
|
||||||
@@ -121,6 +146,54 @@ switch ($action) {
|
|||||||
$response = file_get_contents($url);
|
$response = file_get_contents($url);
|
||||||
echo $response;
|
echo $response;
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
case 'setStarsRating':
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO movies (rating) VALUES (?) WHERE id = ?");
|
||||||
|
$success = $stmt->execute([
|
||||||
|
(int)$params['movie_id'],
|
||||||
|
(int)$params['rating']
|
||||||
|
]);
|
||||||
|
echo json_encode(['success' => $success]);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'getStarsRating':
|
||||||
|
$stmt = $pdo->prepare("SELECT rating FROM movies WHERE id = ?");
|
||||||
|
$stmt->execute([(int)$params['movie_id']]);
|
||||||
|
$rating = $stmt->fetchColumn();
|
||||||
|
echo json_encode(['success' => true, 'rating' => $rating]);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'register':
|
||||||
|
$pseudo = $params['pseudo'];
|
||||||
|
$pass = password_hash($params['password'], PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO users (pseudo, password) VALUES (?, ?)");
|
||||||
|
try {
|
||||||
|
$stmt->execute([$pseudo, $pass]);
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Pseudo déjà pris']);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'login':
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM users WHERE pseudo = ?");
|
||||||
|
$stmt->execute([$params['pseudo']]);
|
||||||
|
$user = $stmt->fetch();
|
||||||
|
|
||||||
|
if ($user && password_verify($params['password'], $user['password'])) {
|
||||||
|
$_SESSION['user_id'] = $user['id'];
|
||||||
|
$_SESSION['pseudo'] = $user['pseudo'];
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Identifiants incorrects']);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'logout':
|
||||||
|
session_destroy();
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
echo json_encode(['success' => false, 'error' => 'Action inconnue']);
|
echo json_encode(['success' => false, 'error' => 'Action inconnue']);
|
||||||
|
|||||||
+31
-14
@@ -2,25 +2,42 @@
|
|||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>WatchGether - Recherche</title>
|
<title>WatchGether - Connexion</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-slate-900 text-white p-8">
|
<body class="bg-slate-900 text-white flex items-center justify-center min-h-screen">
|
||||||
|
|
||||||
<div class="max-w-4xl mx-auto">
|
<div class="bg-slate-800 p-8 rounded-2xl shadow-xl w-full max-w-md border border-white/5">
|
||||||
<h1 class="text-3xl font-bold mb-8 text-blue-400 text-center">WatchGether</h1>
|
<h1 class="text-3xl font-black text-center mb-8 text-blue-400 italic">WATCHGETHER</h1>
|
||||||
|
|
||||||
<div class="flex gap-2 mb-10">
|
<div id="authForm">
|
||||||
<input type="text" id="searchInput" placeholder="Chercher un film ou une série..."
|
<input type="text" id="pseudo" placeholder="Pseudo" class="w-full p-4 mb-4 bg-slate-900 rounded-lg border border-slate-700 focus:border-blue-500 outline-none">
|
||||||
class="flex-grow p-4 rounded-lg bg-slate-800 border border-slate-700 focus:outline-none focus:border-blue-500">
|
<input type="password" id="password" placeholder="Mot de passe" class="w-full p-4 mb-6 bg-slate-900 rounded-lg border border-slate-700 focus:border-blue-500 outline-none">
|
||||||
<button onclick="performSearch()" class="bg-blue-600 px-8 py-4 rounded-lg font-bold hover:bg-blue-500 transition">
|
|
||||||
Chercher
|
<button onclick="handleAuth('login')" class="w-full bg-blue-600 hover:bg-blue-500 py-4 rounded-xl font-bold mb-4 transition">Se connecter</button>
|
||||||
</button>
|
<button onclick="handleAuth('register')" class="w-full bg-slate-700 hover:bg-slate-600 py-4 rounded-xl font-bold transition">Créer un compte</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="resultsGrid" class="grid grid-cols-2 md:grid-cols-4 gap-6"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<?php include 'modal-template.php';?>
|
|
||||||
<script src="js/index.js"></script>
|
<script>
|
||||||
|
async function handleAuth(action) {
|
||||||
|
const pseudo = document.getElementById('pseudo').value;
|
||||||
|
const password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
const response = await fetch('RequestHandler.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ action, params: { pseudo, password } })
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
if (action === 'register') alert("Compte créé ! Connecte-toi maintenant.");
|
||||||
|
else window.location.href = 'search/index.php';
|
||||||
|
} else {
|
||||||
|
alert(data.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+225
-17
@@ -1,7 +1,46 @@
|
|||||||
let allMovies = []; // Stockage local de la liste entière
|
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() {
|
async function loadList() {
|
||||||
const response = await fetch('RequestHandler.php', {
|
const response = await fetch('../RequestHandler.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ action: 'getMyList' })
|
body: JSON.stringify({ action: 'getMyList' })
|
||||||
@@ -40,28 +79,74 @@ function renderList() {
|
|||||||
|
|
||||||
filtered.forEach(m => {
|
filtered.forEach(m => {
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = `relative group bg-slate-800 rounded-xl overflow-hidden border ${m.vu == 1 ? 'border-green-500/50' : 'border-slate-700'}`;
|
// On ajoute 'flex flex-col' pour que le contenu s'empile proprement
|
||||||
card.innerHTML = `
|
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`;
|
||||||
<img src="https://image.tmdb.org/t/p/w500${m.affiche_path}" class="w-full h-auto ${m.vu == 1 ? 'opacity-40 grayscale' : ''}">
|
|
||||||
<div class="p-3">
|
if (currentView === 'partner') {
|
||||||
<h3 class="font-bold text-sm truncate">${m.titre}</h3>
|
card.innerHTML = `
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="relative aspect-[2/3] overflow-hidden cursor-pointer" onclick="showDetails(${m.tmdb_id}, '${m.type}', ${m.id}, ${m.vu})">
|
||||||
<button onclick="toggleVu(${m.id})" class="flex-grow py-1 rounded text-[10px] font-bold ${m.vu == 1 ? 'bg-green-600' : 'bg-slate-700 hover:bg-slate-600'}">
|
<img src="https://image.tmdb.org/t/p/w500${m.affiche_path}"
|
||||||
${m.vu == 1 ? 'VU' : 'À VOIR'}
|
class="w-full h-full object-cover transition-transform group-hover:scale-110 ${m.vu == 1 ? 'opacity-40 grayscale' : ''}">
|
||||||
</button>
|
|
||||||
<button onclick="deleteMovie(${m.id})" class="bg-red-900/50 hover:bg-red-600 px-2 py-1 rounded text-[10px]">
|
|
||||||
🗑️
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
`;
|
<div class="p-3 flex flex-col justify-between flex-grow bg-slate-800">
|
||||||
|
<h3 class="font-bold text-sm text-white truncate mb-2" title="${m.titre}">${m.titre}</h3>
|
||||||
|
|
||||||
|
<div class="flex gap-2 mt-auto">
|
||||||
|
<button onclick="addMovie(${m.tmdb_id}, '${m.titre}', '${m.affiche_path}', '${m.type}')" class="w-full bg-blue-600 hover:bg-blue-500 text-white py-4 rounded-xl font-black shadow-lg transition-all active:scale-95">
|
||||||
|
+ AJOUTER À LA LISTE
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
} else if (currentView === 'common') {
|
||||||
|
|
||||||
|
card.innerHTML = `
|
||||||
|
<div class="relative aspect-[2/3] overflow-hidden cursor-pointer" onclick="showDetails(${m.tmdb_id}, '${m.type}', ${m.id}, ${m.vu})">
|
||||||
|
<img src="https://image.tmdb.org/t/p/w500${m.affiche_path}"
|
||||||
|
class="w-full h-full object-cover transition-transform group-hover:scale-110 ${m.vu == 1 ? 'opacity-40 grayscale' : ''}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-3 flex flex-col justify-between flex-grow bg-slate-800">
|
||||||
|
<h3 class="font-bold text-sm text-white truncate mb-2" title="${m.titre}">${m.titre}</h3>
|
||||||
|
|
||||||
|
<div class="flex gap-2 mt-auto">
|
||||||
|
<button onclick="toggleVu(${m.id})" class="flex-grow py-2 rounded text-[10px] font-black tracking-wider transition-colors ${m.vu == 1 ? 'bg-green-600 text-white' : 'bg-slate-700 text-gray-300 hover:bg-slate-600'}">
|
||||||
|
${m.vu == 1 ? 'VU' : 'À VOIR'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
card.innerHTML = `
|
||||||
|
<div class="relative aspect-[2/3] overflow-hidden cursor-pointer" onclick="showDetails(${m.tmdb_id}, '${m.type}', ${m.id}, ${m.vu})">
|
||||||
|
<img src="https://image.tmdb.org/t/p/w500${m.affiche_path}"
|
||||||
|
class="w-full h-full object-cover transition-transform group-hover:scale-110 ${m.vu == 1 ? 'opacity-40 grayscale' : ''}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-3 flex flex-col justify-between flex-grow bg-slate-800">
|
||||||
|
<h3 class="font-bold text-sm text-white truncate mb-2" title="${m.titre}">${m.titre}</h3>
|
||||||
|
|
||||||
|
<div class="flex gap-2 mt-auto">
|
||||||
|
<button onclick="showDetails(${m.tmdb_id}, '${m.type}', ${m.id}, ${m.vu})" class="flex-grow py-2 rounded text-[10px] font-black tracking-wider transition-colors bg-slate-700 text-gray-300 hover:bg-slate-600">
|
||||||
|
Voir plus
|
||||||
|
</button>
|
||||||
|
<button onclick="deleteMovie(${m.id})" class="bg-red-900/30 hover:bg-red-600 text-red-500 hover:text-white px-3 py-2 rounded transition-colors text-[10px]">
|
||||||
|
🗑️
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
grid.appendChild(card);
|
grid.appendChild(card);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions rapides
|
// Actions rapides
|
||||||
async function toggleVu(id) {
|
async function toggleVu(id) {
|
||||||
const res = await fetch('RequestHandler.php', {
|
const res = await fetch('../RequestHandler.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ action: 'toggleViewed', params: { movie_id: id } })
|
body: JSON.stringify({ action: 'toggleViewed', params: { movie_id: id } })
|
||||||
@@ -77,7 +162,7 @@ async function toggleVu(id) {
|
|||||||
|
|
||||||
async function deleteMovie(id) {
|
async function deleteMovie(id) {
|
||||||
if(!confirm("Supprimer ce film de ta liste ?")) return;
|
if(!confirm("Supprimer ce film de ta liste ?")) return;
|
||||||
const res = await fetch('RequestHandler.php', {
|
const res = await fetch('../RequestHandler.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ action: 'deleteMovie', params: { movie_id: id } })
|
body: JSON.stringify({ action: 'deleteMovie', params: { movie_id: id } })
|
||||||
@@ -89,4 +174,127 @@ async function deleteMovie(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 => `
|
||||||
|
<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 text-white">${actor.name}</p>
|
||||||
|
</div>
|
||||||
|
`).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();
|
loadList();
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
async function apiRequest(action, params = {}) {
|
async function apiRequest(action, params = {}) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('RequestHandler.php', {
|
const response = await fetch('../RequestHandler.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -21,6 +21,8 @@ async function apiRequest(action, params = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('ratingZone').classList.add('hidden');
|
||||||
|
|
||||||
// --- RECHERCHE ---
|
// --- RECHERCHE ---
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,7 +118,13 @@ async function showDetails(id, type) {
|
|||||||
|
|
||||||
// 5. Bouton Ajouter (on passe les infos pour la BDD)
|
// 5. Bouton Ajouter (on passe les infos pour la BDD)
|
||||||
const simplifiedType = (mediaType === 'tv') ? 'serie' : 'film';
|
const simplifiedType = (mediaType === 'tv') ? 'serie' : 'film';
|
||||||
document.getElementById('modalAddBtn').onclick = () => addMovie(movie.id, movie.title || movie.name, movie.poster_path, simplifiedType);
|
const btn = document.getElementById('modalMainBtn');
|
||||||
|
btn.innerText = "+ AJOUTER À LA LISTE";
|
||||||
|
btn.className = "w-full bg-blue-600 hover:bg-blue-500 text-white py-4 rounded-xl font-black shadow-lg transition-all active:scale-95";
|
||||||
|
btn.onclick = () => addMovie(movie.id, movie.title || movie.name, movie.poster_path, simplifiedType);
|
||||||
|
|
||||||
|
// Cache les étoiles en mode recherche
|
||||||
|
document.getElementById('ratingZone').classList.add('hidden');
|
||||||
|
|
||||||
// Affichage
|
// Affichage
|
||||||
modal.classList.remove('hidden');
|
modal.classList.remove('hidden');
|
||||||
@@ -157,4 +165,16 @@ document.getElementById('searchInput').addEventListener('keypress', function (e)
|
|||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
performSearch();
|
performSearch();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function LogOut() {
|
||||||
|
const res = await fetch('../RequestHandler.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ action: 'logout' })
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (data.success) {
|
||||||
|
window.location.href = '../index.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION['user_id'])) {
|
||||||
|
header('Location: ../index.php'); // Redirige vers le login si pas de session
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
@@ -10,7 +18,24 @@
|
|||||||
<div class="max-w-6xl mx-auto">
|
<div class="max-w-6xl mx-auto">
|
||||||
<div class="flex justify-between items-center mb-10">
|
<div class="flex justify-between items-center mb-10">
|
||||||
<h1 class="text-3xl font-bold text-blue-400">Ma Liste 🍿</h1>
|
<h1 class="text-3xl font-bold text-blue-400">Ma Liste 🍿</h1>
|
||||||
<a href="index.php" class="bg-slate-800 px-4 py-2 rounded-lg hover:bg-slate-700 transition">← Retour à la recherche</a>
|
<a href="../search/index.php" class="bg-slate-800 px-4 py-2 rounded-lg hover:bg-slate-700 transition">← Retour à la recherche</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-end mb-0 border-b border-slate-700">
|
||||||
|
<button onclick="switchTab('my')" id="tab-my"
|
||||||
|
class="px-8 py-4 bg-slate-800 text-white font-bold text-sm uppercase tracking-widest border-b-4 border-blue-500 transition-all">
|
||||||
|
Ma Liste
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick="switchTab('common')" id="tab-common"
|
||||||
|
class="px-8 py-4 bg-slate-700/50 text-gray-400 font-bold text-sm uppercase tracking-widest border-b-4 border-transparent hover:bg-slate-800 hover:text-white transition-all">
|
||||||
|
Notre Liste
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick="switchTab('partner')" id="tab-partner"
|
||||||
|
class="px-8 py-4 bg-slate-700/50 text-gray-400 font-bold text-sm uppercase tracking-widest border-b-4 border-transparent hover:bg-slate-800 hover:text-white transition-all">
|
||||||
|
Sa Liste
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-slate-800 p-4 rounded-xl mb-8 flex flex-wrap gap-4 items-center">
|
<div class="bg-slate-800 p-4 rounded-xl mb-8 flex flex-wrap gap-4 items-center">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div id="movieModal" class="fixed inset-0 bg-black/95 z-50 hidden overflow-y-auto">
|
<div id="movieModal" class="fixed inset-0 bg-black/95 z-50 hidden overflow-y-auto">
|
||||||
<div class="relative w-full max-w-5xl mx-auto min-h-screen bg-slate-900 shadow-2xl border-x border-white/10">
|
<div class="relative w-full max-w-5xl mx-auto min-h-screen bg-slate-900 shadow-2xl border-x border-white/10">
|
||||||
|
|
||||||
<button onclick="closeModal()" class="absolute top-6 right-6 z-50 bg-black/50 text-white p-2 rounded-full hover:bg-red-600 transition">
|
<button onclick="closeModal()" class="absolute top-6 right-6 z-50 bg-black/50 text-white p-2 rounded-full hover:bg-red-600 transition">
|
||||||
@@ -21,8 +21,7 @@
|
|||||||
<p id="modalOverview" class="text-gray-300 leading-relaxed text-lg mb-8"></p>
|
<p id="modalOverview" class="text-gray-300 leading-relaxed text-lg mb-8"></p>
|
||||||
|
|
||||||
<h3 class="text-xl font-bold mb-4 text-white border-b border-white/10 pb-2">Casting principal</h3>
|
<h3 class="text-xl font-bold mb-4 text-white border-b border-white/10 pb-2">Casting principal</h3>
|
||||||
<div id="modalCast" class="flex gap-4 overflow-x-auto pb-6 scrollbar-hide">
|
<div id="modalCast" class="flex gap-4 overflow-x-auto pb-6 scrollbar-hide"></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
@@ -34,12 +33,25 @@
|
|||||||
<span class="text-gray-500 font-bold">/ 10</span>
|
<span class="text-gray-500 font-bold">/ 10</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<span class="text-gray-400 text-xs uppercase tracking-widest block mb-1">Réalisateur</span>
|
<span class="text-gray-400 text-xs uppercase tracking-widest block mb-1">Réalisateur</span>
|
||||||
<span id="modalDirector" class="text-xl font-bold text-white"></span>
|
<span id="modalDirector" class="text-xl font-bold text-white"></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="modalAddBtn" class="w-full bg-green-600 hover:bg-green-500 text-white py-4 rounded-xl font-black text-lg shadow-lg shadow-green-900/20 transition-all active:scale-95">
|
|
||||||
+ AJOUTER À LA LISTE
|
<div id="ratingZone" class="mb-6 hidden">
|
||||||
|
<span class="text-gray-400 text-xs uppercase tracking-widest block mb-2">Ta note</span>
|
||||||
|
<div class="flex gap-2 text-2xl" id="starContainer">
|
||||||
|
<span onclick="setRating(1)" class="cursor-pointer hover:text-yellow-400 transition text-gray-600">★</span>
|
||||||
|
<span onclick="setRating(2)" class="cursor-pointer hover:text-yellow-400 transition text-gray-600">★</span>
|
||||||
|
<span onclick="setRating(3)" class="cursor-pointer hover:text-yellow-400 transition text-gray-600">★</span>
|
||||||
|
<span onclick="setRating(4)" class="cursor-pointer hover:text-yellow-400 transition text-gray-600">★</span>
|
||||||
|
<span onclick="setRating(5)" class="cursor-pointer hover:text-yellow-400 transition text-gray-600">★</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="modalMainBtn" class="w-full py-4 rounded-xl font-black text-lg shadow-lg transition-all active:scale-95 text-white bg-blue-600 hover:bg-blue-500">
|
||||||
|
ACTION
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION['user_id'])) {
|
||||||
|
header('Location: ../index.php'); // Redirige vers le login si pas de session
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>WatchGether - Recherche</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-slate-900 text-white p-8">
|
||||||
|
|
||||||
|
<div class="max-w-4xl mx-auto">
|
||||||
|
<div class="flex justify-between items-center mb-8">
|
||||||
|
<a href="../ma-liste" class="bg-slate-800 hover:bg-slate-700 text-white px-6 py-3 rounded-xl font-bold border border-white/5 transition-all active:scale-95 shadow-lg">
|
||||||
|
🍿 Ma liste
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<h1 class="text-5xl md:text-6xl font-black tracking-tighter italic">
|
||||||
|
<span class="text-blue-500">WATCH</span><span class="text-white">GETHER</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<button onclick="LogOut()" class="bg-red-600 hover:bg-red-500 text-white px-6 py-3 rounded-xl font-bold shadow-lg shadow-red-900/20 transition-all active:scale-95">
|
||||||
|
👤 Se déconnecter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2 mb-10">
|
||||||
|
<input type="text" id="searchInput" placeholder="Chercher un film ou une série..."
|
||||||
|
class="flex-grow p-4 rounded-lg bg-slate-800 border border-slate-700 focus:outline-none focus:border-blue-500 text-white">
|
||||||
|
<button onclick="performSearch()" class="bg-blue-600 px-8 py-4 rounded-lg font-bold hover:bg-blue-500 transition shadow-lg">
|
||||||
|
Chercher
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="resultsGrid" class="grid grid-cols-2 md:grid-cols-4 gap-6"></div>
|
||||||
|
</div>
|
||||||
|
<?php include '../modal-template.php';?>
|
||||||
|
<script src="../js/search.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user