@graphcommerce/magento-customer 9.0.0-canary.65 → 9.0.0-canary.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 9.0.0-canary.67
4
+
5
+ ## 9.0.0-canary.66
6
+
7
+ ### Minor Changes
8
+
9
+ - [#2339](https://github.com/graphcommerce-org/graphcommerce/pull/2339) [`df942e5`](https://github.com/graphcommerce-org/graphcommerce/commit/df942e5726ddb4d7c7d4b583aa474c7c0f0dea7d) - Show actual order status from the backend, improve order state logic ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
10
+
3
11
  ## 9.0.0-canary.65
4
12
 
5
13
  ### Patch Changes
@@ -87,7 +87,7 @@ export function GuestOrderOverviewForm() {
87
87
  ) : (
88
88
  <>
89
89
  <Typography sx={(theme) => ({ textAlign: 'center', mb: theme.spacings.lg })}>
90
- <OrderStateLabel items={orderData?.guestOrder.items} />
90
+ <OrderStateLabel {...orderData.guestOrder} />
91
91
  </Typography>
92
92
  <OrderDetails {...orderData?.guestOrder} />
93
93
  <OrderItems {...orderData?.guestOrder} images={images} />
@@ -13,7 +13,7 @@ type OrderCardProps = Partial<OrderCardFragment> & {
13
13
  sx?: SxProps<Theme>
14
14
  }
15
15
 
16
- const componentName = 'OrderCard' as const
16
+ const componentName = 'OrderCard'
17
17
  const parts = [
18
18
  'orderContainer',
19
19
  'orderRow',
@@ -42,7 +42,17 @@ const OrderRow = styled(Box, { name: componentName, target: classes.orderRow })(
42
42
  }))
43
43
 
44
44
  export function OrderCard(props: OrderCardProps) {
45
- const { number, shipments, total, items, order_date, images, loading, sx = [] } = props
45
+ const {
46
+ number,
47
+ shipments,
48
+ total,
49
+ items,
50
+ order_date,
51
+ images,
52
+ loading,
53
+ status = '',
54
+ sx = [],
55
+ } = props
46
56
 
47
57
  const totalItems = items?.length ?? 0
48
58
  const maxItemsInRow = 5
@@ -96,7 +106,7 @@ export function OrderCard(props: OrderCardProps) {
96
106
  <span>#{number}</span>
97
107
  </OrderRow>
98
108
  <OrderRow>
99
- <OrderStateLabel {...props} />
109
+ <OrderStateLabel {...props} status={status} />
100
110
  </OrderRow>
101
111
  <Box className={classes.orderProducts}>
102
112
  <Box
@@ -1,4 +1,5 @@
1
1
  fragment OrderStateLabel on CustomerOrder {
2
+ status
2
3
  items {
3
4
  quantity_ordered
4
5
  quantity_shipped
@@ -1,49 +1,29 @@
1
1
  import { extendableComponent } from '@graphcommerce/next-ui'
2
- import { Trans } from '@lingui/react'
2
+ import { Trans } from '@lingui/macro'
3
3
  import { Box, SxProps, Theme } from '@mui/material'
4
4
  import { OrderStateProps, OrderState, getOrderState } from '../../utils'
5
5
 
6
6
  type OrderStateLabelPropsBase = OrderStateProps
7
7
 
8
- export type OrderStateRenderer = Record<
9
- OrderState,
10
- (props: OrderStateLabelPropsBase) => React.ReactElement | null
11
- >
12
-
13
8
  export type OrderStateLabelProps = {
14
- renderer?: Partial<OrderStateRenderer>
15
9
  sx?: SxProps<Theme>
10
+ short?: boolean
16
11
  } & OrderStateLabelPropsBase
17
12
 
18
13
  type OwnerState = {
19
14
  orderState: OrderState
20
15
  }
21
- const componentName = 'OrderStateLabel' as const
16
+ const componentName = 'OrderStateLabel'
22
17
  const parts = ['root'] as const
23
18
  const { withState } = extendableComponent<OwnerState, typeof componentName, typeof parts>(
24
19
  componentName,
25
20
  parts,
26
21
  )
27
22
 
28
- const defaultRenderer: OrderStateRenderer = {
29
- Ordered: () => <Trans id='Your order is being processed' />,
30
- Processing: () => <Trans id='Your order has been invoiced' />,
31
- Closed: () => <Trans id='Your order is on its way!' />,
32
- Refunded: () => <Trans id='Your order has been refunded' />,
33
- Canceled: () => <Trans id='Your order has been canceled' />,
34
- Returned: () => <Trans id='Your order has been returned' />,
35
- Pending: () => <Trans id='Your order has been partially processed' />,
36
- }
37
-
38
23
  export function OrderStateLabel(props: OrderStateLabelProps) {
39
- const { items, renderer: incomingRenderer, sx = [], ...orderProps } = props
40
-
41
- const renderer: OrderStateRenderer = { ...defaultRenderer, ...incomingRenderer }
42
-
24
+ const { sx = [], status, short = false } = props
43
25
  const orderState = getOrderState(props)
44
26
 
45
- const StateLabel = renderer[orderState]
46
-
47
27
  const classes = withState({ orderState })
48
28
 
49
29
  return (
@@ -54,34 +34,23 @@ export function OrderStateLabel(props: OrderStateLabelProps) {
54
34
  (theme) => ({
55
35
  fontStyle: 'italic',
56
36
  fontWeight: 'normal',
57
- '&.orderStateOrdered': {
58
- color: theme.palette.secondary.main,
37
+ '&.orderStatePending': {
38
+ color: theme.palette.text.disabled,
59
39
  },
60
40
  '&.orderStateProcessing': {
61
- color: theme.palette.secondary.main,
41
+ color: theme.palette.info.main,
62
42
  },
63
- '&.orderStateRefunded': {
64
- color: theme.palette.primary.main,
65
- },
66
- '&.orderStateClosed': {
43
+ '&.orderStateComplete': {
67
44
  color: theme.palette.success.main,
68
- fontStyle: 'normal',
69
- fontWeight: 600,
70
- },
71
- '&.orderStateCanceled': {
72
- color: theme.palette.primary.main,
73
45
  },
74
- '&.orderStateReturned': {
75
- color: theme.palette.secondary.main,
76
- },
77
- '&.orderStatePending': {
78
- color: theme.palette.secondary.main,
46
+ '&.orderStateClosed': {
47
+ color: theme.palette.text.disabled,
79
48
  },
80
49
  }),
81
50
  ...(Array.isArray(sx) ? sx : [sx]),
82
51
  ]}
83
52
  >
84
- <StateLabel items={items} {...orderProps} />
53
+ {short ? status : <Trans>Order status: {status}</Trans>}
85
54
  </Box>
86
55
  )
87
56
  }
@@ -1,26 +1,14 @@
1
- import { Trans } from '@lingui/react'
2
- import { OrderStateLabel, OrderStateLabelProps, OrderStateRenderer } from './OrderStateLabel'
1
+ import { OrderStateLabel, OrderStateLabelProps } from './OrderStateLabel'
3
2
 
4
3
  type OrderStateLabelInlineProps = OrderStateLabelProps
5
4
 
6
- const defaultRenderer: OrderStateRenderer = {
7
- Ordered: () => <Trans id='processed' />,
8
- Processing: () => <Trans id='invoiced' />,
9
- Closed: () => <Trans id='shipped' />,
10
- Refunded: () => <Trans id='refunded' />,
11
- Canceled: () => <Trans id='canceled' />,
12
- Returned: () => <Trans id='returned' />,
13
- Pending: () => <Trans id='partially processed' />,
14
- }
15
-
16
5
  export function OrderStateLabelInline(props: OrderStateLabelInlineProps) {
17
- const { sx = [], renderer: incomingRenderer } = props
18
- const renderer: OrderStateRenderer = { ...defaultRenderer, ...incomingRenderer }
6
+ const { sx = [] } = props
19
7
 
20
8
  return (
21
9
  <OrderStateLabel
22
10
  {...props}
23
- renderer={renderer}
11
+ short
24
12
  sx={[
25
13
  (theme) => ({
26
14
  fontStyle: 'normal',
@@ -30,18 +18,20 @@ export function OrderStateLabelInline(props: OrderStateLabelInlineProps) {
30
18
  fontWeight: 'normal',
31
19
  background: `${theme.palette.secondary.main}20`,
32
20
 
33
- '&.orderStateRefunded': {
34
- color: theme.palette.primary.main,
35
- background: `${theme.palette.primary.main}20`,
21
+ '&.orderStatePending': {
22
+ color: theme.palette.text.disabled,
36
23
  },
37
- '&.orderStateClosed': {
24
+ '&.orderStateProcessing': {
25
+ color: theme.palette.info.main,
26
+ background: `${theme.palette.info.main}20`,
27
+ },
28
+ '&.orderStateComplete': {
38
29
  color: theme.palette.success.main,
39
- fontWeight: 'normal',
40
30
  background: `${theme.palette.success.main}20`,
41
31
  },
42
- '&.orderStateCanceled': {
43
- color: theme.palette.primary.main,
44
- background: `${theme.palette.primary.main}20`,
32
+ '&.orderStateClosed': {
33
+ color: theme.palette.text.disabled,
34
+ background: `${theme.palette.text.disabled}20`,
45
35
  },
46
36
  }),
47
37
  ...(Array.isArray(sx) ? sx : [sx]),
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-customer",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "9.0.0-canary.65",
5
+ "version": "9.0.0-canary.67",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,19 +12,19 @@
12
12
  }
13
13
  },
14
14
  "peerDependencies": {
15
- "@graphcommerce/ecommerce-ui": "^9.0.0-canary.65",
16
- "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.65",
17
- "@graphcommerce/framer-next-pages": "^9.0.0-canary.65",
18
- "@graphcommerce/framer-utils": "^9.0.0-canary.65",
19
- "@graphcommerce/graphql": "^9.0.0-canary.65",
20
- "@graphcommerce/graphql-mesh": "^9.0.0-canary.65",
21
- "@graphcommerce/image": "^9.0.0-canary.65",
22
- "@graphcommerce/magento-graphql": "^9.0.0-canary.65",
23
- "@graphcommerce/magento-store": "^9.0.0-canary.65",
24
- "@graphcommerce/next-ui": "^9.0.0-canary.65",
25
- "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.65",
26
- "@graphcommerce/react-hook-form": "^9.0.0-canary.65",
27
- "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.65",
15
+ "@graphcommerce/ecommerce-ui": "^9.0.0-canary.67",
16
+ "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.67",
17
+ "@graphcommerce/framer-next-pages": "^9.0.0-canary.67",
18
+ "@graphcommerce/framer-utils": "^9.0.0-canary.67",
19
+ "@graphcommerce/graphql": "^9.0.0-canary.67",
20
+ "@graphcommerce/graphql-mesh": "^9.0.0-canary.67",
21
+ "@graphcommerce/image": "^9.0.0-canary.67",
22
+ "@graphcommerce/magento-graphql": "^9.0.0-canary.67",
23
+ "@graphcommerce/magento-store": "^9.0.0-canary.67",
24
+ "@graphcommerce/next-ui": "^9.0.0-canary.67",
25
+ "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.67",
26
+ "@graphcommerce/react-hook-form": "^9.0.0-canary.67",
27
+ "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.67",
28
28
  "@lingui/core": "^4.2.1",
29
29
  "@lingui/macro": "^4.2.1",
30
30
  "@lingui/react": "^4.2.1",
@@ -1,43 +1,51 @@
1
+ import { filterNonNullableKeys } from '@graphcommerce/next-ui'
1
2
  import { OrderDetailsFragment } from '../components/OrderDetails/OrderDetails.gql'
2
3
  import { OrderStateLabelFragment } from '../components/OrderStateLabel/OrderStateLabel.gql'
3
4
 
4
- export type OrderState =
5
- | 'Ordered'
6
- | 'Processing'
7
- | 'Closed'
8
- | 'Refunded'
9
- | 'Canceled'
10
- | 'Returned'
11
- | 'Pending'
5
+ export type OrderState = 'pending' | 'processing' | 'complete' | 'closed'
12
6
 
13
7
  export type OrderStateProps = Pick<OrderDetailsFragment, 'shipping_address' | 'shipments'> &
14
8
  OrderStateLabelFragment
15
9
 
16
- export function getOrderState(props: OrderStateProps) {
10
+ export function getOrderState(props: OrderStateProps): OrderState {
17
11
  const { items, shipping_address } = props
18
12
 
19
- let orderState: OrderState = 'Pending'
20
- if (items?.every((item) => item?.quantity_ordered === item?.quantity_invoiced))
21
- orderState = 'Processing'
22
- if (items?.every((item) => item?.quantity_ordered === item?.quantity_shipped))
23
- orderState = 'Closed'
24
- if (items?.every((item) => item?.quantity_ordered === item?.quantity_refunded))
25
- orderState = 'Refunded'
26
- if (items?.every((item) => item?.quantity_ordered === item?.quantity_canceled))
27
- orderState = 'Canceled'
28
- if (items?.every((item) => item?.quantity_ordered === item?.quantity_returned))
29
- orderState = 'Returned'
30
-
31
- if (orderState === 'Processing' && !shipping_address) {
32
- orderState = 'Closed'
33
- }
34
-
35
- return orderState
13
+ const itemss = filterNonNullableKeys(items, [
14
+ 'quantity_ordered',
15
+ 'quantity_canceled',
16
+ 'quantity_invoiced',
17
+ 'quantity_refunded',
18
+ 'quantity_shipped',
19
+ ]).map((i) => ({
20
+ ordered: i.quantity_ordered,
21
+ canceled: i.quantity_canceled,
22
+ invoiced: i.quantity_invoiced,
23
+ refunded: i.quantity_refunded,
24
+ returned: i.quantity_returned ?? 0,
25
+ shipped: i.quantity_shipped,
26
+ }))
27
+
28
+ const nothingInvoiced = itemss.every((i) => i.invoiced === 0)
29
+ const nothingShipped = itemss.every((i) => i.shipped === 0)
30
+
31
+ const needsInvoicing = itemss.some((i) => i.ordered - i.canceled - i.invoiced)
32
+ const needsShipping = itemss.some((i) => {
33
+ if (!shipping_address) return 0
34
+ return i.ordered <= i.canceled - i.shipped - i.refunded
35
+ })
36
+
37
+ if (nothingInvoiced && nothingShipped && needsInvoicing && needsShipping) return 'pending'
38
+ if (needsShipping || needsInvoicing) return 'processing'
39
+
40
+ const canRefundOrReturn = itemss.some(
41
+ (i) => i.ordered - i.canceled - Math.max(i.refunded, i.returned),
42
+ )
43
+ return canRefundOrReturn ? 'complete' : 'closed'
36
44
  }
37
45
 
38
46
  export function canCancelOrder(props: OrderStateProps) {
39
47
  const state = getOrderState(props)
40
48
  const { shipments } = props
41
49
 
42
- return (state === 'Pending' || state === 'Processing') && !shipments?.length
50
+ return (state === 'pending' || state === 'processing') && !shipments?.length
43
51
  }