| import React, { useState, useEffect } from 'react'; |
| import './App.css'; |
|
|
| function App() { |
| const [movies, setMovies] = useState([]); |
| const [selectedMovie, setSelectedMovie] = useState(''); |
| const [recommendations, setRecommendations] = useState([]); |
| const [loading, setLoading] = useState(false); |
| const [error, setError] = useState(''); |
|
|
| |
| useEffect(() => { |
| fetch('/api/movies') |
| .then(response => response.json()) |
| .then(data => { |
| console.log("Movies fetched:", data.movies); |
| if(Array.isArray(data.movies)){ |
| setMovies(data.movies); |
| if(data.movies.length > 0){ |
| setSelectedMovie(data.movies[0]); |
| } |
| } else { |
| console.error("Movies data is not an array:", data.movies); |
| } |
| }) |
| .catch(err => { |
| console.error("Failed to fetch movies:", err); |
| setError('Failed to fetch movie list'); |
| }); |
| }, []); |
|
|
| const handleRecommend = () => { |
| if (!selectedMovie) return; |
| setLoading(true); |
| setError(''); |
| setRecommendations([]); |
|
|
| fetch(`/api/recommend?title=${encodeURIComponent(selectedMovie)}`) |
| .then(response => { |
| if (!response.ok) throw new Error('Network response was not ok'); |
| return response.json(); |
| }) |
| .then(data => { |
| setRecommendations(data.recommendations || []); |
| setLoading(false); |
| }) |
| .catch(err => { |
| setError('Failed to get recommendations. Please try again.'); |
| setLoading(false); |
| console.error("Error fetching recommendations:", err); |
| }); |
| }; |
|
|
| |
| const fetchPosterUrl = async (movieId) => { |
| const apiKey = "4f26810245b768489a195238ffe92a0b"; |
| const url = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${apiKey}`; |
| try { |
| const response = await fetch(url); |
| if (!response.ok) throw new Error('Failed fetching poster'); |
| const data = await response.json(); |
| if (data.poster_path) { |
| return `https://image.tmdb.org/t/p/w500/${data.poster_path}`; |
| } |
| } catch (err) { |
| console.error("Failed to fetch poster for movie ID:", movieId); |
| } |
| return "https://via.placeholder.com/500x750.png?text=No+Poster"; |
| }; |
|
|
| |
| const Poster = ({ movieId, title }) => { |
| const [posterUrl, setPosterUrl] = useState("https://via.placeholder.com/500x750.png?text=Loading..."); |
|
|
| useEffect(() => { |
| let mounted = true; |
| fetchPosterUrl(movieId).then(url => { |
| if (mounted) setPosterUrl(url); |
| }); |
| return () => { mounted = false; }; |
| }, [movieId]); |
|
|
| return ( |
| <div className="movie-card"> |
| <img src={posterUrl} alt={`${title} poster`} /> |
| <p className="movie-title">{title}</p> |
| </div> |
| ); |
| }; |
|
|
| return ( |
| <div className="App"> |
| <header className="App-header"> |
| <h1>PragyanAI - Super 30 Movie Recommender</h1> |
| <p>Select a movie you like to get 10 similar recommendations.</p> |
| </header> |
| |
| <div className="controls"> |
| <select |
| value={selectedMovie} |
| onChange={e => { |
| console.log("Selected movie changed to:", e.target.value); // Debug log |
| setSelectedMovie(e.target.value); |
| }} |
| > |
| {movies.map(movie => ( |
| <option key={movie} value={movie}> |
| {movie} |
| </option> |
| ))} |
| </select> |
| |
| <button onClick={handleRecommend} disabled={loading || !selectedMovie}> |
| {loading ? 'Searching...' : 'Recommend'} |
| </button> |
| </div> |
| |
| {error && <p className="error">{error}</p>} |
| |
| <div className="recommendation-grid"> |
| {recommendations.map(rec => ( |
| <Poster key={rec.id} movieId={rec.id} title={rec.title} /> |
| ))} |
| </div> |
| </div> |
| ); |
| } |
|
|
| export default App; |
|
|
|
|