diff --git a/ssr/package.json b/ssr/package.json index db1a534..4d26357 100644 --- a/ssr/package.json +++ b/ssr/package.json @@ -4,8 +4,8 @@ "description": "SSR 렌더링으로 영화 목록 불러오기", "main": "server/index.js", "scripts": { - "start": "NODE_TLS_REJECT_UNAUTHORIZED=0 node server/index.js", - "dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 nodemon server/index.js --watch" + "start": "NODE_TLS_REJECT_UNAUTHORIZED=1 node server/index.js", + "dev": "NODE_TLS_REJECT_UNAUTHORIZED=1 nodemon server/index.js --watch" }, "type": "module", "dependencies": { diff --git a/ssr/server/HTMLgenerator.js b/ssr/server/HTMLgenerator.js new file mode 100644 index 0000000..19cd399 --- /dev/null +++ b/ssr/server/HTMLgenerator.js @@ -0,0 +1,63 @@ +import { TMDB_THUMBNAIL_URL } from "./constants.js"; + +export const generateMovieItems = (movies = []) => { + return movies + .map(({ id, title, vote_average, poster_path }) => { + /*html*/ + return ` +
  • + +
    + ${title} +
    +

    + + ${vote_average.toFixed(1)} +

    + ${title} +
    +
    +
    +
  • + `; + }) + .join(""); +}; + +export const generateMovieModal = (movieInfo = {}) => { + const { + title, + poster_path, + genres = [], + vote_average = 0, + overview, + } = movieInfo; + + /*html*/ + return ` + + `; +}; diff --git a/ssr/server/apis/movies.js b/ssr/server/apis/movies.js new file mode 100644 index 0000000..0a33f77 --- /dev/null +++ b/ssr/server/apis/movies.js @@ -0,0 +1,21 @@ +import { + TMDB_MOVIE_LISTS, + FETCH_OPTIONS, + TMDB_MOVIE_DETAIL_URL, +} from "../constants.js"; + +export const fetchMovieItems = async (category = "nowPlaying") => { + const url = TMDB_MOVIE_LISTS[category]; + const response = await fetch(url, FETCH_OPTIONS); + const data = await response.json(); + + return data.results; +}; + +export const fetchMovieDetail = async (id) => { + const url = `${TMDB_MOVIE_DETAIL_URL}${id}?language=ko-KR`; + const response = await fetch(url, FETCH_OPTIONS); + const data = await response.json(); + + return data; +}; diff --git a/ssr/server/constants.js b/ssr/server/constants.js new file mode 100644 index 0000000..c62d0e5 --- /dev/null +++ b/ssr/server/constants.js @@ -0,0 +1,22 @@ +export const BASE_URL = "https://api.themoviedb.org/3/movie"; + +export const TMDB_THUMBNAIL_URL = + "https://media.themoviedb.org/t/p/w440_and_h660_face/"; +export const TMDB_ORIGINAL_URL = "https://image.tmdb.org/t/p/original/"; +export const TMDB_BANNER_URL = + "https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/"; +export const TMDB_MOVIE_LISTS = { + popular: BASE_URL + "/popular?language=ko-KR&page=1", + nowPlaying: BASE_URL + "/now_playing?language=ko-KR&page=1", + topRated: BASE_URL + "/top_rated?language=ko-KR&page=1", + upcoming: BASE_URL + "/upcoming?language=ko-KR&page=1", +}; +export const TMDB_MOVIE_DETAIL_URL = "https://api.themoviedb.org/3/movie/"; + +export const FETCH_OPTIONS = { + method: "GET", + headers: { + accept: "application/json", + Authorization: "Bearer " + process.env.VITE_TMDB_TOKEN, + }, +}; diff --git a/ssr/server/routes/index.js b/ssr/server/routes/index.js index 84d32f2..da02d90 100644 --- a/ssr/server/routes/index.js +++ b/ssr/server/routes/index.js @@ -2,20 +2,73 @@ import { Router } from "express"; import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; +import { generateMovieItems, generateMovieModal } from "../HTMLgenerator.js"; +import { fetchMovieDetail, fetchMovieItems } from "../apis/movies.js"; +import { TMDB_BANNER_URL } from "../constants.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const router = Router(); -router.get("/", (_, res) => { +const renderMovieItemsHTML = (movies) => { const templatePath = path.join(__dirname, "../../views", "index.html"); - const moviesHTML = "

    들어갈 본문 작성

    "; + const template = fs.readFileSync(templatePath, "utf-8"); + + const movieItemsHTML = generateMovieItems(movies); + return template + .replace("", movieItemsHTML) + .replace("${bestMovie.title}", movies[0].title) + .replace("${bestMovie.rate}", movies[0].vote_average.toFixed(1)) + .replace( + "${background-container}", + `${TMDB_BANNER_URL}/${movies[0].backdrop_path}` + ); +}; +const renderMovieModalDetailHTML = (movie) => { + const templatePath = path.join(__dirname, "../../views", "index.html"); const template = fs.readFileSync(templatePath, "utf-8"); - const renderedHTML = template.replace("", moviesHTML); - res.send(renderedHTML); + const movieModalDetailHTML = generateMovieModal(movie); + return template.replace("", movieModalDetailHTML); +}; + +router.get("/", async (_, res) => { + const movies = await fetchMovieItems(); + + res.send(renderMovieItemsHTML(movies)); +}); + +router.get("/now-playing", async (_, res) => { + const movies = await fetchMovieItems("nowPlaying"); + + res.send(renderMovieItemsHTML(movies)); +}); + +router.get("/popular", async (_, res) => { + const movies = await fetchMovieItems("popular"); + + res.send(renderMovieItemsHTML(movies)); +}); + +router.get("/top-rated", async (_, res) => { + const movies = await fetchMovieItems("topRated"); + + res.send(renderMovieItemsHTML(movies)); +}); + +router.get("/upcoming", async (_, res) => { + const movies = await fetchMovieItems("upcoming"); + + res.send(renderMovieItemsHTML(movies)); +}); + +router.get("/detail/:id", async (req, res) => { + const movieId = req.params.id; + const movieDetail = await fetchMovieDetail(movieId); + + res.send(renderMovieModalDetailHTML(movieDetail)); }); export default router;