diff --git a/src/App.jsx b/src/App.jsx index c2435de..6e455c4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,18 +1,20 @@ -import React, {Component} from 'react' -import { Alert, Col, ConfigProvider, Layout, Pagination, Row, Spin, Tabs } from 'antd' +/* eslint-disable react/jsx-no-constructed-context-values */ +import React, { Component } from 'react'; +// eslint-disable-next-line object-curly-newline +import { Alert, Col, ConfigProvider, Layout, Pagination, Row, Spin, Tabs } from 'antd'; -import MovieService from './services/MovieService.js' -import SearchTab from './components/SearchTab' -import RatedTab from './components/RatedTab' -import FilmList from './components/FilmList' -import FetcherService from './services/FetcherService.js'; -import { Context } from './services/Context.js'; +import MovieService from './services/MovieService'; +import SearchTab from './components/SearchTab'; +import RatedTab from './components/RatedTab'; +import FilmList from './components/FilmList'; +import FetcherService from './services/FetcherService'; +import { Context } from './services/Context'; const { Content } = Layout; export default class App extends Component { constructor(props) { - super(props) + super(props); this.state = { movie: new MovieService(), genres: [], @@ -23,68 +25,95 @@ export default class App extends Component { error: false, ratedFilms: [], fetcher: new FetcherService(), + }; + } + + async componentDidMount() { + const { movie, fetcher } = this.state; + + const createSession = async () => { + const x = await movie.createGuestSession(); + return x; + }; + await createSession(); + fetcher.fetch(this.getGenres, (error) => this.setState({ error })); + } + + componentDidUpdate(prevProps, prevState) { + const { fetcher } = this.state; + if (prevState.fetcher.state.loading !== fetcher.state.loading) { + this.setState({ isLoading: fetcher.state.loading }); + } + if (prevState.fetcher.state.error !== fetcher.state.error) { + this.setState({ error: fetcher.state.error }); } } changeRatingHandler = async (filmId, rating) => { - this.setState((oldState) => ({ - ratedFilms: [...oldState.ratedFilms.filter((film) => film.id !== filmId), { id: filmId, rating }], - })) - await this.state.movie.addRatingToFilm(filmId, rating).catch((exception) => this.setState({ error: exception.message })) - } + const { movie } = this.state; + this.setState((state) => ({ + // eslint-disable-next-line prettier/prettier + ratedFilms: [...state.ratedFilms.filter( + (film) => film.id !== filmId, + ), { id: filmId, rating }], + })); + /* eslint-disable prettier/prettier */ + await movie.addRatingToFilm(filmId, rating).catch((exception) => + // eslint-disable-next-line indent, implicit-arrow-linebreak + this.setState({ error: exception.message })); + }; + /* eslint-enable prettier/prettier */ getGenres = async () => { - await this.state.movie.getGenreList().then((response) => { - this.setState({ genres: response.genres }) - }) - } + const { movie } = this.state; + await movie.getGenreList().then((response) => { + this.setState({ genres: response.genres }); + }); + }; setError = (error) => { this.setState({ error }); - } + }; setFilms = (films) => { - this.setState({films}); - } + this.setState({ films }); + }; setTotalItems = (totalItems) => { this.setState({ totalItems }); - } + }; setIsLoading = (isLoading) => { this.setState({ isLoading }); - } + }; setCurrentPage = (page) => { this.setState({ - currentPage: page + currentPage: page, }); - } - - componentDidMount() { - const createSession = async () => await this.state.movie.createGuestSession() - createSession() - this.state.fetcher.fetch(this.getGenres, (error) => this.setState({ error })) - } - - componentDidUpdate(prevProps, prevState) { - if (prevState.fetcher.state.loading !== this.state.fetcher.state.loading) { - this.setState({ isLoading: this.state.fetcher.state.loading }) - } - if (prevState.fetcher.state.error !== this.state.fetcher.state.error) { - this.setState({ error: this.state.fetcher.state.error }) - } - } + }; changeTabHandler = () => { this.setState({ films: [], isLoading: true, currentPage: 1, - }) - } + }); + }; render() { + /* eslint-disable prettier/prettier */ + const { + currentPage, + ratedFilms, + movie, + genres, + error, + isLoading, + films, + totalItems, + } = this.state; + /* eslint-enable prettier/prettier */ const tabs = [ { key: 1, @@ -93,10 +122,10 @@ export default class App extends Component { ), }, @@ -107,16 +136,15 @@ export default class App extends Component { ), }, - ] + ]; return ( - - + <> - {this.state.error && } - {this.state.isLoading ? ( + {error && } + {isLoading ? ( - + ) : ( <> - this.changeRatingHandler(filmId, rating)} + this.changeRatingHandler(filmId, rating)} /> this.setCurrentPage(page)} itemRender={this.paginationItemRender} @@ -174,6 +203,6 @@ export default class App extends Component { - ) + ); } } diff --git a/src/components/FilmCard/FilmCard.module.css b/src/components/FilmCard/FilmCard.module.css index 12faef3..1e45dc2 100644 --- a/src/components/FilmCard/FilmCard.module.css +++ b/src/components/FilmCard/FilmCard.module.css @@ -1,8 +1,10 @@ .film-card { display: flex; border-radius: 0; - height: 300px; + height: 279px; + max-width: 451px; filter: drop-shadow(0px 4px 12px rgba(0, 0, 0, 0.15)); + padding: 0; } .film-card__header { @@ -11,7 +13,12 @@ align-items: center; width: 100%; font-weight: 100 !important; - padding-bottom: 0ch; + margin-bottom: 0; + line-height: 1; +} + +.ant-card-body { + padding: 10px !important; } .film-card__content { @@ -27,18 +34,19 @@ } .film-card__image { - max-width: 18rem; - height: 100%; - min-width: 10rem; + max-width: 12rem; + height: 17.4375rem; border-radius: 0 !important; - object-fit: cover; + object-fit: fill; + margin: 0; + padding: 0; } .film-card__rating { width: 30px; height: 30px; border-radius: 50%; - border: 1px solid; + border: 2px solid; display: flex; justify-content: center; align-items: center; @@ -52,6 +60,7 @@ .film-card__stars { margin: auto 0 0; + font-size: 16px; } @media screen and (max-width: 576px) { @@ -68,7 +77,7 @@ } .film-card__content-wrapper { - margin-top: 20px; + margin-top: 10px; display: flex; flex-direction: column; } diff --git a/src/components/SearchTab/SearchTab.jsx b/src/components/SearchTab/SearchTab.jsx index d830082..d4e8aaa 100644 --- a/src/components/SearchTab/SearchTab.jsx +++ b/src/components/SearchTab/SearchTab.jsx @@ -1,10 +1,10 @@ -import React, { Component } from 'react' -import { Input } from 'antd' -import { debounce } from 'lodash' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import { Input } from 'antd'; +import { debounce } from 'lodash'; +import PropTypes from 'prop-types'; -import FetcherService from '../../services/FetcherService.js' -import { Context } from '../../services/Context.js' +import FetcherService from '../../services/FetcherService'; +import { Context } from '../../services/Context'; export default class SearchTab extends Component { constructor(props) { @@ -34,17 +34,18 @@ export default class SearchTab extends Component { } return film }) - setFilms(films); + setFilms(films); setTotalItems(response.total_results); } catch(error) { this.setState({error: error}); - setError(error); + setError(error); } this.setState({isLoading: false}); } componentDidMount() { this.checkQueryString(); + this.debouncedQueryHandler({ target: { value: 'return' } }); } componentDidUpdate(prevProps, prevState) { @@ -74,7 +75,12 @@ export default class SearchTab extends Component { this.setState({queryString: e.target.value}); } render() { - return + return } }