-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Movies Sofie #67
base: main
Are you sure you want to change the base?
Movies Sofie #67
Changes from 26 commits
56c7bee
e7ea0ee
425fef0
1b80757
b91bf2b
1851161
e03572f
2cb7821
366775f
fdfb810
bda5d30
915d1eb
8722dc4
a828182
069a5e1
2c28160
8c47c74
0b86e37
7c215c1
262187b
58ff6dd
2919289
a75d66b
89f5c85
5e294b2
7dd6d64
8cefaba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
VITE_OPENDB_KEY= 23ace2b0c27910f5cec13f5bdb014044 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
module.exports = { | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:react/recommended', | ||
'plugin:react/jsx-runtime', | ||
'plugin:react-hooks/recommended', | ||
], | ||
ignorePatterns: ['dist', '.eslintrc.cjs'], | ||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, | ||
settings: { react: { version: '18.2' } }, | ||
plugins: ['react-refresh'], | ||
rules: { | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
"eslint:recommended", | ||
"plugin:react/recommended", | ||
"plugin:react/jsx-runtime", | ||
"plugin:react-hooks/recommended", | ||
], | ||
ignorePatterns: ["dist", ".eslintrc.cjs"], | ||
parserOptions: { ecmaVersion: "latest", sourceType: "module" }, | ||
settings: { react: { version: "18.2" } }, | ||
plugins: ["react-refresh"], | ||
rules: { | ||
"react-refresh/only-export-components": [ | ||
"warn", | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[[redirects]] | ||
from = "/*" | ||
to = "/index.html" | ||
status = 200 |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,22 @@ | ||
import { BrowserRouter, Routes, Route } from "react-router-dom" | ||
import { useParams } from "react-router-dom" | ||
import { Movies } from "./components/FirstPage.jsx" | ||
import { Details } from "./components/SecondPage.jsx" | ||
import { Nav } from "./components/Nav" | ||
import { useEffect, useState } from "react" | ||
import { NotFound } from "./components/NotFound.jsx" | ||
|
||
export const App = () => { | ||
return <div>Find me in src/app.jsx!</div>; | ||
}; | ||
return ( | ||
<BrowserRouter> | ||
<main> | ||
{/* <Nav /> */} | ||
<Routes> | ||
<Route path="/" element={<Movies />} /> | ||
<Route path="/details/:slug" element={<Details />} /> | ||
<Route path="/notfound/" element={<NotFound />} /> | ||
</Routes> | ||
</main> | ||
</BrowserRouter> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Lottie from "react-lottie" | ||
import animationData from "../lotties/backanimation.json" | ||
|
||
export const BackImage = () => { | ||
const defaultOptions = { | ||
loop: true, | ||
autoplay: true, | ||
animationData: animationData, | ||
rendererSettings: { | ||
preserveAspectRatio: "xMidYMid slice", | ||
}, | ||
} | ||
|
||
return ( | ||
<div> | ||
<Lottie options={defaultOptions} height={200} width={200} /> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Link } from "react-router-dom" | ||
import "../styling/DetailList.css" | ||
import { BackImage } from "./BackImage" | ||
|
||
export const DetailList = ({ detailData }) => { | ||
console.log("check data in DetailList", detailData) | ||
return ( | ||
<> | ||
{/* {detailData && | ||
detailData.results.map((detail) => ( */} | ||
<div className="detail-wrapper"> | ||
<div | ||
className="detail-background" | ||
style={{ | ||
backgroundImage: `url(https://media.themoviedb.org/t/p/w780${detailData.backdrop_path})`, | ||
backgroundRepeat: "no-repeat", | ||
backgroundSize: "cover", | ||
minWidth: "100VW", | ||
}}> | ||
<div className="details-card"> | ||
<Link to={"/"}> | ||
<BackImage className="back-btn" /> | ||
</Link> | ||
<img | ||
className="poster-image" | ||
src={`https://image.tmdb.org/t/p/w342${detailData.poster_path}`} | ||
alt={`Movie poster for ${detailData.title}`} | ||
/> | ||
<div className="poster-text"> | ||
<h1>{detailData.title}</h1> | ||
<h2>⭐ {detailData.vote_average.toFixed(1)}</h2> | ||
<p>{detailData.overview}</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { useState, useEffect } from "react" | ||
import { PopularList } from "./PopularList.jsx" | ||
import { Loader } from "./Loader" | ||
|
||
export const Movies = () => { | ||
const [movieData, setMovieData] = useState(null) | ||
const [isLoading, setIsLoading] = useState(true) | ||
|
||
const apiEnv = import.meta.env.VITE_OPENDB_KEY | ||
const testUrl = `https://api.themoviedb.org/3/movie/popular?api_key=${apiEnv}&language=en-US&page=1` | ||
|
||
useEffect(() => { | ||
fetch(testUrl) | ||
.then((result) => result.json()) | ||
.then((json) => { | ||
setMovieData(json) | ||
setIsLoading(false) | ||
}) | ||
.catch((error) => { | ||
console.error(error) | ||
}) | ||
}, [testUrl]) | ||
console.log("moviedata firstpage", movieData) | ||
return ( | ||
<> | ||
{isLoading && <Loader />} | ||
<PopularList movieData={movieData} /> | ||
</> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const Images = ({ url, altText }) => { | ||
return <img className="images" src=""></img> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Lottie from "react-lottie" | ||
import animationData from "../lotties/animation.json" | ||
|
||
export const Loader = () => { | ||
const defaultOptions = { | ||
loop: true, | ||
autoplay: true, | ||
animationData: animationData, | ||
rendererSettings: { | ||
preserveAspectRatio: "xMidYMid slice", | ||
}, | ||
} | ||
|
||
return ( | ||
<div> | ||
<Lottie options={defaultOptions} height={300} width={300} /> | ||
</div> | ||
) | ||
} | ||
|
||
//nedan är försök att få animationen att visas längre. | ||
|
||
// useEffect(() => { | ||
// export const DelayLottie = setTimeout(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the next time you might want to consider creating the function "DelayLottie" before (for example, around line 5) and then you can call the function inside of the useEffect. 👍 |
||
// setLoading(true) | ||
// }, 3000) | ||
// }) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from "react" | ||
import { Link, NavLink } from "react-router-dom" | ||
import "../styling/Nav.css" | ||
|
||
export const Nav = () => { | ||
return ( | ||
<> | ||
<div className="navbar-title"> | ||
<h1>RomComs</h1> | ||
</div> | ||
<ul className="navbar"> | ||
<li> | ||
<NavLink to="/">Movies</NavLink> | ||
</li> | ||
<li> | ||
<NavLink to="/details">Details</NavLink> | ||
</li> | ||
</ul> | ||
</> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const NotFound = () => { | ||
return <div>Page not found</div> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import "../styling/PopularList.css" | ||
import { Link } from "react-router-dom" | ||
|
||
//functional component | ||
export const PopularList = ({ movieData }) => { | ||
|
||
return ( | ||
<div className="movie-wrapper"> | ||
<div className="movie-list"> | ||
{movieData && | ||
movieData.results.map((movie) => ( | ||
<Link key={movie.id} to={`/details/${movie.id}`}> | ||
<div className="movie-card" key={movie.id}> | ||
<div className="hover-text"> | ||
<h1 className="title">{movie.title}</h1> | ||
<h2 className="release-date"> | ||
Released {movie.release_date} | ||
</h2> | ||
</div> | ||
<div className="poster"> | ||
<img | ||
className="movie-image" | ||
src={`https://image.tmdb.org/t/p/w342${movie.poster_path}`} | ||
alt={`Movie poster for ${movie.title}`} | ||
/> | ||
</div> | ||
</div> | ||
</Link> | ||
))} | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
// return ( | ||
// <> | ||
// {jsonMovies.map((movie) => ( | ||
// <article className="movie-card" key={movie.id}> | ||
// <Link to={`/details/${movie.id}`}></Link> | ||
// </article> | ||
// ))} | ||
// </> | ||
// ) | ||
// } |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is interesting how you split in two different components the fetching and the data rendering. Maybe you can explain us why you choose that logic 😊. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import "../styling/SecondPage.css" | ||
import { useState, useEffect } from "react" | ||
import { Loader } from "./Loader" | ||
import { NotFound } from "./NotFound" | ||
import { Link, useParams } from "react-router-dom" | ||
import { DetailList } from "./DetailList" | ||
|
||
export const Details = () => { | ||
const [detailData, setDetailData] = useState(null) | ||
const [isLoading, setIsLoading] = useState(true) | ||
|
||
const params = useParams() | ||
const movieId = params.slug | ||
const API_KEY = "23ace2b0c27910f5cec13f5bdb014044" | ||
|
||
const listUrl = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US` | ||
|
||
useEffect(() => { | ||
fetch(listUrl) | ||
.then((result) => result.json()) | ||
.then((json) => { | ||
setDetailData(json) | ||
setIsLoading(false) | ||
}) | ||
.catch((error) => { | ||
console.error(error) | ||
}) | ||
}, [listUrl]) | ||
|
||
if (!detailData || detailData === undefined) { | ||
return <Loader /> | ||
} | ||
|
||
if (detailData.success === false) { | ||
return <NotFound /> | ||
} | ||
console.log("detailtdata secondpage", detailData) | ||
return ( | ||
<> | ||
{isLoading && <Loader />} | ||
<DetailList detailData={detailData} /> | ||
</> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
:root { | ||
margin: 0; | ||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", | ||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", | ||
sans-serif; | ||
-webkit-font-smoothing: antialiased; | ||
-moz-osx-font-smoothing: grayscale; | ||
margin: 0; | ||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", | ||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", | ||
sans-serif; | ||
-webkit-font-smoothing: antialiased; | ||
-moz-osx-font-smoothing: grayscale; | ||
background-color: rgb(252, 213, 220); | ||
} | ||
|
||
code { | ||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", | ||
monospace; | ||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", | ||
monospace; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there are screens that are bigger than 780; maybe next time you could consider on taking 1280px for background images.
-Izabel&Etna