From fd68f60232fee8b7d9dd49e582b8ad92a39f8b6e Mon Sep 17 00:00:00 2001 From: koretskiyav Date: Fri, 15 Jan 2021 21:20:03 +0200 Subject: [PATCH 1/4] add HT6 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index dad2ff4..6726697 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,8 @@ 5. При загрузках показывать лоадеры, все грузить максимально низко, там где эти данные нужны 6. Все данные грузить только один раз (не загружать повторно данные, которые уже есть) 7. (Опционально) переписать все на **immer** + +# HT6 + +1. Сделать reviews/menu отдельными роутами (/restaurant/:id/reviews) +2. В корзине сделать продукты линками на их ресторан From ecf473c2a95348902ce87b5066240a562ce938fb Mon Sep 17 00:00:00 2001 From: Marina Balioura Date: Sat, 16 Jan 2021 15:20:40 +0100 Subject: [PATCH 2/4] HT6: restaurant.js: replacing Tabs with Route --- src/components/restaurant/restaurant.js | 30 +++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/restaurant/restaurant.js b/src/components/restaurant/restaurant.js index c3bef92..d37be57 100644 --- a/src/components/restaurant/restaurant.js +++ b/src/components/restaurant/restaurant.js @@ -2,30 +2,42 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { createStructuredSelector } from 'reselect'; +import { Route, Switch, Link } from 'react-router-dom'; import Menu from '../menu'; import Reviews from '../reviews'; import Banner from '../banner'; import Rate from '../rate'; -import Tabs from '../tabs'; +// import Tabs from '../tabs'; import { averageRatingSelector } from '../../redux/selectors'; const Restaurant = ({ restaurant, averageRating }) => { const { id, name, menu, reviews } = restaurant; - const tabs = [ - { title: 'Menu', content: }, - { - title: 'Reviews', - content: , - }, - ]; + // const tabs = [ + // { title: 'Menu', content: }, + // { + // title: 'Reviews', + // content: , + // }, + // ]; return (
{!!averageRating && } - + {/* */} + + Menu + Reviews + + + + + + + +
); }; From 42d75bae2ba336f03a0c194dc4afe00301068910 Mon Sep 17 00:00:00 2001 From: Marina Balioura Date: Sat, 16 Jan 2021 16:51:25 +0100 Subject: [PATCH 3/4] HT6: the use of Tabs for both cases (Restaurants and Menu/Reviews) --- src/components/restaurant/restaurant.js | 48 +++++++++++-------- src/components/restaurants/restaurants.js | 22 +++------ .../restaurants/restaurants.module.css | 20 -------- src/components/tabs/tabs.js | 26 +++++----- src/components/tabs/tabs.module.css | 1 + 5 files changed, 50 insertions(+), 67 deletions(-) delete mode 100644 src/components/restaurants/restaurants.module.css diff --git a/src/components/restaurant/restaurant.js b/src/components/restaurant/restaurant.js index d37be57..461c1b5 100644 --- a/src/components/restaurant/restaurant.js +++ b/src/components/restaurant/restaurant.js @@ -2,41 +2,51 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { createStructuredSelector } from 'reselect'; -import { Route, Switch, Link } from 'react-router-dom'; +import { Route, Switch } from 'react-router-dom'; import Menu from '../menu'; import Reviews from '../reviews'; import Banner from '../banner'; import Rate from '../rate'; -// import Tabs from '../tabs'; +import Tabs from '../tabs'; import { averageRatingSelector } from '../../redux/selectors'; const Restaurant = ({ restaurant, averageRating }) => { const { id, name, menu, reviews } = restaurant; - // const tabs = [ - // { title: 'Menu', content: }, - // { - // title: 'Reviews', - // content: , - // }, - // ]; + const tabs = [ + { + title: 'Menu', + target: `/restaurants/${id}`, + exact: true, + }, + { + title: 'Reviews', + target: `/restaurants/${id}/reviews`, + exact: true, + }, + ]; return (
{!!averageRating && } - {/* */} - - Menu - Reviews + - - - - - - + ( + + )} + /> + ( + + )} + />
); diff --git a/src/components/restaurants/restaurants.js b/src/components/restaurants/restaurants.js index 5054773..0971e59 100644 --- a/src/components/restaurants/restaurants.js +++ b/src/components/restaurants/restaurants.js @@ -1,31 +1,23 @@ import React from 'react'; import { connect } from 'react-redux'; -import { NavLink } from 'react-router-dom'; import { createStructuredSelector } from 'reselect'; import PropTypes from 'prop-types'; +import Tabs from '../tabs'; import Restaurant from '../restaurant'; import { restaurantsListSelector } from '../../redux/selectors'; -import styles from './restaurants.module.css'; - const Restaurants = ({ restaurants, match }) => { const { restId } = match.params; const restaurant = restaurants.find((restaurant) => restaurant.id === restId); + const tabs = restaurants.map(({ id, name }) => ({ + title: name, + target: `/restaurants/${id}`, + })) + return ( <> -
- {restaurants.map(({ id, name }, index) => ( - - {name} - - ))} -
+ ); diff --git a/src/components/restaurants/restaurants.module.css b/src/components/restaurants/restaurants.module.css deleted file mode 100644 index 654ebcd..0000000 --- a/src/components/restaurants/restaurants.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.tabs { - height: auto; - text-align: center; - padding: 12px; - background-color: var(--grey); -} - -.tabs span { - cursor: pointer; -} - -.tab { - padding: 4px 12px; - color: var(--black); - text-decoration: none; -} - -.tab.active { - border-bottom: 1px solid var(--black); -} diff --git a/src/components/tabs/tabs.js b/src/components/tabs/tabs.js index b96b039..fd9cf13 100644 --- a/src/components/tabs/tabs.js +++ b/src/components/tabs/tabs.js @@ -1,28 +1,27 @@ -import React, { useState } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import cn from 'classnames'; +import { NavLink } from 'react-router-dom'; import styles from './tabs.module.css'; const Tabs = ({ tabs }) => { - const [activeTab, setActiveTab] = useState(0); - - const { content } = tabs[activeTab]; return ( <>
- {tabs.map(({ title }, index) => ( - setActiveTab(index)} + {tabs.map(({ target, title, exact, ...props }, index) => ( + {title} - + ))}
- {content} + ); }; @@ -31,7 +30,8 @@ Tabs.propTypes = { tabs: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string.isRequired, - content: PropTypes.element.isRequired, + target: PropTypes.string.isRequired, + exact: PropTypes.bool, }).isRequired ).isRequired, }; diff --git a/src/components/tabs/tabs.module.css b/src/components/tabs/tabs.module.css index ecf138e..f93fc10 100644 --- a/src/components/tabs/tabs.module.css +++ b/src/components/tabs/tabs.module.css @@ -11,6 +11,7 @@ .tab { padding: 4px 12px; + color: var(--black); } .tab.active { From 1aacd4984f9c00c3637f4ce3ba031337dfd7b1cd Mon Sep 17 00:00:00 2001 From: Marina Balioura Date: Sat, 16 Jan 2021 20:29:09 +0100 Subject: [PATCH 4/4] HT6: link products to restaurants in Basket --- .../basket/basket-item/basket-item.js | 10 +++++++++- .../basket/basket-item/basket-item.module.css | 9 +++++++++ src/components/basket/basket.js | 3 ++- src/redux/selectors.js | 18 +++++++++++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/components/basket/basket-item/basket-item.js b/src/components/basket/basket-item/basket-item.js index 534c734..d36f6fe 100644 --- a/src/components/basket/basket-item/basket-item.js +++ b/src/components/basket/basket-item/basket-item.js @@ -1,5 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; +import { NavLink } from 'react-router-dom'; import cn from 'classnames'; import { increment, decrement, remove } from '../../../redux/actions'; import Button from '../../button'; @@ -7,6 +8,7 @@ import styles from './basket-item.module.css'; function BasketItem({ product, + restaurant, amount, subtotal, increment, @@ -16,7 +18,13 @@ function BasketItem({ return (
- {product.name} + + {product.name} +
diff --git a/src/components/basket/basket-item/basket-item.module.css b/src/components/basket/basket-item/basket-item.module.css index 8cd24ea..8358fe6 100644 --- a/src/components/basket/basket-item/basket-item.module.css +++ b/src/components/basket/basket-item/basket-item.module.css @@ -60,6 +60,15 @@ display: inline-block; text-decoration: none; color: var(--black); + transition: transform 150ms ease-out 0s; +} + +.name > a:hover { + transform: translateY(-1px); +} + +.active { + font-weight: bold; } .info { diff --git a/src/components/basket/basket.js b/src/components/basket/basket.js index 8ae1b08..180f652 100644 --- a/src/components/basket/basket.js +++ b/src/components/basket/basket.js @@ -21,9 +21,10 @@ function Basket({ title = 'Basket', total, orderProducts }) { return (

{title}

- {orderProducts.map(({ product, amount, subtotal }) => ( + {orderProducts.map(({ product, restaurant, amount, subtotal }) => ( + restaurants.reduce((acc, restaurant) => + ({ + ...acc, + ...restaurant.menu.reduce((acc, product) => + ({ + ...acc, + [product]: restaurant.id + }), {}) + }), {}) +); + export const orderProductsSelector = createSelector( productsSelector, orderSelector, - (products, order) => + productsWithRestaurantIdSelector, + (products, order, restaurants) => Object.keys(order) .filter((productId) => order[productId] > 0) .map((productId) => products[productId]) .map((product) => ({ product, + restaurant: restaurants[product.id], amount: order[product.id], subtotal: order[product.id] * product.price, }))