File size: 3,971 Bytes
759fb1a f9f6cec 759fb1a f9f6cec 24a68db f9f6cec 24a68db f9f6cec 759fb1a f9f6cec 759fb1a f9f6cec 759fb1a 24a68db 759fb1a f9f6cec 759fb1a 24a68db f9f6cec 24a68db 759fb1a 24a68db 759fb1a 24a68db f9f6cec 759fb1a 24a68db 759fb1a 24a68db f9f6cec 24a68db 759fb1a f9f6cec 759fb1a f9f6cec 759fb1a f9f6cec 24a68db 759fb1a f9f6cec 24a68db 759fb1a f9f6cec 759fb1a f9f6cec 759fb1a f9f6cec 759fb1a 24a68db f9f6cec | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 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('');
// Fetch movie list on mount
useEffect(() => {
fetch('/api/movies')
.then(response => response.json())
.then(data => {
console.log("Movies fetched:", data.movies); // Debug log
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);
});
};
// Fetch poster URL helper
const fetchPosterUrl = async (movieId) => {
const apiKey = "4f26810245b768489a195238ffe92a0b"; // Replace with your TMDB API key
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";
};
// Poster component for displaying movie posters
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;
|