modal showing for each movie

Co-authored-by: Sindre Kjelsrud <kjelsrudsindre@gmail.com>
This commit is contained in:
haraldnilsen 2023-09-05 15:54:36 +02:00
parent 882df70ce5
commit 431e1bd472
6 changed files with 92 additions and 17 deletions

View file

@ -13,11 +13,13 @@
"git-mob": "^2.4.0", "git-mob": "^2.4.0",
"qjuul": "^1.0.7", "qjuul": "^1.0.7",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0",
"react-modal": "^3.16.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.15", "@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
"@types/react-modal": "^3.16.0",
"@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0", "@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3", "@vitejs/plugin-react": "^4.0.3",

View file

@ -1,8 +1,10 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import './App.css' import './App.css'
import q from 'qjuul' import q from 'qjuul'
import { PaginationButton } from './components'
import Pagination from './components/Pagination' import Pagination from './components/Pagination'
import { MovieTableRow } from './components'
import type { movieObject } from './types/movie'
import Modal from 'react-modal'
function App() { function App() {
const API_MOVIE_KEY = 'd92949d8' const API_MOVIE_KEY = 'd92949d8'
@ -10,6 +12,8 @@ function App() {
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [currentPage, setCurrentPage] = useState(1) const [currentPage, setCurrentPage] = useState(1)
const [totalPages, setTotalPages] = useState(0) const [totalPages, setTotalPages] = useState(0)
const [modalOpen, setModalOpen] = useState(false)
const [modalMovie, setModalMovie] = useState<movieObject | null>(null)
useEffect(() => { useEffect(() => {
fetch( fetch(
@ -18,6 +22,7 @@ function App() {
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
setMovies(data.Search) setMovies(data.Search)
console.log(data)
setTotalPages(data.totalResults) setTotalPages(data.totalResults)
}) })
.then(() => setLoading(false)) .then(() => setLoading(false))
@ -32,9 +37,41 @@ function App() {
setCurrentPage(pageNumber) setCurrentPage(pageNumber)
} }
const handleModalOpen = (movie: movieObject) => {
setModalOpen(true)
setModalMovie(movie)
}
return ( return (
<> <>
<q.div className="flex flex-col justify-center items-center mx-auto w-3/4"> <q.div className="flex flex-col justify-center items-center mx-auto w-3/4">
<Modal
className="p-6 bg-black rounded-lg outline-none" // styles for the modal container
overlayClassName="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center" // styles for the overlay
isOpen={modalOpen}
onRequestClose={() => setModalOpen(false)}
>
<q.div className="flex">
<q.img
className="h-44 max-w-sm mx-auto mb-4 rounded-md shadow"
src={modalMovie?.Poster}
alt={modalMovie?.Title}
/>
<q.div className="flex flex-col px-10 pt-5">
<q.h1 className="text-xl font-bold mb-4">
{modalMovie?.Title}
</q.h1>
<q.p>Year: {modalMovie?.Year}</q.p>
<q.p>Type: {modalMovie?.Type}</q.p>
<q.a
className='"underline text-blue-500 hover:text-blue-700"'
href={`https://www.imdb.com/title/${modalMovie?.imdbID}`}
>
{`https://www.imdb.com/title/${modalMovie?.imdbID}`}
</q.a>
</q.div>
</q.div>
</Modal>
<q.div className="flex flex-col w-full items-center"> <q.div className="flex flex-col w-full items-center">
<q.h1>All movies</q.h1> <q.h1>All movies</q.h1>
<q.div className="flex pt-2"> <q.div className="flex pt-2">
@ -50,20 +87,22 @@ function App() {
{!loading && movies ? ( {!loading && movies ? (
<q.div> <q.div>
<q.table className="border-separate border-spacing-y-5"> <q.table className="border-separate border-spacing-y-5">
<q.thead>
<q.tr> <q.tr>
<q.th>Poster</q.th> <q.th>Poster</q.th>
<q.th>Title</q.th> <q.th>Title</q.th>
<q.th>Year</q.th> <q.th>Year</q.th>
</q.tr> </q.tr>
</q.thead>
<q.tbody>
{movies.map((movie: any) => ( {movies.map((movie: any) => (
<q.tr className="card rounded-md"> <MovieTableRow
<q.td className="p-2"> movie={movie}
<q.img src={movie.Poster} alt={movie.Title} width="100" /> key={movie.imdbID}
</q.td> onClick={() => handleModalOpen(movie)}
<q.td>{movie.Title}</q.td> />
<q.td>{movie.Year}</q.td>
</q.tr>
))} ))}
</q.tbody>
</q.table> </q.table>
</q.div> </q.div>
) : ( ) : (

View file

@ -0,0 +1,27 @@
import type { movieObject } from '../../types/movie'
import Modal from 'react-modal'
import q from 'qjuul'
import { useState } from 'react'
interface MovieTableRowProps {
movie: movieObject
onClick: () => void
}
const mainAppElement = document.getElementById('root')
Modal.setAppElement(mainAppElement as HTMLElement)
const MovieTableRow: React.FC<MovieTableRowProps> = ({ movie, onClick }) => {
return (
<q.tr onClick={onClick} className="card rounded-md">
<q.td className="p-2">
<q.img src={movie.Poster} alt={movie.Title} width="100" />
</q.td>
<q.td>{movie.Title}</q.td>
<q.td>{movie.Year}</q.td>
</q.tr>
)
}
export default MovieTableRow

View file

@ -22,7 +22,6 @@ const Pagination: React.FC<PaginationProps> = ({
setShowLeftDots(currentPage > 4 ? true : false) setShowLeftDots(currentPage > 4 ? true : false)
setShowRightDots(currentPage < totalPages - 3 ? true : false) setShowRightDots(currentPage < totalPages - 3 ? true : false)
} }
console.log('hei')
if (!showLeftDots && !showRightDots) { if (!showLeftDots && !showRightDots) {
setShowingNumbers(Array.from(Array(totalPages).keys())) setShowingNumbers(Array.from(Array(totalPages).keys()))
} }
@ -60,7 +59,7 @@ const Pagination: React.FC<PaginationProps> = ({
)} )}
{showingNumbers.map((page) => ( {showingNumbers.map((page) => (
<q.div> <q.div key={page}>
<PaginationButton <PaginationButton
pageNumber={page} pageNumber={page}
handlePageChange={handlePageChange} handlePageChange={handlePageChange}

View file

@ -1 +1,2 @@
export { default as PaginationButton } from './PaginationButton' export { default as PaginationButton } from './PaginationButton'
export { default as MovieTableRow } from './MovieTableRow'

View file

@ -0,0 +1,7 @@
export type movieObject = {
Poster: string
Title: string
Type: string
Year: string
imdbID: string
}