Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion webstudy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.5",
"axios": "^1.9.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react-dom": "^19.1.0",
"react-router-dom": "^7.5.3",
"tailwindcss": "^4.1.5"
},
"devDependencies": {
"@eslint/js": "^9.25.0",
Expand Down
525 changes: 490 additions & 35 deletions webstudy/pnpm-lock.yaml

Large diffs are not rendered by default.

33 changes: 28 additions & 5 deletions webstudy/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import './App.css'
import {createBrowserRouter, RouterProvider} from "react-router-dom";

//만든 페이지들을 import
// import HomePage from "./pages/home.tsx";
import Movies from "./pages/movies.tsx";
import NotFound from "./pages/not-found.tsx";
import RootLayout from "./layout/root-layout.tsx";
import HomePage from "./pages/home.tsx";

const router = createBrowserRouter([
{
path: '/',
// element: <HomePage/>,
element: <RootLayout/>,
errorElement: <NotFound/>,
children: [
{
index : true,
element: <HomePage/>
},
{
path: 'movies/:movieId',
element: <Movies/>
}
]
},
])

function App() {
return (
<>
<h1>Hello React</h1>
</>
)
return <RouterProvider router={router}/>
}

export default App
12 changes: 12 additions & 0 deletions webstudy/src/component/navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Link} from "react-router-dom";

const Navbar = () => {
return (
<nav>
<Link to={'/'}>홈 페이지로 이동</Link>
<Link to='/movies'>영화 목록 페이지로 이동</Link>
</nav>
);
};

export default Navbar;
1 change: 1 addition & 0 deletions webstudy/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "tailwindcss";
13 changes: 13 additions & 0 deletions webstudy/src/layout/root-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {Outlet} from "react-router-dom";
import Navbar from "../component/navbar.tsx";

const RootLayout = () => {
return (
<>
<Navbar/>
<Outlet/>
</>
);
};

export default RootLayout;
7 changes: 7 additions & 0 deletions webstudy/src/pages/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const HomePage = () => {
return (
<h1>Home Page 야호~!</h1>
);
};

export default HomePage;
35 changes: 35 additions & 0 deletions webstudy/src/pages/movies.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type {Movie, MovieResponse} from '../types/movie';
import {useEffect, useState} from "react";
import axios from 'axios';

const MoviesPage = () => {
const [movies, setMovies] = useState<Movie[]>([]);

useEffect(() => {
const fetchMovies = async () => {
const {data} = await axios.get<MovieResponse>(
`https://api.themoviedb.org/3/movie/popular?language=ko-KR&&page=1`,
Copy link

Copilot AI May 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL query string contains '&&' instead of a single '&', which may lead to incorrect API request behavior. Please replace '&&' with '&' to conform with standard URL parameter syntax.

Suggested change
`https://api.themoviedb.org/3/movie/popular?language=ko-KR&&page=1`,
`https://api.themoviedb.org/3/movie/popular?language=ko-KR&page=1`,

Copilot uses AI. Check for mistakes.
{
headers: {
Authorization: `Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIzOGNlZWMyODYzZDQzYThlNWZlMTU0NDhmMjVmNDVhYyIsIm5iZiI6MTc0NjYzOTU1MS4zOTYsInN1YiI6IjY4MWI5YWJmNjM1OTVkNWFiMWRmOTQ2MCIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.D6RnsiRAA2YgiMNuElMVOXOWgVu_mWX4OKrmzvB36xU`,
},
}
);
setMovies(data.results);
};
fetchMovies();
}, []);

return (
<ul>
{/* 옵셔널 체인 활용 */}
{movies?.map((movie) => (
<li key={movie.id}>
<h1>{movie.title}</h1>
</li>
))}
</ul>
);
};

export default MoviesPage;
7 changes: 7 additions & 0 deletions webstudy/src/pages/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const NotFound = () => {
return (
<h1>너는 찾을 수 없는 페이지 야호~!</h1>
);
};

export default NotFound;
23 changes: 23 additions & 0 deletions webstudy/src/types/movie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type Movie = {
adult: boolean;
backdrop_path: string;
genre_ids: number[];
id: number;
original_language: string;
original_title: string;
overview: string;
popularity: number;
poster_path: string;
release_date: string;
title: string;
video: boolean;
vote_average: number;
vote_count: number;
};

export type MovieResponse = {
page: number;
results: Movie[]; // 실제로 들어오는거는 여러개의 영화 데이터니 Movie의 배열로 표현
total_pages: number;
total_results: number;
};
6 changes: 4 additions & 2 deletions webstudy/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite';

// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [
tailwindcss(),
],
})