Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ht5 #67

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
16,664 changes: 16,664 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@wojtekmaj/enzyme-adapter-react-17": "^0.3.1",
"body-parser": "^1.19.0",
"classnames": "^2.2.6",
"concurrently": "^5.3.0",
"core-js": "^3.8.0",
"enzyme": "^3.11.0",
"express": "^4.17.1",
"immer": "^8.0.0",
"normalize.css": "^8.0.1",
"object-assign": "^4.1.1",
"prop-types": "^15.7.2",
"qs": "^6.9.4",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-redux": "^7.2.2",
Expand All @@ -26,7 +31,7 @@
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "concurrently \"react-scripts start\" \"yarn api\"",
"start": "concurrently \"react-scripts start\" \"npm run api\"",
"api": "node simple_api/server.js",
"build": "react-scripts build",
"test": "react-scripts test",
Expand Down
39 changes: 38 additions & 1 deletion src/components/menu/menu.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Product from '../product';
import Basket from '../basket';
import Loader from '../loader';
import {
productsListSelector,
productsLoadedSelector,
productsLoadingSelector,
} from '../../redux/selectors';
import { loadProducts } from '../../redux/actions';

import styles from './menu.module.css';

Expand All @@ -16,9 +24,23 @@ class Menu extends React.Component {
this.setState({ error });
}

componentDidMount() {
if (!this.props.loading && !this.props.loaded) {
this.props.loadProducts(this.props.restaurantId);
}
}

componentDidUpdate(prevProps) {
if (this.props.restaurantId !== prevProps.restaurantId) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут тоже нужна проверка на loading и loaded

this.props.loadProducts(this.props.restaurantId);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут будет повторно грузиться для ресторана, для которого уже загружено

}
}

render() {
const { menu } = this.props;

if (this.props.loading || !this.props.loaded) return <Loader />;

if (this.state.error) {
return <p>В этом ресторане меню не доступно</p>;
}
Expand All @@ -38,4 +60,19 @@ class Menu extends React.Component {
}
}

export default Menu;
const mapStateToProps = (state) => ({
products: productsListSelector(state),
loading: productsLoadingSelector(state),
loaded: productsLoadedSelector(state),
});

const mapDispatchToProps = (dispatch, props) => ({
loadProducts: () => dispatch(loadProducts(props.restaurantId)),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

restaurantId передается в componentDidMount

});

//&&
// !this.props.loading &&
// !this.props.loaded
//connect(null, { loadProducts })(

export default connect(mapStateToProps, mapDispatchToProps)(Menu);
44 changes: 23 additions & 21 deletions src/components/product/product.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
Expand All @@ -10,31 +10,33 @@ import Button from '../button';
import { productAmountSelector, productSelector } from '../../redux/selectors';

