| <!DOCTYPE html> |
| <html lang="fr"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Tableau de Bord Cinéma</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .movie-card:hover .movie-overlay { |
| opacity: 1; |
| } |
| .movie-overlay { |
| transition: opacity 0.3s ease; |
| } |
| .skeleton { |
| animation: pulse 2s infinite ease-in-out; |
| } |
| @keyframes pulse { |
| 0%, 100% { opacity: 0.6; } |
| 50% { opacity: 0.3; } |
| } |
| .server-btn { |
| transition: all 0.3s ease; |
| } |
| .server-btn:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
| } |
| .player-container { |
| display: none; |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| background-color: rgba(0, 0, 0, 0.9); |
| z-index: 1000; |
| justify-content: center; |
| align-items: center; |
| } |
| .player-wrapper { |
| width: 80%; |
| max-width: 1200px; |
| position: relative; |
| } |
| .close-player { |
| position: absolute; |
| top: -40px; |
| right: 0; |
| color: white; |
| font-size: 24px; |
| cursor: pointer; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900 text-white min-h-screen"> |
| <div class="container mx-auto px-4 py-8"> |
| |
| <header class="flex justify-between items-center mb-10"> |
| <div> |
| <h1 class="text-3xl font-bold text-indigo-400">CinéDashboard</h1> |
| <p class="text-gray-400">Votre tableau de bord cinématographique</p> |
| </div> |
| <div class="flex items-center space-x-4"> |
| <div class="relative"> |
| <input type="text" placeholder="Rechercher un film..." class="bg-gray-800 rounded-full py-2 px-4 pl-10 focus:outline-none focus:ring-2 focus:ring-indigo-500 w-64"> |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
| </div> |
| <div class="h-10 w-10 rounded-full bg-indigo-600 flex items-center justify-center"> |
| <i class="fas fa-user"></i> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-10"> |
| <div class="bg-gray-800 rounded-lg p-6 flex items-center"> |
| <div class="bg-indigo-600 p-3 rounded-full mr-4"> |
| <i class="fas fa-film text-white"></i> |
| </div> |
| <div> |
| <p class="text-gray-400">Films chargés</p> |
| <h3 class="text-2xl font-bold" id="movies-count">0</h3> |
| </div> |
| </div> |
| <div class="bg-gray-800 rounded-lg p-6 flex items-center"> |
| <div class="bg-purple-600 p-3 rounded-full mr-4"> |
| <i class="fas fa-star text-white"></i> |
| </div> |
| <div> |
| <p class="text-gray-400">Note moyenne</p> |
| <h3 class="text-2xl font-bold" id="avg-rating">0</h3> |
| </div> |
| </div> |
| <div class="bg-gray-800 rounded-lg p-6 flex items-center"> |
| <div class="bg-green-600 p-3 rounded-full mr-4"> |
| <i class="fas fa-calendar text-white"></i> |
| </div> |
| <div> |
| <p class="text-gray-400">Dernière MAJ</p> |
| <h3 class="text-2xl font-bold" id="last-update">Aujourd'hui</h3> |
| </div> |
| </div> |
| <div class="bg-gray-800 rounded-lg p-6 flex items-center"> |
| <div class="bg-red-600 p-3 rounded-full mr-4"> |
| <i class="fas fa-fire text-white"></i> |
| </div> |
| <div> |
| <p class="text-gray-400">Tendance</p> |
| <h3 class="text-2xl font-bold" id="trending">0</h3> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="flex flex-wrap items-center justify-between mb-8 bg-gray-800 p-4 rounded-lg"> |
| <div class="flex space-x-4 mb-4 md:mb-0"> |
| <button class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-lg transition" id="filter-popular"> |
| Populaires |
| </button> |
| <button class="bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-lg transition" id="filter-top"> |
| Top Rated |
| </button> |
| <button class="bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-lg transition" id="filter-upcoming"> |
| Prochainement |
| </button> |
| </div> |
| <div class="flex items-center"> |
| <label for="year-filter" class="mr-2 text-gray-400">Année:</label> |
| <select id="year-filter" class="bg-gray-700 rounded px-3 py-2 focus:outline-none"> |
| <option value="all">Toutes</option> |
| |
| </select> |
| </div> |
| </div> |
|
|
| |
| <div class="mb-10"> |
| <h2 class="text-2xl font-bold mb-6 flex items-center"> |
| <i class="fas fa-fire text-red-500 mr-2"></i> |
| <span id="section-title">Films populaires</span> |
| </h2> |
| |
| <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6" id="movies-grid"> |
| |
| <div class="skeleton bg-gray-800 rounded-lg h-96"></div> |
| <div class="skeleton bg-gray-800 rounded-lg h-96"></div> |
| <div class="skeleton bg-gray-800 rounded-lg h-96"></div> |
| <div class="skeleton bg-gray-800 rounded-lg h-96"></div> |
| <div class="skeleton bg-gray-800 rounded-lg h-96"></div> |
| </div> |
| |
| <div class="flex justify-center mt-8"> |
| <button id="load-more" class="bg-indigo-600 hover:bg-indigo-700 px-6 py-3 rounded-lg transition font-medium"> |
| Charger plus de films |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div class="player-container" id="player-container"> |
| <div class="player-wrapper"> |
| <div class="close-player" id="close-player"> |
| <i class="fas fa-times"></i> |
| </div> |
| <iframe id="movie-player" width="100%" height="600" frameborder="0" allowfullscreen></iframe> |
| </div> |
| </div> |
|
|
| |
| <footer class="border-t border-gray-800 pt-6 mt-10"> |
| <div class="flex flex-col md:flex-row justify-between items-center"> |
| <div class="mb-4 md:mb-0"> |
| <h2 class="text-xl font-bold text-indigo-400">CinéDashboard</h2> |
| <p class="text-gray-400">Powered by TMDb API</p> |
| </div> |
| <div class="flex space-x-6"> |
| <a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-twitter"></i></a> |
| <a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-facebook"></i></a> |
| <a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-instagram"></i></a> |
| <a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-github"></i></a> |
| </div> |
| </div> |
| <p class="text-center text-gray-500 mt-6 text-sm">© 2023 CinéDashboard. Tous droits réservés.</p> |
| </footer> |
| </div> |
|
|
| <script> |
| |
| const API_KEY = 'fb437b10727a5a4eb8d9134e29c82ae0'; |
| const BASE_URL = 'https://api.themoviedb.org/3'; |
| const STREAMING_SERVERS = { |
| 'server1': { name: 'Serveur Premium', icon: 'fas fa-bolt', color: 'bg-purple-600' }, |
| 'server2': { name: 'Serveur Rapide', icon: 'fas fa-tachometer-alt', color: 'bg-blue-600' }, |
| 'server3': { name: 'Serveur HD', icon: 'fas fa-high-definition', color: 'bg-green-600' }, |
| 'server4': { name: 'Serveur Backup', icon: 'fas fa-shield-alt', color: 'bg-yellow-600' } |
| }; |
| |
| let currentPage = 1; |
| let currentFilter = 'popular'; |
| let currentYear = 'all'; |
| let isLoading = false; |
| |
| |
| const moviesGrid = document.getElementById('movies-grid'); |
| const loadMoreBtn = document.getElementById('load-more'); |
| const moviesCount = document.getElementById('movies-count'); |
| const avgRating = document.getElementById('avg-rating'); |
| const lastUpdate = document.getElementById('last-update'); |
| const trending = document.getElementById('trending'); |
| const sectionTitle = document.getElementById('section-title'); |
| const yearFilter = document.getElementById('year-filter'); |
| const playerContainer = document.getElementById('player-container'); |
| const moviePlayer = document.getElementById('movie-player'); |
| const closePlayer = document.getElementById('close-player'); |
| |
| |
| const filterPopular = document.getElementById('filter-popular'); |
| const filterTop = document.getElementById('filter-top'); |
| const filterUpcoming = document.getElementById('filter-upcoming'); |
| |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| |
| const today = new Date(); |
| lastUpdate.textContent = today.toLocaleDateString('fr-FR'); |
| |
| |
| populateYearFilter(); |
| |
| |
| loadMovies(); |
| |
| |
| loadMoreBtn.addEventListener('click', loadMoreMovies); |
| |
| filterPopular.addEventListener('click', () => { |
| changeFilter('popular', 'Films populaires'); |
| }); |
| |
| filterTop.addEventListener('click', () => { |
| changeFilter('top_rated', 'Top Rated'); |
| }); |
| |
| filterUpcoming.addEventListener('click', () => { |
| changeFilter('upcoming', 'Prochainement'); |
| }); |
| |
| yearFilter.addEventListener('change', (e) => { |
| currentYear = e.target.value; |
| currentPage = 1; |
| moviesGrid.innerHTML = createSkeletons(5); |
| loadMovies(); |
| }); |
| |
| |
| closePlayer.addEventListener('click', () => { |
| playerContainer.style.display = 'none'; |
| moviePlayer.src = ''; |
| }); |
| }); |
| |
| |
| function populateYearFilter() { |
| const currentYear = new Date().getFullYear(); |
| for (let year = currentYear; year >= 2000; year--) { |
| const option = document.createElement('option'); |
| option.value = year; |
| option.textContent = year; |
| yearFilter.appendChild(option); |
| } |
| } |
| |
| function changeFilter(filter, title) { |
| currentFilter = filter; |
| currentPage = 1; |
| sectionTitle.textContent = title; |
| |
| |
| document.querySelectorAll('#filters button').forEach(btn => { |
| btn.classList.remove('bg-indigo-600', 'hover:bg-indigo-700'); |
| btn.classList.add('bg-gray-700', 'hover:bg-gray-600'); |
| }); |
| |
| event.target.classList.remove('bg-gray-700', 'hover:bg-gray-600'); |
| event.target.classList.add('bg-indigo-600', 'hover:bg-indigo-700'); |
| |
| |
| moviesGrid.innerHTML = createSkeletons(5); |
| loadMovies(); |
| } |
| |
| function createSkeletons(count) { |
| let skeletons = ''; |
| for (let i = 0; i < count; i++) { |
| skeletons += `<div class="skeleton bg-gray-800 rounded-lg h-96"></div>`; |
| } |
| return skeletons; |
| } |
| |
| async function loadMovies() { |
| if (isLoading) return; |
| |
| isLoading = true; |
| loadMoreBtn.disabled = true; |
| loadMoreBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Chargement...'; |
| |
| try { |
| let url = `${BASE_URL}/movie/${currentFilter}?api_key=${API_KEY}&page=${currentPage}&language=fr-FR`; |
| |
| if (currentYear !== 'all') { |
| url += `&primary_release_year=${currentYear}`; |
| } |
| |
| const response = await fetch(url); |
| const data = await response.json(); |
| |
| if (currentPage === 1) { |
| moviesGrid.innerHTML = ''; |
| |
| moviesCount.textContent = data.total_results; |
| trending.textContent = data.total_results > 1000 ? 'Élevée' : 'Moyenne'; |
| } |
| |
| displayMovies(data.results); |
| |
| |
| if (currentPage === 1) { |
| const ratings = data.results.map(movie => movie.vote_average); |
| const average = (ratings.reduce((a, b) => a + b, 0) / ratings.length).toFixed(1); |
| avgRating.textContent = average; |
| } |
| |
| currentPage++; |
| |
| |
| if (currentPage > data.total_pages) { |
| loadMoreBtn.style.display = 'none'; |
| } else { |
| loadMoreBtn.style.display = 'flex'; |
| } |
| } catch (error) { |
| console.error('Error fetching movies:', error); |
| moviesGrid.innerHTML = ` |
| <div class="col-span-full text-center py-10"> |
| <i class="fas fa-exclamation-triangle text-red-500 text-4xl mb-4"></i> |
| <h3 class="text-xl font-bold">Erreur de chargement</h3> |
| <p class="text-gray-400">Impossible de charger les films. Veuillez réessayer.</p> |
| </div> |
| `; |
| } finally { |
| isLoading = false; |
| loadMoreBtn.disabled = false; |
| loadMoreBtn.innerHTML = 'Charger plus de films'; |
| } |
| } |
| |
| function loadMoreMovies() { |
| loadMovies(); |
| } |
| |
| function displayMovies(movies) { |
| movies.forEach(movie => { |
| const movieCard = document.createElement('div'); |
| movieCard.className = 'movie-card bg-gray-800 rounded-lg overflow-hidden shadow-lg hover:shadow-xl transition relative'; |
| movieCard.innerHTML = ` |
| <div class="relative h-80 overflow-hidden"> |
| <img |
| src="${movie.poster_path ? `https://image.tmdb.org/t/p/w500${movie.poster_path}` : 'https://via.placeholder.com/500x750?text=No+Image'}" |
| alt="${movie.title}" |
| class="w-full h-full object-cover" |
| onerror="this.src='https://via.placeholder.com/500x750?text=No+Image'" |
| > |
| <div class="movie-overlay absolute inset-0 bg-black bg-opacity-70 opacity-0 flex flex-col justify-between p-4"> |
| <div class="flex justify-between items-start"> |
| <span class="bg-indigo-600 text-white text-xs font-bold px-2 py-1 rounded"> |
| ${movie.release_date ? movie.release_date.split('-')[0] : 'N/A'} |
| </span> |
| <span class="bg-yellow-500 text-gray-900 text-xs font-bold px-2 py-1 rounded flex items-center"> |
| <i class="fas fa-star mr-1"></i> ${movie.vote_average.toFixed(1)} |
| </span> |
| </div> |
| <div> |
| <p class="text-sm text-gray-300 line-clamp-3">${movie.overview || 'Aucune description disponible.'}</p> |
| </div> |
| <div class="flex flex-col space-y-2"> |
| <!-- Play button --> |
| <button class="play-btn bg-red-600 hover:bg-red-700 text-white px-3 py-2 rounded font-medium transition flex items-center justify-center w-full" data-movie-id="${movie.id}"> |
| <i class="fas fa-play mr-2"></i> Regarder maintenant |
| </button> |
| |
| <!-- Watch later button --> |
| <button class="watch-later-btn bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-2 rounded font-medium transition flex items-center justify-center w-full"> |
| <i class="fas fa-clock mr-2"></i> À regarder plus tard |
| </button> |
| |
| <!-- Details button --> |
| <a href="https://www.themoviedb.org/movie/${movie.id}" target="_blank" class="bg-white text-gray-900 hover:bg-gray-200 px-3 py-2 rounded text-sm font-medium transition flex items-center justify-center"> |
| <i class="fas fa-info-circle mr-2"></i> Détails |
| </a> |
| </div> |
| </div> |
| </div> |
| <div class="p-4"> |
| <h3 class="font-bold text-lg mb-1 truncate">${movie.title}</h3> |
| <div class="flex justify-between items-center text-gray-400 text-sm"> |
| <span>${movie.genre_ids.length ? 'Genre' : 'Pas de genre'}</span> |
| <span class="flex items-center"> |
| <i class="fas fa-heart text-red-500 mr-1"></i> ${movie.popularity.toFixed(0)} |
| </span> |
| </div> |
| </div> |
| `; |
| moviesGrid.appendChild(movieCard); |
| |
| |
| const playBtn = movieCard.querySelector('.play-btn'); |
| playBtn.addEventListener('click', () => showStreamingOptions(movie)); |
| }); |
| } |
| |
| function showStreamingOptions(movie) { |
| |
| const modal = document.createElement('div'); |
| modal.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50'; |
| modal.innerHTML = ` |
| <div class="bg-gray-800 rounded-lg p-6 w-full max-w-md"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-bold">Choisissez un serveur</h3> |
| <button class="close-modal text-gray-400 hover:text-white"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| <p class="text-gray-400 mb-4">Sélectionnez un serveur pour regarder "${movie.title}"</p> |
| |
| <div class="grid grid-cols-2 gap-3 mb-4" id="server-buttons"> |
| ${Object.entries(STREAMING_SERVERS).map(([key, server]) => ` |
| <button class="server-btn ${server.color} hover:${server.color.replace('600', '700')} text-white px-4 py-3 rounded-lg transition flex flex-col items-center" data-server="${key}"> |
| <i class="${server.icon} text-xl mb-1"></i> |
| <span>${server.name}</span> |
| </button> |
| `).join('')} |
| </div> |
| |
| <div class="bg-gray-700 rounded-lg p-4 hidden" id="quality-options"> |
| <h4 class="font-medium mb-2">Qualité disponible :</h4> |
| <div class="flex space-x-2"> |
| <button class="quality-btn bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded" data-quality="1080">1080p</button> |
| <button class="quality-btn bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded" data-quality="720">720p</button> |
| <button class="quality-btn bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded" data-quality="480">480p</button> |
| </div> |
| </div> |
| </div> |
| `; |
| |
| document.body.appendChild(modal); |
| |
| |
| const closeModal = modal.querySelector('.close-modal'); |
| closeModal.addEventListener('click', () => { |
| document.body.removeChild(modal); |
| }); |
| |
| |
| const serverButtons = modal.querySelectorAll('.server-btn'); |
| const qualityOptions = modal.querySelector('#quality-options'); |
| |
| serverButtons.forEach(btn => { |
| btn.addEventListener('click', () => { |
| |
| serverButtons.forEach(b => b.classList.remove('ring-2', 'ring-white')); |
| btn.classList.add('ring-2', 'ring-white'); |
| |
| |
| qualityOptions.classList.remove('hidden'); |
| |
| |
| const qualityBtns = qualityOptions.querySelectorAll('.quality-btn'); |
| qualityBtns.forEach(qBtn => { |
| qBtn.addEventListener('click', () => { |
| const quality = qBtn.dataset.quality; |
| playMovie(movie, btn.dataset.server, quality); |
| document.body.removeChild(modal); |
| }); |
| }); |
| }); |
| }); |
| } |
| |
| function playMovie(movie, server, quality) { |
| |
| |
| const streamingUrl = `https://example-stream-provider.com/player?movie_id=${movie.id}&server=${server}&quality=${quality}`; |
| |
| |
| playerContainer.style.display = 'flex'; |
| |
| |
| moviePlayer.src = streamingUrl; |
| |
| |
| const moviesCountEl = document.getElementById('movies-count'); |
| moviesCountEl.textContent = parseInt(moviesCountEl.textContent) + 1; |
| |
| |
| const watched = JSON.parse(localStorage.getItem('recentlyWatched') || '[]'); |
| watched.unshift({ |
| id: movie.id, |
| title: movie.title, |
| poster: movie.poster_path ? `https://image.tmdb.org/t/p/w200${movie.poster_path}` : null, |
| date: new Date().toISOString() |
| }); |
| localStorage.setItem('recentlyWatched', JSON.stringify(watched.slice(0, 10))); |
| } |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=docto41/cin" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |