From e15596009747fa59b549454d9942d9bb44a3dea3 Mon Sep 17 00:00:00 2001 From: satoshiuy Date: Sun, 19 Feb 2023 01:10:43 +0700 Subject: [PATCH 1/3] add redux --- components/CartIcon.tsx | 33 +++++++++++++++++++++ components/LandingUI.tsx | 30 +++++++++++-------- components/MainNavigation.tsx | 7 ++--- components/Product/Product.tsx | 45 +++++++++++++++-------------- components/Product/ProductList.tsx | 14 +++++---- container/HomeContainer.tsx | 25 +++++++--------- interfaces/index.ts | 33 +++++++++++++++++++++ pages/index.tsx | 43 ++++++++++++++++++++++++++-- store/models/index.ts | 4 +++ store/models/user.ts | 46 ++++++++++++++++++++++++++++++ styles/components/product.scss | 2 +- tsconfig.json | 2 +- utils/firebase.js | 21 +++++++------- 13 files changed, 232 insertions(+), 73 deletions(-) create mode 100644 components/CartIcon.tsx create mode 100644 interfaces/index.ts create mode 100644 store/models/user.ts diff --git a/components/CartIcon.tsx b/components/CartIcon.tsx new file mode 100644 index 0000000..3285ed2 --- /dev/null +++ b/components/CartIcon.tsx @@ -0,0 +1,33 @@ +import { ShoppingCartOutlined } from '@ant-design/icons'; +import { Badge } from 'antd'; +import { useRouter } from 'next/router'; +import { connect } from 'react-redux'; +import { Dispatch, RootState } from "../store" + +const mapState = (state: RootState) => ({ + user: state.user, +}); +const mapDispatch = (dispatch: Dispatch) => ({ + increment: () => dispatch.count.increment(1), + incrementAsync: () => dispatch.count.incrementAsync(1), +}); +type StateProps = ReturnType; +type DispatchProps = ReturnType; +type Props = StateProps & DispatchProps; + + + +function Cart(props:StateProps) : JSX.Element { + const router = useRouter(); + return ( +
router.push("/order")}> + + + +
+ ) +} + +const CartIcon = connect(mapState, mapDispatch)(Cart); + +export default CartIcon \ No newline at end of file diff --git a/components/LandingUI.tsx b/components/LandingUI.tsx index f92bc21..68aa3f1 100644 --- a/components/LandingUI.tsx +++ b/components/LandingUI.tsx @@ -1,4 +1,4 @@ -import { Badge, Col, Row } from "antd" +import { Badge, Col, Row, Skeleton } from "antd" import Image from "next/image" import Product from "./Product/Product" import { FieldTimeOutlined } from '@ant-design/icons'; @@ -30,7 +30,7 @@ const products = [ }, ] -function LandingUI() : JSX.Element { +function LandingUI({products} : any) : JSX.Element { return ( @@ -41,16 +41,22 @@ function LandingUI() : JSX.Element {
Your University
-
-
- - -
-
- - -
-
+ { + products ? ( +
+
+ + +
+
+ + +
+
+ ) : ( + + ) + } hero
diff --git a/components/MainNavigation.tsx b/components/MainNavigation.tsx index c3f758a..8f565a4 100644 --- a/components/MainNavigation.tsx +++ b/components/MainNavigation.tsx @@ -8,7 +8,8 @@ import Logo from '../public/main/logo.svg' import { signOut } from 'firebase/auth' import { auth } from '../utils/firebase' import { useAuthState } from 'react-firebase-hooks/auth' -function MainNavigation() : JSX.Element { +import CartIcon from './CartIcon' +function MainNavigation({user} : any) : JSX.Element { const [loggedInUser, loading, error] = useAuthState(auth); return ( @@ -30,9 +31,7 @@ function MainNavigation() : JSX.Element { {/* User */}
- - - + { + dispatch.user.addProductCart(product); + } return ( -
- {"product"} -
- {product.name} -
- {convertToDongString(product.price)} - - -
- + product &&
+ {"product"} +
+ {product.name} +
+ {convertToDongString(product.price)} + + +
+
) } diff --git a/components/Product/ProductList.tsx b/components/Product/ProductList.tsx index f3f44e3..0a48d96 100644 --- a/components/Product/ProductList.tsx +++ b/components/Product/ProductList.tsx @@ -1,4 +1,4 @@ -import { Typography } from "antd" +import { Skeleton, Typography } from "antd" import { useEffect, useState } from "react" import { getProductsFromFirebaseBasedOnCategory } from "../../utils/firebase" import Product from "./Product" @@ -9,11 +9,13 @@ function ProductList({category, products} : any) : JSX.Element {
{category}
{ - products.map((product : any) => { - return ( - - ) - }) + products.length == 0 ? : ( + products.map((product : any) => { + return ( + + ) + }) + ) }
diff --git a/container/HomeContainer.tsx b/container/HomeContainer.tsx index e3f3a62..2c3cb13 100644 --- a/container/HomeContainer.tsx +++ b/container/HomeContainer.tsx @@ -5,35 +5,30 @@ import ProductList from '../components/Product/ProductList' import { useEffect, useState } from 'react'; import { getAllProductsFromFirebase } from '../utils/firebase'; import { message } from 'antd'; +import { collection, onSnapshot } from 'firebase/firestore'; +import { db } from '../utils/firebase'; +function HomeContainer({ user, setUser,products,loading }: any): JSX.Element { -function HomeContainer() : JSX.Element { - const [products, setProducts] = useState([]); - console.log(products); - useEffect(() => { - getAllProductsFromFirebase() - .then((res) => { - if(!res){ - message.error('Get products failed') - return; - } - setProducts(res) - }) - },[]) const filterCategoryProducts = (category: string) => { return products.filter((product: any) => product.category === category) } + const randomProducts = products + .sort(() => Math.random() - 0.5) // Shuffle the array + .slice(0, 4); // Take the first 4 elements + + const CategoryTitle = ["Đồ Ăn", "Đồ Uống", "Khác"]; return ( <> - + { CategoryTitle.map((category) => { console.log("category", category) return ( - + ) }) } diff --git a/interfaces/index.ts b/interfaces/index.ts new file mode 100644 index 0000000..fe7c355 --- /dev/null +++ b/interfaces/index.ts @@ -0,0 +1,33 @@ +export type IProduct = { + id: String, + name: String, + price: Number, + quantity: Number, + image: String, + shop: String, + category: String, + isAvailable: Boolean, + createdate: { + second: Number, + nanosecond: Number, + }, + lastupdate: { + second: Number, + nanosecond: Number, + }, + createdby: String, + updatedby: String, +} + +export type ICart = { + product: IProduct, + quantity: number, +} +export type IUser = { + email: String, + displayName: String, + photoURL: String, + lastSeen: any, + cart: ICart[], + phoneNumber: String, +} \ No newline at end of file diff --git a/pages/index.tsx b/pages/index.tsx index d932caf..9830f08 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -4,13 +4,50 @@ import MainFooter from '../components/MainFooter'; import { Layout, message } from 'antd'; import HomeContainer from '../container/HomeContainer'; import { useEffect, useState } from 'react'; -import { getAllProductsFromFirebase } from '../utils/firebase'; +import { auth, getAllProductsFromFirebase, getUserFromFirebase } from '../utils/firebase'; +import { useAuthState } from 'react-firebase-hooks/auth'; function App() { + const [loggedInUser, loading, error] = useAuthState(auth); + const [products, setProducts] = useState([]); + const [loadingProduct, setLoading] = useState(true); + const [user, setUser] = useState({ + email: '', + displayName: '', + photoURL: '', + lastSeen: '', + cart: [], + phoneNumber: '', + }); + + useEffect(() => { + if (loggedInUser) { + getUserFromFirebase(loggedInUser.uid) + .then((res) => { + console.log(res); + + if (!res) { + message.error('Get user failed') + return; + } + setUser(res) + } + ) + + + } + (async () => { + const products = await getAllProductsFromFirebase() + setProducts(products); + setLoading(loadingProduct); + + })(); + }, []) + return <> - - + + ; diff --git a/store/models/index.ts b/store/models/index.ts index 5d3f2ae..3cf1f8f 100644 --- a/store/models/index.ts +++ b/store/models/index.ts @@ -1,11 +1,15 @@ import { Models } from '@rematch/core'; import { count } from './count'; import { authStore } from './auth-store'; +import { user } from './user'; export interface RootModel extends Models { count: typeof count; authStore: typeof authStore; + user: typeof user; + } export const models: RootModel = { count, authStore, + user, }; diff --git a/store/models/user.ts b/store/models/user.ts new file mode 100644 index 0000000..3a6edac --- /dev/null +++ b/store/models/user.ts @@ -0,0 +1,46 @@ +import { createModel } from "@rematch/core"; +import { ICart, IProduct, IUser } from "../../interfaces"; + + +const initialState : IUser = { + email: "", + displayName: "", + photoURL: "", + lastSeen: null, + cart: [], + phoneNumber: "", +}; + +export const user = createModel()({ + state: initialState, // initial state + reducers: { + // handle state changes with pure functions + addProductCart(state, payload):IUser { + console.log("This is current root state", state); + // Add product to cart + const newCart : ICart[] = [...state.cart]; + const index = newCart.findIndex((item: ICart) => item.product.id === payload.id); + if (index !== -1) { + newCart[index].quantity += 1; + } else { + newCart.push({ product: payload, quantity: 1 }); + } + + return { + ...state, + cart: newCart + + }; + }, + }, + effects: (dispatch) => ({ + // handle state changes with impure functions. + // use async/await for async actions + // async incrementAsync(payload, state) { + // console.log("This is current root state", state); + // await new Promise((resolve) => setTimeout(resolve, 1000)); + // dispatch.count.increment(payload); + // }, + }), +}); + diff --git a/styles/components/product.scss b/styles/components/product.scss index f37a2f0..41b5eaf 100644 --- a/styles/components/product.scss +++ b/styles/components/product.scss @@ -1,5 +1,5 @@ .product-list{ - padding: 10px 50px; + padding: 10px 60px; &-title{ font-family: 'Roboto'; diff --git a/tsconfig.json b/tsconfig.json index c674928..7786ffd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,6 @@ "jsx": "preserve", "incremental": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/index.jsx", "pages/_app.jsx", "src/**/*", "components/Admin/user.jsx", "components/Admin/product.jsx", "components/Admin/AdminPage.jsx", "pages/test.jsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/index.jsx", "pages/_app.jsx", "src/**/*", "components/Admin/user.jsx", "components/Admin/product.jsx", "components/Admin/AdminPage.jsx", "pages/test.jsx", "store/models/user.ts"], "exclude": ["node_modules"] } diff --git a/utils/firebase.js b/utils/firebase.js index 85c446b..1032834 100644 --- a/utils/firebase.js +++ b/utils/firebase.js @@ -127,15 +127,6 @@ export const getNoteFromFirebase = async (noteID) => { } }; - export const getUserFromFirebase = async (loggedInUser) => { - const noteRef = doc(db, 'users' ,`${loggedInUser.uid}`); - const noteSnap = await getDoc(noteRef); - if (noteSnap.exists()) { - return noteSnap.data(); - } else { - return null; - } - }; // New Code export const getAllProductsFromFirebase = async () => { const queryQuestion = query(collection(db, 'Products')); @@ -156,6 +147,16 @@ export const getProductsFromFirebaseBasedOnCategory = async (category) => { output.push(doc.data()); }); return output; -}; +}; + +export const getUserFromFirebase = async (loggedInUser) => { + const noteRef = doc(db, 'users' ,`${loggedInUser.uid}`); + const noteSnap = await getDoc(noteRef); + if (noteSnap.exists()) { + return noteSnap.data(); + } else { + return null; + } +}; export { db, auth, storage }; From 9c2314cd76ac2a5d1e036404106cf44f2233b308 Mon Sep 17 00:00:00 2001 From: MarkVoVN Date: Sun, 19 Feb 2023 01:13:42 +0700 Subject: [PATCH 2/3] refactor cart order page --- components/Order/OrderDetailsComponent.jsx | 34 ---- components/Order/OrderDetailsComponent.tsx | 56 +++++++ components/Order/OrderItemComponent.jsx | 33 ---- components/Order/OrderItemComponent.tsx | 44 +++++ components/Order/OrderItemListComponent.jsx | 32 ---- components/Order/OrderItemListComponent.tsx | 37 +++++ container/OrderContainer.tsx | 168 +++++++++++++++++--- 7 files changed, 281 insertions(+), 123 deletions(-) delete mode 100644 components/Order/OrderDetailsComponent.jsx create mode 100644 components/Order/OrderDetailsComponent.tsx delete mode 100644 components/Order/OrderItemComponent.jsx create mode 100644 components/Order/OrderItemComponent.tsx delete mode 100644 components/Order/OrderItemListComponent.jsx create mode 100644 components/Order/OrderItemListComponent.tsx diff --git a/components/Order/OrderDetailsComponent.jsx b/components/Order/OrderDetailsComponent.jsx deleted file mode 100644 index dda4e0c..0000000 --- a/components/Order/OrderDetailsComponent.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Typography } from "antd"; -import { Col, Row } from "antd"; -import React from "react"; - -function OrderDetailsComponent(props) { - const deliveryInfo = props.data - - return ( -
-
- - {deliveryInfo.section} - - - {deliveryInfo.option} - -
- - - {deliveryInfo.sub[0]} - - - {deliveryInfo.sub[1]} - - - - {deliveryInfo.data[0]} - {deliveryInfo.data[1]} - -
- ); -} - -export default OrderDetailsComponent; diff --git a/components/Order/OrderDetailsComponent.tsx b/components/Order/OrderDetailsComponent.tsx new file mode 100644 index 0000000..cc81e3b --- /dev/null +++ b/components/Order/OrderDetailsComponent.tsx @@ -0,0 +1,56 @@ +import { Typography } from "antd"; +import { Col, Row } from "antd"; +import { useState } from "react"; +import { HighlightOutlined } from "@ant-design/icons"; +import React from "react"; + +function OrderDetailsComponent(props: { + headings: {section: string, sub: string[]} + data: {info: string, handler: (value: string) => void}[] +}) { + const headings = props.headings; + const data = props.data; + + return ( +
+
+ + {headings.section} + + {/* + {deliveryInfo.option} + */} +
+ + + {headings.sub[0]} + + + {headings.sub[1]} + + + + + , + tooltip: "click to edit text", + onChange: data[0].handler, + enterIcon: null, + }} + >{data[0].info} + + , + tooltip: "click to edit text", + onChange: data[1].handler, + enterIcon: null, + }} + >{data[1].info} + +
+ ); +} + +export default OrderDetailsComponent; diff --git a/components/Order/OrderItemComponent.jsx b/components/Order/OrderItemComponent.jsx deleted file mode 100644 index 1971f83..0000000 --- a/components/Order/OrderItemComponent.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Col, Image, InputNumber, Row, Typography } from "antd"; -import React from "react"; - -function OrderItemComponent({photoURL, amount, name, price}) { - - const itemAmountChangeHandler = () => { - - } - - return ( - - - {photoURL} - - - - - - {name} - - - {price} - - - ); -} - -export default OrderItemComponent; diff --git a/components/Order/OrderItemComponent.tsx b/components/Order/OrderItemComponent.tsx new file mode 100644 index 0000000..1b7c176 --- /dev/null +++ b/components/Order/OrderItemComponent.tsx @@ -0,0 +1,44 @@ +import { Col, Image, InputNumber, Row, Typography } from "antd"; +import React, { useState } from "react"; +import { Product } from "../../container/OrderContainer"; + +interface Props { + data: Product + handler: (id:string, value:number) => void +} + +function OrderItemComponent(props:Props) { + let {data, handler} = props + + let {id, image, amount, name, price} = data + + const itemAmountChangeHandler = (value: any) => { + console.log(value); + if (typeof value === 'number') + handler(id, value) + } + + return ( + + + {image} + + + + + + {name} + + + {price} + + + ); +} + +export default OrderItemComponent; diff --git a/components/Order/OrderItemListComponent.jsx b/components/Order/OrderItemListComponent.jsx deleted file mode 100644 index 31e1f19..0000000 --- a/components/Order/OrderItemListComponent.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Typography } from "antd"; -import React, { useState } from "react"; -import OrderItemComponent from "./OrderItemComponent"; - -function OrderItemListComponent() { - const Product = { - photoURL: "", - name: "Banh mi thit", - // seller: "711", - // description: "This is banh mi thit", - amount: 1, - price: 15000, - }; - - let ProductListMock = [Product, Product, Product]; - - - const [ProductList, setProductList] = useState(ProductListMock); - - console.log(ProductList); - return ( -
- Thông tin giỏ hàng - {ProductList.map((p) => ( - - ))} - -
- ); -} - -export default OrderItemListComponent; diff --git a/components/Order/OrderItemListComponent.tsx b/components/Order/OrderItemListComponent.tsx new file mode 100644 index 0000000..a37c1b0 --- /dev/null +++ b/components/Order/OrderItemListComponent.tsx @@ -0,0 +1,37 @@ +import { Button, Typography } from "antd"; +import React, { useEffect, useState } from "react"; +import OrderItemComponent from "./OrderItemComponent"; +import { Product } from "../../container/OrderContainer"; + +interface Props { + ProductList: Product[] + amountChangeHandler: (id:string, value:number) => void + total: number +} + +function OrderItemListComponent(props: Props) { + + const {ProductList, amountChangeHandler, total} = props + + + + + return ( +
+ Thông tin giỏ hàng + {ProductList.map((p) => ( + + ))} +
+ Tổng tiền: + {total} +
+
+ ); +} + +export default OrderItemListComponent; + diff --git a/container/OrderContainer.tsx b/container/OrderContainer.tsx index 8633a48..7fbaba3 100644 --- a/container/OrderContainer.tsx +++ b/container/OrderContainer.tsx @@ -1,34 +1,154 @@ -import { Typography } from 'antd' -import React from 'react' -import OrderDetailsComponent from '../components/Order/OrderDetailsComponent' -import OrderItemListComponent from '../components/Order/OrderItemListComponent' -function OrderContainer() : JSX.Element{ +import { Button, Typography } from "antd"; +import React from "react"; +import OrderDetailsComponent from "../components/Order/OrderDetailsComponent"; +import OrderItemListComponent from "../components/Order/OrderItemListComponent"; +import { useState, useEffect } from "react"; +import { useAuthState } from "react-firebase-hooks/auth"; +import { auth } from "../utils/firebase"; - const deliveryInfo = { - section: "Thông tin giao hàng", - option: "Sửa đổi", - sub: ["Room No.", "Thời gian giao hàng"], - data: ["202", "9:15-9:30"] - - } +export interface Product { + price: number; + name: string; + amount: number; + image: string; + id: string; +} +function OrderContainer(): JSX.Element { - const recipientInfo = { + const [loginUser] = useAuthState(auth) + + + const deliveryHeading = { + section: "Thông tin giao hàng", + sub: ["Room No.", "Thời gian giao hàng"], + }; + const recipientHeading = { section: "Thông tin người nhận", - option: "Sửa đổi", sub: ["Tên người nhận", "SĐT người nhận"], - data: ["John Cena", "0123456789"] - } + }; + + let product: Product = { + id: "1", + image: "", + name: "Banh mi thit", + amount: 1, + price: 15000, + }; + + let ProductListMock: Product[] = [ + { + id: "1", + image: "", + name: "Banh mi thit", + amount: 1, + price: 15000, + }, + { + id: "2", + image: "", + name: "Banh mi thit", + amount: 1, + price: 15000, + }, + { + id: "3", + image: "", + name: "Banh mi thit", + amount: 1, + price: 15000, + }, + ]; + const [cart, setCart] = useState({ + ProductList: ProductListMock, + Location: "202", + DeliveryTime: "9:15-9:30", + RecipientName: "John Cena", + PhoneNumber: "0123456789", + Total: 0 + }) + + //update productList when amount is changed + const amountChangeHandler = (id: string, value: number) => { + const ProductList = cart.ProductList + const index = ProductList.findIndex((p) => p.id === id); + + setCart({ + ...cart, + ProductList: [ + ...ProductList.slice(0, index), + { ...ProductList[index], amount: value }, + ...ProductList.slice(index + 1), + ] + }); + }; + + //update total when productList is changed + + useEffect(() => { + let temp = 0; + cart.ProductList.map((p) => { + temp += p.amount * p.price; + }); + setCart({ + ...cart, + Total: temp + }); + }, [cart.ProductList]); + + const locationChangeHandler = (value: string) => { + setCart({ + ...cart, + Location: value + }); + }; + const deliveryTimeChangeHandler = (value: string) => { + setCart({ + ...cart, + DeliveryTime: value + }); + }; + const recipientNameChangeHandler = (value: string) => { + setCart({ + ...cart, + RecipientName: value + }); + }; + const phoneNumberChangeHandler = (value: string) => { + setCart({ + ...cart, + PhoneNumber: value + }); + }; return ( -
- THÔNG TIN ĐƠN HÀNG - - - -
- ) +
+ + THÔNG TIN ĐƠN HÀNG + + + + + +
+ ); } -export default OrderContainer \ No newline at end of file +export default OrderContainer; From 6774726d4dd505a670f77e950e218eda7ab45e9b Mon Sep 17 00:00:00 2001 From: satoshiuy Date: Sun, 19 Feb 2023 05:45:12 +0700 Subject: [PATCH 3/3] update --- components/Order/OrderItemComponent.tsx | 18 +-- components/Order/OrderItemListComponent.tsx | 19 ++- container/OrderContainer.tsx | 147 ++++++++++++-------- container/SearchContainer.tsx | 0 interfaces/index.ts | 37 ++--- pages/client/search/index.jsx | 13 ++ 6 files changed, 145 insertions(+), 89 deletions(-) create mode 100644 container/SearchContainer.tsx create mode 100644 pages/client/search/index.jsx diff --git a/components/Order/OrderItemComponent.tsx b/components/Order/OrderItemComponent.tsx index 1b7c176..37b2e34 100644 --- a/components/Order/OrderItemComponent.tsx +++ b/components/Order/OrderItemComponent.tsx @@ -1,41 +1,41 @@ import { Col, Image, InputNumber, Row, Typography } from "antd"; import React, { useState } from "react"; import { Product } from "../../container/OrderContainer"; +import { ICart } from "../../interfaces"; interface Props { - data: Product + product: ICart, handler: (id:string, value:number) => void } function OrderItemComponent(props:Props) { - let {data, handler} = props + let {product, handler} = props - let {id, image, amount, name, price} = data + // console.log("product", product) const itemAmountChangeHandler = (value: any) => { console.log(value); if (typeof value === 'number') - handler(id, value) + handler(product.product.id, value) } - return ( - {image} + - {name} + {product.product.name} - {price} + {product.product.price} ); diff --git a/components/Order/OrderItemListComponent.tsx b/components/Order/OrderItemListComponent.tsx index a37c1b0..52310f7 100644 --- a/components/Order/OrderItemListComponent.tsx +++ b/components/Order/OrderItemListComponent.tsx @@ -2,18 +2,18 @@ import { Button, Typography } from "antd"; import React, { useEffect, useState } from "react"; import OrderItemComponent from "./OrderItemComponent"; import { Product } from "../../container/OrderContainer"; +import { ICart } from "../../interfaces"; interface Props { - ProductList: Product[] - amountChangeHandler: (id:string, value:number) => void + ProductList: ICart[] + quantityChangeHandler: (id:string, value:number) => void total: number + deliveryFee: number } function OrderItemListComponent(props: Props) { - const {ProductList, amountChangeHandler, total} = props - - + const {ProductList, quantityChangeHandler, total, deliveryFee} = props return ( @@ -21,14 +21,19 @@ function OrderItemListComponent(props: Props) { Thông tin giỏ hàng {ProductList.map((p) => ( ))} +
+ Phí ship: + {deliveryFee} +
Tổng tiền: {total}
+
); } diff --git a/container/OrderContainer.tsx b/container/OrderContainer.tsx index 7fbaba3..f47e7e5 100644 --- a/container/OrderContainer.tsx +++ b/container/OrderContainer.tsx @@ -1,23 +1,43 @@ import { Button, Typography } from "antd"; -import React from "react"; +import { useEffect, useState } from "react"; +import { connect } from "react-redux"; import OrderDetailsComponent from "../components/Order/OrderDetailsComponent"; import OrderItemListComponent from "../components/Order/OrderItemListComponent"; -import { useState, useEffect } from "react"; -import { useAuthState } from "react-firebase-hooks/auth"; -import { auth } from "../utils/firebase"; +import { ICart, IProduct } from "../interfaces"; +import { Dispatch, RootState } from "../store"; +import { Modal } from "antd"; +import ProductList from "../components/Product/ProductList"; export interface Product { price: number; name: string; - amount: number; + quantity: number; image: string; id: string; } -function OrderContainer(): JSX.Element { - const [loginUser] = useAuthState(auth) +const mapState = (state: RootState) => ({ + user: state.user, +}); +const mapDispatch = (dispatch: Dispatch) => ({ + increment: () => dispatch.count.increment(1), + incrementAsync: () => dispatch.count.incrementAsync(1), +}); + + +const removeItem = (id: string, array: any[]) => { + const clone = [...array]; + const index = clone.findIndex((p: any) => p.product.id === id); + if (index !== -1) { + clone.splice(index, 1); + } + return clone +} + + +let idRemove : string = ""; +function OrderContainer(props: any): JSX.Element { - const deliveryHeading = { section: "Thông tin giao hàng", sub: ["Room No.", "Thời gian giao hàng"], @@ -27,71 +47,57 @@ function OrderContainer(): JSX.Element { sub: ["Tên người nhận", "SĐT người nhận"], }; - let product: Product = { - id: "1", - image: "", - name: "Banh mi thit", - amount: 1, - price: 15000, - }; - let ProductListMock: Product[] = [ - { - id: "1", - image: "", - name: "Banh mi thit", - amount: 1, - price: 15000, - }, - { - id: "2", - image: "", - name: "Banh mi thit", - amount: 1, - price: 15000, - }, - { - id: "3", - image: "", - name: "Banh mi thit", - amount: 1, - price: 15000, - }, - ]; const [cart, setCart] = useState({ - ProductList: ProductListMock, + ProductList: props.user.cart, Location: "202", DeliveryTime: "9:15-9:30", RecipientName: "John Cena", PhoneNumber: "0123456789", + DeliveryFee: 0, Total: 0 }) + // console.log(cart) - //update productList when amount is changed - const amountChangeHandler = (id: string, value: number) => { - const ProductList = cart.ProductList - const index = ProductList.findIndex((p) => p.id === id); - + //update productList when quantity is changed + + const quantityChangeHandler = (id: string, value: number) => { + const index = cart.ProductList.findIndex((p: any) => p.product.id === id); + if (value == 0) { + idRemove = id + + showModal() + } else { setCart({ ...cart, ProductList: [ - ...ProductList.slice(0, index), - { ...ProductList[index], amount: value }, - ...ProductList.slice(index + 1), + ...cart.ProductList.slice(0, index), + { ...cart.ProductList[index], quantity: value }, + ...cart.ProductList.slice(index + 1), ] }); + } }; //update total when productList is changed useEffect(() => { let temp = 0; - cart.ProductList.map((p) => { - temp += p.amount * p.price; + cart.ProductList.map((p: any) => { + temp += p.quantity * p.product.price; }); + let shipFee = 2000; + if (temp > 49000 && temp < 99000) { + shipFee = 5000} + else if (temp >= 99000 && temp < 149000) { + shipFee = 7000 + } else if (temp >= 149000) { + shipFee = 10000 + } setCart({ ...cart, - Total: temp + DeliveryFee: shipFee, + Total: temp*1.05 + shipFee, }); }, [cart.ProductList]); @@ -101,29 +107,57 @@ function OrderContainer(): JSX.Element { Location: value }); }; - const deliveryTimeChangeHandler = (value: string) => { setCart({ ...cart, DeliveryTime: value }); }; - const recipientNameChangeHandler = (value: string) => { setCart({ ...cart, RecipientName: value }); }; - const phoneNumberChangeHandler = (value: string) => { setCart({ ...cart, PhoneNumber: value }); }; + + const [isModalOpen, setIsModalOpen] = useState(false); + + const showModal = () => { + setIsModalOpen(true); + }; + + const handleOk = () => { + setIsModalOpen(false); + const productList = removeItem(idRemove, cart.ProductList); + + setCart({ + ...cart, + ProductList: productList + }); + console.log(productList); + + }; + + const handleCancel = () => { + setIsModalOpen(false); + }; + + const handleSubmit = () => { + + } + + return (
+ +

HI

+
THÔNG TIN ĐƠN HÀNG @@ -143,12 +177,13 @@ function OrderContainer(): JSX.Element { > - +
); } -export default OrderContainer; +export default connect(mapState, mapDispatch)(OrderContainer); diff --git a/container/SearchContainer.tsx b/container/SearchContainer.tsx new file mode 100644 index 0000000..e69de29 diff --git a/interfaces/index.ts b/interfaces/index.ts index fe7c355..4aa6b31 100644 --- a/interfaces/index.ts +++ b/interfaces/index.ts @@ -1,22 +1,25 @@ export type IProduct = { - id: String, - name: String, - price: Number, - quantity: Number, - image: String, - shop: String, - category: String, + id: string, + name: string, + price: number, + quantity: number, + image: { + src: string, + title: string, + }, + shop: string, + category: string, isAvailable: Boolean, createdate: { - second: Number, - nanosecond: Number, + second: number, + nanosecond: number, }, lastupdate: { - second: Number, - nanosecond: Number, + second: number, + nanosecond: number, }, - createdby: String, - updatedby: String, + createdby: string, + updatedby: string, } export type ICart = { @@ -24,10 +27,10 @@ export type ICart = { quantity: number, } export type IUser = { - email: String, - displayName: String, - photoURL: String, + email: string, + displayName: string, + photoURL: string, lastSeen: any, cart: ICart[], - phoneNumber: String, + phoneNumber: string, } \ No newline at end of file diff --git a/pages/client/search/index.jsx b/pages/client/search/index.jsx new file mode 100644 index 0000000..462dd33 --- /dev/null +++ b/pages/client/search/index.jsx @@ -0,0 +1,13 @@ +import React from 'react' + +function index() { + return ( + <> + + + + + ) +} + +export default index \ No newline at end of file