mirror of
https://github.com/vercel/commerce.git
synced 2025-06-20 06:01:21 +00:00
Restricting user to add more product items than the stock has
This commit is contained in:
parent
bf0b9807e6
commit
6b49f58eaa
@ -8,7 +8,7 @@ import type { Page } from '@commerce/types/page'
|
|||||||
import { Navbar, Footer } from '@components/common'
|
import { Navbar, Footer } from '@components/common'
|
||||||
import type { Category } from '@commerce/types/site'
|
import type { Category } from '@commerce/types/site'
|
||||||
import ShippingView from '@theme/checkout/ShippingView'
|
import ShippingView from '@theme/checkout/ShippingView'
|
||||||
import CartSidebarView from '@components/cart/CartSidebarView'
|
import CartSidebarView from '@theme/cart/CartSidebarView'
|
||||||
import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
|
import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
|
||||||
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
|
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
|
||||||
import PaymentMethodView from '@components/checkout/PaymentMethodView'
|
import PaymentMethodView from '@components/checkout/PaymentMethodView'
|
||||||
|
@ -54,6 +54,7 @@ export type ProductVariant = {
|
|||||||
// The variant's depth. If a depth was not explicitly specified on the
|
// The variant's depth. If a depth was not explicitly specified on the
|
||||||
// variant, this will be the product's depth.
|
// variant, this will be the product's depth.
|
||||||
depth?: Measurement
|
depth?: Measurement
|
||||||
|
stockLevel?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shopping cart, a.k.a Checkout
|
// Shopping cart, a.k.a Checkout
|
||||||
|
@ -46,6 +46,7 @@ export function normalizeCart(order: CartFragment): Cart {
|
|||||||
sku: l.productVariant.sku,
|
sku: l.productVariant.sku,
|
||||||
price: l.discountedUnitPriceWithTax / 100,
|
price: l.discountedUnitPriceWithTax / 100,
|
||||||
listPrice: l.unitPriceWithTax / 100,
|
listPrice: l.unitPriceWithTax / 100,
|
||||||
|
stockLevel: l.productVariant.stockLevel,
|
||||||
image: {
|
image: {
|
||||||
url: l.featuredAsset?.preview + '?preset=thumb' || '',
|
url: l.featuredAsset?.preview + '?preset=thumb' || '',
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,7 @@ import commerce from '@lib/api/commerce'
|
|||||||
import { Layout } from '@components/common'
|
import { Layout } from '@components/common'
|
||||||
import { Button, Text } from '@components/ui'
|
import { Button, Text } from '@components/ui'
|
||||||
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
|
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
|
||||||
import { CartItem } from '@components/cart'
|
import { CartItem } from '@theme/cart'
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
|
32
theme/dap/cart/CartItem/CartItem.module.css
Normal file
32
theme/dap/cart/CartItem/CartItem.module.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.root {
|
||||||
|
@apply flex flex-col py-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity {
|
||||||
|
appearance: textfield;
|
||||||
|
@apply w-8 border-accent-2 border mx-3 rounded text-center text-sm text-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity::-webkit-outer-spin-button,
|
||||||
|
.quantity::-webkit-inner-spin-button {
|
||||||
|
@apply appearance-none m-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.productImage {
|
||||||
|
position: absolute;
|
||||||
|
transform: scale(1.9);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 30% !important;
|
||||||
|
top: 30% !important;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.productName {
|
||||||
|
@apply font-medium cursor-pointer pb-1;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
152
theme/dap/cart/CartItem/CartItem.tsx
Normal file
152
theme/dap/cart/CartItem/CartItem.tsx
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { ChangeEvent, FocusEventHandler, useEffect, useState } from 'react'
|
||||||
|
import cn from 'classnames'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import s from './CartItem.module.css'
|
||||||
|
import { Trash, Plus, Minus, Cross } from '@components/icons'
|
||||||
|
import { useUI } from '@components/ui/context'
|
||||||
|
import type { LineItem } from '@commerce/types/cart'
|
||||||
|
import usePrice from '@framework/product/use-price'
|
||||||
|
import useUpdateItem from '@framework/cart/use-update-item'
|
||||||
|
import useRemoveItem from '@framework/cart/use-remove-item'
|
||||||
|
import Quantity from '@components/ui/Quantity'
|
||||||
|
|
||||||
|
type ItemOption = {
|
||||||
|
name: string
|
||||||
|
nameId: number
|
||||||
|
value: string
|
||||||
|
valueId: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const CartItem = ({
|
||||||
|
item,
|
||||||
|
variant = 'default',
|
||||||
|
currencyCode,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
variant?: 'default' | 'display'
|
||||||
|
item: LineItem
|
||||||
|
currencyCode: string
|
||||||
|
}) => {
|
||||||
|
const { closeSidebarIfPresent } = useUI()
|
||||||
|
const [removing, setRemoving] = useState(false)
|
||||||
|
const [quantity, setQuantity] = useState<number>(item.quantity)
|
||||||
|
const removeItem = useRemoveItem()
|
||||||
|
const updateItem = useUpdateItem({ item })
|
||||||
|
|
||||||
|
const { price } = usePrice({
|
||||||
|
amount: item.variant.price * item.quantity,
|
||||||
|
baseAmount: item.variant.listPrice * item.quantity,
|
||||||
|
currencyCode,
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChange = async ({
|
||||||
|
target: { value },
|
||||||
|
}: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setQuantity(Number(value))
|
||||||
|
await updateItem({ quantity: Number(value) })
|
||||||
|
}
|
||||||
|
|
||||||
|
const increaseQuantity = async (n = 1) => {
|
||||||
|
const val = Number(quantity) + n
|
||||||
|
setQuantity(val)
|
||||||
|
await updateItem({ quantity: val })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRemove = async () => {
|
||||||
|
setRemoving(true)
|
||||||
|
try {
|
||||||
|
await removeItem(item)
|
||||||
|
} catch (error) {
|
||||||
|
setRemoving(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add a type for this
|
||||||
|
const options = (item as any).options
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Reset the quantity state if the item quantity changes
|
||||||
|
if (item.quantity !== Number(quantity)) {
|
||||||
|
setQuantity(item.quantity)
|
||||||
|
}
|
||||||
|
}, [item.quantity])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
className={cn(s.root, {
|
||||||
|
'opacity-50 pointer-events-none': removing,
|
||||||
|
})}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<div className="flex flex-row space-x-4 py-4">
|
||||||
|
<div className="w-16 h-16 bg-violet relative overflow-hidden cursor-pointer z-0">
|
||||||
|
<Link href={`/product/${item.path}`}>
|
||||||
|
<Image
|
||||||
|
onClick={() => closeSidebarIfPresent()}
|
||||||
|
className={s.productImage}
|
||||||
|
width={150}
|
||||||
|
height={150}
|
||||||
|
src={item.variant.image!.url}
|
||||||
|
alt={item.variant.image!.altText}
|
||||||
|
unoptimized
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1 flex flex-col text-base">
|
||||||
|
<Link href={`/product/${item.path}`}>
|
||||||
|
<span
|
||||||
|
className={s.productName}
|
||||||
|
onClick={() => closeSidebarIfPresent()}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
{options && options.length > 0 && (
|
||||||
|
<div className="flex items-center pb-1">
|
||||||
|
{options.map((option: ItemOption, i: number) => (
|
||||||
|
<div
|
||||||
|
key={`${item.id}-${option.name}`}
|
||||||
|
className="text-sm font-semibold text-accent-7 inline-flex items-center justify-center"
|
||||||
|
>
|
||||||
|
{option.name}
|
||||||
|
{option.name === 'Color' ? (
|
||||||
|
<span
|
||||||
|
className="mx-2 rounded-full bg-transparent border w-5 h-5 p-1 text-accent-9 inline-flex items-center justify-center overflow-hidden"
|
||||||
|
style={{
|
||||||
|
backgroundColor: `${option.value}`,
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
) : (
|
||||||
|
<span className="mx-2 rounded-full bg-transparent border h-5 p-1 text-accent-9 inline-flex items-center justify-center overflow-hidden">
|
||||||
|
{option.value}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{i === options.length - 1 ? '' : <span className="mr-3" />}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{variant === 'display' && (
|
||||||
|
<div className="text-sm tracking-wider">{quantity}x</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col justify-between space-y-2 text-sm">
|
||||||
|
<span>{price}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{variant === 'default' && (
|
||||||
|
<Quantity
|
||||||
|
value={quantity}
|
||||||
|
handleRemove={handleRemove}
|
||||||
|
handleChange={handleChange}
|
||||||
|
increase={() => increaseQuantity(1)}
|
||||||
|
decrease={() => increaseQuantity(-1)}
|
||||||
|
max={Number(item.variant.stockLevel)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CartItem
|
1
theme/dap/cart/CartItem/index.ts
Normal file
1
theme/dap/cart/CartItem/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './CartItem'
|
11
theme/dap/cart/CartSidebarView/CartSidebarView.module.css
Normal file
11
theme/dap/cart/CartSidebarView/CartSidebarView.module.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.root {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root.empty {
|
||||||
|
@apply bg-secondary text-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lineItemsList {
|
||||||
|
@apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2;
|
||||||
|
}
|
129
theme/dap/cart/CartSidebarView/CartSidebarView.tsx
Normal file
129
theme/dap/cart/CartSidebarView/CartSidebarView.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import cn from 'classnames'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { FC } from 'react'
|
||||||
|
import s from './CartSidebarView.module.css'
|
||||||
|
import CartItem from '../CartItem'
|
||||||
|
import { Button, Text } from '@components/ui'
|
||||||
|
import { useUI } from '@components/ui/context'
|
||||||
|
import { Bag, Cross, Check } from '@components/icons'
|
||||||
|
import useCart from '@framework/cart/use-cart'
|
||||||
|
import usePrice from '@framework/product/use-price'
|
||||||
|
import SidebarLayout from '@components/common/SidebarLayout'
|
||||||
|
|
||||||
|
const CartSidebarView: FC = () => {
|
||||||
|
const { closeSidebar, setSidebarView } = useUI()
|
||||||
|
const { data, isLoading, isEmpty } = useCart()
|
||||||
|
|
||||||
|
const { price: subTotal } = usePrice(
|
||||||
|
data && {
|
||||||
|
amount: Number(data.subtotalPrice),
|
||||||
|
currencyCode: data.currency.code,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const { price: total } = usePrice(
|
||||||
|
data && {
|
||||||
|
amount: Number(data.totalPrice),
|
||||||
|
currencyCode: data.currency.code,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const handleClose = () => closeSidebar()
|
||||||
|
const goToCheckout = () => setSidebarView('CHECKOUT_VIEW')
|
||||||
|
|
||||||
|
const error = null
|
||||||
|
const success = null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarLayout
|
||||||
|
className={cn({
|
||||||
|
[s.empty]: error || success || isLoading || isEmpty,
|
||||||
|
})}
|
||||||
|
handleClose={handleClose}
|
||||||
|
>
|
||||||
|
{isLoading || isEmpty ? (
|
||||||
|
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||||
|
<span className="border border-dashed border-primary rounded-full flex items-center justify-center w-16 h-16 p-12 bg-secondary text-secondary">
|
||||||
|
<Bag className="absolute" />
|
||||||
|
</span>
|
||||||
|
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
|
||||||
|
Your cart is empty
|
||||||
|
</h2>
|
||||||
|
<p className="text-accent-3 px-10 text-center pt-2">
|
||||||
|
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : error ? (
|
||||||
|
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||||
|
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
|
||||||
|
<Cross width={24} height={24} />
|
||||||
|
</span>
|
||||||
|
<h2 className="pt-6 text-xl font-light text-center">
|
||||||
|
We couldn’t process the purchase. Please check your card information
|
||||||
|
and try again.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
) : success ? (
|
||||||
|
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||||
|
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
|
||||||
|
<Check />
|
||||||
|
</span>
|
||||||
|
<h2 className="pt-6 text-xl font-light text-center">
|
||||||
|
Thank you for your order.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="px-4 sm:px-6 flex-1">
|
||||||
|
<Link href="/cart">
|
||||||
|
<Text variant="sectionHeading" onClick={handleClose}>
|
||||||
|
My Cart
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
|
<ul className={s.lineItemsList}>
|
||||||
|
{data!.lineItems.map((item: any) => (
|
||||||
|
<CartItem
|
||||||
|
key={item.id}
|
||||||
|
item={item}
|
||||||
|
currencyCode={data!.currency.code}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex-shrink-0 px-6 py-6 sm:px-6 sticky z-20 bottom-0 w-full right-0 left-0 bg-accent-0 border-t text-sm">
|
||||||
|
<ul className="pb-2">
|
||||||
|
<li className="flex justify-between py-1">
|
||||||
|
<span>Subtotal</span>
|
||||||
|
<span>{subTotal}</span>
|
||||||
|
</li>
|
||||||
|
<li className="flex justify-between py-1">
|
||||||
|
<span>Taxes</span>
|
||||||
|
<span>Calculated at checkout</span>
|
||||||
|
</li>
|
||||||
|
<li className="flex justify-between py-1">
|
||||||
|
<span>Shipping</span>
|
||||||
|
<span className="font-bold tracking-wide">FREE</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-2">
|
||||||
|
<span>Total</span>
|
||||||
|
<span>{total}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED ? (
|
||||||
|
<Button Component="a" width="100%" onClick={goToCheckout}>
|
||||||
|
Proceed to Checkout ({total})
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button href="/checkout" Component="a" width="100%">
|
||||||
|
Proceed to Checkout
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</SidebarLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CartSidebarView
|
1
theme/dap/cart/CartSidebarView/index.ts
Normal file
1
theme/dap/cart/CartSidebarView/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './CartSidebarView'
|
2
theme/dap/cart/index.ts
Normal file
2
theme/dap/cart/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { default as CartSidebarView } from './CartSidebarView'
|
||||||
|
export { default as CartItem } from './CartItem'
|
@ -17,7 +17,7 @@ import request from '@commerce/utils/request'
|
|||||||
const CheckoutSidebarView: FC = () => {
|
const CheckoutSidebarView: FC = () => {
|
||||||
const { setSidebarView, closeSidebarIfPresent } = useUI()
|
const { setSidebarView, closeSidebarIfPresent } = useUI()
|
||||||
const { data } = useCart()
|
const { data } = useCart()
|
||||||
|
console.log(data, 555)
|
||||||
const { price: subTotal } = usePrice(
|
const { price: subTotal } = usePrice(
|
||||||
data && {
|
data && {
|
||||||
amount: Number(data.subtotalPrice),
|
amount: Number(data.subtotalPrice),
|
||||||
@ -109,12 +109,17 @@ const CheckoutSidebarView: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{/* Once data is correcly filled */}
|
{/* Once data is correcly filled */}
|
||||||
|
{data?.customerId ? (
|
||||||
<Button Component="a" width="100%" onClick={handleConfirmPurchase}>
|
<Button Component="a" width="100%" onClick={handleConfirmPurchase}>
|
||||||
Confirm Purchase
|
Confirm Purchase
|
||||||
</Button>
|
</Button>
|
||||||
{/* <Button Component="a" width="100%" variant="ghost" disabled>
|
) : (
|
||||||
|
<Button Component="a" width="100%" variant="ghost" disabled>
|
||||||
Continue
|
Continue
|
||||||
</Button> */}
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SidebarLayout>
|
</SidebarLayout>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { FC, useState } from 'react'
|
import { FC, useState, useCallback, useEffect } from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import s from './ShippingView.module.css'
|
import s from './ShippingView.module.css'
|
||||||
import { Button, Input } from '@components/ui'
|
import { Button, Input } from '@components/ui'
|
||||||
import { useUI } from '@components/ui/context'
|
import { useUI } from '@components/ui/context'
|
||||||
import SidebarLayout from '@components/common/SidebarLayout'
|
import SidebarLayout from '@components/common/SidebarLayout'
|
||||||
|
|
||||||
|
import { validate } from 'email-validator'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-customer-for-order-mutation'
|
import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-customer-for-order-mutation'
|
||||||
import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set-order-shipping-address-mutation'
|
import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set-order-shipping-address-mutation'
|
||||||
@ -19,7 +20,7 @@ const PaymentMethodView: FC = () => {
|
|||||||
const [streetDetails, setStreetDetails] = useState('')
|
const [streetDetails, setStreetDetails] = useState('')
|
||||||
const [apartmentDetails, setApartmentDetails] = useState('')
|
const [apartmentDetails, setApartmentDetails] = useState('')
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [disabled, setDisabled] = useState(true)
|
||||||
const { setSidebarView } = useUI()
|
const { setSidebarView } = useUI()
|
||||||
|
|
||||||
const setCustomerForOrder = async () => {
|
const setCustomerForOrder = async () => {
|
||||||
@ -54,10 +55,30 @@ const PaymentMethodView: FC = () => {
|
|||||||
})
|
})
|
||||||
console.log(data, 222)
|
console.log(data, 222)
|
||||||
}
|
}
|
||||||
|
const handleValidation = useCallback(
|
||||||
|
() => {
|
||||||
|
|
||||||
|
setDisabled(
|
||||||
|
!validate(email)
|
||||||
|
|| firstName.length < 3
|
||||||
|
|| lastName.length < 3
|
||||||
|
|| phoneNumber.length < 6
|
||||||
|
|| streetDetails.length < 5
|
||||||
|
)
|
||||||
|
},
|
||||||
|
[
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
phoneNumber,
|
||||||
|
email,
|
||||||
|
streetDetails,
|
||||||
|
apartmentDetails
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
const handleAddShippingAddress = async (e: React.SyntheticEvent<EventTarget>) => {
|
const handleAddShippingAddress = async (e: React.SyntheticEvent<EventTarget>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
handleValidation()
|
||||||
console.log('Handle Add Shipping Address')
|
console.log('Handle Add Shipping Address')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -71,6 +92,10 @@ const PaymentMethodView: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
handleValidation()
|
||||||
|
}, [handleValidation])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
|
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
|
||||||
<form
|
<form
|
||||||
@ -143,6 +168,7 @@ const PaymentMethodView: FC = () => {
|
|||||||
type="submit"
|
type="submit"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
width="100%"
|
width="100%"
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
Continue
|
Continue
|
||||||
</Button>
|
</Button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user