diff --git a/package.json b/package.json index 5f5082d..fcf1e9e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "0.1.0", "private": true, "dependencies": { - "@aws-amplify/auth": "^4.4.4", "@chakra-ui/icons": "^1.1.7", "@chakra-ui/react": "^1.8.3", "@emotion/react": "^11", diff --git a/src/App.tsx b/src/App.tsx index 8265622..bee5e5d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,7 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import Routes from "./routes"; import chakraTheme from "./config/theme"; import { CartProvider } from "./context/cart"; +import { CheckoutProvider } from "./context/checkout"; const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false } } }); @@ -22,7 +23,9 @@ const App = () => { - + + + diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 0a9bb6d..81c636e 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -8,27 +8,9 @@ type FooterLinkProps = { function Footer() { return ( - - - - - SCSE Logo - - - - + + SCSE Logo + ); } diff --git a/src/components/Header.tsx b/src/components/Header.tsx index c2bcd81..a42b8db 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -10,35 +10,28 @@ import { Show, Hide, Icon, + Text, } from "@chakra-ui/react"; import { useState, useEffect } from "react"; import { Link as RouterLink } from "react-router-dom"; -import CognitoClient from "../utils/aws/cognito/cognitoClient"; import routes from "../utils/constants/routes"; import { useCartStore } from "../context/cart"; import { CartItemType } from "../typings/cart"; const Header = () => { - const [isAuthenticated, setIsAuthenticated] = useState(false); const cartContext = useCartStore(); const { state: cartState } = cartContext; const cartLength = cartState.items.reduce((acc: number, cur: CartItemType) => acc + cur.quantity, 0); - useEffect(() => { - CognitoClient.isUserSignedIn().then((isSignedIn) => { - setIsAuthenticated(isSignedIn); - }); - }, []); - return ( - + - - SCSE Logo - SCSE MERCH - + + SCSE Logo + SCSE MERCH + @@ -46,23 +39,27 @@ const Header = () => { - - {cartLength > 0 && {cartLength > 99 ? "99+" : cartLength}} + + {cartLength > 0 && {cartLength > 99 ? "99+" : cartLength}} - Home + _hover={{ bg: "#426899", transition: "0.5s", color: "white" }}> + + Home + - - - {cartLength > 0 && {cartLength > 99 ? "99+" : cartLength}} - + + + + {cartLength > 0 && {cartLength > 99 ? "99+" : cartLength}} + + diff --git a/src/components/OrderItem.tsx b/src/components/OrderItem.tsx index 1f875d5..7ab9436 100644 --- a/src/components/OrderItem.tsx +++ b/src/components/OrderItem.tsx @@ -36,7 +36,7 @@ const OrderItem: React.FC = (props: OrderItemProps) => { Color: - {data.color} + {data.colorway} diff --git a/src/context/checkout/index.tsx b/src/context/checkout/index.tsx new file mode 100644 index 0000000..52d809e --- /dev/null +++ b/src/context/checkout/index.tsx @@ -0,0 +1,28 @@ +import React, { useContext, useMemo, useState } from "react"; +import { CheckoutResponseDto } from "../../typings/cart"; + +type ContextType = { + state: CheckoutResponseDto | null; + setState: React.Dispatch> +} | null + +const CheckoutContext = React.createContext(null) + +export const useCheckoutStore = () => { + const context = useContext(CheckoutContext); + if (context === null){ + throw new Error("useCheckoutStore must be used within a CheckoutProvider.") + } + return context +} + +export const CheckoutProvider: React.FC = ({ children }) => { + const [checkoutState, setCheckoutState] = useState(null) + + const value = useMemo(() => ({ + state: checkoutState, + setState: setCheckoutState + }), [checkoutState]) + return {children} + +} diff --git a/src/data/mock/orderList/index.tsx b/src/data/mock/orderList/index.tsx deleted file mode 100644 index c0f237f..0000000 --- a/src/data/mock/orderList/index.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { OrderStatusType, OrderType } from "../../../typings/order"; - -export const orderList: OrderType[] = [ - { - userId: "jacob", - orderID: "1234567891023456", - orderItems: [ - { - id: "1", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/448391/item/sggoods_36_448391.jpg?width=1600&impolicy=quality_75", - name: "SCSE Sweater", - size: "m", - color: "Brown", - price: 25.0, - quantity: 3, - }, - { - id: "2", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/444545/item/sggoods_00_444545.jpg?width=1008&impolicy=quality_75", - - name: "SCSE Shirt", - size: "l", - color: "Black", - price: 30.0, - quantity: 2, - }, - ], - status: OrderStatusType.DELAY, - billing: { - subtotal: 125.0, - total: 110.0, - }, - orderDateTime: new Date(1280981217 * 1000).toLocaleDateString("en-SG"), - lastUpdate: new Date(1610981217 * 1000).toLocaleDateString("en-SG"), - }, - { - userId: "jacob", - - orderID: "1234567891023455", - orderItems: [ - { - id: "1", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/457111/item/sggoods_00_457111.jpg?width=1008&impolicy=quality_75", - name: "SCSE Hoodie", - size: "m", - color: "White", - price: 25.0, - quantity: 3, - }, - { - id: "2", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/425974/item/sggoods_56_425974.jpg?width=1600&impolicy=quality_75", - name: "SCSE Shirt", - size: "l", - color: "Blue", - price: 30.0, - quantity: 2, - }, - ], - status: OrderStatusType.RECEIVED, - billing: { - subtotal: 125.0, - total: 151210.0, - }, - orderDateTime: new Date(73636123123 * 1000).toLocaleDateString("en-SG"), - lastUpdate: new Date(83636123123 * 1000).toLocaleDateString("en-SG"), - }, - - { - userId: "jacob", - orderID: "1234567891023456", - orderItems: [ - { - id: "1", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/448391/item/sggoods_36_448391.jpg?width=1600&impolicy=quality_75", - name: "SCSE Sweater", - size: "m", - color: "Brown", - price: 25.0, - quantity: 3, - }, - { - id: "2", - image: - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/452344/item/sggoods_09_452344.jpg?width=1008&impolicy=quality_75", - name: "SCSE Shirt", - size: "l", - color: "Black", - price: 30.0, - quantity: 2, - }, - ], - status: OrderStatusType.PROCESSING, - billing: { - subtotal: 1525.0, - total: 320.0, - }, - orderDateTime: new Date(1210981217 * 1000).toLocaleDateString("en-SG"), - lastUpdate: new Date(1210981217 * 1000).toLocaleDateString("en-SG"), - }, -]; diff --git a/src/data/mock/product/index.ts b/src/data/mock/product/index.ts deleted file mode 100644 index 8043bcc..0000000 --- a/src/data/mock/product/index.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { ProductType, ProductCategoryType } from "../../../typings/product"; - -export const productCategoryList: ProductCategoryType[] = ["sweater", "t-shirt", "hoodie"]; - -export const productList: ProductType[] = [ - { - id: "1", - images: [ - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/453401/item/sggoods_69_453401.jpg?width=1008&impolicy=quality_75", - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/444593/item/sggoods_32_444593.jpg?width=1008&impolicy=quality_75" - ], - name: "SCSE Sweater", - sizes: ["s", "m", "l", "xl"], - price: 2500, - colorways: ["Brown", "Beige"], - stock: [[5, 0, 3, 1], [1, 0, 5, 7]], - isAvailable: true, - productCategory: productCategoryList[0], - }, - { - id: "2", - name: "Sweater for Winter", - price: 4990, - sizes: ["xs", "s", "m", "l", "xl"], - images: [ - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/433037/item/sggoods_67_433037.jpg?width=1600&impolicy=quality_75", - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/433037/sub/sggoods_433037_sub1.jpg?width=1600&impolicy=quality_75", - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/433037/sub/sggoods_433037_sub2.jpg?width=1600&impolicy=quality_75", - ], - colorways: ["White", "Black", "Navy"], - stock: [[0, 10, 0, 0, 2], [5, 0, 0, 1, 0], [0, 0, 0, 0, 0]], - isAvailable: true, - productCategory: productCategoryList[0], - }, - { - id: "3", - images: [ - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/448969/item/sggoods_65_448969.jpg?width=1008&impolicy=quality_75", - ], - name: "SCSE Graphic Tee - G", - sizes: ["s", "m", "l", "xl"], - colorways: ["Grey"], - stock: [[0, 0, 3, 12]], - price: 2500, - isAvailable: true, - productCategory: productCategoryList[0], - }, - { - id: "4", - images: [ - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/435805/item/sggoods_03_435805.jpg?width=1008&impolicy=quality_75", - ], - name: "There's Jam on his shirt", - sizes: ["s", "m", "l", "xl"], - colorways: ["Red"], - stock: [[5, 0, 3, 1]], - price: 8500, - isAvailable: false, - productCategory: productCategoryList[1], - }, - { - id: "5", - images: [ - "https://image.uniqlo.com/UQ/ST3/sg/imagesgoods/446382/item/sggoods_15_446382.jpg?width=1008&impolicy=quality_75", - ], - name: "Blue note Records UT", - sizes: ["s", "m", "l", "xl"], - colorways: ["Blue", "Green"], - stock: [[0, 0, 0, 0], [0, 0, 0, 0]], - price: 1200, - isAvailable: true, - productCategory: productCategoryList[1], - }, - { - id: "6", - images: [ - "https://image.uniqlo.com/UQ/ST3/AsianCommon/imagesgoods/447167/item/goods_09_447167.jpg?width=1008&impolicy=quality_75", - ], - name: "Mango Looking T-Shirt from Daiso", - sizes: ["s", "m", "l", "xl"], - colorways: ["Yellow"], - stock: [[0, 0, 0, 0]], - price: 8500, - isAvailable: false, - productCategory: productCategoryList[1], - }, -]; diff --git a/src/pages/Cart/CartItem.tsx b/src/pages/Cart/CartItem.tsx index 4611966..979b99d 100644 --- a/src/pages/Cart/CartItem.tsx +++ b/src/pages/Cart/CartItem.tsx @@ -89,7 +89,13 @@ const CartItem: React.FC = ({ isMobile, data, onRemove, onQuantit - + diff --git a/src/pages/Checkout/Checkout.tsx b/src/pages/Checkout/Checkout.tsx index 87369da..c31890e 100644 --- a/src/pages/Checkout/Checkout.tsx +++ b/src/pages/Checkout/Checkout.tsx @@ -12,13 +12,14 @@ import CheckoutSkeleton from "./Skeleton"; import StripeForm from "./StripeForm"; import { QueryKeys } from "../../utils/constants/queryKeys"; import { displayPrice } from "../../utils/functions/currency"; +import { useCheckoutStore } from "../../context/checkout"; export const Checkout: FC = () => { // Cart Context Hook. const cartContext = useCartStore(); const [isLoading, setIsLoading] = useState(true); const { state: cartState, dispatch: cartDispatch } = cartContext; - const [checkoutState, setCheckoutState] = useState(null); + const { state: checkoutState, setState: setCheckoutState } = useCheckoutStore() // For mapping between cart item and info // const [productInfo, setProductInfo] = useState({}); @@ -72,7 +73,13 @@ export const Checkout: FC = () => { const subtotal = (product?.price ?? -1) * item.quantity; return ( - + @@ -80,6 +87,9 @@ export const Checkout: FC = () => { {displayPrice(subtotal)} + + {`Color: ${item.colorway}`} + {`Qty x${item.quantity}`} @@ -97,13 +107,13 @@ export const Checkout: FC = () => { - {/*Subtotal:*/} - {/*Discount:*/} + {/* Subtotal: */} + {/* Discount: */} Grand total: - {/*{displayPrice(checkoutState?.price?.subtotal ?? 0)}*/} - {/*{displayPrice(checkoutState?.price?.discount ?? 0)}*/} + {/* {displayPrice(checkoutState?.price?.subtotal ?? 0)} */} + {/* {displayPrice(checkoutState?.price?.discount ?? 0)} */} {displayPrice(checkoutState?.price?.grandTotal ?? 0)} diff --git a/src/pages/Checkout/StripeForm.tsx b/src/pages/Checkout/StripeForm.tsx index beb5a3c..f92c6d6 100644 --- a/src/pages/Checkout/StripeForm.tsx +++ b/src/pages/Checkout/StripeForm.tsx @@ -7,6 +7,7 @@ import { CartAction,CartActionType, useCartStore } from "../../context/cart"; import routes from "../../utils/constants/routes"; import { OrderStatusType } from "../../typings/order"; import { api } from "../../services/api"; +import { useCheckoutStore } from "../../context/checkout"; @@ -25,6 +26,9 @@ const PaymentForm = () => { const { dispatch: cartDispatch, state: cartState } = cartContext; const [isLoading, setIsLoading] = useState(false); const toast = useToast(); + + const { state: checkoutState } = useCheckoutStore() + const handleSubmit = async (event: React.FormEvent) => { // We don't want to let default form submission happen here, // which would refresh the page. @@ -55,13 +59,13 @@ const PaymentForm = () => { // TODO: remove userId as we do not have a login // TODO: order ID to be generated iteratively with api call setIsLoading(true); - const checkoutCart = await api.postCheckoutCart(cartState.items, cartState.billingEmail, cartState.voucher) + const payload : CartAction = { type: CartActionType.RESET_CART } cartDispatch(payload); setIsLoading(false); - navigate(`${routes.ORDER_SUMMARY}/${checkoutCart.orderId}`); + navigate(`${routes.ORDER_SUMMARY}/${checkoutState?.orderId}`); } }; return ( diff --git a/src/pages/ConfirmSignUp/ConfirmSignUp.tsx b/src/pages/ConfirmSignUp/ConfirmSignUp.tsx deleted file mode 100644 index c897b9d..0000000 --- a/src/pages/ConfirmSignUp/ConfirmSignUp.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Flex } from "@chakra-ui/react"; -import Header from "../../components/Header"; -import Footer from "../../components/Footer"; -import ConfirmSignUpForm from "./ConfirmSignUpForm"; - -const ConfirmSignUp = () => { - return ( - -
- -