from course, placeholder files
This commit is contained in:
parent
982d8d4393
commit
398290cd9e
@ -1,64 +1,73 @@
|
|||||||
import React, { useState } from "react"
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
|
|
||||||
import MoviesList from "./components/MoviesList"
|
import MoviesList from './components/MoviesList';
|
||||||
import "./App.css"
|
import AddMovie from './components/AddMovie';
|
||||||
|
import './App.css';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [movies, setMovies] = useState([])
|
const [movies, setMovies] = useState([]);
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [error, setError] = useState(null)
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
const fetchMoviesHandler = async () => {
|
const fetchMoviesHandler = useCallback(async () => {
|
||||||
setIsLoading(true)
|
setIsLoading(true);
|
||||||
setError(null)
|
setError(null);
|
||||||
|
try {
|
||||||
|
const response = await fetch('https://swapi.dev/api/films/');
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Something went wrong!');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
const data = await response.json();
|
||||||
const response = await fetch("https://swapi.dev/api/films/")
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`something went wrong ${response.status}`)
|
|
||||||
}
|
|
||||||
const data = await response.json()
|
|
||||||
|
|
||||||
setIsLoading(false)
|
const transformedMovies = data.results.map((movieData) => {
|
||||||
|
return {
|
||||||
const transformedMovies = data.results.map((movieData) => {
|
id: movieData.episode_id,
|
||||||
return {
|
title: movieData.title,
|
||||||
id: movieData.episode_id,
|
openingText: movieData.opening_crawl,
|
||||||
title: movieData.title,
|
releaseDate: movieData.release_date,
|
||||||
openingText: movieData.opening_crawl,
|
};
|
||||||
releaseDate: movieData.release_date,
|
});
|
||||||
}
|
setMovies(transformedMovies);
|
||||||
})
|
} catch (error) {
|
||||||
|
setError(error.message);
|
||||||
setMovies(transformedMovies)
|
|
||||||
} catch (error) {
|
|
||||||
setError(error.message)
|
|
||||||
}
|
|
||||||
setIsLoading(false)
|
|
||||||
}
|
}
|
||||||
|
setIsLoading(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
let content = <p>Found no movies.</p>
|
useEffect(() => {
|
||||||
if (movies.length > 0) {
|
fetchMoviesHandler();
|
||||||
content = <MoviesList movies={movies} />
|
}, [fetchMoviesHandler]);
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
content = <p>{error}</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLoading) {
|
function addMovieHandler(movie) {
|
||||||
content = <p>Loading...</p>
|
console.log(movie);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
let content = <p>Found no movies.</p>;
|
||||||
<React.Fragment>
|
|
||||||
<section>
|
if (movies.length > 0) {
|
||||||
<button onClick={fetchMoviesHandler}>Fetch Movies</button>
|
content = <MoviesList movies={movies} />;
|
||||||
</section>
|
}
|
||||||
<section>
|
|
||||||
{content}
|
if (error) {
|
||||||
</section>
|
content = <p>{error}</p>;
|
||||||
</React.Fragment>
|
}
|
||||||
)
|
|
||||||
|
if (isLoading) {
|
||||||
|
content = <p>Loading...</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<section>
|
||||||
|
<AddMovie onAddMovie={addMovieHandler} />
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<button onClick={fetchMoviesHandler}>Fetch Movies</button>
|
||||||
|
</section>
|
||||||
|
<section>{content}</section>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App;
|
||||||
|
43
http-sw/src/components/AddMovie.js
Normal file
43
http-sw/src/components/AddMovie.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React, { useRef } from 'react';
|
||||||
|
|
||||||
|
import classes from './AddMovie.module.css';
|
||||||
|
|
||||||
|
function AddMovie(props) {
|
||||||
|
const titleRef = useRef('');
|
||||||
|
const openingTextRef = useRef('');
|
||||||
|
const releaseDateRef = useRef('');
|
||||||
|
|
||||||
|
function submitHandler(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// could add validation here...
|
||||||
|
|
||||||
|
const movie = {
|
||||||
|
title: titleRef.current.value,
|
||||||
|
openingText: openingTextRef.current.value,
|
||||||
|
releaseDate: releaseDateRef.current.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
props.onAddMovie(movie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={submitHandler}>
|
||||||
|
<div className={classes.control}>
|
||||||
|
<label htmlFor='title'>Title</label>
|
||||||
|
<input type='text' id='title' ref={titleRef} />
|
||||||
|
</div>
|
||||||
|
<div className={classes.control}>
|
||||||
|
<label htmlFor='opening-text'>Opening Text</label>
|
||||||
|
<textarea rows='5' id='opening-text' ref={openingTextRef}></textarea>
|
||||||
|
</div>
|
||||||
|
<div className={classes.control}>
|
||||||
|
<label htmlFor='date'>Release Date</label>
|
||||||
|
<input type='text' id='date' ref={releaseDateRef} />
|
||||||
|
</div>
|
||||||
|
<button>Add Movie</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddMovie;
|
26
http-sw/src/components/AddMovie.module.css
Normal file
26
http-sw/src/components/AddMovie.module.css
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.control {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control label {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control input,
|
||||||
|
.control textarea {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font: inherit;
|
||||||
|
padding: 0.2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control input:focus,
|
||||||
|
.control textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #230052;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user