Skip to content

Commit

Permalink
Merge pull request #2340 from graphcommerce-org/feature/select-defaul…
Browse files Browse the repository at this point in the history
…t-shipping

feat: select default shipping method when there is just one available
  • Loading branch information
paales authored Aug 2, 2024
2 parents fba1bbd + 18691c7 commit 2f58b9f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/breezy-badgers-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphcommerce/magento-cart-shipping-method": patch
---

Select the only available shipping method as the current cart shipping method when there is only one shipping method available.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { i18n } from '@lingui/core'
import { Trans } from '@lingui/react'
import { SxProps, Theme } from '@mui/material'
import { useMemo } from 'react'
import { useEffect, useMemo } from 'react'
import { GetShippingMethodsDocument } from './GetShippingMethods.gql'
import { ShippingMethodActionCard } from './ShippingMethodActionCard'
import {
Expand All @@ -45,10 +45,9 @@ function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
export function ShippingMethodForm(props: ShippingMethodFormProps) {
const { step, sx, children, onBeforeSubmit = (vars) => vars, ...options } = props
const { data: cartQuery } = useCartQuery(GetShippingMethodsDocument)
const availableMethods = (
cartQuery?.cart?.shipping_addresses?.[0]?.available_shipping_methods ?? []
).filter(notEmpty)
const selectedMethod = cartQuery?.cart?.shipping_addresses?.[0]?.selected_shipping_method

const shippingAddress = cartQuery?.cart?.shipping_addresses?.[0]
const availableMethods = (shippingAddress?.available_shipping_methods ?? []).filter(notEmpty)

const items = useMemo(
() =>
Expand All @@ -67,12 +66,11 @@ export function ShippingMethodForm(props: ShippingMethodFormProps) {
[availableMethods],
)

// The default: When there is only a single shipping method, select that one.
let carrierMethod: string | undefined = items.length === 1 ? items[0]?.value : undefined

// Override with the currently selected method if there is one.
if (selectedMethod?.method_code)
carrierMethod = `${selectedMethod.carrier_code}-${selectedMethod.method_code}`
const selectedMethod = cartQuery?.cart?.shipping_addresses?.[0]?.selected_shipping_method
const carrierMethod = selectedMethod?.method_code
? `${selectedMethod.carrier_code}-${selectedMethod.method_code}`
: undefined

const form = useFormGqlMutationCart<
ShippingMethodFormMutation,
Expand All @@ -87,13 +85,14 @@ export function ShippingMethodForm(props: ShippingMethodFormProps) {
...options,
})

const { handleSubmit, control, error } = form
const { handleSubmit, control, error, setValue } = form
const submit = handleSubmit(() => {})

useFormCompose({ form, step, submit, key: 'ShippingMethodForm' })

if (items.length === 0) {
items.push({
const renderItems = [...items]
if (renderItems.length === 0) {
renderItems.push({
disabled: true,
value: '',
available: false,
Expand All @@ -107,6 +106,18 @@ export function ShippingMethodForm(props: ShippingMethodFormProps) {
})
}

const firstCarrierMethod = items.length === 1 ? items[0].value : undefined
useEffect(() => {
// If there is a shipping address AND there is only one shipping method
if (shippingAddress && firstCarrierMethod) {
// AND the current carrierMethod is not the same (or not set) as the single shipping method
if (carrierMethod !== firstCarrierMethod) {
// THEN set the shipping method to the only one available.
setValue('carrierMethod', firstCarrierMethod, { shouldValidate: true })
}
}
}, [shippingAddress, firstCarrierMethod, carrierMethod, setValue])

return (
<FormProvider {...form}>
<FormAutoSubmit
Expand All @@ -127,7 +138,7 @@ export function ShippingMethodForm(props: ShippingMethodFormProps) {
size='large'
color='secondary'
rules={{ required: i18n._(/* i18n */ 'Please select a shipping method') }}
items={items}
items={renderItems}
render={
ShippingMethodActionCard as React.FC<ActionCardItemRenderProps<ActionCardItemBase>>
}
Expand Down

0 comments on commit 2f58b9f

Please sign in to comment.