const Product = ({ product, amount, increment, decrement, fetchData }) => {
useEffect(() => {
fetchData && fetchData(product.id);
}, []); // eslint-disable-line

return (
<div className={styles.product} data-id="product">
<div className={styles.content}>
<div>
<h4 className={styles.title}>{product.name}</h4>
<p className={styles.description}>{product.ingredients.join(', ')}</p>
<div className={styles.price}>{product.price} $</div>
</div>
<div>
<div className={styles.counter}>
<div className={styles.count} data-id="product-amount">
{amount}
<React.Fragment>
{product && (
<div className={styles.product} data-id="product">
<div className={styles.content}>
<div>
<h4 className={styles.title}>{product.name}</h4>
<p className={styles.description}>
{product.ingredients.join(', ')}
</p>
<div className={styles.price}>{product.price} $</div>
</div>
<div className={styles.buttons}>
<Button onClick={decrement} icon="minus" />
<Button onClick={increment} icon="plus" />
<div>
<div className={styles.counter}>
<div className={styles.count} data-id="product-amount">
{amount}
</div>
<div className={styles.buttons}>
<Button onClick={decrement} icon="minus" />
<Button onClick={increment} icon="plus" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</React.Fragment>
);
};

Expand Down
27 changes: 21 additions & 6 deletions src/components/restaurant/restaurant.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Menu from '../menu';
Expand All @@ -7,10 +7,22 @@ import Banner from '../banner';
import Rate from '../rate';
import Tabs from '../tabs';
import { averageRatingSelector } from '../../redux/selectors';
import { loadReviews } from '../../redux/actions';

const Restaurant = ({
id,
name,
menu,
reviews,
averageRating,
loadReviews,
}) => {
useEffect(() => {
loadReviews(id);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут будет повторно грузиться для ресторана, для которого уже загружено

}, [loadReviews, id]);

const Restaurant = ({ id, name, menu, reviews, averageRating }) => {
const tabs = [
{ title: 'Menu', content: <Menu menu={menu} /> },
{ title: 'Menu', content: <Menu menu={menu} restaurantId={id} /> },
{
title: 'Reviews',
content: <Reviews reviews={reviews} restaurantId={id} />,
Expand All @@ -35,6 +47,9 @@ Restaurant.propTypes = {
averageRating: PropTypes.number,
};

export default connect((state, props) => ({
averageRating: averageRatingSelector(state, props),
}))(Restaurant);
export default connect(
(state, props) => ({
averageRating: averageRatingSelector(state, props),
}),
{ loadReviews }
)(Restaurant);
32 changes: 17 additions & 15 deletions src/components/reviews/review/review.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ import styles from './review.module.css';
import { connect } from 'react-redux';
import { reviewWitUserSelector } from '../../../redux/selectors';

const Review = ({ review: { user = 'Anonymous', text, rating } }) => (
<div className={styles.review} data-id="review">
<div className={styles.content}>
<div>
<h4 className={styles.name} data-id="review-user">
{user}
</h4>
<p className={styles.comment} data-id="review-text">
{text}
</p>
</div>
<div className={styles.rate}>
<Rate value={rating} />
const Review = ({ review: { user = 'Anonymous', text, rating } }) => {
return (
<div className={styles.review} data-id="review">
<div className={styles.content}>
<div>
<h4 className={styles.name} data-id="review-user">
{user}
</h4>
<p className={styles.comment} data-id="review-text">
{text}
</p>
</div>
<div className={styles.rate}>
<Rate value={rating} />
</div>
</div>
</div>
</div>
);
);
};

Review.propTypes = {
review: PropTypes.shape({
Expand Down
40 changes: 31 additions & 9 deletions src/components/reviews/reviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@ import Review from './review';
import ReviewForm from './review-form';
import styles from './reviews.module.css';
import { connect } from 'react-redux';
import Loader from '../loader';
import {
reviewsListSelector,
usersListSelector,
usersLoadedSelector,
usersLoadingSelector,
} from '../../redux/selectors';
import { loadUsers } from '../../redux/actions';

import { loadReviews } from '../../redux/actions';

const Reviews = ({ reviews, restaurantId, loadReviews }) => {
const Reviews = ({ reviews, restaurantId, loadUsers, loading, loaded }) => {
useEffect(() => {
loadReviews(restaurantId);
}, [loadReviews, restaurantId]);
if (!loading && !loaded) {
loadUsers();
}
}, [loadUsers, restaurantId]); // eslint-disable-line

if (loading || !loaded) return <Loader />;

return (
<div className={styles.reviews}>
{reviews.map((id) => (
<Review key={id} id={id} />
{reviews.map((review) => (
<Review key={review.id} id={review.id} />
))}
<ReviewForm restaurantId={restaurantId} />
</div>
Expand All @@ -24,7 +34,19 @@ const Reviews = ({ reviews, restaurantId, loadReviews }) => {

Reviews.propTypes = {
restaurantId: PropTypes.string.isRequired,
reviews: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired,
reviews: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
}).isRequired
).isRequired,
};

export default connect(null, { loadReviews })(Reviews);
export default connect(
(state) => ({
reviews: reviewsListSelector(state),
users: usersListSelector(state),
loading: usersLoadingSelector(state),
loaded: usersLoadedSelector(state),
}),
{ loadUsers }
)(Reviews);
Loading