diff --git a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx index fb562e7af..5060dac41 100644 --- a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx +++ b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx @@ -1,9 +1,8 @@ -import cn from 'classnames' import Link from 'next/link' import { FC } from 'react' import CartItem from '@components/cart/CartItem' import { Button, Text } from '@components/ui' -import { useUI } from '@components/ui/context' +import { initialState as initialUIState, useUI } from '@components/ui/context' import useCart from '@framework/cart/use-cart' import usePrice from '@framework/product/use-price' import ShippingWidget from '../ShippingWidget' @@ -12,7 +11,7 @@ import SidebarLayout from '@components/common/SidebarLayout' import s from './CheckoutSidebarView.module.css' const CheckoutSidebarView: FC = () => { - const { setSidebarView } = useUI() + const { paymentMethodDetails, setPaymentMethodDetails, setSidebarView } = useUI() const { data } = useCart() const { price: subTotal } = usePrice( @@ -38,11 +37,19 @@ const CheckoutSidebarView: FC = () => { Checkout - setSidebarView('PAYMENT_VIEW')} /> + { + if (paymentMethodDetails.paymentMethod) { + setPaymentMethodDetails(initialUIState.paymentMethodDetails) + } else { + setSidebarView('PAYMENT_VIEW') + } + }} + /> setSidebarView('SHIPPING_VIEW')} />
    - {data!.lineItems.map((item: any) => ( + {data!.lineItems?.map((item: any) => ( { - const { setSidebarView } = useUI() + const { paymentMethodDetails, setPaymentMethodDetails, setSidebarView } = useUI() + const { address } = paymentMethodDetails + const stripe = useStripe() + const elements = useElements() + + const handleSubmit = async () => { + if (!stripe || !elements) { + return + } + + const card = elements.getElement(CardNumberElement) + + const { error, paymentMethod } = await stripe.createPaymentMethod({ + type: 'card', + card + }) + + if (error) { + console.error(error) + } + + setPaymentMethodDetails({ address, paymentMethod }) + setSidebarView('CHECKOUT_VIEW') + } + + const updateAddressData = ({ target }: any) => setPaymentMethodDetails({ + ...paymentMethodDetails, + address: { + ...paymentMethodDetails.address, + [target.name]: target.value, + }, + }) return ( - setSidebarView('CHECKOUT_VIEW')}> +
    Payment Method
    - +
    @@ -42,38 +78,78 @@ const PaymentMethodView: FC = () => {
    - +
    - +
    - +
    - +
    - +
    - +
    - +
    -
    diff --git a/components/checkout/PaymentWidget/PaymentWidget.tsx b/components/checkout/PaymentWidget/PaymentWidget.tsx index e1892934e..f3e89c730 100644 --- a/components/checkout/PaymentWidget/PaymentWidget.tsx +++ b/components/checkout/PaymentWidget/PaymentWidget.tsx @@ -1,26 +1,41 @@ import { FC } from 'react' import s from './PaymentWidget.module.css' -import { ChevronRight, CreditCard } from '@components/icons' +import { ChevronRight, CreditCard, Trash } from '@components/icons' +import { useUI } from '@components/ui/context' interface ComponentProps { onClick?: () => any } const PaymentWidget: FC = ({ onClick }) => { - /* Shipping Address - Only available with checkout set to true - + const { paymentMethodDetails } = useUI() + + console.log(paymentMethodDetails) + + /* Shipping Address + Only available with checkout set to true - This means that the provider does offer checkout functionality. */ return (
    - - Add Payment Method - - {/* VISA #### #### #### 2345 */} +
    + {paymentMethodDetails?.paymentMethod ? + + {paymentMethodDetails.address.cardholderName}
    + {paymentMethodDetails.paymentMethod.card.brand.toUpperCase()} **** **** **** {paymentMethodDetails.paymentMethod.card.last4} +
    + : + Add Payment Method + } +
    - + {paymentMethodDetails?.paymentMethod ? + + : + + }
    ) diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 736ce3ce6..67276aa8b 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -84,7 +84,8 @@ const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({ } const SidebarUI: FC = () => { - const { displaySidebar, closeSidebar, sidebarView } = useUI() + const { displaySidebar, closeSidebar, sidebarView, paymentMethodDetails } = useUI() + console.log("paymentMethodDetails", paymentMethodDetails) return displaySidebar ? ( ) : null diff --git a/components/ui/context.tsx b/components/ui/context.tsx index ca2bfd7ed..490761a7a 100644 --- a/components/ui/context.tsx +++ b/components/ui/context.tsx @@ -8,15 +8,30 @@ export interface State { sidebarView: string modalView: string userAvatar: string + paymentMethodDetails: PAYMENT_METHOD_DETAILS } -const initialState = { +export const initialState = { displaySidebar: false, displayDropdown: false, displayModal: false, modalView: 'LOGIN_VIEW', sidebarView: 'CART_VIEW', userAvatar: '', + paymentMethodDetails: { + address: { + cardholderName: '', + firstName: '', + lastName: '', + company: '', + addressLine1: '', + addressLine2: '', + postalCode: '', + city: '', + countryOrRegion: '', + }, + paymentMethod: null, + }, } type Action = @@ -50,6 +65,10 @@ type Action = type: 'SET_USER_AVATAR' value: string } + | { + type: 'SET_PAYMENT_METHOD_DETAILS', + paymentMethodDetails: PAYMENT_METHOD_DETAILS + } type MODAL_VIEWS = | 'SIGNUP_VIEW' @@ -60,6 +79,11 @@ type MODAL_VIEWS = type SIDEBAR_VIEWS = 'CART_VIEW' | 'CHECKOUT_VIEW' | 'PAYMENT_METHOD_VIEW' +type PAYMENT_METHOD_DETAILS = { + address: object, + paymentMethod: object, +} + export const UIContext = React.createContext(initialState) UIContext.displayName = 'UIContext' @@ -121,6 +145,12 @@ function uiReducer(state: State, action: Action) { userAvatar: action.value, } } + case 'SET_PAYMENT_METHOD_DETAILS': { + return { + ...state, + paymentMethodDetails: action.paymentMethodDetails + } + } } } @@ -180,6 +210,11 @@ export const UIProvider: FC = (props) => { [dispatch] ) + const setPaymentMethodDetails = useCallback( + (paymentMethodDetails: PAYMENT_METHOD_DETAILS) => dispatch({ type: 'SET_PAYMENT_METHOD_DETAILS', paymentMethodDetails }), + [dispatch] + ) + const value = useMemo( () => ({ ...state, @@ -192,6 +227,7 @@ export const UIProvider: FC = (props) => { openModal, closeModal, setModalView, + setPaymentMethodDetails, setSidebarView, setUserAvatar, }), diff --git a/framework/reactioncommerce/cart/use-cart.tsx b/framework/reactioncommerce/cart/use-cart.tsx index 89ce14c70..1881f79c3 100644 --- a/framework/reactioncommerce/cart/use-cart.tsx +++ b/framework/reactioncommerce/cart/use-cart.tsx @@ -32,7 +32,7 @@ export const handler: SWRHook< Object.create(response, { isEmpty: { get() { - return (response.data?.lineItems.length ?? 0) <= 0 + return (response.data?.lineItems?.length ?? 0) <= 0 }, enumerable: true, },