diff --git a/README.md b/README.md index abe3db5d7..11f959b10 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,4 @@ const pattern = /^((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|( - Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline). - Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript). - Open one more terminal and run tests with `npm test` to ensure your solution is correct. -- Replace `` with your Github username in the [DEMO LINK](https://.github.io/react_movies-list-add-form/) and add it to the PR description. +- Replace `` with your Github username in the [DEMO LINK](https://amir-al-mohamad.github.io/react_movies-list-add-form/) and add it to the PR description. diff --git a/src/App.tsx b/src/App.tsx index 34be670b0..63c4eaa84 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,24 @@ import './App.scss'; +import { useState } from 'react'; import { MoviesList } from './components/MoviesList'; import { NewMovie } from './components/NewMovie'; import moviesFromServer from './api/movies.json'; +import { Movie } from './types/Movie'; export const App = () => { + const [movies, setMovies] = useState(moviesFromServer); + return (
- +
- {}} */ /> + { + setMovies([...movies, movie]); + }} + />
); diff --git a/src/components/NewMovie/NewMovie.tsx b/src/components/NewMovie/NewMovie.tsx index 85bace9dd..8bd17eec0 100644 --- a/src/components/NewMovie/NewMovie.tsx +++ b/src/components/NewMovie/NewMovie.tsx @@ -1,30 +1,97 @@ import { useState } from 'react'; import { TextField } from '../TextField'; +import { Movie } from '../../types/Movie'; -export const NewMovie = () => { +type Props = { + onAdd: (movie: Movie) => void; +}; + +export const NewMovie: React.FC = ({ onAdd }) => { // Increase the count after successful form submission // to reset touched status of all the `Field`s - const [count] = useState(0); + const [count, setCount] = useState(0); + const [newMovie, setNewMovie] = useState({ + title: '', + description: '', + imgUrl: '', + imdbUrl: '', + imdbId: '', + }); + + const { title, description, imgUrl, imdbUrl, imdbId } = newMovie; + + const isValid = () => { + return Boolean( + title.trim() && imgUrl.trim() && imdbUrl.trim() && imdbId.trim(), + ); + }; + + const handleChange = (event: React.ChangeEvent) => { + const { name, value } = event.target; + + setNewMovie(prevMovie => ({ ...prevMovie, [name]: value })); + }; + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + + if (!isValid()) { + return; + } + + onAdd(newMovie); + setCount(count + 1); + setNewMovie({ + title: '', + description: '', + imgUrl: '', + imdbUrl: '', + imdbId: '', + }); + }; return ( -
+

Add a movie

{}} + value={title} + onChange={handleChange} required /> - + - + - + - +
@@ -32,6 +99,8 @@ export const NewMovie = () => { type="submit" data-cy="submit-button" className="button is-link" + disabled={!isValid()} + onClick={handleSubmit} > Add diff --git a/src/components/TextField/TextField.tsx b/src/components/TextField/TextField.tsx index e24856c4b..ee4f37c24 100644 --- a/src/components/TextField/TextField.tsx +++ b/src/components/TextField/TextField.tsx @@ -7,7 +7,7 @@ type Props = { label?: string; placeholder?: string; required?: boolean; - onChange?: (newValue: string) => void; + onChange?: (newValue: React.ChangeEvent) => void; }; function getRandomDigits() { @@ -39,13 +39,14 @@ export const TextField: React.FC = ({ onChange(event.target.value)} + onChange={onChange} onBlur={() => setTouched(true)} />