Skip to content

Commit

Permalink
add HW6
Browse files Browse the repository at this point in the history
  • Loading branch information
koretskiyav committed Dec 8, 2020
1 parent ee772c5 commit 352129d
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 88 deletions.
1 change: 0 additions & 1 deletion src/components/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export default class App extends PureComponent {
<div>
<Header />
<Switch>
<Route path="/" exact component={() => 'Main page'} />
<Route path="/checkout" component={Basket} />
<Route path="/restaurants" component={RestaurantsPage} />
<Route path="/" component={() => '404 - not found'} />
Expand Down
6 changes: 5 additions & 1 deletion src/components/basket/basket-item/basket-item.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import cn from 'classnames';
import { increment, decrement, remove } from '../../../redux/actions';
import Button from '../../button';
Expand All @@ -9,14 +10,17 @@ function BasketItem({
product,
amount,
subtotal,
restaurantId,
increment,
decrement,
remove,
}) {
return (
<div className={styles.basketItem}>
<div className={styles.name}>
<span>{product.name}</span>
<Link to={`/restaurants/${restaurantId}/menu`}>
<span>{product.name}</span>
</Link>
</div>
<div className={styles.info}>
<div className={styles.counter}>
Expand Down
3 changes: 2 additions & 1 deletion src/components/basket/basket.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ function Basket({ title = 'Basket', total, orderProducts }) {
return (
<div className={styles.basket}>
<h4 className={styles.title}>{title}</h4>
{orderProducts.map(({ product, amount, subtotal }) => (
{orderProducts.map(({ product, amount, subtotal, restaurantId }) => (
<BasketItem
product={product}
amount={amount}
key={product.id}
subtotal={subtotal}
restaurantId={restaurantId}
/>
))}
<hr className={styles.hr} />
Expand Down
16 changes: 11 additions & 5 deletions src/components/restaurant/restaurant.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { Route } from 'react-router-dom';
import PropTypes from 'prop-types';
import { createStructuredSelector } from 'reselect';

Expand All @@ -12,11 +13,8 @@ import { averageRatingSelector } from '../../redux/selectors';

const Restaurant = ({ id, name, menu, reviews, averageRating }) => {
const tabs = [
{ title: 'Menu', content: <Menu menu={menu} restaurantId={id} /> },
{
title: 'Reviews',
content: <Reviews reviews={reviews} restaurantId={id} />,
},
{ title: 'Menu', to: `/restaurants/${id}/menu` },
{ title: 'Reviews', to: `/restaurants/${id}/reviews` },
];

return (
Expand All @@ -25,6 +23,14 @@ const Restaurant = ({ id, name, menu, reviews, averageRating }) => {
{!!averageRating && <Rate value={averageRating} />}
</Banner>
<Tabs tabs={tabs} />
<Route
path="/restaurants/:restId/menu"
render={() => <Menu menu={menu} restaurantId={id} />}
/>
<Route
path="/restaurants/:restId/reviews"
render={() => <Reviews reviews={reviews} restaurantId={id} />}
/>
</div>
);
};
Expand Down
28 changes: 11 additions & 17 deletions src/components/restaurants/restaurants.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
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 Restaurant from '../restaurant';
import { restaurantsListSelector } from '../../redux/selectors';
import Tabs from '../tabs';

import styles from './restaurants.module.css';
import { restaurantsListSelector } from '../../redux/selectors';

const Restaurants = ({ restaurants, match }) => {
const { restId } = match.params;
const { restId, tabId = 'menu' } = match.params;

const restaurant = restaurants.find((restaurant) => restaurant.id === restId);

const tabs = restaurants.map(({ id, name }) => ({
title: name,
to: `/restaurants/${id}/${tabId}`,
}));

return (
<>
<div className={styles.tabs}>
{restaurants.map(({ id, name }) => (
<NavLink
key={id}
to={`/restaurants/${id}`}
className={styles.tab}
activeClassName={styles.active}
>
{name}
</NavLink>
))}
</div>
<Restaurant {...restaurant} />
<Tabs tabs={tabs} />
{restaurant && <Restaurant {...restaurant} />}
</>
);
};
Expand Down
20 changes: 0 additions & 20 deletions src/components/restaurants/restaurants.module.css

This file was deleted.

36 changes: 15 additions & 21 deletions src/components/tabs/tabs.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
import React, { useState } from 'react';
import React from 'react';
import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import cn from 'classnames';

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

const Tabs = ({ tabs }) => {
const [activeTab, setActiveTab] = useState(0);

const { content } = tabs[activeTab];

return (
<>
<div className={styles.tabs}>
{tabs.map(({ title }, index) => (
<span
key={title}
className={cn(styles.tab, { [styles.active]: index === activeTab })}
onClick={() => setActiveTab(index)}
>
{title}
</span>
))}
</div>
{content}
</>
<div className={styles.tabs}>
{tabs.map(({ title, to }) => (
<NavLink
to={to}
key={title}
className={styles.tab}
activeClassName={styles.active}
>
{title}
</NavLink>
))}
</div>
);
};

Tabs.propTypes = {
tabs: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string.isRequired,
content: PropTypes.element.isRequired,
to: PropTypes.string.isRequired,
}).isRequired
).isRequired,
};
Expand Down
2 changes: 2 additions & 0 deletions src/components/tabs/tabs.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

.tab {
padding: 4px 12px;
color: var(--black);
text-decoration: none;
}

.tab.active {
Expand Down
24 changes: 7 additions & 17 deletions src/pages/restaurants-page.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { Route, Link } from 'react-router-dom';
import { Route } from 'react-router-dom';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import Restaurants from '../components/restaurants';
Expand All @@ -12,13 +12,7 @@ import {

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

function RestaurantsPage({
loadRestaurants,
loading,
loaded,
restaurants,
match,
}) {
function RestaurantsPage({ loadRestaurants, loading, loaded, match }) {
useEffect(() => {
if (!loading && !loaded) loadRestaurants();
}, []); // eslint-disable-line
Expand All @@ -27,18 +21,14 @@ function RestaurantsPage({

if (match.isExact) {
return (
<div>
<div>select page</div>
{restaurants.map(({ id, name }) => (
<div key={id}>
<Link to={`/restaurants/${id}`}>{name}</Link>
</div>
))}
</div>
<>
<Restaurants match={match} />
<h2 style={{ textAlign: 'center' }}>Select restaurant</h2>
</>
);
}

return <Route path="/restaurants/:restId" component={Restaurants} />;
return <Route path="/restaurants/:restId/:tabId" component={Restaurants} />;
}

export default connect(
Expand Down
26 changes: 21 additions & 5 deletions src/redux/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,37 @@ export const reviewsLoadedSelector = (state, props) =>
export const usersLoadingSelector = (state) => state.users.loading;
export const usersLoadedSelector = (state) => state.users.loaded;

export const restaurantsListSelector = createSelector(
restaurantsSelector,
Object.values
);

const restaurantsIdsByProductsSelector = createSelector(
restaurantsListSelector,
(restaurants) =>
restaurants
.flatMap((rest) =>
rest.menu.map((productId) => ({ productId, restId: rest.id }))
)
.reduce(
(acc, { productId, restId }) => ({ ...acc, [productId]: restId }),
{}
)
);

export const orderProductsSelector = createSelector(
productsSelector,
orderSelector,
(products, order) => {
restaurantsIdsByProductsSelector,
(products, order, restaurantsIds) => {
return Object.keys(order)
.filter((productId) => order[productId] > 0)
.map((productId) => products[productId])
.map((product) => ({
product,
amount: order[product.id],
subtotal: order[product.id] * product.price,
restaurantId: restaurantsIds[product.id],
}));
}
);
Expand All @@ -45,10 +65,6 @@ export const totalSelector = createSelector(
orderProducts.reduce((acc, { subtotal }) => acc + subtotal, 0)
);

export const restaurantsListSelector = createSelector(
restaurantsSelector,
Object.values
);
export const productAmountSelector = getById(orderSelector, 0);
export const productSelector = getById(productsSelector);
const reviewSelector = getById(reviewsSelector);
Expand Down

0 comments on commit 352129d

Please sign in to comment.