Skip to content

Commit

Permalink
Merge pull request #6 from miptleha/sprint-2/step-1
Browse files Browse the repository at this point in the history
sprint-2/step-1
  • Loading branch information
miptleha authored Jan 28, 2023
2 parents cb74370 + 7b26fe7 commit 993d40d
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 104 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ git checkout sprint-1/step-1
git checkout sprint-1/step-2
```
Были [замечания](https://github.com/miptleha/react-burger/pull/4) по загрузке данных с сервера, успешно их исправил, работу приняли и я смержил все в main ветку.

## Спринт 2
### Шаг 1
Данные перенесены в Context. Заказ отправляется на сервер.
```
git checkout sprint-2/step-1
```
[Замечания](https://github.com/miptleha/react-burger/pull/6) по изменениям в ветке
50 changes: 30 additions & 20 deletions src/components/app/app.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useEffect, useState } from 'react';
import styles from './app.module.css';
import { useEffect, useState, useReducer } from 'react';
import { dataLoad } from '../../utils/dataLoad';
import { sumReducer, sumInitialValue } from '../../services/sum-reducer';
import { OrderContext } from '../../services/order-context';

import styles from './app.module.css';
import AppHeader from '../app-header/app-header';
import BurgerConstructor from '../burger-constructor/burger-constructor';
import BurgerIngredients from '../burger-ingredients/burger-ingredients';
Expand All @@ -14,15 +17,19 @@ function App() {

useEffect(() => {
dataLoad()
.then(data => {
setState({ data: data, isLoading: false, isError: false });
})
.catch(err => {
console.log('ошибка получения данных', err);
setState({ data: null, isLoading: false, isError: true });
});
.then(data => {
setState({ data: data, isLoading: false, isError: false });
})
.catch(err => {
console.log('ошибка получения данных', err);
setState({ data: null, isLoading: false, isError: true });
});
}, []);

const [bun, setBun] = useState(null);
const [ingredients, setIngredients] = useState([]);
const [sumState, sumDispatcher] = useReducer(sumReducer, sumInitialValue);

return (
<>
{(state.isLoading || state.isError) ? (
Expand All @@ -32,17 +39,20 @@ function App() {
</p>
</main>
) :
state.data && (
<>
<AppHeader />
<main className={styles.main}>
<div className={styles.inner}>
<BurgerIngredients data={state.data} />
<BurgerConstructor data={state.data} />
</div>
</main>
</>
)}
state.data && (
<>
<AppHeader />
<main className={styles.main}>
<div className={styles.inner}>
<OrderContext.Provider value={{data: state.data, bun, setBun,
ingredients, setIngredients, sumState, sumDispatcher}}>
<BurgerIngredients />
<BurgerConstructor />
</OrderContext.Provider>
</div>
</main>
</>
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import { useState } from 'react';
import PropTypes from 'prop-types';
import { useState, useContext } from 'react';
import { CurrencyIcon, Button } from "@ya.praktikum/react-developer-burger-ui-components";
import styles from './burger-constructor-order.module.css';
import OrderDetails from '../order-details/order-details';
import { OrderContext } from '../../services/order-context';
import { orderCreate } from '../../utils/orderCreate';
import Modal from '../modal/modal';

function BurgerConstructorOrder({ sum, number }) {
function BurgerConstructorOrder() {
const [show, setShow] = useState(false);
const [number, setNumber] = useState('');
const { ingredients, sumState } = useContext(OrderContext);

function showOrder() {
setShow(true);
orderCreate(ingredients)
.then(num => {
setNumber(num);
setShow(true);
})
.catch(error => {
console.log(error);
});
}

function hideOrder() {
Expand All @@ -17,17 +28,16 @@ function BurgerConstructorOrder({ sum, number }) {

return (
<div className={`${styles.total} mr-4 mt-10`}>
<div className="text text_type_digits-medium mr-2 mb-1">{sum}</div>
<div className="text text_type_digits-medium mr-2 mb-1">{sumState.sum}</div>
<div className={`${styles['total-icon']} mr-10`}><CurrencyIcon type="primary" /></div>
<Button htmlType="button" type="primary" onClick={showOrder}>Оформить заказ</Button>
{show && <OrderDetails number={number} onClose={hideOrder} />}
{show && (
<Modal onClose={hideOrder}>
<OrderDetails number={number} />
</Modal>
)}
</div>
);
}

BurgerConstructorOrder.propTypes = {
sum: PropTypes.number.isRequired,
number: PropTypes.string.isRequired
}

export default BurgerConstructorOrder;
39 changes: 24 additions & 15 deletions src/components/burger-constructor/burger-constructor.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import { useMemo } from 'react';
import PropTypes from 'prop-types';
import { useContext, useEffect } from 'react';
import styles from './burger-constructor.module.css';
import { dataPropTypes } from '../../utils/dataPropTypes';
import { BUN } from '../../utils/dataNames';
import { ConstructorElement, DragIcon } from '@ya.praktikum/react-developer-burger-ui-components';
import BurgerConstructorOrder from '../burger-constructor-order/burger-constructor-order';
import { OrderContext } from '../../services/order-context';

function BurgerConstructor() {

function BurgerConstructor({ data }) {
const list = useMemo(() => data.filter(item => item.type !== BUN), [data]);
const bun = useMemo(() => data.find(item => item.type === BUN), [data]);
const sum = useMemo(() => bun.price * 2 + list.reduce((sum, item) => sum += item.price, 0), [list, bun]);
const { data, bun, setBun, ingredients, setIngredients, sumDispatcher } = useContext(OrderContext);

return (
useEffect(() => {
const buns = data.filter(item => item.type === BUN);
setBun(buns[Math.floor(Math.random() * buns.length)]);

const list = data.filter(item => item.type !== BUN &&
Math.round(Math.random()) === 1);
setIngredients(list);
}, [data, setBun, setIngredients]);

useEffect(() => {
if (bun) {
const sum = bun.price * 2 + ingredients.reduce((sum, item) => sum += item.price, 0);
sumDispatcher({ type: 'set', value: sum });
}
}, [bun, ingredients, sumDispatcher]);

return bun && (
<section className={styles.section}>
<div className={`${styles.burger} mt-25 ml-4`}>
<ConstructorElement
Expand All @@ -24,9 +37,9 @@ function BurgerConstructor({ data }) {
extraClass={`${styles.ingredient} ml-8`}
/>
<ul className={`${styles.scroll} mt-4 mb-4`}>
{list.map((item, index) => (
{ingredients.map((item, index) => (
<li className={`${styles['list-item']} mt-4`} key={index}>
<span className={styles.draggable}><DragIcon type="primary" /></span>
<DragIcon type="primary" />
<ConstructorElement
text={item.name}
price={item.price}
Expand All @@ -46,13 +59,9 @@ function BurgerConstructor({ data }) {
/>
</div>

<BurgerConstructorOrder sum={sum} number="034536" />
<BurgerConstructorOrder />
</section>
);
}

BurgerConstructor.propTypes = {
data: PropTypes.arrayOf(dataPropTypes.isRequired).isRequired
}

export default BurgerConstructor;
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,10 @@
.list-item {
display: flex;
align-items: center;
cursor: move;
}

.ingredient {
background: var(--background);
}

.draggable {
cursor: grabbing;
}
38 changes: 22 additions & 16 deletions src/components/burger-ingredients-item/burger-ingredients-item.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,45 @@
import { useState } from 'react';
import { useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import { dataPropTypes } from '../../utils/dataPropTypes';
import { OrderContext } from '../../services/order-context';
import { BUN } from '../../utils/dataNames';

import styles from './burger-ingredients-item.module.css';
import { CurrencyIcon, Counter } from '@ya.praktikum/react-developer-burger-ui-components';
import IngredientDetails from '../ingredient-details/ingredient-details';

function BurgerIngredientItem({ item, count }) {
const [show, setShow] = useState(false);
function BurgerIngredientsItem({ item, onShowDetails }) {
const { ingredients, bun } = useContext(OrderContext);

function showDialog() {
setShow(true);
}
const count = useMemo(() => {
if (item.type === BUN && bun) {
return bun._id === item._id ? 1 : 0;
}
else {
const list = ingredients.filter(i => i._id === item._id);
return list.length;
}
}, [item, bun, ingredients]);

function hideDialog(e) {
setShow(false);
e.stopPropagation();
function showDialogItem() {
onShowDetails(item);
}

return (
<li className={`${styles.card} mt-6 mb-8 ml-3 mr-2`} onClick={showDialog}>
<li className={`${styles.card} mt-6 mb-8 ml-3 mr-2`} onClick={showDialogItem}>
<img className={`${styles.image} ml-4 mr-4 mb-1`} src={item.image} alt="Ингридиент" />
<div className={`${styles.price} mb-1`}>
<span className="text text_type_digits-default mr-2">{item.price}</span>
<CurrencyIcon type="primary" />
</div>
<div className={`${styles.title} text text_type_main-default`}>{item.name}</div>
{count && count > 0 ? <Counter count={count} size="default" extraClass={styles.count} /> : undefined}
{show && <IngredientDetails item={item} onClose={hideDialog} />}
{count > 0 && <Counter count={count} size="default" extraClass={styles.count} />}
</li>
);
}

BurgerIngredientItem.propTypes = {
BurgerIngredientsItem.propTypes = {
item: dataPropTypes.isRequired,
count: PropTypes.number
onShowDetails: PropTypes.func.isRequired
}

export default BurgerIngredientItem;
export default BurgerIngredientsItem;
39 changes: 28 additions & 11 deletions src/components/burger-ingredients/burger-ingredients.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { useMemo, useRef } from 'react';
import PropTypes from 'prop-types';
import styles from './burger-ingredients.module.css';
import { useContext, useMemo, useRef, useState } from 'react';
import { BUN, SAUCE, MAIN, names } from '../../utils/dataNames';
import { dataPropTypes } from '../../utils/dataPropTypes';
import { OrderContext } from '../../services/order-context';

import styles from './burger-ingredients.module.css';
import BurgerIngredientsTabs from '../burger-ingredients-tabs/burger-ingredients-tabs';
import BurgerIngredientsItem from '../burger-ingredients-item/burger-ingredients-item';
import Modal from '../modal/modal';
import IngredientDetails from '../ingredient-details/ingredient-details';

function BurgerIngredients({ data }) {
function BurgerIngredients() {
const [itemShow, setItemShow] = useState(null);

const { data } = useContext(OrderContext);

const groups = useMemo(() => {
let res = {};
res[BUN] = data.filter(i => i.type === BUN);
Expand All @@ -24,6 +30,15 @@ function BurgerIngredients({ data }) {
headers[value].current.scrollIntoView({ behavior: "smooth" });
}

function showDialog(item) {
setItemShow(item);
}

function hideDialog(e) {
setItemShow(null);
e.stopPropagation();
}

return (
<section className={styles.section}>
<h1 className="text text_type_main-large mt-10 mb-5">Соберите бургер</h1>
Expand All @@ -34,19 +49,21 @@ function BurgerIngredients({ data }) {
<div key={typeIndex}>
<h2 className="text text_type_main-medium mt-2" ref={headers[type]}>{names[type]}</h2>
<ul className={styles['group-content']}>
{groups[type].map((item, index) => (
<BurgerIngredientsItem key={type + index} item={item} count={index === 0 ? 1 : 0}/>
{groups[type].map((item) => (
<BurgerIngredientsItem key={item._id} item={item} onShowDetails={showDialog}/>
))}
</ul>
</div>
))}
</div>

{itemShow && (
<Modal caption="Детали ингридиента" onClose={hideDialog}>
<IngredientDetails item={itemShow} />
</Modal>
)}
</section>
);
}

BurgerIngredients.propTypes = {
data: PropTypes.arrayOf(dataPropTypes.isRequired).isRequired
}

export default BurgerIngredients;
11 changes: 4 additions & 7 deletions src/components/ingredient-details/ingredient-details.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import PropTypes from 'prop-types';
import styles from './ingredient-details.module.css';
import Modal from '../modal/modal';
import { dataPropTypes } from '../../utils/dataPropTypes';

function IngredientDetails({ item, onClose }) {
function IngredientDetails({ item }) {
return (
<Modal caption="Детали ингридиента" onClose={onClose}>
<>
<img className={`${styles.image} mb-4`} src={item.image_large} alt="Изображение ингридиента" />
<p className={`${styles.name} text-center text text_type_main-medium mb-8`}>{item.name}</p>
<div className={`${styles.detail} mb-15`}>
Expand All @@ -26,13 +24,12 @@ function IngredientDetails({ item, onClose }) {
<div className="text-center text text_type_digits-default text_color_inactive">{item.carbohydrates}</div>
</div>
</div>
</Modal>
</>
);
}

IngredientDetails.propTypes = {
item: dataPropTypes.isRequired,
onClose: PropTypes.func.isRequired
item: dataPropTypes.isRequired
}

export default IngredientDetails;
2 changes: 1 addition & 1 deletion src/components/modal/modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function Modal({ caption, children, onClose }) {

Modal.propTypes = {
caption: PropTypes.string,
children: PropTypes.arrayOf(PropTypes.element),
children: PropTypes.element.isRequired,
onClose: PropTypes.func.isRequired
}

Expand Down
Loading

0 comments on commit 993d40d

Please sign in to comment.