From 3e1891f06f7b63c7bfff3b902a7442951922c4be Mon Sep 17 00:00:00 2001 From: Andrii Zakharenko Date: Tue, 6 Aug 2024 15:14:36 +0300 Subject: [PATCH 1/2] add task solution --- README.md | 2 +- src/App.tsx | 12 +++- src/components/NewMovie/NewMovie.tsx | 87 +++++++++++++++++++++++--- src/components/TextField/TextField.tsx | 2 +- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4a0f7851a..cc7c64a49 100644 --- a/README.md +++ b/README.md @@ -30,4 +30,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://AndriiZakharenko.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..43c3f7626 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,15 +2,23 @@ import './App.scss'; import { MoviesList } from './components/MoviesList'; import { NewMovie } from './components/NewMovie'; import moviesFromServer from './api/movies.json'; +import { useState } from 'react'; +import { Movie } from './types/Movie'; export const App = () => { + const [movies, setMovies] = useState(moviesFromServer); + + const addMovie = (movie: Movie) => { + setMovies(currentMovies => [...currentMovies, movie]); + }; + return (
- +
- {}} */ /> +
); diff --git a/src/components/NewMovie/NewMovie.tsx b/src/components/NewMovie/NewMovie.tsx index 85bace9dd..60b9067f5 100644 --- a/src/components/NewMovie/NewMovie.tsx +++ b/src/components/NewMovie/NewMovie.tsx @@ -1,30 +1,98 @@ 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 [title, setTitle] = useState(''); + const [description, setDescription] = useState(''); + const [imgUrl, setImgUrl] = useState(''); + const [imdbUrl, setImdbUrl] = useState(''); + const [imdbId, setImdbId] = useState(''); + + const fieldsValues = { + title, + imgUrl, + imdbUrl, + imdbId, + }; + + const trimmedFieldsValues = Object.values(fieldsValues).map(value => + value.trim(), + ); + + const hasEmptyField = trimmedFieldsValues.includes(''); + + function reset() { + setTitle(''); + setDescription(''); + setImgUrl(''); + setImdbUrl(''); + setImdbId(''); + } + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + + onAdd({ + ...fieldsValues, + description, + }); + + setCount(currentCount => currentCount + 1); + + reset(); + }; return ( -
+

Add a movie

{}} + value={title} + onChange={setTitle} required /> - + - + - + - +
@@ -32,6 +100,7 @@ export const NewMovie = () => { type="submit" data-cy="submit-button" className="button is-link" + disabled={hasEmptyField} > Add diff --git a/src/components/TextField/TextField.tsx b/src/components/TextField/TextField.tsx index e24856c4b..f695b8d44 100644 --- a/src/components/TextField/TextField.tsx +++ b/src/components/TextField/TextField.tsx @@ -22,7 +22,7 @@ export const TextField: React.FC = ({ required = false, onChange = () => {}, }) => { - // generate a unique id once on component load + // generage a unique id once on component load const [id] = useState(() => `${name}-${getRandomDigits()}`); // To show errors only if the field was touched (onBlur) From a5f797bcff53306fa03d3486fd2135c8b8ff6822 Mon Sep 17 00:00:00 2001 From: Andrii Zakharenko <82187654+AndriiZakharenko@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:05:38 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index cc7c64a49..ee2b25865 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,26 @@ # Movies list - Add Form -You have the `App` with the `MoviesList` and `NewMovie` form containing ready -to use `TextField` components. Learn how it works and implement an ability to -add movies from [IMDB](https://www.imdb.com/). - -If you want to test your page you can get first image from a [movie page](https://www.imdb.com/title/tt1312171) using `DevTools` -> `Network` -> `Img` - -> Here is [the demo page](https://mate-academy.github.io/react_movies-list-add-form/) - -1. `NewMovie` should check if `title`, `imgUrl`, `imdbUrl`, `imdbId` are -entered when an input looses focus (`onBlur`) and show an error and a red -border if needed (learn how it it implemented in the `TextField`); -1. The `description` is optional; -1. Disable the submit button until all the required fields are filled (spaces should be trimmed); -1. Clear the form after adding a new movie. -1. Errors should not be shown after clearing the form (change its key to -reinitialize the form); - -## (Optional) Advanced validation -Implement the ability to add custom validation callback to the `TextField`. -Check if `imgUrl` and `imdbUrl` are valid URLs (you can use the next regex) - -```js -const pattern = /^((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@,.\w_]*)#?(?:[,.!/\\\w]*))?)$/; -``` - -## Instructions -- Install Prettier Extention and use this [VSCode settings](https://mate-academy.github.io/fe-program/tools/vscode/settings.json) to enable format on save. -- 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://AndriiZakharenko.github.io/react_movies-list-add-form/) and add it to the PR description. +### Description + +- Implemented possibility to add a movie to Movie List + +### Stack + +- HTML (BEM) +- CSS (Bulma) +- JS +- Typescript +- React +- ReactDOM + +### Tools + +- ESlint +- Prettier +- Cypress +- Mochawesome +- Babel + +### Demo links + +- [Demo](https://AndriiZakharenko.github.io/movies-list-add-form/)