mirror of
https://github.com/vercel/commerce.git
synced 2025-08-11 03:11:23 +00:00
.vscode
ISSUE_TEMPLATE
packages
site
assets
components
auth
cart
checkout
CheckoutSidebarView
CheckoutSidebarView.module.css
CheckoutSidebarView.tsx
index.ts
PaymentMethodView
PaymentWidget
ShippingMethodView
ShippingMethodWidget
ShippingView
ShippingWidget
context.tsx
common
icons
product
ui
wishlist
search.tsx
config
lib
pages
public
.env.template
.eslintrc
.gitignore
.prettierignore
.prettierrc
commerce-config.js
commerce.config.json
global.d.ts
next-env.d.ts
next.config.js
package.json
postcss.config.js
tailwind.config.js
tsconfig.json
.editorconfig
.gitignore
.prettierignore
.prettierrc
README.md
license.md
package.json
turbo.json
yarn.lock
148 lines
4.5 KiB
TypeScript
148 lines
4.5 KiB
TypeScript
import Link from 'next/link'
|
|
import { FC, useState } from 'react'
|
|
import CartItem from '@components/cart/CartItem'
|
|
import { Button, Text } from '@components/ui'
|
|
import { useUI } from '@components/ui/context'
|
|
import SidebarLayout from '@components/common/SidebarLayout'
|
|
import useCart from '@framework/cart/use-cart'
|
|
import usePrice from '@framework/product/use-price'
|
|
import useCheckout from '@framework/checkout/use-checkout'
|
|
import useSubmitCheckout from '@framework/checkout/use-submit-checkout'
|
|
import ShippingWidget from '../ShippingWidget'
|
|
import PaymentWidget from '../PaymentWidget'
|
|
import ShippingMethodWidget from '../ShippingMethodWidget'
|
|
import { useCheckoutContext } from '../context'
|
|
|
|
import s from './CheckoutSidebarView.module.css'
|
|
|
|
const CheckoutSidebarView: FC = () => {
|
|
const [loadingSubmit, setLoadingSubmit] = useState(false)
|
|
const { setSidebarView, closeSidebar } = useUI()
|
|
const { data: cartData, mutate: refreshCart } = useCart()
|
|
const { data: checkoutData } = useCheckout()
|
|
const onCheckout = useSubmitCheckout()
|
|
|
|
const { clearCheckoutFields, cardFields, addressFields } =
|
|
useCheckoutContext()
|
|
|
|
async function handleSubmit(event: React.ChangeEvent<HTMLFormElement>) {
|
|
try {
|
|
setLoadingSubmit(true)
|
|
event.preventDefault()
|
|
await onCheckout({
|
|
card: cardFields,
|
|
address: addressFields,
|
|
checkout: { cart: cartData },
|
|
})
|
|
clearCheckoutFields()
|
|
setLoadingSubmit(false)
|
|
refreshCart()
|
|
closeSidebar()
|
|
} catch {
|
|
// TODO - handle error UI here.
|
|
setLoadingSubmit(false)
|
|
}
|
|
}
|
|
|
|
const { price: subTotal } = usePrice(
|
|
cartData && {
|
|
amount: Number(cartData.subtotalPrice),
|
|
currencyCode: cartData.currency.code,
|
|
}
|
|
)
|
|
const { price: total } = usePrice(
|
|
cartData && {
|
|
amount: Number(cartData.totalPrice),
|
|
currencyCode: cartData.currency.code,
|
|
}
|
|
)
|
|
|
|
return (
|
|
<SidebarLayout
|
|
className={s.root}
|
|
handleBack={() => setSidebarView('CART_VIEW')}
|
|
>
|
|
<div className="px-4 sm:px-6 flex-1">
|
|
<Link href="/cart">
|
|
<a>
|
|
<Text variant="sectionHeading">Checkout</Text>
|
|
</a>
|
|
</Link>
|
|
|
|
<PaymentWidget
|
|
isValid={checkoutData?.hasPayment}
|
|
onClick={() => setSidebarView('PAYMENT_VIEW')}
|
|
/>
|
|
<ShippingWidget
|
|
isValid={checkoutData?.hasShipping}
|
|
onClick={() => setSidebarView('SHIPPING_VIEW')}
|
|
/>
|
|
|
|
{checkoutData?.hasShippingMethods && (
|
|
<ShippingMethodWidget
|
|
isValid={checkoutData?.hasSelectedShippingMethod}
|
|
onClick={() => setSidebarView('SHIPPING_METHOD_VIEW')}
|
|
/>
|
|
)}
|
|
|
|
<ul className={s.lineItemsList}>
|
|
{cartData!.lineItems.map((item: any) => (
|
|
<CartItem
|
|
key={item.id}
|
|
item={item}
|
|
currencyCode={cartData!.currency.code}
|
|
variant="display"
|
|
/>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
|
|
<form
|
|
onSubmit={handleSubmit}
|
|
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>
|
|
{checkoutData?.hasSelectedShippingMethod ? (
|
|
<li className="flex justify-between py-1">
|
|
<span>Shipping</span>
|
|
<span>
|
|
{cartData?.checkout?.summary.fulfillmentTotal?.displayAmount}
|
|
</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>
|
|
{/* Once data is correctly filled */}
|
|
<Button
|
|
type="submit"
|
|
width="100%"
|
|
disabled={!checkoutData?.hasPayment || !checkoutData?.hasShipping}
|
|
loading={loadingSubmit}
|
|
>
|
|
Confirm Purchase
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</SidebarLayout>
|
|
)
|
|
}
|
|
|
|
export default CheckoutSidebarView
|