Commit dbeea4e9 authored by Pavel Mishakov's avatar Pavel Mishakov

69 done

parent 7b91a650
......@@ -12,7 +12,7 @@ const Burger = () => {
const {ingredients} = useAppSelector(state => state.burger)
Object.keys(ingredients)
.forEach((igKey: string) => {
let amount: number = ingredients[igKey as keyof typeof ingredients]
const amount: number = ingredients[igKey as keyof typeof ingredients]
for (let i = 0; i < amount; i++) {
ingList.push(<Ingredient key={igKey + i} type={igKey as keyof typeof ingredients} />)
}
......
import { useEffect, useRef, useState } from "react";
import { TIngredients } from "../../types/TIngredients";
import { CheckoutSummary } from "../CheckoutSummary/CheckoutSummary";
import { useNavigate, useSearchParams } from "react-router-dom";
import { getTotalPrice } from "../../utils/getTotalPrice";
export function Checkout() {
const [searchParams] = useSearchParams()
const ingredients = useRef(Object.fromEntries(searchParams) as unknown as TIngredients)
const [price, setPrice] = useState<number>(0)
const navigate = useNavigate();
const checkoutCancelledHandler = () => {
navigate('/');
};
useEffect(() => {
const tempPrice = getTotalPrice({...ingredients.current})
setPrice(tempPrice)
}, [ingredients.current])
const checkoutContinuedHandler = () => {
navigate({
pathname: 'contact-data',
search: searchParams.toString()
}, {state: {
ingredients: ingredients.current,
price
}});
});
};
return <CheckoutSummary
price={price}
ingredients={ingredients.current}
checkoutContinued={checkoutContinuedHandler}
checkoutCancelled={checkoutCancelledHandler}
/>;
......
'use client'
import { useAppSelector } from "../../hooks/useAppSelector";
import Burger from "../Burger/Burger";
import { TIngredients } from "../../types/TIngredients";
import Button from "../UI/Button/Button";
import styles from "./CheckoutSummary.module.css";
import { MouseEventHandler } from "react";
import { Outlet } from "react-router-dom";
interface Props {
price: number
ingredients: TIngredients;
checkoutContinued: MouseEventHandler<HTMLButtonElement>
checkoutCancelled: MouseEventHandler<HTMLButtonElement>
}
export function CheckoutSummary({ price, ingredients, checkoutContinued, checkoutCancelled }: Props) {
export function CheckoutSummary({ checkoutContinued, checkoutCancelled }: Props) {
const {totalPrice} = useAppSelector(state => state.burger)
return (
<div className={styles.CheckoutSummary}>
<h1>We hope it tastes well!</h1>
<h2>Price: {price}</h2>
<h2>Price: {totalPrice}</h2>
<div className={styles.CheckoutSummaryBurger}>
<Burger ingredients={ingredients} />
<Burger />
</div>
<Button btnType="Danger" onClick={checkoutCancelled}>
CANCEL
......
'use client'
import { ChangeEvent, FormEvent, useState } from 'react';
import Button from '../UI/Button/Button';
import styles from './ContactData.module.css';
import { axiosOrder } from '../../axios/axiosOrder';
import { TCustomerData } from '../../types/TCustomerData';
import { useLocation, useNavigate } from 'react-router';
import { useNavigate } from 'react-router';
import Spinner from '../UI/Spinner/Spinner';
import { useAppSelector } from '../../hooks/useAppSelector';
import { useAppDispatch } from '../../hooks/useAppDispatch';
import { createOrder } from '../../stores/newStore/ordersSlice';
import { shallowEqual } from 'react-redux';
export function ContactData() {
const location = useLocation()
const {ingredients, totalPrice} = useAppSelector(state => state.burger)
const {isLoading} = useAppSelector(state => state.orders, shallowEqual)
const dispatch = useAppDispatch()
const navigate = useNavigate()
const [isLoading, setIsLoading] = useState<boolean>(false)
const [isSubmited, setIsSubmited] = useState<boolean>(false)
const [customerData, setCustomerData] = useState<TCustomerData>({
name: '',
......@@ -18,6 +23,7 @@ export function ContactData() {
postal: ''
})
const inputHandler = (e: ChangeEvent<HTMLInputElement>) => {
setCustomerData(prevState => ({ ...prevState, [e.target.name]: e.target.value }))
}
......@@ -26,20 +32,16 @@ export function ContactData() {
e.preventDefault()
if (isSubmited) return
try {
setIsLoading(true)
const { ingredients, price } = location.state
const response = await axiosOrder.post('orders.json', {
const order = {
customer: { ...customerData },
ingredients,
price
})
console.log(response.data)
price: totalPrice
}
dispatch(createOrder(order))
setIsSubmited(true)
} catch (err) {
console.log(err)
setIsSubmited(false)
} finally {
setIsLoading(false)
}
}
const goBack = () => {
......
import { axiosOrder } from '../../axios/axiosOrder';
import type { TFirebaseData } from "../../types/TFirebaseData";
import { TOrder } from '../../types/TOrder';
'use client'
import { useEffect } from 'react';
import { useAppSelector } from '../../hooks/useAppSelector';
import OrderItem from '../OrderItem/OrderItem';
import { useLoaderData } from 'react-router';
import { useAppDispatch } from '../../hooks/useAppDispatch';
import { getOrders } from '../../stores/newStore/ordersSlice';
export const fetchOrders = async () => {
const response = await axiosOrder.get('orders.json');
const data: TFirebaseData<TOrder> = response.data
const fetchedOrders: TOrder[] = Object.keys(data).map(id => {
return { ...data[id], id };
});
return fetchedOrders
}
const Orders = () => {
const orders: TOrder[] = useLoaderData()
const {orders} = useAppSelector(state => state.orders)
const dispatch = useAppDispatch()
useEffect(() => {
dispatch(getOrders())
}, [dispatch])
return (
<>
{orders.map(order => {
......
......@@ -6,9 +6,7 @@ import BurgerBuilder from './components/BurgerBuilder/BurgerBuilder.tsx'
import { Checkout } from './components/Checkout/Checkout.tsx'
import { ContactData } from './components/ContactData/ContactData.tsx'
import Layout from './components/layouts/Layout/Layout.tsx'
import { fetchOrders } from './components/Orders/Orders.tsx'
import { lazy, Suspense } from 'react'
import Spinner from './components/UI/Spinner/Spinner.tsx'
import { lazy } from 'react'
import { Provider } from 'react-redux'
import store from './stores/newStore/store.ts'
const Orders = lazy(() => import('./components/Orders/Orders.tsx'))
......@@ -35,11 +33,8 @@ const router = createBrowserRouter([
{
path: '/orders',
element: (
<Suspense fallback={<Spinner />}>
<Orders />
</Suspense>
),
loader: fetchOrders
}
]
},
......
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"
import { axiosOrder } from "../../axios/axiosOrder"
import { TFirebaseData } from "../../types/TFirebaseData"
import { TOrder } from "../../types/TOrder"
import { AxiosRequestConfig, AxiosResponse } from "axios"
type State = {
orders: TOrder[]
isLoading: boolean
error: Error | null,
}
const initialState: State = {
orders: [],
error: null,
isLoading: false
}
const namespace = 'orders'
export const getOrders = createAsyncThunk(
`${namespace}/getOrders`,
async (): Promise<TFirebaseData<TOrder>> => {
const response = await axiosOrder.get('orders.json')
return response.data
}
)
export const createOrder = createAsyncThunk(
`${namespace}/createOrder`,
async (payload: Omit<TOrder, 'id'>) => {
await axiosOrder.post<AxiosRequestConfig, AxiosResponse, Omit<TOrder, 'id'>>('orders.json', payload);
}
)
const orderSlice = createSlice({
name: namespace,
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(getOrders.pending, (state) => {
state.isLoading = true
state.error = null
})
.addCase(getOrders.rejected, (state, action) => {
state.isLoading = false
state.error = action.payload as Error
})
.addCase(getOrders.fulfilled, (state, action) => {
state.isLoading = false
const fetchedOrders: TOrder[] = Object.keys(action.payload).map(id => {
return { ...action.payload[id] as TOrder, id };
});
state.orders = fetchedOrders
state.error = null
})
.addCase(createOrder.pending, (state) => {
state.isLoading = true;
state.error = null;
})
.addCase(createOrder.rejected, (state, action) => {
state.error = action.error as Error;
state.isLoading = false
})
.addCase(createOrder.fulfilled, (state) => {
state.isLoading = false;
})
}
})
export default orderSlice.reducer
\ No newline at end of file
import { configureStore } from "@reduxjs/toolkit";
import burgerReducer from './burgerSlice'
import ordersReducer from './ordersSlice'
const store = configureStore({
reducer: {
burger: burgerReducer
burger: burgerReducer,
orders: ordersReducer
}
})
......
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