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

Lesson7 #91

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions src/components/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@ import { Redirect, Route, Switch } from 'react-router-dom';
import Restaurants from '../restaurants';
import Header from '../header';
import Basket from '../basket';
import OrderError from '../order-result';
import { UserProvider } from '../../contexts/user-context';
import { useState } from 'react';
import { CurrencyProvider } from '../../contexts/currency-context';

const App = () => {
const [name, setName] = useState('Andrey');
const [current, setCurrent] = useState('dollar');
Copy link
Owner

Choose a reason for hiding this comment

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

Не стоит данные контекста хранить в состоянии нашего приложения. Покажу как это можно сделать удобнее на своей домашке.

return (
<div>
<UserProvider value={{ name, setName }}>
<Header />
<Switch>
<Redirect exact from="/" to="/restaurants" />
<Route path="/checkout" component={Basket} />
<Route path="/restaurants" component={Restaurants} />
<Route path="/error" component={() => <h2>Error Page!</h2>} />
<Route component={() => <h2>404 - Not found :(</h2>} />
</Switch>
<CurrencyProvider value={{ current, setCurrent }}>
<Header />
<Switch>
<Redirect exact from="/" to="/restaurants" />
<Route path="/checkout" component={Basket} />
<Route path="/restaurants" component={Restaurants} />
<Route path="/error" component={() => <h2>Error Page!</h2>} />
<Route path="/orser-failed" component={OrderError} />
<Route
path="/orser-success"
component={() => <h2>Thanks for order!</h2>}
/>
<Route component={() => <h2>404 - Not found :(</h2>} />
</Switch>
</CurrencyProvider>
</UserProvider>
</div>
);
Expand Down
5 changes: 4 additions & 1 deletion src/components/basket/basket-item/basket-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import cn from 'classnames';
import { Link } from 'react-router-dom';
import { increment, decrement, remove } from '../../../redux/actions';
import Button from '../../button';
import Money from '../../money';
import styles from './basket-item.module.css';

function BasketItem({
Expand All @@ -25,7 +26,9 @@ function BasketItem({
<span className={styles.count}>{amount}</span>
<Button onClick={increment} icon="plus" secondary small />
</div>
<p className={cn(styles.count, styles.price)}>{subtotal} $</p>
<p className={cn(styles.count, styles.price)}>
<Money value={subtotal} />
</p>
<Button onClick={remove} icon="delete" secondary small />
</div>
</div>
Expand Down
40 changes: 28 additions & 12 deletions src/components/basket/basket.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { CSSTransition, TransitionGroup } from 'react-transition-group';

import cn from 'classnames';
import styles from './basket.module.css';
import './basket.css';
import itemStyles from './basket-item/basket-item.module.css';
import BasketItem from './basket-item';
import Button from '../button';
import { orderProductsSelector, totalSelector } from '../../redux/selectors';
import Loader from '../loader';
import Money from '../money';
import {
orderProductsSelector,
totalSelector,
chechoutSendingSelector,
} from '../../redux/selectors';
import { UserConsumer } from '../../contexts/user-context';
import { checkoutOrder } from '../../redux/actions';

function Basket({ title = 'Basket', total, orderProducts }) {
function Basket({
title = 'Basket',
total,
orderProducts,
checkoutOrder,
sending,
}) {
// const { name } = useContext(userContext);

if (!total) {
Expand All @@ -22,7 +34,7 @@ function Basket({ title = 'Basket', total, orderProducts }) {
}

return (
<div className={styles.basket}>
<div className={cn(styles.basket, { [styles.disable]: sending })}>
<h4 className={styles.title}>
<UserConsumer>{({ name }) => `${name}'s ${title}`}</UserConsumer>
</h4>
Expand All @@ -49,14 +61,14 @@ function Basket({ title = 'Basket', total, orderProducts }) {
<p>Total</p>
</div>
<div className={itemStyles.info}>
<p>{`${total} $`}</p>
<p>
<Money value={total} />
</p>
</div>
</div>
<Link to="/checkout">
<Button primary block>
checkout
</Button>
</Link>
<Button primary block onClick={checkoutOrder}>
{sending ? <Loader /> : 'checkout'}
</Button>
</div>
);
}
Expand All @@ -65,7 +77,11 @@ const mapStateToProps = (state) => {
return {
total: totalSelector(state),
orderProducts: orderProductsSelector(state),
sending: chechoutSendingSelector(state),
};
};

export default connect(mapStateToProps)(Basket);
const mapDispatchToProps = {
checkoutOrder,
};
export default connect(mapStateToProps, mapDispatchToProps)(Basket);
6 changes: 6 additions & 0 deletions src/components/basket/basket.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@
padding: 20px 24px;
}
}

.disable {
user-select: none;
pointer-events: none;
box-shadow: inset 0 0 0 500px rgba(0, 0, 0, 0.5);
}
17 changes: 17 additions & 0 deletions src/components/header/header.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import { useContext } from 'react';
import cn from 'classnames';
import { Link } from 'react-router-dom';
import { userContext } from '../../contexts/user-context';
import { ReactComponent as Logo } from '../../icons/logo.svg';
import {
currDictionary,
currencyContext,
} from '../../contexts/currency-context';
import styles from './header.module.css';

const Header = () => {
const { name, setName } = useContext(userContext);
const { current, setCurrent } = useContext(currencyContext);

return (
<header className={styles.header} onClick={() => setName('Igor')}>
<div className={styles.tabs}>
Copy link
Owner

Choose a reason for hiding this comment

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

лучше это вынести в отдельный компонент

{Object.entries(currDictionary).map(([id, curr]) => (
<span
key={id}
className={cn(styles.tab, { [styles.active]: id === current })}
onClick={() => setCurrent(id)}
>
{curr.name}
</span>
))}
</div>
<Link to="/restaurants">
<Logo />
</Link>
Expand Down
21 changes: 21 additions & 0 deletions src/components/header/header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,24 @@
right: 20px;
top: 0;
}

.tabs {
height: auto;
text-align: center;
margin-right: auto;
padding: 12px;
background-color: var(--grey);
}

.tabs span {
cursor: pointer;
}

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

.tab.active {
border-bottom: 1px solid var(--black);
}
1 change: 1 addition & 0 deletions src/components/money/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './money';
13 changes: 13 additions & 0 deletions src/components/money/money.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
CurrencyConsumer,
getMoneyInCurr,
currDictionary,
} from '../../contexts/currency-context';

export default function Money({ value }) {
return (
<CurrencyConsumer>
{({ current }) => getMoneyInCurr(value, current, currDictionary)}
</CurrencyConsumer>
);
}
1 change: 1 addition & 0 deletions src/components/order-result/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './order-error';
17 changes: 17 additions & 0 deletions src/components/order-result/order-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import { chechoutErrorSelector } from '../../redux/selectors';

const OrderError = ({ error = '' }) => {
return (
<div>
<h2>Wrong order!</h2>
<p>{error}</p>
</div>
);
};

const mapStateToProps = (state) => ({
error: chechoutErrorSelector(state),
});

export default connect(mapStateToProps)(OrderError);
7 changes: 5 additions & 2 deletions src/components/product/product.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import styles from './product.module.css';
import Button from '../button';
import Money from '../money';
import { decrement, increment } from '../../redux/actions';
import { amountSelector, productSelector } from '../../redux/selectors';

Expand All @@ -12,12 +13,14 @@ function Product({ product, amount, decrement, increment }) {
<div>
<h4 className={styles.title}>{product.name}</h4>
<p className={styles.description}>{product.ingredients.join(', ')}</p>
<div className={styles.price}>{product.price} $</div>
<div className={styles.price}>
<Money value={product.price} />
</div>
</div>
<div>
<div className={styles.counter}>
<div className={styles.count} data-id="product-amount">
{amount}
<Money value={amount} />
Copy link
Owner

Choose a reason for hiding this comment

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

это количество в штуках, а не в валюте :)

</div>
<div className={styles.buttons}>
<Button
Expand Down
22 changes: 22 additions & 0 deletions src/components/reviews/review.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.review-enter {
opacity: 0.2;
background-color: blue;
transform: scale(0.8);
}

.review-enter-active {
opacity: 1;
background-color: #8e44ad;
transform: translateX(0);
transition: opacity 500ms, background-color 500ms, transform 500ms;
}

.review-exit {
opacity: 1;
}

.review-exit-active {
opacity: 0;
transform: scale(0.9);
transition: opacity 500ms, transform 500ms;
}
14 changes: 10 additions & 4 deletions src/components/reviews/reviews.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useEffect } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Review from './review';
import Loader from '../loader';
import ReviewForm from './review-form';
import styles from './reviews.module.css';
import './review.css';
Copy link
Owner

Choose a reason for hiding this comment

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

необходимо было сделать вариант через css modules


import { loadReviews, loadUsers } from '../../redux/actions';
import {
Expand All @@ -29,10 +31,14 @@ const Reviews = ({

return (
<div className={styles.reviews}>
{reviews.map((id) => (
<Review key={id} id={id} />
))}
<ReviewForm restId={restId} />
<TransitionGroup>
{reviews.map((id) => (
<CSSTransition key={id} timeout={2000} classNames="review">
<Review id={id} />
</CSSTransition>
))}
<ReviewForm restId={restId} />
</TransitionGroup>
</div>
);
};
Expand Down
27 changes: 27 additions & 0 deletions src/contexts/currency-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createContext } from 'react';

export const currDictionary = {
ruble: {
name: 'руб.',
rateToDollar: 70,
},
dollar: {
name: '$',
rateToDollar: 1,
},
euro: {
name: 'eur.',
rateToDollar: 0.8,
},
};

export const getMoneyInCurr = (value, curr, currDictionary) => {
const countedVal = value * currDictionary[curr].rateToDollar;
const roundedVal = parseInt(countedVal * 100) / 100;
return `${roundedVal} ${currDictionary[curr].name}`;
};

export const currencyContext = createContext();

export const CurrencyProvider = currencyContext.Provider;
export const CurrencyConsumer = currencyContext.Consumer;
Loading