File size: 3,496 Bytes
cd6b2d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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(res => res.json())
      .then(data => {
        if(Array.isArray(data.movies)){
          setMovies(data.movies);
          if(data.movies.length > 0){
            setSelectedMovie(data.movies[0]);
          }
        } else {
          setError('Invalid movies list received');
        }
      })
      .catch(() => setError('Failed to fetch movie list'));
  }, []);

  const handleRecommend = () => {
    if (!selectedMovie) return;
    setLoading(true);
    setError('');
    setRecommendations([]);

    fetch(`/api/recommend?title=${encodeURIComponent(selectedMovie)}`)
      .then(res => {
        if (!res.ok) throw new Error('Failed to fetch recommendations');
        return res.json();
      })
      .then(data => {
        setRecommendations(data.recommendations || []);
        setLoading(false);
      })
      .catch(() => {
        setError('Failed to get recommendations');
        setLoading(false);
      });
  };

  // Fetch poster with TMDB API key - replace with your key or environment variable
  const fetchPosterUrl = async (movieId) => {
    const apiKey = "YOUR_TMDB_API_KEY"; // <--- replace here
    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 {
      // Ignore poster fetching errors
    }
    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 => 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;