Skip to content

Commit

Permalink
HW-6
Browse files Browse the repository at this point in the history
  • Loading branch information
vera-l committed Dec 21, 2021
1 parent 2fd8587 commit 8036c7e
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 55 deletions.
6 changes: 4 additions & 2 deletions src/components/app/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PureComponent } from 'react';
import { Route, Switch } from 'react-router-dom';
import { Redirect, Route, Switch } from 'react-router-dom';
import Restaurants from '../restaurants';
import Header from '../header';
import Basket from '../basket';
Expand All @@ -10,7 +10,9 @@ export default class App extends PureComponent {
<div>
<Header />
<Switch>
<Route path="/" exact component={() => <h2>Home Page!</h2>} />
<Route path="/" exact>
<Redirect to="/restaurants" />
</Route>
<Route path="/checkout" component={Basket} />
<Route path="/restaurants" component={Restaurants} />
<Route path="/" component={() => <h2>404 - Page Not Found :(</h2>} />
Expand Down
4 changes: 3 additions & 1 deletion src/components/basket/basket-item/basket-item.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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';
import styles from './basket-item.module.css';

function BasketItem({
product,
restId,
amount,
subtotal,
increment,
Expand All @@ -15,7 +17,7 @@ function BasketItem({
return (
<div className={styles.basketItem}>
<div className={styles.name}>
<span>{product.name}</span>
<Link to={`/restaurants/${restId}`}>{product.name}</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 @@ -19,9 +19,10 @@ 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, restId, amount, subtotal }) => (
<BasketItem
product={product}
restId={restId}
amount={amount}
key={product.id}
subtotal={subtotal}
Expand Down
23 changes: 16 additions & 7 deletions src/components/restaurant/restaurant.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useState } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Switch, Route, NavLink, Redirect } from 'react-router-dom';

import Menu from '../menu';
import Reviews from '../reviews';
import Banner from '../banner';
Expand All @@ -14,21 +16,28 @@ import {
const Restaurant = ({ restaurant, averageRating }) => {
const { id, name, menu, reviews } = restaurant;

const [activeTab, setActiveTab] = useState('menu');

const tabs = [
{ id: 'menu', label: 'Menu' },
{ id: 'reviews', label: 'Reviews' },
{ id: 'menu', name: 'Menu' },
{ id: 'reviews', name: 'Reviews' },
];

return (
<div>
<Banner heading={name}>
<Rate value={averageRating} />
</Banner>
<Tabs tabs={tabs} activeId={activeTab} onChange={setActiveTab} />
{activeTab === 'menu' && <Menu menu={menu} key={id} restId={id} />}
{activeTab === 'reviews' && <Reviews reviews={reviews} restId={id} />}

<Tabs tabs={tabs} prefix={`/restaurants/${id}`} />

<Switch>
<Route path="/restaurants/:id/menu">
<Menu menu={menu} key={id} restId={id} />
</Route>
<Route path="/restaurants/:id/reviews">
<Reviews reviews={reviews} restId={id} />
</Route>
<Redirect to={`/restaurants/${id}/menu`} />
</Switch>
</div>
);
};
Expand Down
15 changes: 2 additions & 13 deletions src/components/restaurants/restaurants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
restaurantsLoadedSelector,
} from '../../redux/selectors';
import { loadRestaurants } from '../../redux/actions';
import Tabs from '../tabs';

import styles from './restaurants.module.css';
function Restaurants({ restaurants, loading, loaded, loadRestaurants }) {
useEffect(() => {
if (!loading && !loaded) loadRestaurants();
Expand All @@ -22,18 +22,7 @@ function Restaurants({ restaurants, loading, loaded, loadRestaurants }) {

return (
<div>
<div className={styles.tabs}>
{restaurants.map(({ id, name }) => (
<NavLink
key={id}
to={`/restaurants/${id}`}
className={styles.tab}
activeClassName={styles.active}
>
{name}
</NavLink>
))}
</div>
<Tabs tabs={restaurants} prefix="/restaurants" />
<Switch>
<Route path="/restaurants/:restId">
{({ match }) => <Restaurant id={match.params.restId} />}
Expand Down
19 changes: 0 additions & 19 deletions src/components/restaurants/restaurants.module.css

This file was deleted.

24 changes: 14 additions & 10 deletions src/components/tabs/tabs.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import PropTypes from 'prop-types';
import cn from 'classnames';
import { NavLink } from 'react-router-dom';

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

function Tabs({ tabs, activeId, onChange }) {
function Tabs({ tabs, prefix }) {
return (
<div className={styles.tabs}>
{tabs.map(({ id, label }) => (
<span
{tabs.map(({ id, name }) => (
<NavLink
key={id}
className={cn(styles.tab, { [styles.active]: id === activeId })}
onClick={() => onChange(id)}
to={`${prefix}/${id}`}
className={styles.tab}
activeClassName={styles.active}
>
{label}
</span>
{name}
</NavLink>
))}
</div>
);
}

Tabs.defaultProps = {
prefix: '',
};

Tabs.propTypes = {
tabs: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
label: PropTypes.string,
}).isRequired
).isRequired,
activeId: PropTypes.string,
onChange: PropTypes.func.isRequired,
prefix: PropTypes.string,
};

export default Tabs;
19 changes: 17 additions & 2 deletions src/redux/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,29 @@ export const restaurantSelector = (state, { id }) =>
export const productSelector = (state, { id }) => productsSelector(state)[id];
export const reviewSelector = (state, { id }) => reviewsSelector(state)[id];
export const amountSelector = (state, { id }) => orderSelector(state)[id] || 0;

const productToRestaurantMapSelector = createSelector(
[restaurantsListSelector],
(restaurants) => {
const map = new Map();
restaurants.forEach((restaurant) => {
restaurant.menu.forEach((product) => {
map.set(product.id, restaurant.id);
});
});
return map;
}
);

export const orderProductsSelector = createSelector(
[productsSelector, orderSelector],
(products, order) =>
[productsSelector, orderSelector, productToRestaurantMapSelector],
(products, order, productToRestaurantMap) =>
Object.keys(order)
.filter((productId) => order[productId] > 0)
.map((productId) => products[productId])
.map((product) => ({
product,
restId: productToRestaurantMap.get(product.id),
amount: order[product.id],
subtotal: order[product.id] * product.price,
}))
Expand Down

0 comments on commit 8036c7e

Please sign in to comment.