mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 20:01:59 +00:00
Update sample code
This commit is contained in:
@@ -1,80 +1,103 @@
|
||||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
const tempMovieData = [
|
||||
{
|
||||
imdbID: "tt1375666",
|
||||
Title: "Inception",
|
||||
Year: "2010",
|
||||
Poster:
|
||||
"https://m.media-amazon.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
},
|
||||
{
|
||||
imdbID: "tt0133093",
|
||||
Title: "The Matrix",
|
||||
Year: "1999",
|
||||
Poster:
|
||||
"https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SX300.jpg",
|
||||
},
|
||||
{
|
||||
imdbID: "tt6751668",
|
||||
Title: "Parasite",
|
||||
Year: "2019",
|
||||
Poster:
|
||||
"https://m.media-amazon.com/images/M/MV5BYWZjMjk3ZTItODQ2ZC00NTY5LWE0ZDYtZTI3MjcwN2Q5NTVkXkEyXkFqcGdeQXVyODk4OTc3MTY@._V1_SX300.jpg",
|
||||
},
|
||||
];
|
||||
|
||||
const tempWatchedData = [
|
||||
{
|
||||
imdbID: "tt1375666",
|
||||
Title: "Inception",
|
||||
Year: "2010",
|
||||
Poster:
|
||||
"https://m.media-amazon.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
runtime: 148,
|
||||
imdbRating: 8.8,
|
||||
userRating: 10,
|
||||
},
|
||||
{
|
||||
imdbID: "tt0088763",
|
||||
Title: "Back to the Future",
|
||||
Year: "1985",
|
||||
Poster:
|
||||
"https://m.media-amazon.com/images/M/MV5BZmU0M2Y1OGUtZjIxNi00ZjBkLTg1MjgtOWIyNThiZWIwYjRiXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg",
|
||||
runtime: 116,
|
||||
imdbRating: 8.5,
|
||||
userRating: 9,
|
||||
},
|
||||
];
|
||||
|
||||
const average = (arr) =>
|
||||
arr.reduce((acc, cur, i, arr) => acc + cur / arr.length, 0);
|
||||
|
||||
const KEY = "68ff4a55";
|
||||
const BASE_URL = "http://www.omdbapi.com/";
|
||||
|
||||
export default function App() {
|
||||
const [movies, setMovies] = useState(tempMovieData);
|
||||
const [watched, setWatched] = useState(tempWatchedData);
|
||||
const [query, setQuery] = useState("");
|
||||
const [movies, setMovies] = useState([]);
|
||||
const [watched, setWatched] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [selectedId, setSelectedId] = useState(null);
|
||||
|
||||
const handleSelectMovie = (id) => {
|
||||
setSelectedId((selectedId) => (id === selectedId ? null : id));
|
||||
};
|
||||
|
||||
const handleCloseMovie = () => {
|
||||
setSelectedId(null);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchMovies = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setError("");
|
||||
|
||||
const res = await fetch(BASE_URL + `?apikey=${KEY}&s=${query}`);
|
||||
|
||||
if (!res.ok)
|
||||
throw new Error("Something went wrong with fetching movies");
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.Response === "False") throw new Error("Movie not found!");
|
||||
|
||||
setMovies(data.Search);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (query.length < 3) {
|
||||
setMovies([]);
|
||||
setError("");
|
||||
return;
|
||||
}
|
||||
|
||||
fetchMovies();
|
||||
}, [query]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar>
|
||||
<Search />
|
||||
<Search query={query} setQuery={setQuery} />
|
||||
<NumResults movies={movies} />
|
||||
</NavBar>
|
||||
|
||||
<Main>
|
||||
<Box>
|
||||
<MovieList movies={movies} />
|
||||
{/* {isLoading ? <Loader /> : <MovieList movies={movies} />} */}
|
||||
{isLoading && <Loader />}
|
||||
{!isLoading && !error && (
|
||||
<MovieList movies={movies} onSelectMovie={handleSelectMovie} />
|
||||
)}
|
||||
{error && <ErrorMessage message={error} />}
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<WatchedSummary watched={watched} />
|
||||
<WatchMovieList watched={watched} />
|
||||
{selectedId ? (
|
||||
<MovieDetails
|
||||
selectedId={selectedId}
|
||||
onCloseMovie={handleCloseMovie}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<WatchedSummary watched={watched} />
|
||||
<WatchMovieList watched={watched} />
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
</Main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Loader() {
|
||||
return <p className="loader">Loading...</p>;
|
||||
}
|
||||
|
||||
function ErrorMessage({ message }) {
|
||||
return <p className="error">{message}</p>;
|
||||
}
|
||||
|
||||
function NavBar({ children }) {
|
||||
return (
|
||||
<nav className="nav-bar">
|
||||
@@ -93,8 +116,7 @@ function Logo() {
|
||||
);
|
||||
}
|
||||
|
||||
function Search() {
|
||||
const [query, setQuery] = useState("");
|
||||
function Search({ query, setQuery }) {
|
||||
return (
|
||||
<input
|
||||
className="search"
|
||||
@@ -153,19 +175,19 @@ function Box({ children }) {
|
||||
// );
|
||||
// }
|
||||
|
||||
function MovieList({ movies }) {
|
||||
function MovieList({ movies, onSelectMovie }) {
|
||||
return (
|
||||
<ul className="list">
|
||||
<ul className="list list-movies">
|
||||
{movies?.map((movie) => (
|
||||
<Movie movie={movie} key={movie.imdbID} />
|
||||
<Movie movie={movie} key={movie.imdbID} onSelectMovie={onSelectMovie} />
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
function Movie({ movie }) {
|
||||
function Movie({ movie, onSelectMovie }) {
|
||||
return (
|
||||
<li key={movie.imdbID}>
|
||||
<li key={movie.imdbID} onClick={() => onSelectMovie(movie.imdbID)}>
|
||||
<img src={movie.Poster} alt={`${movie.Title} poster`} />
|
||||
<h3>{movie.Title}</h3>
|
||||
<div>
|
||||
@@ -178,6 +200,17 @@ function Movie({ movie }) {
|
||||
);
|
||||
}
|
||||
|
||||
function MovieDetails({ selectedId, onCloseMovie }) {
|
||||
return (
|
||||
<div className="details">
|
||||
<button className="btn-back" onClick={onCloseMovie}>
|
||||
←
|
||||
</button>
|
||||
{selectedId}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function WatchedSummary({ watched }) {
|
||||
const avgImdbRating = average(watched.map((movie) => movie.imdbRating));
|
||||
const avgUserRating = average(watched.map((movie) => movie.userRating));
|
||||
|
||||
@@ -10,6 +10,17 @@ const containerStyle = {
|
||||
const starContainerStyle = {
|
||||
display: "flex",
|
||||
};
|
||||
|
||||
StarRating.propTypes = {
|
||||
maxRating: PropTypes.number,
|
||||
defaultRating: PropTypes.number,
|
||||
color: PropTypes.string,
|
||||
size: PropTypes.number,
|
||||
messages: PropTypes.array,
|
||||
className: PropTypes.string,
|
||||
onSetRating: PropTypes.func,
|
||||
};
|
||||
|
||||
export default function StarRating({
|
||||
maxRating = 5,
|
||||
color = "#fcc419",
|
||||
|
||||
@@ -54,8 +54,12 @@ body {
|
||||
max-width: 42rem;
|
||||
background-color: var(--color-background-500);
|
||||
border-radius: 0.9rem;
|
||||
/* overflow: scroll; */
|
||||
position: relative;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.box::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loader {
|
||||
@@ -138,7 +142,11 @@ body {
|
||||
.list {
|
||||
list-style: none;
|
||||
padding: 0.8rem 0;
|
||||
/* overflow: scroll; */
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-watched {
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
// import "./index.css";
|
||||
import StarRating from "./StarRating.jsx";
|
||||
import { useState } from "react";
|
||||
|
||||
function Test() {
|
||||
const [movieRating, setMovieRating] = useState(0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<StarRating color="blue" maxRating={10} />
|
||||
<p>The move was rated {movieRating} stars</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import "./index.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
{/* <App /> */}
|
||||
<StarRating
|
||||
maxRating={5}
|
||||
messages={["Terrible", "Bad", "Okay", "Good", "Amazing"]}
|
||||
/>
|
||||
<StarRating size={24} color="red" className="test" defaultRating={3} />
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user