diff --git a/Pagination.tsx b/Pagination.tsx deleted file mode 100644 index cd54fbb..0000000 --- a/Pagination.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { ReactEventHandler, useState } from "react"; -export default function Pagination({ pages, onPageChange, currentPage }: any) { - const [page, setPage] = useState(currentPage); - const handleClick = (e: any) => { - const { value } = e.target; - let newPage; - - if (isNaN(parseInt(value))) { - switch (value) { - case "<<": - // goto start - newPage = 0; - break; - case "<": - newPage = page - 1; - break; - case ">": - newPage = page + 1; - break; - case ">>": - //goto end - newPage = pages.length - 1; - break; - - default: - break; - } - } else { - newPage = value; - } - - setPage(newPage); - onPageChange(newPage); - }; - - // useEffect(() => { - // onPageChange(page); - // }, [page]); - - const QuickLink = ({ value }: { value: string }) => { - return ( - - {value} - - ); - }; - - return ( - <> - - - {pages.map((p: number) => ( - - ))} - "} /> - >"} /> - > - ); -} diff --git a/movie-search/__tests__/MovieCard.test.jsx b/movie-search/__tests__/MovieCard.test.jsx deleted file mode 100644 index afd49cb..0000000 --- a/movie-search/__tests__/MovieCard.test.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import "@testing-library/jest-dom"; -import { render, screen } from "@testing-library/react"; -import MovieCard from "../src/common/components/MovieCard.tsx"; -const movie = { - Title: "Dune", - Year: "2000", - imdbID: "tt0142032", - Type: "series", - Poster: - "https://m.media-amazon.com/images/M/MV5BMTU4MjMyMTkxN15BMl5BanBnXkFtZTYwODA5OTU5._V1_SX300.jpg", -}; -describe("MovieCard Rendering", () => { - test("should render with Dune title.", () => { - render(); - const movieTitle = screen.getByRole("heading"); - expect(movieTitle).toHaveTextContent("Dune"); - }); - test("should render with Year 2000.", () => { - render(); - const movieTitle = screen.getByTestId("MovieCard-Year"); - expect(movieTitle).toHaveTextContent("2000"); - }); -}); diff --git a/movie-search/__tests__/SearchBar.test.jsx b/movie-search/__tests__/SearchBar.test.jsx deleted file mode 100644 index 6e63c87..0000000 --- a/movie-search/__tests__/SearchBar.test.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import "@testing-library/jest-dom"; -import { fireEvent, render, screen } from "@testing-library/react"; -import SearchBar from "@/app/Search/SearchBar.tsx"; -import { queryOMDb } from "@/api/omdb"; - -describe("SearchBar Operations", () => { - test("SearchBar Allows user input", () => { - render(); - const input = screen.getByPlaceholderText("Search by Title"); - - fireEvent.change(input, { target: { value: "some value" } }); - - expect(input.value).toBe("some value"); - }); - - test("SearchBar Allows user input and Clear button clears", () => { - render(); - const input = screen.getByTestId("SearchBar-input"); - const clear = screen.getByText("Clear"); - - fireEvent.change(input, { target: { value: "some value" } }); - expect(input.value).toBe("some value"); - - fireEvent.click(clear); - - expect(input.value).toBe(""); - }); - - // test("SearchBar Allows user submit", () => { - // render(); - // const input = screen.getByPlaceholderText("Search by Title"); - // const submit = screen.getByText("Search"); - // const spy = jest.spyOn({ queryOMDb }, "queryOMDb"); - - // fireEvent.change(input, { target: { value: "back to the" } }); - // fireEvent.click(submit); - // // Somehow test for form submission - currently facing this issue - // // https://github.com/vercel/next.js/issues/54757 - // // expect(spy).toHaveBeenCalled(); - // }); -}); diff --git a/movie-search/__tests__/omdb.test.jsx b/movie-search/__tests__/omdb.test.jsx deleted file mode 100644 index 918cdf6..0000000 --- a/movie-search/__tests__/omdb.test.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import "@testing-library/jest-dom"; -import { queryOMDb } from "../src/api/omdb.ts"; - -describe("OMDb API Integration", () => { - test("queryOMDb returns movie data successfully", async () => { - const data = await queryOMDb("s=back to"); - - expect(data).toHaveProperty("Response", "True"); - }); - - test("queryOMDb returns movie with error", async () => { - const data = await queryOMDb("f=dune"); - - expect(data).toHaveProperty("Response", "False"); - }); -}); \ No newline at end of file diff --git a/movie-search/src/api/omdb.ts b/movie-search/src/api/omdb.ts deleted file mode 100644 index 487fbc3..0000000 --- a/movie-search/src/api/omdb.ts +++ /dev/null @@ -1,19 +0,0 @@ -const url = `${process.env.OMDB_URL}?apikey=${process.env.API_KEY}`; - -export const queryOMDb = async (queryParamString: string) => { - "use server"; - try { - // await new Promise((resolve) => setTimeout(resolve, 2000)); - - const queryUrl = `${url}&${queryParamString}`; - const response = await fetch(queryUrl); - if (!response.ok) { - throw new Error("Failed to fetch movie data"); - } - const result = await response.json(); - // console.log(queryUrl, result); - return result; - } catch (e) { - throw new Error("Something went wrong searching OMDb"); - } -}; diff --git a/movie-search/src/app/Favorites/favoriteList.tsx b/movie-search/src/app/Favorites/favoriteList.tsx deleted file mode 100644 index 48cad13..0000000 --- a/movie-search/src/app/Favorites/favoriteList.tsx +++ /dev/null @@ -1,12 +0,0 @@ -"use client"; - -import { FavoriteContext } from "@/common/components/FavoriteContext"; -import MovieList from "@/common/components/MovieList"; -import { useContext } from "react"; - -export default function FavoriteList() { - const { favorites } = useContext(FavoriteContext); - return ( - - ); -} diff --git a/movie-search/src/app/Favorites/page.tsx b/movie-search/src/app/Favorites/page.tsx deleted file mode 100644 index b146d5e..0000000 --- a/movie-search/src/app/Favorites/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import FavoriteList from "./favoriteList"; - -export default function Favorites() { - return ( - - Your Favorites! - - - ); -}; diff --git a/movie-search/src/app/Movie/loading.tsx b/movie-search/src/app/Movie/loading.tsx deleted file mode 100644 index ba73539..0000000 --- a/movie-search/src/app/Movie/loading.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Loading from "@/common/components/Loading"; - -export default function loading() { - return ; -} diff --git a/movie-search/src/app/Movie/page.tsx b/movie-search/src/app/Movie/page.tsx deleted file mode 100644 index b664216..0000000 --- a/movie-search/src/app/Movie/page.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { queryOMDb } from "@/api/omdb"; -import { INextJsProps } from "../Search/page"; -import ImgCard from "@/common/components/ImgCard"; -import { stringifyQueryParams } from "@/common/utils/searchParams"; - -export default async function Movie({ searchParams }: INextJsProps) { - const movie = await queryOMDb(stringifyQueryParams(searchParams!)); - const { Poster, Title, Ratings, ...details } = movie; - return ( - - - - {Title} - {Object.entries(details).map(([key, value]) => { - return ( - - {key}: - {value as string} - - ); - })} - Ratings: - - {Ratings.map((r: { Source: string; Value: string }) => ( - - {r.Source} - {r.Value} - - ))} - - - - - ); -} diff --git a/movie-search/src/app/Search/SearchBar.tsx b/movie-search/src/app/Search/SearchBar.tsx deleted file mode 100644 index f56bdf7..0000000 --- a/movie-search/src/app/Search/SearchBar.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { primaryBtn, secondaryBtn } from "@/common/classes"; -import { revalidatePath } from "next/cache"; -import { redirect } from "next/navigation"; - -export default function SearchBar() { - const searchMovies = async (formData: FormData) => { - "use server"; - - const movieTitle = formData.get("movieTitle"); - // revalidatePath('/Search') - redirect(`/Search?s=${movieTitle}`); - }; - return ( - - - - - - - Search - - - Clear - - - - ); -} diff --git a/movie-search/src/app/Search/SearchPage.tsx b/movie-search/src/app/Search/SearchPage.tsx deleted file mode 100644 index 70c4b71..0000000 --- a/movie-search/src/app/Search/SearchPage.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { queryOMDb } from "@/api/omdb"; -import MovieList from "../../common/components/MovieList"; - -export default async function SearchPage({ - queryParamString, -}: { - queryParamString: string; -}) { - - const { Search } = await queryOMDb(queryParamString); - const movies = Search || []; - - return ( - - ); -} diff --git a/movie-search/src/app/Search/page.tsx b/movie-search/src/app/Search/page.tsx deleted file mode 100644 index fab1fb2..0000000 --- a/movie-search/src/app/Search/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { stringifyQueryParams } from "@/common/utils/searchParams"; -import { Suspense } from "react"; -import SearchPage from "./SearchPage"; -import SearchBar from "./SearchBar"; -import Loading from "@/common/components/Loading"; - -export interface INextJsProps { - searchParams?: object; -} - -export default async function Search({ searchParams }: INextJsProps) { - const queryParamString = stringifyQueryParams(searchParams!); - - return ( - - - }> - - - - ); -} diff --git a/movie-search/src/app/layout.tsx b/movie-search/src/app/layout.tsx index d483bea..cc2bef5 100644 --- a/movie-search/src/app/layout.tsx +++ b/movie-search/src/app/layout.tsx @@ -1,8 +1,6 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; -import NavBar from "@/common/components/NavBar"; -import { FavoriteProvider } from "@/common/components/FavoriteContext"; const inter = Inter({ subsets: ["latin"] }); @@ -19,10 +17,7 @@ export default function RootLayout({ return ( - - {children} - ); diff --git a/movie-search/src/common/components/FavoriteBtn.tsx b/movie-search/src/common/components/FavoriteBtn.tsx deleted file mode 100644 index 79e5b7d..0000000 --- a/movie-search/src/common/components/FavoriteBtn.tsx +++ /dev/null @@ -1,34 +0,0 @@ -"use client"; - -import { useContext } from "react"; -import { FavoriteContext } from "./FavoriteContext"; - -export default function FavoriteBtn({ movie }: any) { - const { favorites, - dispatch - // setFavorites - } = useContext(FavoriteContext); - const filteredFavorites = favorites.filter((f) => f.imdbID != movie.imdbID); - const isFavorite = - favorites.filter((f) => f.imdbID == movie.imdbID).length == 1; - - return ( - { - if (isFavorite) { - dispatch({type:'Remove', payload: movie}) - // setFavorites([...filteredFavorites]); - } else { - dispatch({type:'Add', payload: movie}) - // setFavorites([...favorites, movie]); - } - }} - className={`block text-yellow-500 rounded my-auto h-8 w-8 - ${ - isFavorite ? " bg-black" : "border-2 border-gray-300 bg-white" - }`} - > - ★ - - ); -} diff --git a/movie-search/src/common/components/FavoriteContext.tsx b/movie-search/src/common/components/FavoriteContext.tsx deleted file mode 100644 index ffc4c7f..0000000 --- a/movie-search/src/common/components/FavoriteContext.tsx +++ /dev/null @@ -1,59 +0,0 @@ -"use client"; - -import { PropsWithChildren, createContext, useReducer - // , useState -} from "react"; - -// interface IFavoriteContext { -// favorites: Array -// setFavorites: (value: Array) => void -// } -// export const FavoriteContext = createContext({ -// favorites: [], -// setFavorites: (_value: Array) => { }, -// }); - -// // Using interleaving to render this context provider client-side, but still utilize server-side renderung for children components -// export const FavoriteProvider = ({ children }: PropsWithChildren) => { -// const [favorites, setFavorites] = useState>([]) -// return ( -// {children} -// ) -// } - -interface IFavoriteContext { - favorites: FavoriteState; - dispatch: React.Dispatch; -} - -type FavoriteState = Array; -type FavoriteAction = { type: "Add" | "Remove"; payload: IMovieSearch }; - -function FavoriteReducer(state: FavoriteState, action: FavoriteAction) { - switch (action.type) { - case "Add": - state = [...state, action.payload]; - break; - case "Remove": - state = state.filter((s) => s.imdbID != action.payload.imdbID); - default: - break; - } - return state; -} - -const initialState: FavoriteState = []; - -export const FavoriteContext = createContext({ - favorites: initialState, - dispatch: () => null, -}); - -export function FavoriteProvider({ children }: PropsWithChildren) { - const [favorites, dispatch] = useReducer(FavoriteReducer, initialState); - return ( - - {children} - - ); -} diff --git a/movie-search/src/common/components/ImgCard.tsx b/movie-search/src/common/components/ImgCard.tsx deleted file mode 100644 index 79d0c9c..0000000 --- a/movie-search/src/common/components/ImgCard.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import Image from "next/image"; -import { PropsWithChildren } from "react"; -interface ICardProps extends PropsWithChildren { - width: number; - height: number; - src: string; - alt: string; - classNames?: string; -} -export default function ImgCard({ - classNames, - width, - height, - src, - alt, - children, -}: ICardProps) { - return ( - - - {children} - - ); -}; diff --git a/movie-search/src/common/components/Loading.tsx b/movie-search/src/common/components/Loading.tsx deleted file mode 100644 index 8a9ff27..0000000 --- a/movie-search/src/common/components/Loading.tsx +++ /dev/null @@ -1,9 +0,0 @@ -export default function Loading() { - return ( - - - Loading... - - - ); -} diff --git a/movie-search/src/common/components/MovieCard.tsx b/movie-search/src/common/components/MovieCard.tsx deleted file mode 100644 index 7cac5f3..0000000 --- a/movie-search/src/common/components/MovieCard.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import FavoriteBtn from "@/common/components/FavoriteBtn"; -import ImgCard from "@/common/components/ImgCard"; -import Link from "next/link"; -import { primaryBtn } from "../classes"; - -interface IMovieCardProps { - movie: IMovieSearch; -} - -export default function MovieCard({ movie }: IMovieCardProps) { - return ( - - - {movie.Title} - Circa: {movie.Year} - - - - Movie Details - - - - - - ); -} diff --git a/movie-search/src/common/components/MovieList.tsx b/movie-search/src/common/components/MovieList.tsx deleted file mode 100644 index b69253e..0000000 --- a/movie-search/src/common/components/MovieList.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import MovieCard from "./MovieCard"; - -export interface IMovieListProps { - movies: Array; -} - -export default function MovieList({ movies }: IMovieListProps) { - return ( - - {movies.length > 0 ? ( - movies.map((m) => ( - - - - )) - ) : ( - Nothing to show - )} - - ); -} diff --git a/movie-search/src/common/components/NavBar.tsx b/movie-search/src/common/components/NavBar.tsx deleted file mode 100644 index 13c9a36..0000000 --- a/movie-search/src/common/components/NavBar.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import Link from "next/link"; - -export default function NavBar() { - return ( - - - Home - - Search - Favorites - - ); -} diff --git a/movie-search/src/common/utils/searchParams.ts b/movie-search/src/common/utils/searchParams.ts deleted file mode 100644 index 282aa63..0000000 --- a/movie-search/src/common/utils/searchParams.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const stringifyQueryParams = (searchParams: object) => - Object.entries(searchParams) - .map( - ([key, value], i, arr) => - `${key}=${value}${i < arr.length - 1 ? "&" : ""}` - ) - .toString();
- {key}: - {value as string} -
Circa: {movie.Year}