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;