-
Notifications
You must be signed in to change notification settings - Fork 13
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
Ht7 #55
base: master
Are you sure you want to change the base?
Ht7 #55
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,35 @@ | ||
import React, { PureComponent } from 'react'; | ||
import { Route, Switch } from 'react-router-dom'; | ||
import React, { useState } from 'react'; | ||
import { Redirect, Route, Switch } from 'react-router-dom'; | ||
import RestaurantsPage from '../../pages/restaurants-page'; | ||
import Header from '../header'; | ||
import Basket from '../basket'; | ||
import { UserProvider } from '../../contexts/user-context'; | ||
import CheckOutSuccess from '../basket/checkOutResult/checkoutSuccess'; | ||
import CheckOutFail from '../basket/checkOutResult/checkOutFail'; | ||
|
||
export default class App extends PureComponent { | ||
render() { | ||
return ( | ||
<div> | ||
const App = () => { | ||
const [name, setName] = useState('Igor'); | ||
|
||
return ( | ||
<div> | ||
<UserProvider value={{ name, setName }}> | ||
<Header /> | ||
<Switch> | ||
<Route path="/" exact component={() => 'Main page'} /> | ||
<Route path="/checkout/error" component={CheckOutFail} /> | ||
<Route path="/checkout/success" component={CheckOutSuccess} /> | ||
<Route path="/checkout" component={Basket} /> | ||
<Route path="/restaurants" component={RestaurantsPage} /> | ||
<Route path="/" component={() => '404 - Not found'} /> | ||
<Route path="/error" component={() => <h1>Error Page</h1>} /> | ||
<Route | ||
path="/" | ||
component={() => { | ||
return <Redirect to="/restaurants" />; | ||
}} | ||
/> | ||
</Switch> | ||
</div> | ||
); | ||
} | ||
} | ||
</UserProvider> | ||
</div> | ||
); | ||
}; | ||
|
||
export default App; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.basket-animation-enter { | ||
opacity: 0; | ||
transform: scale(0.9); | ||
} | ||
|
||
.basket-animation-enter-active { | ||
opacity: 1; | ||
transform: translateX(0); | ||
transition: opacity 10000ms, transform 10000ms; | ||
} | ||
|
||
.basket-animation-exit { | ||
opacity: 1; | ||
} | ||
|
||
.basket-animation-exit-active { | ||
opacity: 0; | ||
transform: scale(0.9); | ||
transition: opacity 10000ms, transform 10000ms; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,87 @@ | ||
import React from 'react'; | ||
import { connect } from 'react-redux'; | ||
import { Link } from 'react-router-dom'; | ||
import { connect, useDispatch, useSelector } from 'react-redux'; | ||
import { Link, useHistory } from 'react-router-dom'; | ||
import { createStructuredSelector } from 'reselect'; | ||
import { CSSTransition, TransitionGroup } from 'react-transition-group'; | ||
|
||
import './basket.css'; | ||
import styles from './basket.module.css'; | ||
import Loader from '../loader'; | ||
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 { | ||
activeCurrencySelector, | ||
orderProductsSelector, | ||
totalSelector, | ||
} from '../../redux/selectors'; | ||
import { UserConsumer } from '../../contexts/user-context'; | ||
import { checkoutProducts } from '../../redux/actions'; | ||
|
||
function Basket({ title = 'Basket', total, orderProducts }) { | ||
const activeCurrency = useSelector(activeCurrencySelector); | ||
const [currencyName, currencyValue] = Object.entries(activeCurrency)[0]; | ||
const history = useHistory(); | ||
const dispatch = useDispatch(); | ||
const checkOutState = useSelector((state) => state.checkout); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. используйте отдельно написаные селекторы |
||
|
||
const onCheckoutClickHandler = () => { | ||
if (history.location.pathname === '/checkout') { | ||
dispatch(checkoutProducts(orderProducts)); | ||
} | ||
}; | ||
if (checkOutState.loading) { | ||
return <Loader />; | ||
} | ||
if (checkOutState.loaded) { | ||
history.push('/checkout/success'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. это лучше делать на уровне редакса, непосредственно при получение ответа с сервера, а не в компоненте |
||
//return <Redirect to='/checkout/success' /> | ||
} | ||
if (checkOutState.error) { | ||
history.replace('/checkout/error'); | ||
// return <Redirect to='/checkout/error' /> | ||
} | ||
if (!total) { | ||
return ( | ||
<div className={styles.basket}> | ||
<h4 className={styles.title}>Select a meal from the list</h4> | ||
</div> | ||
); | ||
} | ||
|
||
const totalprice = Math.round(total * currencyValue); | ||
return ( | ||
<div className={styles.basket}> | ||
<h4 className={styles.title}>{title}</h4> | ||
{orderProducts.map(({ product, amount, subtotal }) => ( | ||
<BasketItem | ||
product={product} | ||
amount={amount} | ||
key={product.id} | ||
subtotal={subtotal} | ||
/> | ||
))} | ||
{/* <h4 className={styles.title}>{`${name}'s ${title}`}</h4> */} | ||
<h4 className={styles.title}> | ||
<UserConsumer>{({ name }) => `${name}'s ${title}`}</UserConsumer> | ||
</h4> | ||
<TransitionGroup> | ||
{orderProducts.map(({ product, amount, subtotal, restaurantId }) => ( | ||
<CSSTransition | ||
key={product.id} | ||
timeout={10000} | ||
classNames="basket-animation" | ||
> | ||
<BasketItem | ||
product={product} | ||
amount={amount} | ||
subtotal={subtotal} | ||
restaurantId={restaurantId} | ||
/> | ||
</CSSTransition> | ||
))} | ||
</TransitionGroup> | ||
<hr className={styles.hr} /> | ||
<div className={itemStyles.basketItem}> | ||
<div className={itemStyles.name}> | ||
<p>Total</p> | ||
</div> | ||
<div className={itemStyles.info}> | ||
<p>{`${total} $`}</p> | ||
<p>{`${totalprice} ${currencyName}`}</p> | ||
</div> | ||
</div> | ||
<Link to="/checkout"> | ||
<Button primary block> | ||
<Button onClick={onCheckoutClickHandler} primary block> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в этом случае проще сделать две отдельные кнопки |
||
checkout | ||
</Button> | ||
</Link> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,51 @@ | ||
import React from 'react'; | ||
import React, { useContext } from 'react'; | ||
import { | ||
activeCurrencySelector, | ||
allCurrenciesArraySelector, | ||
} from '../../redux/selectors'; | ||
|
||
import Logo from './logo'; | ||
import styles from './header.module.css'; | ||
import { userContext } from '../../contexts/user-context'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { setCurrency } from '../../redux/actions'; | ||
|
||
const Header = () => ( | ||
<header className={styles.header}> | ||
<Logo /> | ||
</header> | ||
); | ||
const Header = () => { | ||
const allCurrenciesEnteries = useSelector(allCurrenciesArraySelector); | ||
const activeCurrency = useSelector(activeCurrencySelector); | ||
const dispatch = useDispatch(); | ||
|
||
const { name, setName } = useContext(userContext); | ||
|
||
return ( | ||
<header className={styles.header} onClick={() => setName('Ivan')}> | ||
<Logo /> | ||
{/* <h2>{name}</h2> */} | ||
<div className={styles.currencySwitcher}> | ||
{allCurrenciesEnteries.map((currArr) => { | ||
const [name, value] = currArr; | ||
return ( | ||
<h4 | ||
className={styles.currencyItem} | ||
key={name} | ||
onClick={() => dispatch(setCurrency(name))} | ||
> | ||
{' '} | ||
{name} : {value}{' '} | ||
</h4> | ||
); | ||
})} | ||
{Object.entries(activeCurrency).map((activeItemArr) => { | ||
const [name, value] = activeItemArr; | ||
return ( | ||
<h4 className={styles.currencyItemActive} key={name}> | ||
{name} : {value} | ||
</h4> | ||
); | ||
})} | ||
</div> | ||
</header> | ||
); | ||
}; | ||
|
||
export default Header; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вот это все вычисление повторяется много раза и его лучше вынести в отдельный файл, я покажу на своей домашке, как это лучше делать