Add SearchMovies component for movie search functionality, integrating TMDB API; update Home page to include search feature.
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
|
import { SearchMovies } from "@/components/molecules/SearchMovies";
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<h1>Hello World</h1>
|
<SearchMovies />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/components/molecules/SearchMovies/index.tsx
Normal file
37
src/components/molecules/SearchMovies/index.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"use client";
|
||||||
|
import { SearchInput } from "@/components/atoms/SearchInput";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { TMDB } from "@/lib/tmdb";
|
||||||
|
import { MovieCard } from "@/components/atoms/MovieCard";
|
||||||
|
import { SearchResult } from "@/lib/tmdb/types";
|
||||||
|
|
||||||
|
export const SearchMovies = () => {
|
||||||
|
const [results, setResults] = useState<SearchResult["results"]>([]);
|
||||||
|
|
||||||
|
const handleSearch = async (query: string) => {
|
||||||
|
const data = await TMDB.search(query);
|
||||||
|
setResults(data.results);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div className="row justify-center">
|
||||||
|
<div className="col-5">
|
||||||
|
<SearchInput onChange={handleSearch} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 mt-8">
|
||||||
|
{results.map((result) => (
|
||||||
|
<MovieCard
|
||||||
|
key={result.id}
|
||||||
|
title={result.title}
|
||||||
|
releaseDate={result.release_date}
|
||||||
|
popularity={result.popularity}
|
||||||
|
overview={result.overview}
|
||||||
|
imagePath={result.poster_path}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
5
src/lib/tmdb/index.ts
Normal file
5
src/lib/tmdb/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { search } from "./server";
|
||||||
|
|
||||||
|
export const TMDB = {
|
||||||
|
search,
|
||||||
|
};
|
||||||
19
src/lib/tmdb/server.ts
Normal file
19
src/lib/tmdb/server.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { SearchResult } from "./types";
|
||||||
|
|
||||||
|
const fetchTmbd = async (url: string) => {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${process.env.TMDB_BEARER}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = "https://api.themoviedb.org/3";
|
||||||
|
|
||||||
|
export async function search(query: string): Promise<SearchResult> {
|
||||||
|
return await fetchTmbd(`${url}/search/movie?query=${query}`);
|
||||||
|
}
|
||||||
19
src/lib/tmdb/types.ts
Normal file
19
src/lib/tmdb/types.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export type SearchResult = {
|
||||||
|
page: number;
|
||||||
|
results: {
|
||||||
|
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;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user