Mini_Project_03

정상희·2025년 5월 12일

코딩공부

목록 보기
46/60

영화 웹 만들기_미니 프로젝트

- 3단계 완료


1단계 메인 페이지 및 영화 상세 페이지 레이아웃 구성하기

구현 사항

  • 더미데이터를 사용한 메인 페이지와 디테일 페이지 레이아웃 구성완료
  • React-Router-Dom을 사용하여 라우팅 main.jsx 구성완료
  • Layout Component를 사용하여 Nav바 상단 구성완료

어려웠던 점

  • 장르 리스트를 불러오지 못해 undefined 오류가 발생했는데, 구글링과 AI 도구를 활용해 원인을 찾고, data에 장르 리스트를 추가하여 해결했습니다.
  • 메인 페이지에서 상영작(p 태그)과 포스터가 왼쪽 정렬되지 않아 문제가 있었지만, grid를 사용해 정렬을 맞춰 해결했습니다.

구현 이미지



코드 MainPage.jsx

import React from 'react';
import MovieCard from '../component/MovieCard';
import movieList from '../data/movieListData.json';

const MainPage = () => {
  return (
    <>
      <main className="grid grid-cols-1 pt-[80px] px-4 md:px-20">
        <p className="text-[30px] font-bold w-full text-left">상영작</p>
        <div className="col-span-1 w-full grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 justify-items-center">
            {Array.isArray(movieList?.results) && movieList.results.map((movie) => (
            <MovieCard
                key={movie.id}
                id={movie.id}
                title={movie.title}
                posterPath={movie.poster_path}
                rating={movie.vote_average}
            />
            ))}
        </div>
      </main>
    </>
  );
};

export default MainPage;


2단계 TMdb API를 이용한 영화 웹 애플리케이션 확장

구현 사항

  • TMdb DB와 프로젝트를 연결
  • API 호출해서 더미데이터를 응답 데이터로 변경
  • 클릭한 MovieCard에 맞는 MovieDetail로 이동하도록 라우팅

어려웠던 점

  • TMDB API 연동 과정이 복잡하게 느껴져 유튜브 영상을 참고하여 구현을 진행했습니다.
  • Tailwind CSS 4버전에서 스타일링이 제대로 적용되지 않는 오류가 발생하여, 임시로 3버전을 설치해 문제를 해결한 뒤 다시 4버전으로 적용하였습니다.

구현 이미지



코드 api > tmdb.js

const API_KEY = import.meta.env.VITE_TMDB_API_KEY;
const BASE_URL = 'https://api.themoviedb.org/3';

export const fetchPopularMovies = async () => {
    try {
        const response = await fetch(
            `${BASE_URL}/movie/popular?api_key=${API_KEY}&language=ko-KR&page=1`
        );
        if (!response.ok) {
            throw new Error('인기 영화를 불러오는 데 실패했습니다.');
            // throw new Error()는 강제로 에러를 발생시키는 문법
        }
        const data = await response.json();

        return data.results;
    } catch (error) {
        console.error('인기 영화 가져오기 오류:', error);
        return [];
    }
};

export const fetchMovieDetail = async (movieId) => {
    try {
        const response = await fetch(
            `${BASE_URL}/movie/${movieId}?api_key=${API_KEY}&language=ko-KR`
        );

        if (!response.ok) {
            throw new Error('영화 상세 정보를 불러오는 데 실패했습니다.');
        }
        const data = await response.json();

        return data;

    } catch (error) {
        console.error(`영화 상세 정보 오류 (ID: ${movieId}):`, error);
        return null;
    }
};


3단계 Nav-bar 검색 기능 구현 및 반응형 디자인

구현 사항

  • Nav-bar 검색 기능 구현하기 (API 사용)
  • 자유롭게 디자인하기(반응형 디자인)

어려웠던 점

  • GitHub Push 오류
  • Tailwind CSS 4버전에서 스타일링이 제대로 적용되지 않는 오류가 발생하여, 임시로 3버전을 설치해 문제를 해결한 뒤 다시 4버전으로 적용하였습니다.

구현 이미지


Tailwind CSS 4버전


Tailwind CSS 3버전


코드 NavBar.jsx

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import useDebounce from '../hooks/useDebounce';

const Navbar = ({ onSearch }) => {
    const [searchTerm, setSearchTerm] = useState('');
    const debouncedSearchTerm = useDebounce(searchTerm, 500);

    useEffect(() => {
        if (debouncedSearchTerm !== undefined) { 
            onSearch(debouncedSearchTerm);
        }
    }, [debouncedSearchTerm, onSearch]);

    const handleInputChange = (event) => {
        setSearchTerm(event.target.value);
    };

    return (
        <>
            <header className="fixed w-full bg-[#601b85] text-white p-[16px] z-10">
                <div className="w-full container mx-auto flex items-center">
                    <Link to="/" className="text-xl font-bold mr-[20px]">Maga Movie</Link>
                    <div className="flex-1 mx-[16px] bg-white rounded-[6px]">
                        <input
                            className="p-[8px] w-full text-gray-600 outline-none border-none rounded-md"
                            type="text"
                            placeholder="찾고 싶은 영화를 검색하세요."
                            value={searchTerm} // input 값과 searchTerm 상태 연결
                            onChange={handleInputChange} // input 변경 이벤트 처리
                        />
                    </div>

                    <nav className="flex items-center">
                        <Link to="/" className="ml-[16px] p-[10px] border rounded-[5px] hover:bg-white hover:text-[#601b85] transition-colors">
                            로그인
                        </Link>
                        <Link to="/" className="ml-[16px] p-[10px] border rounded-[5px] hover:bg-white hover:text-[#601b85] transition-colors">
                            회원가입
                        </Link>
                    </nav>
                </div>
            </header>
        </>
    );
}

export default Navbar;

4단계 추후 진행예정...

profile
UI/UX디자이너의 코딩 공부

0개의 댓글