@graphcommerce/magento-customer 9.0.0-canary.60 → 9.0.0-canary.62
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 +10 -0
- package/components/CancelOrder/CancelOrder.graphql +12 -0
- package/components/CancelOrder/CancelOrderForm.tsx +160 -0
- package/components/OrderCard/OrderCard.graphql +11 -0
- package/components/OrderCard/OrderCard.tsx +2 -2
- package/components/OrderDetails/OrderDetails.graphql +3 -3
- package/components/OrderDetails/OrderDetails.tsx +9 -9
- package/components/OrderItem/OrderItem.tsx +1 -4
- package/components/OrderItems/OrderItems.graphql +2 -0
- package/components/OrderStateLabel/OrderStateLabel.tsx +9 -28
- package/components/OrderStateLabel/OrderStateLabelInline.tsx +4 -4
- package/components/ReorderItems/ReorderItems.graphql +11 -0
- package/components/ReorderItems/ReorderItems.tsx +47 -0
- package/components/index.ts +2 -0
- package/index.ts +5 -4
- package/package.json +14 -14
- package/utils/index.ts +1 -0
- package/utils/orderState.ts +43 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 9.0.0-canary.62
|
|
4
|
+
|
|
5
|
+
## 9.0.0-canary.61
|
|
6
|
+
|
|
7
|
+
### Minor Changes
|
|
8
|
+
|
|
9
|
+
- [#2327](https://github.com/graphcommerce-org/graphcommerce/pull/2327) [`be719fc`](https://github.com/graphcommerce-org/graphcommerce/commit/be719fc465c8804ddcb720a93813262e3a292b69) - Implement CancelOrder mutation, add cancel order overlay to account section ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
|
|
10
|
+
|
|
11
|
+
- [#2327](https://github.com/graphcommerce-org/graphcommerce/pull/2327) [`af83d81`](https://github.com/graphcommerce-org/graphcommerce/commit/af83d81656a4c1a014802fb052a94a079e9f60c1) - Add reorderItems mutation, add reorder button to order detail page ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
|
|
12
|
+
|
|
3
13
|
## 9.0.0-canary.60
|
|
4
14
|
|
|
5
15
|
## 9.0.0-canary.59
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { ApolloErrorSnackbar, CheckboxElement, SelectElement } from '@graphcommerce/ecommerce-ui'
|
|
2
|
+
import {
|
|
3
|
+
breakpointVal,
|
|
4
|
+
Button,
|
|
5
|
+
filterNonNullableKeys,
|
|
6
|
+
FormRow,
|
|
7
|
+
iconChevronDown,
|
|
8
|
+
IconSvg,
|
|
9
|
+
} from '@graphcommerce/next-ui'
|
|
10
|
+
import { useFormGqlMutation } from '@graphcommerce/react-hook-form'
|
|
11
|
+
import { Trans } from '@lingui/macro'
|
|
12
|
+
import {
|
|
13
|
+
Accordion,
|
|
14
|
+
AccordionDetails,
|
|
15
|
+
AccordionProps,
|
|
16
|
+
AccordionSummary,
|
|
17
|
+
Alert,
|
|
18
|
+
Box,
|
|
19
|
+
} from '@mui/material'
|
|
20
|
+
import {
|
|
21
|
+
CancelOrderDocument,
|
|
22
|
+
CancelOrderMutation,
|
|
23
|
+
CancelOrderMutationVariables,
|
|
24
|
+
} from './CancelOrder.gql'
|
|
25
|
+
import { OrderDetailsFragment } from '../OrderDetails/OrderDetails.gql'
|
|
26
|
+
import { useQuery } from '@graphcommerce/graphql'
|
|
27
|
+
import { StoreConfigDocument } from '@graphcommerce/magento-store'
|
|
28
|
+
import { canCancelOrder } from '../../utils'
|
|
29
|
+
|
|
30
|
+
type CancelOrderFormProps = {
|
|
31
|
+
order: OrderDetailsFragment
|
|
32
|
+
} & Omit<AccordionProps, 'children'>
|
|
33
|
+
|
|
34
|
+
export function CancelOrderForm(props: CancelOrderFormProps) {
|
|
35
|
+
const { order, sx, ...rest } = props
|
|
36
|
+
const { id: orderId, number: orderNumber } = order
|
|
37
|
+
|
|
38
|
+
const form = useFormGqlMutation<
|
|
39
|
+
CancelOrderMutation,
|
|
40
|
+
CancelOrderMutationVariables & { confirm: boolean }
|
|
41
|
+
>(CancelOrderDocument, { defaultValues: { orderId: atob(orderId) } })
|
|
42
|
+
|
|
43
|
+
const options = useQuery(StoreConfigDocument).data?.storeConfig?.order_cancellation_reasons
|
|
44
|
+
|
|
45
|
+
const { control, formState, required, handleSubmit, error, data: cancelOrderData } = form
|
|
46
|
+
|
|
47
|
+
const submitHandler = handleSubmit(() => {})
|
|
48
|
+
|
|
49
|
+
const submittedWithoutErrors =
|
|
50
|
+
formState.isSubmitSuccessful && !error && !cancelOrderData?.cancelOrder?.error
|
|
51
|
+
|
|
52
|
+
const visible = canCancelOrder(order) || submittedWithoutErrors
|
|
53
|
+
|
|
54
|
+
if (!visible) return null
|
|
55
|
+
|
|
56
|
+
if (submittedWithoutErrors)
|
|
57
|
+
return (
|
|
58
|
+
<Alert sx={(theme) => ({ mb: theme.spacings.xxl })}>
|
|
59
|
+
<Trans>Order has successfully been canceled</Trans>
|
|
60
|
+
</Alert>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Accordion
|
|
65
|
+
sx={[
|
|
66
|
+
(theme) => ({
|
|
67
|
+
mb: theme.spacings.xxl,
|
|
68
|
+
...breakpointVal(
|
|
69
|
+
'borderRadius',
|
|
70
|
+
theme.shape.borderRadius * 2,
|
|
71
|
+
theme.shape.borderRadius * 3,
|
|
72
|
+
theme.breakpoints.values,
|
|
73
|
+
),
|
|
74
|
+
'::before': { display: 'none' },
|
|
75
|
+
'&.Mui-expanded:last-of-type': {
|
|
76
|
+
mb: theme.spacings.xxl,
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
...(Array.isArray(sx) ? sx : [sx]),
|
|
80
|
+
]}
|
|
81
|
+
{...rest}
|
|
82
|
+
>
|
|
83
|
+
<AccordionSummary
|
|
84
|
+
expandIcon={<IconSvg src={iconChevronDown} />}
|
|
85
|
+
sx={[
|
|
86
|
+
(theme) => ({
|
|
87
|
+
px: theme.spacings.xs,
|
|
88
|
+
'& .MuiAccordionSummary-content': {
|
|
89
|
+
alignItems: 'center',
|
|
90
|
+
columnGap: 2,
|
|
91
|
+
justifyContent: 'space-between',
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
]}
|
|
95
|
+
>
|
|
96
|
+
<Trans>Cancel order</Trans>
|
|
97
|
+
</AccordionSummary>
|
|
98
|
+
<AccordionDetails sx={(theme) => ({ px: theme.spacings.xs, py: 0 })}>
|
|
99
|
+
<Box component='form' onSubmit={submitHandler} noValidate>
|
|
100
|
+
<FormRow>
|
|
101
|
+
<SelectElement
|
|
102
|
+
control={control}
|
|
103
|
+
name='reason'
|
|
104
|
+
label={<Trans>Reason</Trans>}
|
|
105
|
+
required={required.reason}
|
|
106
|
+
disabled={formState.isSubmitting || submittedWithoutErrors}
|
|
107
|
+
options={filterNonNullableKeys(options)?.map(({ description }) => ({
|
|
108
|
+
id: description,
|
|
109
|
+
label: description,
|
|
110
|
+
}))}
|
|
111
|
+
/>
|
|
112
|
+
</FormRow>
|
|
113
|
+
|
|
114
|
+
<CheckboxElement
|
|
115
|
+
required
|
|
116
|
+
control={control}
|
|
117
|
+
name='confirm'
|
|
118
|
+
color='error'
|
|
119
|
+
label={
|
|
120
|
+
<Trans>I understand that my order will be canceled and this can not be undone.</Trans>
|
|
121
|
+
}
|
|
122
|
+
/>
|
|
123
|
+
|
|
124
|
+
{submittedWithoutErrors && (
|
|
125
|
+
<Alert>
|
|
126
|
+
<Trans>Order has successfully been canceled</Trans>
|
|
127
|
+
</Alert>
|
|
128
|
+
)}
|
|
129
|
+
|
|
130
|
+
{cancelOrderData?.cancelOrder?.error && (
|
|
131
|
+
<Alert severity='error'>{cancelOrderData?.cancelOrder?.error}</Alert>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
<ApolloErrorSnackbar error={error} />
|
|
135
|
+
|
|
136
|
+
<FormRow
|
|
137
|
+
sx={(theme) => ({
|
|
138
|
+
justifyContent: 'center',
|
|
139
|
+
justifyItems: 'start',
|
|
140
|
+
gridAutoFlow: 'column',
|
|
141
|
+
gap: theme.spacings.sm,
|
|
142
|
+
})}
|
|
143
|
+
>
|
|
144
|
+
<Button
|
|
145
|
+
type='submit'
|
|
146
|
+
variant='pill'
|
|
147
|
+
color='error'
|
|
148
|
+
loading={formState.isSubmitting}
|
|
149
|
+
disabled={submittedWithoutErrors}
|
|
150
|
+
size='large'
|
|
151
|
+
sx={{ color: 'white', bgcolor: 'error.main' }}
|
|
152
|
+
>
|
|
153
|
+
<Trans>Cancel order</Trans>
|
|
154
|
+
</Button>
|
|
155
|
+
</FormRow>
|
|
156
|
+
</Box>
|
|
157
|
+
</AccordionDetails>
|
|
158
|
+
</Accordion>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
fragment OrderCard on CustomerOrder {
|
|
2
2
|
number
|
|
3
3
|
shipments {
|
|
4
|
+
id
|
|
4
5
|
tracking {
|
|
5
6
|
...TrackingLink
|
|
6
7
|
}
|
|
7
8
|
}
|
|
9
|
+
|
|
8
10
|
total {
|
|
9
11
|
grand_total {
|
|
10
12
|
...Money
|
|
@@ -15,4 +17,13 @@ fragment OrderCard on CustomerOrder {
|
|
|
15
17
|
}
|
|
16
18
|
...OrderStateLabel
|
|
17
19
|
order_date
|
|
20
|
+
shipping_address {
|
|
21
|
+
city
|
|
22
|
+
postcode
|
|
23
|
+
firstname
|
|
24
|
+
lastname
|
|
25
|
+
street
|
|
26
|
+
country_code
|
|
27
|
+
region_id
|
|
28
|
+
}
|
|
18
29
|
}
|
|
@@ -73,7 +73,7 @@ export function OrderCard(props: OrderCardProps) {
|
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
75
|
<ListItemButton
|
|
76
|
-
href={`/account/orders/view?
|
|
76
|
+
href={`/account/orders/view?orderNumber=${number}`}
|
|
77
77
|
component={NextLink}
|
|
78
78
|
className={classes.buttonRoot}
|
|
79
79
|
sx={[
|
|
@@ -96,7 +96,7 @@ export function OrderCard(props: OrderCardProps) {
|
|
|
96
96
|
<span>#{number}</span>
|
|
97
97
|
</OrderRow>
|
|
98
98
|
<OrderRow>
|
|
99
|
-
<OrderStateLabel
|
|
99
|
+
<OrderStateLabel {...props} />
|
|
100
100
|
</OrderRow>
|
|
101
101
|
<Box className={classes.orderProducts}>
|
|
102
102
|
<Box
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
fragment OrderDetails on CustomerOrder {
|
|
2
|
+
id
|
|
2
3
|
number
|
|
3
4
|
order_date
|
|
5
|
+
status
|
|
4
6
|
invoices {
|
|
5
7
|
id
|
|
6
8
|
number
|
|
@@ -9,9 +11,7 @@ fragment OrderDetails on CustomerOrder {
|
|
|
9
11
|
shipments {
|
|
10
12
|
id
|
|
11
13
|
tracking {
|
|
12
|
-
|
|
13
|
-
carrier
|
|
14
|
-
number
|
|
14
|
+
...TrackingLink
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
payment_methods {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
breakpointVal,
|
|
7
7
|
DateTimeFormat,
|
|
8
8
|
} from '@graphcommerce/next-ui'
|
|
9
|
-
import { Trans } from '@lingui/
|
|
9
|
+
import { Trans } from '@lingui/macro'
|
|
10
10
|
import { Box, SxProps, Theme, Typography, lighten } from '@mui/material'
|
|
11
11
|
import { AddressMultiLine } from '../AddressMultiLine/AddressMultiLine'
|
|
12
12
|
import { TrackingLink } from '../TrackingLink/TrackingLink'
|
|
@@ -41,7 +41,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
43
|
<SectionContainer
|
|
44
|
-
labelLeft={<Trans
|
|
44
|
+
labelLeft={<Trans>Order details</Trans>}
|
|
45
45
|
sx={[
|
|
46
46
|
(theme) => ({
|
|
47
47
|
padding: theme.spacings.sm,
|
|
@@ -82,7 +82,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
82
82
|
<Box className={classes.orderDetailRow}>
|
|
83
83
|
<SectionContainer
|
|
84
84
|
variantLeft='h5'
|
|
85
|
-
labelLeft={<Trans
|
|
85
|
+
labelLeft={<Trans>Order number</Trans>}
|
|
86
86
|
className={classes.orderDetailTitle}
|
|
87
87
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
88
88
|
>
|
|
@@ -93,7 +93,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
93
93
|
<Box className={classes.orderDetailRow}>
|
|
94
94
|
<SectionContainer
|
|
95
95
|
variantLeft='h5'
|
|
96
|
-
labelLeft={<Trans
|
|
96
|
+
labelLeft={<Trans>Order date</Trans>}
|
|
97
97
|
className={classes.orderDetailTitle}
|
|
98
98
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
99
99
|
>
|
|
@@ -104,7 +104,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
104
104
|
<Box className={classes.orderDetailRow}>
|
|
105
105
|
<SectionContainer
|
|
106
106
|
variantLeft='h5'
|
|
107
|
-
labelLeft={<Trans
|
|
107
|
+
labelLeft={<Trans>Shipping method</Trans>}
|
|
108
108
|
className={classes.orderDetailTitle}
|
|
109
109
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
110
110
|
>
|
|
@@ -124,13 +124,13 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
124
124
|
<Box className={classes.orderDetailRow}>
|
|
125
125
|
<SectionContainer
|
|
126
126
|
variantLeft='h5'
|
|
127
|
-
labelLeft={<Trans
|
|
127
|
+
labelLeft={<Trans>Payment method</Trans>}
|
|
128
128
|
className={classes.orderDetailTitle}
|
|
129
129
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
130
130
|
>
|
|
131
131
|
{payment_methods && payment_methods.length < 1 && (
|
|
132
132
|
<Typography>
|
|
133
|
-
<Trans
|
|
133
|
+
<Trans>No payment information</Trans>
|
|
134
134
|
</Typography>
|
|
135
135
|
)}
|
|
136
136
|
|
|
@@ -158,7 +158,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
158
158
|
<Box className={classes.orderDetailRow}>
|
|
159
159
|
<SectionContainer
|
|
160
160
|
variantLeft='h5'
|
|
161
|
-
labelLeft={<Trans
|
|
161
|
+
labelLeft={<Trans>Shipping address</Trans>}
|
|
162
162
|
className={classes.orderDetailTitle}
|
|
163
163
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
164
164
|
>
|
|
@@ -169,7 +169,7 @@ export function OrderDetails(props: OrderDetailsProps) {
|
|
|
169
169
|
<Box className={classes.orderDetailRow}>
|
|
170
170
|
<SectionContainer
|
|
171
171
|
variantLeft='h5'
|
|
172
|
-
labelLeft={<Trans
|
|
172
|
+
labelLeft={<Trans>Billing address</Trans>}
|
|
173
173
|
className={classes.orderDetailTitle}
|
|
174
174
|
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
|
|
175
175
|
>
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Image } from '@graphcommerce/image'
|
|
2
2
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
|
-
import {
|
|
4
|
-
useProductLink,
|
|
5
|
-
ProductLinkProps,
|
|
6
|
-
} from '@graphcommerce/magento-product/hooks/useProductLink'
|
|
3
|
+
import { useProductLink } from '@graphcommerce/magento-product/hooks/useProductLink'
|
|
7
4
|
import { Money } from '@graphcommerce/magento-store'
|
|
8
5
|
import { responsiveVal, extendableComponent, NextLink } from '@graphcommerce/next-ui'
|
|
9
6
|
import { Box } from '@mui/material'
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import { extendableComponent } from '@graphcommerce/next-ui'
|
|
2
2
|
import { Trans } from '@lingui/react'
|
|
3
3
|
import { Box, SxProps, Theme } from '@mui/material'
|
|
4
|
-
import {
|
|
4
|
+
import { OrderStateProps, OrderState, getOrderState } from '../../utils'
|
|
5
5
|
|
|
6
|
-
type
|
|
7
|
-
| 'Ordered'
|
|
8
|
-
| 'Invoiced'
|
|
9
|
-
| 'Shipped'
|
|
10
|
-
| 'Refunded'
|
|
11
|
-
| 'Canceled'
|
|
12
|
-
| 'Returned'
|
|
13
|
-
| 'Partial'
|
|
14
|
-
|
|
15
|
-
type OrderStateLabelPropsBase = OrderStateLabelFragment
|
|
6
|
+
type OrderStateLabelPropsBase = OrderStateProps
|
|
16
7
|
|
|
17
8
|
export type OrderStateRenderer = Record<
|
|
18
9
|
OrderState,
|
|
@@ -36,12 +27,12 @@ const { withState } = extendableComponent<OwnerState, typeof componentName, type
|
|
|
36
27
|
|
|
37
28
|
const defaultRenderer: OrderStateRenderer = {
|
|
38
29
|
Ordered: () => <Trans id='Your order is being processed' />,
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
Processing: () => <Trans id='Your order has been invoiced' />,
|
|
31
|
+
Closed: () => <Trans id='Your order is on its way!' />,
|
|
41
32
|
Refunded: () => <Trans id='Your order has been refunded' />,
|
|
42
33
|
Canceled: () => <Trans id='Your order has been canceled' />,
|
|
43
34
|
Returned: () => <Trans id='Your order has been returned' />,
|
|
44
|
-
|
|
35
|
+
Pending: () => <Trans id='Your order has been partially processed' />,
|
|
45
36
|
}
|
|
46
37
|
|
|
47
38
|
export function OrderStateLabel(props: OrderStateLabelProps) {
|
|
@@ -49,17 +40,7 @@ export function OrderStateLabel(props: OrderStateLabelProps) {
|
|
|
49
40
|
|
|
50
41
|
const renderer: OrderStateRenderer = { ...defaultRenderer, ...incomingRenderer }
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
if (items?.every((item) => item?.quantity_ordered === item?.quantity_invoiced))
|
|
54
|
-
orderState = 'Invoiced'
|
|
55
|
-
if (items?.every((item) => item?.quantity_ordered === item?.quantity_shipped))
|
|
56
|
-
orderState = 'Shipped'
|
|
57
|
-
if (items?.every((item) => item?.quantity_ordered === item?.quantity_refunded))
|
|
58
|
-
orderState = 'Refunded'
|
|
59
|
-
if (items?.every((item) => item?.quantity_ordered === item?.quantity_canceled))
|
|
60
|
-
orderState = 'Canceled'
|
|
61
|
-
if (items?.every((item) => item?.quantity_ordered === item?.quantity_returned))
|
|
62
|
-
orderState = 'Returned'
|
|
43
|
+
const orderState = getOrderState(props)
|
|
63
44
|
|
|
64
45
|
const StateLabel = renderer[orderState]
|
|
65
46
|
|
|
@@ -76,13 +57,13 @@ export function OrderStateLabel(props: OrderStateLabelProps) {
|
|
|
76
57
|
'&.orderStateOrdered': {
|
|
77
58
|
color: theme.palette.secondary.main,
|
|
78
59
|
},
|
|
79
|
-
'&.
|
|
60
|
+
'&.orderStateProcessing': {
|
|
80
61
|
color: theme.palette.secondary.main,
|
|
81
62
|
},
|
|
82
63
|
'&.orderStateRefunded': {
|
|
83
64
|
color: theme.palette.primary.main,
|
|
84
65
|
},
|
|
85
|
-
'&.
|
|
66
|
+
'&.orderStateClosed': {
|
|
86
67
|
color: theme.palette.success.main,
|
|
87
68
|
fontStyle: 'normal',
|
|
88
69
|
fontWeight: 600,
|
|
@@ -93,7 +74,7 @@ export function OrderStateLabel(props: OrderStateLabelProps) {
|
|
|
93
74
|
'&.orderStateReturned': {
|
|
94
75
|
color: theme.palette.secondary.main,
|
|
95
76
|
},
|
|
96
|
-
'&.
|
|
77
|
+
'&.orderStatePending': {
|
|
97
78
|
color: theme.palette.secondary.main,
|
|
98
79
|
},
|
|
99
80
|
}),
|
|
@@ -5,12 +5,12 @@ type OrderStateLabelInlineProps = OrderStateLabelProps
|
|
|
5
5
|
|
|
6
6
|
const defaultRenderer: OrderStateRenderer = {
|
|
7
7
|
Ordered: () => <Trans id='processed' />,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Processing: () => <Trans id='invoiced' />,
|
|
9
|
+
Closed: () => <Trans id='shipped' />,
|
|
10
10
|
Refunded: () => <Trans id='refunded' />,
|
|
11
11
|
Canceled: () => <Trans id='canceled' />,
|
|
12
12
|
Returned: () => <Trans id='returned' />,
|
|
13
|
-
|
|
13
|
+
Pending: () => <Trans id='partially processed' />,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export function OrderStateLabelInline(props: OrderStateLabelInlineProps) {
|
|
@@ -34,7 +34,7 @@ export function OrderStateLabelInline(props: OrderStateLabelInlineProps) {
|
|
|
34
34
|
color: theme.palette.primary.main,
|
|
35
35
|
background: `${theme.palette.primary.main}20`,
|
|
36
36
|
},
|
|
37
|
-
'&.
|
|
37
|
+
'&.orderStateClosed': {
|
|
38
38
|
color: theme.palette.success.main,
|
|
39
39
|
fontWeight: 'normal',
|
|
40
40
|
background: `${theme.palette.success.main}20`,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { AddProductsToCartSnackbarMessage } from '@graphcommerce/magento-product/components/AddProductsToCart/AddProductsToCartSnackbarMessage'
|
|
3
|
+
import { iconChevronRight, IconSvg, LinkOrButton, nonNullable } from '@graphcommerce/next-ui'
|
|
4
|
+
import { useFormGqlMutation } from '@graphcommerce/react-hook-form'
|
|
5
|
+
import { Trans } from '@lingui/macro'
|
|
6
|
+
import { Box } from '@mui/material'
|
|
7
|
+
import { OrderItemsFragment } from '../OrderItems/OrderItems.gql'
|
|
8
|
+
import { ReorderItemsDocument } from './ReorderItems.gql'
|
|
9
|
+
|
|
10
|
+
export type ReorderItemsProps = { order: OrderItemsFragment }
|
|
11
|
+
|
|
12
|
+
export function ReorderItems(props: ReorderItemsProps) {
|
|
13
|
+
const { order } = props
|
|
14
|
+
|
|
15
|
+
const form = useFormGqlMutation(ReorderItemsDocument, {
|
|
16
|
+
defaultValues: { orderNumber: order.number },
|
|
17
|
+
})
|
|
18
|
+
const { formState, handleSubmit, error, data: cartData } = form
|
|
19
|
+
const submitHandler = handleSubmit(() => {})
|
|
20
|
+
|
|
21
|
+
const errors = cartData?.reorderItems?.userInputErrors
|
|
22
|
+
const cart = cartData?.reorderItems?.cart
|
|
23
|
+
|
|
24
|
+
if (!order.items) return null
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Box component='form' onSubmit={submitHandler}>
|
|
28
|
+
<LinkOrButton
|
|
29
|
+
color='secondary'
|
|
30
|
+
button={{ variant: 'pill', sx: { whiteSpace: 'nowrap' } }}
|
|
31
|
+
link={{ whiteSpace: 'nowrap' }}
|
|
32
|
+
type='submit'
|
|
33
|
+
loading={formState.isSubmitting}
|
|
34
|
+
endIcon={<IconSvg src={iconChevronRight} />}
|
|
35
|
+
>
|
|
36
|
+
<Trans>Reorder</Trans>
|
|
37
|
+
</LinkOrButton>
|
|
38
|
+
|
|
39
|
+
<AddProductsToCartSnackbarMessage
|
|
40
|
+
addedItems={order.items.map((item) => item?.product_name).filter(nonNullable)}
|
|
41
|
+
error={error}
|
|
42
|
+
userErrors={errors?.filter(nonNullable)}
|
|
43
|
+
showSuccess={!!cart}
|
|
44
|
+
/>
|
|
45
|
+
</Box>
|
|
46
|
+
)
|
|
47
|
+
}
|
package/components/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './AddressFields'
|
|
|
11
11
|
export * from './AddressMultiLine/AddressMultiLine'
|
|
12
12
|
export * from './AddressSingleLine/AddressSingleLine'
|
|
13
13
|
export * from './ApolloCustomerError'
|
|
14
|
+
export * from './CancelOrder/CancelOrderForm'
|
|
14
15
|
export * from './ChangeNameForm/ChangeNameForm'
|
|
15
16
|
export * from './ChangePasswordForm/ChangePassword.gql'
|
|
16
17
|
export * from './ChangePasswordForm/ChangePasswordForm'
|
|
@@ -36,6 +37,7 @@ export * from './OrderItem/OrderItem'
|
|
|
36
37
|
export * from './OrderItems/OrderItems'
|
|
37
38
|
export * from './OrderStateLabel/OrderStateLabel'
|
|
38
39
|
export * from './OrderStateLabel/OrderStateLabelInline'
|
|
40
|
+
export * from './ReorderItems/ReorderItems'
|
|
39
41
|
export * from './ResetPasswordForm/ResetPasswordForm'
|
|
40
42
|
export * from './SignInForm/SignIn.gql'
|
|
41
43
|
export * from './SignInForm/SignInForm'
|
package/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './components'
|
|
2
|
-
export * from './hooks'
|
|
3
|
-
export * from './typePolicies'
|
|
4
|
-
export * from './graphql/AccountDashboardOrders.gql'
|
|
5
|
-
export * from './graphql/AccountDashboardAddresses.gql'
|
|
6
2
|
export * from './graphql/AccountDashboard.gql'
|
|
3
|
+
export * from './graphql/AccountDashboardAddresses.gql'
|
|
4
|
+
export * from './graphql/AccountDashboardOrders.gql'
|
|
7
5
|
export * from './graphql/OrderDetailPage.gql'
|
|
6
|
+
export * from './hooks'
|
|
7
|
+
export * from './typePolicies'
|
|
8
|
+
export * from './utils'
|
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.
|
|
5
|
+
"version": "9.0.0-canary.62",
|
|
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.
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.
|
|
17
|
-
"@graphcommerce/framer-next-pages": "^9.0.0-canary.
|
|
18
|
-
"@graphcommerce/framer-utils": "^9.0.0-canary.
|
|
19
|
-
"@graphcommerce/graphql": "^9.0.0-canary.
|
|
20
|
-
"@graphcommerce/graphql-mesh": "^9.0.0-canary.
|
|
21
|
-
"@graphcommerce/image": "^9.0.0-canary.
|
|
22
|
-
"@graphcommerce/magento-graphql": "^9.0.0-canary.
|
|
23
|
-
"@graphcommerce/magento-store": "^9.0.0-canary.
|
|
24
|
-
"@graphcommerce/next-ui": "^9.0.0-canary.
|
|
25
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.
|
|
26
|
-
"@graphcommerce/react-hook-form": "^9.0.0-canary.
|
|
27
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.
|
|
15
|
+
"@graphcommerce/ecommerce-ui": "^9.0.0-canary.62",
|
|
16
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.62",
|
|
17
|
+
"@graphcommerce/framer-next-pages": "^9.0.0-canary.62",
|
|
18
|
+
"@graphcommerce/framer-utils": "^9.0.0-canary.62",
|
|
19
|
+
"@graphcommerce/graphql": "^9.0.0-canary.62",
|
|
20
|
+
"@graphcommerce/graphql-mesh": "^9.0.0-canary.62",
|
|
21
|
+
"@graphcommerce/image": "^9.0.0-canary.62",
|
|
22
|
+
"@graphcommerce/magento-graphql": "^9.0.0-canary.62",
|
|
23
|
+
"@graphcommerce/magento-store": "^9.0.0-canary.62",
|
|
24
|
+
"@graphcommerce/next-ui": "^9.0.0-canary.62",
|
|
25
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.62",
|
|
26
|
+
"@graphcommerce/react-hook-form": "^9.0.0-canary.62",
|
|
27
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.62",
|
|
28
28
|
"@lingui/core": "^4.2.1",
|
|
29
29
|
"@lingui/macro": "^4.2.1",
|
|
30
30
|
"@lingui/react": "^4.2.1",
|
package/utils/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './orderState'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { OrderDetailsFragment } from '../components/OrderDetails/OrderDetails.gql'
|
|
2
|
+
import { OrderStateLabelFragment } from '../components/OrderStateLabel/OrderStateLabel.gql'
|
|
3
|
+
|
|
4
|
+
export type OrderState =
|
|
5
|
+
| 'Ordered'
|
|
6
|
+
| 'Processing'
|
|
7
|
+
| 'Closed'
|
|
8
|
+
| 'Refunded'
|
|
9
|
+
| 'Canceled'
|
|
10
|
+
| 'Returned'
|
|
11
|
+
| 'Pending'
|
|
12
|
+
|
|
13
|
+
export type OrderStateProps = Pick<OrderDetailsFragment, 'shipping_address' | 'shipments'> &
|
|
14
|
+
OrderStateLabelFragment
|
|
15
|
+
|
|
16
|
+
export function getOrderState(props: OrderStateProps) {
|
|
17
|
+
const { items, shipping_address } = props
|
|
18
|
+
|
|
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
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function canCancelOrder(props: OrderStateProps) {
|
|
39
|
+
const state = getOrderState(props)
|
|
40
|
+
const { shipments } = props
|
|
41
|
+
|
|
42
|
+
return (state === 'Pending' || state === 'Processing') && !shipments?.length
|
|
43
|
+
}
|