feat: set shipping method

:%s
This commit is contained in:
lytrankieio123
2021-10-21 10:20:17 +07:00
parent 357e700e32
commit 6b397fc153
13 changed files with 61 additions and 60 deletions

View File

@@ -377,6 +377,13 @@ export type SetShippingMethodMutation = {
| Pick<NoActiveOrderError, 'errorCode' | 'message'>; | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
}; };
export type GetEligibleMethodsQuery = {
eligibleShippingMethods: Array<
Pick<ShippingMethodQuote, 'id' | 'name' | 'description' | 'price' | 'priceWithTax' | 'metadata'>
>;
};
export type Asset = Node & { export type Asset = Node & {
__typename?: 'Asset' __typename?: 'Asset'
id: Scalars['ID'] id: Scalars['ID']

View File

@@ -0,0 +1,13 @@
export const getEligibleShippingMethods = /* GraphQL */ `
query getEligibleShippingMethods {
eligibleShippingMethods {
id
name
description
price
priceWithTax
metadata
__typename
}
}
`

View File

@@ -3,3 +3,6 @@ export { default as useSetOrderShippingAddress } from './useSetOrderShippingAddr
export { default as useApplyCouponCode } from './useApplyCouponCode' export { default as useApplyCouponCode } from './useApplyCouponCode'
export { default as useAvailableCountries } from './useAvailableCountries' export { default as useAvailableCountries } from './useAvailableCountries'
export { default as useSetOrderShippingMethod } from './useSetOrderShippingMethod' export { default as useSetOrderShippingMethod } from './useSetOrderShippingMethod'
export { default as useGetActiveOrderForCheckout } from './useGetActiveOrderForCheckout'
export { default as useEligibleShippingMethods } from './useEligibleShippingMethods'

View File

@@ -3,13 +3,13 @@ import { applyCouponCodeMutation } from '@framework/utils/mutations/apply-coupon
import { useState } from 'react' import { useState } from 'react'
import { CommonError } from 'src/domains/interfaces/CommonError' import { CommonError } from 'src/domains/interfaces/CommonError'
import rawFetcher from 'src/utils/rawFetcher' import rawFetcher from 'src/utils/rawFetcher'
import { useGetActiveOrder } from '../cart' import { useGetActiveOrderForCheckout } from '.'
const useApplyCouponCode = () => { const useApplyCouponCode = () => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<CommonError | null>(null) const [error, setError] = useState<CommonError | null>(null)
const { mutate } = useGetActiveOrder() const { mutate } = useGetActiveOrderForCheckout()
const applyCouponCode = (couponCode: string, const applyCouponCode = (couponCode: string,
fCallBack: (isSuccess: boolean, message?: string) => void fCallBack: (isSuccess: boolean, message?: string) => void

View 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

View File

@@ -3,13 +3,13 @@ import { setCustomerForOrderMutation } from '@framework/utils/mutations/set-cust
import { useState } from 'react' import { useState } from 'react'
import { CommonError } from 'src/domains/interfaces/CommonError' import { CommonError } from 'src/domains/interfaces/CommonError'
import rawFetcher from 'src/utils/rawFetcher' import rawFetcher from 'src/utils/rawFetcher'
import { useGetActiveOrder } from '../cart' import { useGetActiveOrderForCheckout } from '.'
const useSetCustomerForOrder = () => { const useSetCustomerForOrder = () => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<CommonError | null>(null) const [error, setError] = useState<CommonError | null>(null)
const { mutate } = useGetActiveOrder() const { mutate } = useGetActiveOrderForCheckout()
const setCustomerForOrder = (input: CreateCustomerInput, const setCustomerForOrder = (input: CreateCustomerInput,
fCallBack: (isSuccess: boolean, message?: CommonError) => void fCallBack: (isSuccess: boolean, message?: CommonError) => void

View File

@@ -3,13 +3,13 @@ import { setOrderShippingAddressMutation } from '@framework/utils/mutations/set-
import { useState } from 'react' import { useState } from 'react'
import { CommonError } from 'src/domains/interfaces/CommonError' import { CommonError } from 'src/domains/interfaces/CommonError'
import rawFetcher from 'src/utils/rawFetcher' import rawFetcher from 'src/utils/rawFetcher'
import { useGetActiveOrder } from '../cart' import { useGetActiveOrderForCheckout } from '.'
const useSetOrderShippingAddress = () => { const useSetOrderShippingAddress = () => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<CommonError | null>(null) const [error, setError] = useState<CommonError | null>(null)
const { mutate } = useGetActiveOrder() const { mutate } = useGetActiveOrderForCheckout()
const setOrderShippingAddress = (input: CreateAddressInput, const setOrderShippingAddress = (input: CreateAddressInput,
fCallBack: (isSuccess: boolean, message?: string) => void fCallBack: (isSuccess: boolean, message?: string) => void
@@ -21,7 +21,6 @@ const useSetOrderShippingAddress = () => {
variables: { input }, variables: { input },
}) })
.then(({ data }) => { .then(({ data }) => {
console.log("data: ", data)
if (data.setOrderShippingAddress.__typename === 'Order') { if (data.setOrderShippingAddress.__typename === 'Order') {
fCallBack(true) fCallBack(true)
mutate() mutate()

View File

@@ -3,13 +3,13 @@ import { setShippingMethodMutation } from '@framework/utils/mutations/set-order-
import { useState } from 'react' import { useState } from 'react'
import { CommonError } from 'src/domains/interfaces/CommonError' import { CommonError } from 'src/domains/interfaces/CommonError'
import rawFetcher from 'src/utils/rawFetcher' import rawFetcher from 'src/utils/rawFetcher'
import { useGetActiveOrder } from '../cart' import { useGetActiveOrderForCheckout } from '.'
const useSetOrderShippingMethod = () => { const useSetOrderShippingMethod = () => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<CommonError | null>(null) const [error, setError] = useState<CommonError | null>(null)
const { mutate } = useGetActiveOrder() const { mutate } = useGetActiveOrderForCheckout()
const setOrderShippingMethod = (id: string, const setOrderShippingMethod = (id: string,
fCallBack: (isSuccess: boolean, message?: string) => void fCallBack: (isSuccess: boolean, message?: string) => void

View File

@@ -8,7 +8,6 @@ import s from './CheckoutBill.module.scss'
import FormPromotionCode from './FormPromotionCode/FormPromotionCode' import FormPromotionCode from './FormPromotionCode/FormPromotionCode'
interface CheckoutBillProps { interface CheckoutBillProps {
// data: CardItemCheckoutProps[]
data: CartCheckout | null data: CartCheckout | null
} }

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { Logo } from 'src/components/common' import { Logo } from 'src/components/common'
import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse' import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
import { useActiveCustomer } from 'src/components/hooks/auth' 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 s from './CheckoutInfo.module.scss'
import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm' import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm'
import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm' import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm'
@@ -25,7 +25,6 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
const [doneSteps, setDoneSteps] = useState<CheckoutStep[]>([]) const [doneSteps, setDoneSteps] = useState<CheckoutStep[]>([])
const { order } = useGetActiveOrderForCheckout() const { order } = useGetActiveOrderForCheckout()
const { customer } = useActiveCustomer() const { customer } = useActiveCustomer()
console.log("active order checkout: ", order)
useEffect(() => { useEffect(() => {
if (customer) { if (customer) {
@@ -91,6 +90,9 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}` return `${streetLine1}, ${city}, ${province}, ${postalCode}, ${countryCode}, ${phoneNumber}`
} }
return '' return ''
case CheckoutStep.ShippingMethodInfo:
console.log('oder here: ', order?.shippingLine)
return `${order?.shippingLine.shippingMethod.name}, ${order?.shippingLine.priceWithTax ? `${order?.shippingLine.priceWithTax} ${currency}`: 'Free'}` || ''
default: default:
return "" return ""
} }
@@ -105,7 +107,7 @@ const CheckoutInfo = ({ onViewCart, currency = "" }: CheckoutInfoProps) => {
{ {
id: CheckoutStep.ShippingAddressInfo, id: CheckoutStep.ShippingAddressInfo,
title: 'Shipping Address Information', 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, id: CheckoutStep.ShippingMethodInfo,

View File

@@ -19,21 +19,10 @@
} }
.options { .options {
@apply absolute transition-all duration-200 overflow-hidden;
transform: translateX(-100%);
opacity: 0;
margin-top: 0.8rem; margin-top: 0.8rem;
top: 6rem;
left: 0;
width: 100%; width: 100%;
background: var(--white); background: var(--white);
border: 1px solid var(--border-line); border: 1px solid var(--border-line);
border-radius: 0.8rem; border-radius: 0.8rem;
&.show {
z-index: 10;
opacity: 1;
transform: none;
position: initial;
}
} }
} }

View File

@@ -1,31 +1,12 @@
import { ShippingMethodQuote } from '@framework/schema' import { ShippingMethodQuote } from '@framework/schema'
import classNames from 'classnames'
import React, { memo, useState } from 'react' import React, { memo, useState } from 'react'
import { useMessage } from 'src/components/contexts' 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 { Shipping } from 'src/components/icons'
import { CheckoutStep } from '../../CheckoutInfo' import { CheckoutStep } from '../../CheckoutInfo'
import s from './ShippingMethod.module.scss' import s from './ShippingMethod.module.scss'
import ShippingMethodItem from './ShippingMethodItem/ShippingMethodItem' 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 { interface Props {
currency: string currency: string
onConfirm: (id: number) => void onConfirm: (id: number) => void
@@ -33,20 +14,19 @@ interface Props {
} }
const ShippingMethod = memo(({ currency, onConfirm }: Props) => { const ShippingMethod = memo(({ currency, onConfirm }: Props) => {
const { eligibleShippingMethods } = useEligibleShippingMethods()
const { setOrderShippingMethod } = useSetOrderShippingMethod() 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 { showMessageError } = useMessage()
const [isShowOptions, setIsShowOptions] = useState<boolean>(true)
const onChange = (id: string) => { const onChange = (id: string) => {
const newValue = MOCKUP_DATA.find(item => item.id === id) const newValue = eligibleShippingMethods?.find(item => item.id === id)
if (newValue) { if (newValue) {
setSelectedValue(newValue) setSelectedValue(newValue)
if (newValue?.id) { if (newValue?.id) {
setOrderShippingMethod(newValue?.id, onSubmitCalBack) setOrderShippingMethod(newValue?.id, onSubmitCalBack)
} }
} }
setIsShowOptions(false)
} }
const onSubmitCalBack = (isSuccess: boolean, msg?: string) => { const onSubmitCalBack = (isSuccess: boolean, msg?: string) => {
@@ -57,31 +37,26 @@ const ShippingMethod = memo(({ currency, onConfirm }: Props) => {
} }
} }
const onCollapseOptions = () => {
setIsShowOptions(!isShowOptions)
}
return ( return (
<div className={s.shippingMethod}> <div className={s.shippingMethod}>
<div className={s.method} onClick={onCollapseOptions}> <div className={s.method}>
<div className={s.left}> <div className={s.left}>
<div className={s.icon}> <div className={s.icon}>
<Shipping /> <Shipping />
</div> </div>
<div className={s.name}> <div className={s.name}>
{selectedValue.name} {selectedValue?.name}
</div> </div>
</div> </div>
<div className={s.right}> <div className={s.right}>
<div className={s.price}> <div className={s.price}>
{selectedValue.price ? `${selectedValue.price / 100} ${currency}` : "Free"} {selectedValue?.price ? `${selectedValue?.price / 100} ${currency}` : "Free"}
</div> </div>
</div> </div>
</div> </div>
<div className={classNames(s.options, { [s.show]: isShowOptions })}> <div className={s.options}>
<ul> <ul>
{MOCKUP_DATA.map(item => <ShippingMethodItem {eligibleShippingMethods?.map(item => <ShippingMethodItem
key={item.id} key={item.id}
id={item.id} id={item.id}
name={item.name} name={item.name}

View File

@@ -2,7 +2,7 @@ import classNames from 'classnames'
import React, { useState } from 'react' import React, { useState } from 'react'
import { MessageCommon } from 'src/components/common' import { MessageCommon } from 'src/components/common'
import { useMessage } from 'src/components/contexts' 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 IconHide from 'src/components/icons/IconHide'
import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data' import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data'
import { CheckoutBill, CheckoutInfo } from '..' import { CheckoutBill, CheckoutInfo } from '..'
@@ -24,7 +24,7 @@ const CheckoutPage = ({ }: CheckoutPageProps) => {
return ( return (
<div className={s.warrper}> <div className={s.warrper}>
<MessageCommon messages={messages} onRemove={removeMessage} /> <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={s.right}><CheckoutBill data={order} /></div>
<div className={classNames({ [s.mobile]: true, [s.isShow]: isShow })}> <div className={classNames({ [s.mobile]: true, [s.isShow]: isShow })}>
<div className={s.modal}> <div className={s.modal}>