Commit 4820e13f authored by Pavel Mishakov's avatar Pavel Mishakov

finished lesson 69

parent 63ecdad7
......@@ -7,6 +7,8 @@ import Orders from "./containers/Orders/Orders";
import { getIngredients } from "./store/ingredients.slice";
import { useDispatch } from "react-redux";
import { useEffect } from "react";
import AddIngredient from "./containers/AddIngredient/AddIngredient";
import Ingredients from "./containers/Ingredients/Ingredients";
function App() {
const dispatch = useDispatch()
......@@ -22,6 +24,8 @@ function App() {
<Route path='contact-data' element={<ContactData />} />
</Route>
<Route path={'/orders'} element={<Orders />} />
<Route path={'/add-ingredient'} element={<AddIngredient />} />
<Route path={'/ingredients'} element={<Ingredients />} />
<Route path='*' element={<div>NOT FOUND</div>} />
</Route>
</Routes>
......
......@@ -16,7 +16,7 @@ class ApiBurger {
console.log(err)
}
}
getIngredients = async() => {
getIngredients = async () => {
try {
const response = await burgerInstance.get('/ingredients.json')
return response?.data
......@@ -24,6 +24,13 @@ class ApiBurger {
console.log(err)
}
}
addIngredient = async (ingredient) => {
try {
await burgerInstance.post('/ingredients.json', ingredient)
} catch (err) {
console.log(err)
}
}
}
export const apiBurger = new ApiBurger()
\ No newline at end of file
......@@ -7,12 +7,17 @@ import Ingredient from './Ingredient/Ingredient'
// props = {ingredients} {ingredients}
const Burger = () => {
const ingredients = useSelector(state => state.ingredients.basket)
const styles = useSelector(state => state.ingredients.styles)
const ingredientKeys = Object.keys(ingredients) // ['salad', 'bacon'...]
let ingList = []
ingredientKeys.forEach(igKey => {
let amount = ingredients[igKey]
for (let i = 0; i < amount; i++) {
ingList.push(<Ingredient key={igKey + i} type={igKey} />)
ingList.push(<Ingredient
key={igKey + i}
type={igKey}
style={styles[igKey]} />)
}
})
......
......@@ -80,7 +80,7 @@
box-shadow: inset 1px 3px #c9c9c9;
}
.Meat {
/* .Meat {
width: 80%;
height: 8%;
background: linear-gradient(#7f3608, #702e05);
......@@ -116,4 +116,4 @@
height: 8%;
background: linear-gradient(to right, red 50%, white 20%, orange 30%);
margin: 2% auto;
}
} */
import React from 'react';
import './Ingredient.css';
const Ingredient = ({type}) => {
const Ingredient = ({type, style}) => {
switch (type) {
case 'bread-bottom':
return <div className='BreadBottom' />
......@@ -13,7 +13,7 @@ const Ingredient = ({type}) => {
</div>
)
default:
return <div className={type} />
return <div className={type} style={style} />
}
}
......
......@@ -8,6 +8,8 @@ const NavigationItems = () => {
<ul className={'NavigationItems'}>
<NavigationItem to={'/'} end>Burger Builder</NavigationItem>
<NavigationItem to={'/orders'} end>Orders</NavigationItem>
<NavigationItem to={'/add-ingredient'} end>Add ingredient</NavigationItem>
<NavigationItem to={'/ingredients'} end>Ingredients</NavigationItem>
</ul>
)
}
......
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { addNewIngredient } from "../../store/ingredients.slice";
const AddIngredient = () => {
const [inputValues, setInputValues] = useState({
name: '',
price: ''
})
const [style, setStyle] = useState({})
const dispatch = useDispatch()
const navigate = useNavigate()
const inputHandler = (e) => {
setInputValues(prevState => {
return {...prevState, [e.target.name]: e.target.value}
})
}
const inputStyleHandler = (e) => {
setStyle(prevState => {
return {...prevState, [e.target.name]: e.target.value}
})
}
const submit = (e) => {
e.preventDefault()
const styleObj = {}
Object.keys(style).forEach((key) => {
if (style[key].trim() !== '') {
styleObj[key] = style[key]
}
})
dispatch(addNewIngredient({
name: inputValues.name,
price: inputValues.price,
style: styleObj
}))
navigate('/')
}
return (
<div>
<form onSubmit={submit}>
<input type={'text'} onChange={inputHandler} name={'name'} placeholder={'Name'} required/>
<input type={'number'} onChange={inputHandler} name={'price'} placeholder={'Price'} required/>
<div>
<input type={'text'} onChange={inputStyleHandler} name={'width'} placeholder={'Width'}/>
<input type={'text'} onChange={inputStyleHandler} name={'height'} placeholder={'Height'}/>
<input type={'text'} onChange={inputStyleHandler} name={'background'} placeholder={'Background'}/>
<input type={'text'} onChange={inputStyleHandler} name={'margin'} placeholder={'Margin'}/>
<input type={'text'} onChange={inputStyleHandler} name={'borderRadius'} placeholder={'Border-radius'}/>
</div>
<button>Add</button>
</form>
</div>
)
}
export default AddIngredient
\ No newline at end of file
import React from "react";
import { useSelector } from "react-redux";
const Ingredients = () => {
const ingredients = useSelector(state => state.ingredients.ingredients)
return (
<div>
{Object.keys(ingredients).map((key) => {
return <div key={key}>
<p>Name: {ingredients[key].name}</p>
<p>Price {ingredients[key].price}</p>
<p>{JSON.stringify(ingredients[key].style)}</p>
<br/>
</div>
})}
</div>
)
}
export default Ingredients
\ No newline at end of file
......@@ -5,24 +5,16 @@ import OrderItem from "../../components/Order/OrderItem/OrderItem";
import WithErrorHandler from '../../hoc/WithErrorHandler';
import { burgerInstance } from '../../api/instances';
import ErrorBoundary from '../../components/ErrorBoundary/ErrorBoundary';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { getOrders } from '../../store/orders.slice';
const Orders = () => {
const [orders, setOrders] = useState({})
const [loading, setLoading] = useState(false);
const getOrders = async () => {
setLoading(true)
try {
const response = await apiBurger.getOrders()
setOrders(response || {})
} finally {
setLoading(false)
}
}
const dispatch = useDispatch()
const {orders, loading} = useSelector(state => state.orders, shallowEqual)
useEffect(() => {
getOrders()
dispatch(getOrders())
}, [])
return (
<>
......
......@@ -10,14 +10,22 @@ export const getIngredients = createAsyncThunk(
}
)
export const addNewIngredient = createAsyncThunk(
`${namespace}/addIngredient`,
async (ingredient) => {
await apiBurger.addIngredient(ingredient)
}
)
export const ingredientsSlice = createSlice({
name: namespace,
initialState: {
ingredients: [],
ingredients: {},
basket: {},
totalPrice: 200,
loading: false,
prices: {}
prices: {},
styles: {}
},
reducers: {
addIngredient(state, action) {
......@@ -26,7 +34,7 @@ export const ingredientsSlice = createSlice({
...state.basket,
[action.payload]: state.basket[action.payload] + 1 || 1
}
state.totalPrice += state.prices[action.payload]
state.totalPrice += parseInt(state.prices[action.payload])
} catch (err) {
console.log(err);
}
......@@ -56,12 +64,24 @@ export const ingredientsSlice = createSlice({
.addCase(getIngredients.fulfilled, (state, action) => {
state.loading = false
state.ingredients = action.payload
action.payload && action.payload.forEach(ing => {
state.basket[ing.name] = 0
action.payload && Object.keys(action.payload).forEach(key => {
state.basket[action.payload[key].name] = 0
})
action.payload && Object.keys(action.payload).forEach(key => {
state.prices[action.payload[key].name] = action.payload[key].price
})
action.payload && Object.keys(action.payload).forEach(key => {
state.styles[action.payload[key].name] = action.payload[key].style
})
action.payload && action.payload.forEach(ing => {
state.prices[ing.name] = ing.price
})
.addCase(addNewIngredient.pending, (state) => {
state.loading = true
})
.addCase(addNewIngredient.rejected, (state) => {
state.loading = false
})
.addCase(addNewIngredient.fulfilled, (state) => {
state.loading = false
})
}
})
......
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { apiBurger } from "../api/apiBurger";
const namespace = 'orders'
export const getOrders = createAsyncThunk(
`${namespace}/getOrders`,
async () => {
return await apiBurger.getOrders()
}
)
export const ordersSlice = createSlice({
name: namespace,
initialState: {
orders: [],
loading: false
},
extraReducers: builder => {
builder
.addCase(getOrders.pending, (state) => {
state.loading = true
})
.addCase(getOrders.rejected, (state) => {
state.loading = false
})
.addCase(getOrders.fulfilled, (state, action) => {
state.loading = false
state.orders = action.payload
})
}
})
import { configureStore } from "@reduxjs/toolkit";
import { ingredientsSlice } from "./ingredients.slice";
import { ordersSlice } from "./orders.slice";
export const store = configureStore({
reducer: {
ingredients: ingredientsSlice.reducer
ingredients: ingredientsSlice.reducer,
orders: ordersSlice.reducer
},
devTools: true
})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment