mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 12:24:18 +00:00
✨ feat: set shipping method
:%s
This commit is contained in:
7
framework/vendure/schema.d.ts
vendored
7
framework/vendure/schema.d.ts
vendored
@@ -377,6 +377,13 @@ export type SetShippingMethodMutation = {
|
||||
| Pick<NoActiveOrderError, 'errorCode' | 'message'>;
|
||||
};
|
||||
|
||||
|
||||
export type GetEligibleMethodsQuery = {
|
||||
eligibleShippingMethods: Array<
|
||||
Pick<ShippingMethodQuote, 'id' | 'name' | 'description' | 'price' | 'priceWithTax' | 'metadata'>
|
||||
>;
|
||||
};
|
||||
|
||||
export type Asset = Node & {
|
||||
__typename?: 'Asset'
|
||||
id: Scalars['ID']
|
||||
|
@@ -0,0 +1,13 @@
|
||||
export const getEligibleShippingMethods = /* GraphQL */ `
|
||||
query getEligibleShippingMethods {
|
||||
eligibleShippingMethods {
|
||||
id
|
||||
name
|
||||
description
|
||||
price
|
||||
priceWithTax
|
||||
metadata
|
||||
__typename
|
||||
}
|
||||
}
|
||||
`
|
@@ -3,3 +3,6 @@ export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddr
|
||||
export { default as useApplyCouponCode } from './useApplyCouponCode'
|
||||
export { default as useAvailableCountries } from './useAvailableCountries'
|
||||
export { default as useSetOrderShippingMethod } from './useSetOrderShippingMethod'
|
||||
export { default as useGetActiveOrderForCheckout } from './useGetActiveOrderForCheckout'
|
||||
export { default as useEligibleShippingMethods } from './useEligibleShippingMethods'
|
||||
|
||||
|
@@ -3,13 +3,13 @@ import { applyCouponCodeMutation } from '@framework/utils/mutations/apply-coupon
|
||||
import { useState } from 'react'
|
||||
import { CommonError } from 'src/domains/interfaces/CommonError'
|
||||
import rawFetcher from 'src/utils/rawFetcher'
|
||||
import { useGetActiveOrder } from '../cart'
|
||||
import { useGetActiveOrderForCheckout } from '.'
|
||||
|
||||
|
||||
const useApplyCouponCode = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<CommonError | null>(null)
|
||||
const { mutate } = useGetActiveOrder()
|
||||
const { mutate } = useGetActiveOrderForCheckout()
|
||||
|
||||
const applyCouponCode = (couponCode: string,
|
||||
fCallBack: (isSuccess: boolean, message?: string) => void
|
||||
|
14
src/components/hooks/order/useEligibleShippingMethods.tsx
Normal file
14
src/components/hooks/order/useEligibleShippingMethods.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { GetEligibleMethodsQuery, ShippingMethodQuote } from '@framework/schema'
|
||||
import { getEligibleShippingMethods } from '@framework/utils/queries/eligible-shipping-methods-query'
|
||||
import gglFetcher from 'src/utils/gglFetcher'
|
||||
import useSWR from 'swr'
|
||||
|
||||
const useEligibleShippingMethods = () => {
|
||||
const { data, isValidating } = useSWR<GetEligibleMethodsQuery>([getEligibleShippingMethods], gglFetcher)
|
||||
return {
|
||||
eligibleShippingMethods: data?.eligibleShippingMethods as ShippingMethodQuote[],
|
||||
loading: isValidating,
|
||||
}
|
||||
}
|
||||
|
||||
export default useEligibleShippingMethods
|
@@ -3,13 +3,13 @@ import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-cust
|
||||
import { useState } from 'react'
|
||||
import { CommonError } from 'src/domains/interfaces/CommonError'
|
||||
import rawFetcher from 'src/utils/rawFetcher'
|
||||
import { useGetActiveOrder } from '../cart'
|
||||
import { useGetActiveOrderForCheckout } from '.'
|
||||
|
||||
|
||||
const useSetCustomerForOrder = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<CommonError | null>(null)
|
||||
const { mutate } = useGetActiveOrder()
|
||||
const { mutate } = useGetActiveOrderForCheckout()
|
||||
|
||||
const setCustomerForOrder = (input: CreateCustomerInput,
|
||||
fCallBack: (isSuccess: boolean, message?: CommonError) => void
|
||||
|
@@ -3,13 +3,13 @@ import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set-
|
||||
import { useState } from 'react'
|
||||
import { CommonError } from 'src/domains/interfaces/CommonError'
|
||||
import rawFetcher from 'src/utils/rawFetcher'
|
||||
import { useGetActiveOrder } from '../cart'
|
||||
import { useGetActiveOrderForCheckout } from '.'
|
||||
|
||||
|
||||
const useSetOrderShippingAddress = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<CommonError | null>(null)
|
||||
const { mutate } = useGetActiveOrder()
|
||||
const { mutate } = useGetActiveOrderForCheckout()
|
||||
|
||||
const setOrderShippingAddress = (input: CreateAddressInput,
|
||||
fCallBack: (isSuccess: boolean, message?: string) => void
|
||||
@@ -21,7 +21,6 @@ const useSetOrderShippingAddress = () => {
|
||||
variables: { input },
|
||||
})
|
||||
.then(({ data }) => {
|
||||
console.log("data: ", data)
|
||||
if (data.setOrderShippingAddress.__typename === 'Order') {
|
||||
fCallBack(true)
|
||||
mutate()
|
||||
|
@@ -3,13 +3,13 @@ import { setShippingMethodMutation } from '@framework/utils/mutations/set-order-
|
||||
import { useState } from 'react'
|
||||
import { CommonError } from 'src/domains/interfaces/CommonError'
|
||||
import rawFetcher from 'src/utils/rawFetcher'
|
||||
import { useGetActiveOrder } from '../cart'
|
||||
import { useGetActiveOrderForCheckout } from '.'
|
||||
|
||||
|
||||
const useSetOrderShippingMethod = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<CommonError | null>(null)
|
||||
const { mutate } = useGetActiveOrder()
|
||||
const { mutate } = useGetActiveOrderForCheckout()
|
||||
|
||||
const setOrderShippingMethod = (id: string,
|
||||
fCallBack: (isSuccess: boolean, message?: string) => void
|
||||
|
@@ -8,7 +8,6 @@ import s from './CheckoutBill.module.scss'
|
||||
import FormPromotionCode from './FormPromotionCode/FormPromotionCode'
|
||||
|
||||
interface CheckoutBillProps {
|
||||
// data: CardItemCheckoutProps[]
|
||||
data: CartCheckout | null
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
|
||||
import { Logo } from 'src/components/common'
|
||||
import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
|
||||
import { useActiveCustomer } from 'src/components/hooks/auth'
|
||||
import useGetActiveOrderForCheckout from 'src/components/hooks/order/useGetActiveOrderForCheckout'
|
||||
import { useGetActiveOrderForCheckout } from 'src/components/hooks/order'
|
||||
import s from './CheckoutInfo.module.scss'
|
||||
import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm'
|
||||
import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm'
|
||||
@@ -25,7 +25,6 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
|
||||
const [doneSteps, setDoneSteps] = useState<CheckoutStep[]>([])
|
||||
const { order } = useGetActiveOrderForCheckout()
|
||||
const { customer } = useActiveCustomer()
|
||||
console.log("active order checkout: ", order)
|
||||
|
||||
useEffect(() => {
|
||||
if (customer) {
|
||||
@@ -91,6 +90,9 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
|
||||
return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}`
|
||||
}
|
||||
return ''
|
||||
case CheckoutStep.ShippingMethodInfo:
|
||||
console.log('oder here: ', order?.shippingLine)
|
||||
return `${order?.shippingLine.shippingMethod.name}, ${order?.shippingLine.priceWithTax ? `${order?.shippingLine.priceWithTax} ${currency}`: 'Free'}` || ''
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
@@ -105,7 +107,7 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
|
||||
{
|
||||
id: CheckoutStep.ShippingAddressInfo,
|
||||
title: 'Shipping Address Information',
|
||||
form: <ShippingInfoForm onConfirm={onConfirm} id={CheckoutStep.ShippingAddressInfo} activeStep={activeStep}/>,
|
||||
form: <ShippingInfoForm onConfirm={onConfirm} id={CheckoutStep.ShippingAddressInfo} activeStep={activeStep} />,
|
||||
},
|
||||
{
|
||||
id: CheckoutStep.ShippingMethodInfo,
|
||||
|
@@ -19,21 +19,10 @@
|
||||
}
|
||||
|
||||
.options {
|
||||
@apply absolute transition-all duration-200 overflow-hidden;
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
margin-top: 0.8rem;
|
||||
top: 6rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: var(--white);
|
||||
border: 1px solid var(--border-line);
|
||||
border-radius: 0.8rem;
|
||||
&.show {
|
||||
z-index: 10;
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
position: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,31 +1,12 @@
|
||||
import { ShippingMethodQuote } from '@framework/schema'
|
||||
import classNames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { useMessage } from 'src/components/contexts'
|
||||
import { useSetOrderShippingMethod } from 'src/components/hooks/order'
|
||||
import { useEligibleShippingMethods, useSetOrderShippingMethod } from 'src/components/hooks/order'
|
||||
import { Shipping } from 'src/components/icons'
|
||||
import { CheckoutStep } from '../../CheckoutInfo'
|
||||
import s from './ShippingMethod.module.scss'
|
||||
import ShippingMethodItem from './ShippingMethodItem/ShippingMethodItem'
|
||||
|
||||
const MOCKUP_DATA = [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Standard Shipping",
|
||||
"description": "",
|
||||
"price": 0,
|
||||
"priceWithTax": 0,
|
||||
"code": "standard-shipping"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Express Shipping",
|
||||
"description": "",
|
||||
"price": 1000,
|
||||
"priceWithTax": 1000,
|
||||
"code": "express-shipping"
|
||||
}
|
||||
]
|
||||
interface Props {
|
||||
currency: string
|
||||
onConfirm: (id: number) => void
|
||||
@@ -33,20 +14,19 @@ interface Props {
|
||||
}
|
||||
|
||||
const ShippingMethod = memo(({ currency, onConfirm }: Props) => {
|
||||
const { eligibleShippingMethods } = useEligibleShippingMethods()
|
||||
const { setOrderShippingMethod } = useSetOrderShippingMethod()
|
||||
const [selectedValue, setSelectedValue] = useState<ShippingMethodQuote>(MOCKUP_DATA[0])
|
||||
const [selectedValue, setSelectedValue] = useState<ShippingMethodQuote | undefined>(eligibleShippingMethods ? eligibleShippingMethods[0] : undefined)
|
||||
const { showMessageError } = useMessage()
|
||||
const [isShowOptions, setIsShowOptions] = useState<boolean>(true)
|
||||
|
||||
const onChange = (id: string) => {
|
||||
const newValue = MOCKUP_DATA.find(item => item.id === id)
|
||||
const newValue = eligibleShippingMethods?.find(item => item.id === id)
|
||||
if (newValue) {
|
||||
setSelectedValue(newValue)
|
||||
if (newValue?.id) {
|
||||
setOrderShippingMethod(newValue?.id, onSubmitCalBack)
|
||||
}
|
||||
}
|
||||
setIsShowOptions(false)
|
||||
}
|
||||
|
||||
const onSubmitCalBack = (isSuccess: boolean, msg?: string) => {
|
||||
@@ -57,31 +37,26 @@ const ShippingMethod = memo(({ currency, onConfirm }: Props) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onCollapseOptions = () => {
|
||||
setIsShowOptions(!isShowOptions)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={s.shippingMethod}>
|
||||
<div className={s.method} onClick={onCollapseOptions}>
|
||||
<div className={s.method}>
|
||||
<div className={s.left}>
|
||||
<div className={s.icon}>
|
||||
<Shipping />
|
||||
</div>
|
||||
<div className={s.name}>
|
||||
{selectedValue.name}
|
||||
{selectedValue?.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className={s.right}>
|
||||
<div className={s.price}>
|
||||
{selectedValue.price ? `${selectedValue.price / 100} ${currency}` : "Free"}
|
||||
{selectedValue?.price ? `${selectedValue?.price / 100} ${currency}` : "Free"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classNames(s.options, { [s.show]: isShowOptions })}>
|
||||
<div className={s.options}>
|
||||
<ul>
|
||||
{MOCKUP_DATA.map(item => <ShippingMethodItem
|
||||
{eligibleShippingMethods?.map(item => <ShippingMethodItem
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
name={item.name}
|
||||
|
@@ -2,7 +2,7 @@ import classNames from 'classnames'
|
||||
import React, { useState } from 'react'
|
||||
import { MessageCommon } from 'src/components/common'
|
||||
import { useMessage } from 'src/components/contexts'
|
||||
import useGetActiveOrderForCheckout from 'src/components/hooks/order/useGetActiveOrderForCheckout'
|
||||
import { useGetActiveOrderForCheckout } from 'src/components/hooks/order'
|
||||
import IconHide from 'src/components/icons/IconHide'
|
||||
import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data'
|
||||
import { CheckoutBill, CheckoutInfo } from '..'
|
||||
@@ -24,7 +24,7 @@ const CheckoutPage = ({ }: CheckoutPageProps) => {
|
||||
return (
|
||||
<div className={s.warrper}>
|
||||
<MessageCommon messages={messages} onRemove={removeMessage} />
|
||||
<div className={s.left}><CheckoutInfo onViewCart={onViewCart} currency={order?.currency.code}/></div>
|
||||
<div className={s.left}><CheckoutInfo onViewCart={onViewCart} currency={order?.currency.code} /></div>
|
||||
<div className={s.right}><CheckoutBill data={order} /></div>
|
||||
<div className={classNames({ [s.mobile]: true, [s.isShow]: isShow })}>
|
||||
<div className={s.modal}>
|
||||
|
Reference in New Issue
Block a user