@graphcommerce/magento-customer 9.1.0-canary.18 → 9.1.0-canary.19

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/components/AccountAddresses/AccountAddresses.tsx +9 -4
  3. package/components/AccountDeleteForm/AccountDeleteForm.tsx +14 -4
  4. package/components/AccountLatestOrder/AccountLatestOrder.tsx +1 -2
  5. package/components/AccountOrders/AccountOrders.tsx +1 -1
  6. package/components/CancelOrder/CancelOrderForm.tsx +2 -2
  7. package/components/CancelOrder/CancelOrderFragment.graphql +5 -0
  8. package/components/ChangeNameForm/ChangeNameForm.tsx +1 -0
  9. package/components/ContactForm/ContactUsConfig.graphql +3 -0
  10. package/components/CreditMemo/CreditMemo.graphql +43 -0
  11. package/components/CreditMemo/CreditMemoCard.graphql +12 -0
  12. package/components/CreditMemo/CreditMemoCard.tsx +66 -0
  13. package/components/CreditMemo/CreditMemoDetails.tsx +94 -0
  14. package/components/CreditMemo/CreditMemoItem.graphql +26 -0
  15. package/components/CreditMemo/CreditMemoItem.tsx +125 -0
  16. package/components/CreditMemo/CreditMemoItems.tsx +78 -0
  17. package/components/CreditMemo/CreditMemoTotals.tsx +122 -0
  18. package/components/CreditMemo/index.ts +8 -0
  19. package/components/CustomerForms/CustomerAttributeField.tsx +112 -0
  20. package/components/CustomerForms/CustomerAttributeMetadata.graphql +9 -0
  21. package/components/CustomerForms/CustomerUpdateForm.tsx +65 -0
  22. package/components/CustomerForms/UseCustomerCreateForm.graphql +7 -0
  23. package/components/CustomerForms/UseCustomerUpdateForm.graphql +7 -0
  24. package/components/CustomerForms/customerAttributeFieldHelpers.ts +127 -0
  25. package/components/CustomerForms/index.ts +8 -0
  26. package/components/CustomerForms/nameFieldset.tsx +32 -0
  27. package/components/CustomerForms/useCustomerCreateForm.ts +83 -0
  28. package/components/CustomerForms/useCustomerUpdateForm.ts +122 -0
  29. package/components/GuestOrderOverview/GuestOrderOverviewForm.tsx +28 -11
  30. package/components/Invoice/Invoice.graphql +13 -0
  31. package/components/Invoice/InvoiceCard.graphql +9 -0
  32. package/components/Invoice/InvoiceCard.tsx +66 -0
  33. package/components/Invoice/InvoiceDetails.tsx +94 -0
  34. package/components/Invoice/InvoiceItem.graphql +25 -0
  35. package/components/Invoice/InvoiceItem.tsx +125 -0
  36. package/components/Invoice/InvoiceItems.tsx +72 -0
  37. package/components/Invoice/InvoiceTotal.graphql +29 -0
  38. package/components/Invoice/InvoiceTotals.tsx +110 -0
  39. package/components/Invoice/index.ts +9 -0
  40. package/components/NameFields/NameFields.tsx +33 -18
  41. package/components/Order/OrderAdditional/OrderAdditional.graphql +16 -0
  42. package/components/Order/OrderAdditional/OrderAdditional.tsx +51 -0
  43. package/components/Order/OrderCard/OrderCard.graphql +13 -0
  44. package/components/{OrderCard → Order/OrderCard}/OrderCard.tsx +22 -18
  45. package/components/{OrderCardItem → Order/OrderCard}/OrderCardItem.graphql +1 -0
  46. package/components/Order/OrderComments/OrderComments.graphql +5 -0
  47. package/components/Order/OrderComments/SalesCommentItem.graphql +4 -0
  48. package/components/Order/OrderComments/SalesComments.tsx +28 -0
  49. package/components/Order/OrderDetails/OrderAddress.graphql +17 -0
  50. package/components/Order/OrderDetails/OrderDetails.graphql +38 -0
  51. package/components/{OrderDetails → Order/OrderDetails}/OrderDetails.tsx +70 -57
  52. package/components/Order/OrderDetails/ShippingHandling.graphql +19 -0
  53. package/components/Order/OrderDetails/TaxItem.graphql +7 -0
  54. package/components/{OrderItem → Order/OrderItem}/OrderItem.graphql +13 -0
  55. package/components/Order/OrderItem/OrderItem.tsx +144 -0
  56. package/components/Order/OrderItems/OrderItems.tsx +81 -0
  57. package/components/{OrderStateLabel → Order/OrderStateLabel}/OrderStateLabel.tsx +2 -2
  58. package/components/Order/OrderTotals/OrderTotal.graphql +32 -0
  59. package/components/Order/OrderTotals/OrderTotals.graphql +7 -0
  60. package/components/{OrderDetails → Order/OrderTotals}/OrderTotals.tsx +27 -12
  61. package/components/Order/index.ts +16 -0
  62. package/components/ReorderItems/ReorderItems.tsx +1 -1
  63. package/components/Shipment/Shipment.graphql +14 -0
  64. package/components/Shipment/ShipmentCard.graphql +8 -0
  65. package/components/Shipment/ShipmentCard.tsx +71 -0
  66. package/components/Shipment/ShipmentDetails.tsx +100 -0
  67. package/components/Shipment/ShipmentItem.graphql +19 -0
  68. package/components/Shipment/ShipmentItem.tsx +117 -0
  69. package/components/Shipment/ShipmentItems.tsx +72 -0
  70. package/components/Shipment/index.ts +7 -0
  71. package/components/SignUpForm/SignUpForm.tsx +51 -46
  72. package/components/WaitForCustomer/WaitForCustomer.tsx +12 -3
  73. package/components/index.ts +5 -8
  74. package/graphql/{AccountDashboardQueryFragment.graphql → fragments/AccountDashboardQueryFragment.graphql} +8 -3
  75. package/graphql/index.ts +10 -0
  76. package/graphql/queries/CreditMemoDetailPage.graphql +14 -0
  77. package/graphql/queries/InvoiceDetailPage.graphql +14 -0
  78. package/graphql/queries/OrderDetailPage.graphql +14 -0
  79. package/graphql/queries/ShipmentDetailPage.graphql +12 -0
  80. package/hooks/CustomerInfo.graphql +3 -3
  81. package/index.ts +1 -4
  82. package/package.json +14 -14
  83. package/utils/orderState.ts +1 -2
  84. package/components/OrderCard/OrderCard.graphql +0 -29
  85. package/components/OrderDetails/OrderDetails.graphql +0 -77
  86. package/components/OrderItem/OrderItem.tsx +0 -176
  87. package/components/OrderItems/OrderItems.tsx +0 -70
  88. package/graphql/OrderDetailPage.graphql +0 -10
  89. /package/components/{OrderItems → Order/OrderItems}/OrderItems.graphql +0 -0
  90. /package/components/{OrderStateLabel → Order/OrderStateLabel}/OrderStateLabel.graphql +0 -0
  91. /package/components/{OrderStateLabel → Order/OrderStateLabel}/OrderStateLabelInline.tsx +0 -0
  92. /package/graphql/{CustomerStoreConfig.graphql → inject/CustomerStoreConfig.graphql} +0 -0
  93. /package/graphql/{AccountDashboard.graphql → queries/AccountDashboard.graphql} +0 -0
  94. /package/graphql/{AccountDashboardAddresses.graphql → queries/AccountDashboardAddresses.graphql} +0 -0
  95. /package/graphql/{AccountDashboardCustomer.graphql → queries/AccountDashboardCustomer.graphql} +0 -0
  96. /package/graphql/{AccountDashboardOrders.graphql → queries/AccountDashboardOrders.graphql} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Change Log
2
2
 
3
+ ## 9.1.0-canary.19
4
+
5
+ ### Minor Changes
6
+
7
+ - [#2499](https://github.com/graphcommerce-org/graphcommerce/pull/2499) [`20703bc`](https://github.com/graphcommerce-org/graphcommerce/commit/20703bc5c453fb7ee61eb4350e207e84a749bf5e) - Magento 2.4.7: Implemented the `customer_account_create` and `customer_account_edit` forms using the `attributeForm` query for the registration page and customer information form. The forms respect the settings configured in the 'Customer Configuration section'. It allows configuration for `prefix`, `middlename`, `suffix`,`dob`, `gender` and other fields. This also makes the frontend compatible with Adobe Commerce's Customer Attributes module. ([@paales](https://github.com/paales))
8
+
9
+ - [#2499](https://github.com/graphcommerce-org/graphcommerce/pull/2499) [`30f9371`](https://github.com/graphcommerce-org/graphcommerce/commit/30f9371503959b990c65058a88be6f61b4859140) - Added support for viewing Invoices/Shipments and Credit Memo's ([@paales](https://github.com/paales))
10
+
11
+ ### Patch Changes
12
+
13
+ - [#2499](https://github.com/graphcommerce-org/graphcommerce/pull/2499) [`6cb4815`](https://github.com/graphcommerce-org/graphcommerce/commit/6cb4815a0faf4cc2f60c13d9384e3a96b6bdb2bb) - Deleting an account will now require reauthentication and moved the menu item to the Authentication section ([@paales](https://github.com/paales))
14
+
15
+ - [#2499](https://github.com/graphcommerce-org/graphcommerce/pull/2499) [`2409514`](https://github.com/graphcommerce-org/graphcommerce/commit/240951428ac0bdc11649f4190b6d51c004680b34) - Order/Invoice/CreditMemo and Shipment views ([@paales](https://github.com/paales))
16
+
3
17
  ## 9.1.0-canary.18
4
18
 
5
19
  ## 9.1.0-canary.17
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  extendableComponent,
3
+ filterNonNullableKeys,
3
4
  FullPageMessage,
4
5
  iconHome,
5
6
  IconSvg,
@@ -21,7 +22,9 @@ const parts = ['root', 'addresses', 'button', 'link'] as const
21
22
  const { classes } = extendableComponent(name, parts)
22
23
 
23
24
  export function AccountAddresses(props: AccountAddressesProps) {
24
- const { addresses, loading, sx = [] } = props
25
+ const { addresses: addressesIncoming, loading, sx = [] } = props
26
+
27
+ const addresses = filterNonNullableKeys(addressesIncoming)
25
28
 
26
29
  if (loading) {
27
30
  return (
@@ -58,7 +61,7 @@ export function AccountAddresses(props: AccountAddressesProps) {
58
61
 
59
62
  return (
60
63
  <>
61
- {((addresses && addresses.length === 0) || !addresses) && (
64
+ {addresses.length === 0 && (
62
65
  <FullPageMessage
63
66
  title={<Trans id='You have no addresses saved yet' />}
64
67
  icon={<IconSvg src={iconHome} size='xxl' />}
@@ -70,13 +73,15 @@ export function AccountAddresses(props: AccountAddressesProps) {
70
73
  />
71
74
  )}
72
75
 
73
- {addresses && addresses.length >= 1 && (
76
+ {addresses.length >= 1 && (
74
77
  <SectionContainer labelLeft={<Trans id='Shipping addresses' />}>
75
78
  <Box
76
79
  className={classes.addresses}
77
80
  sx={(theme) => ({ '& > div': { borderBottom: `1px solid ${theme.palette.divider}` } })}
78
81
  >
79
- {addresses?.map((address) => <AccountAddress key={address?.id} {...address} />)}
82
+ {addresses.map((address) => (
83
+ <AccountAddress key={address.id} {...address} />
84
+ ))}
80
85
  </Box>
81
86
 
82
87
  <Button
@@ -4,17 +4,17 @@ import { Button, FormActions, FormRow } from '@graphcommerce/next-ui'
4
4
  import { useForm } from '@graphcommerce/react-hook-form'
5
5
  import { t, Trans } from '@lingui/macro'
6
6
  import { Box, Typography } from '@mui/material'
7
- import { CustomerDocument, useCustomerQuery } from '../../hooks'
7
+ import { useRouter } from 'next/router'
8
+ import { CustomerDocument, CustomerTokenDocument, useCustomerQuery } from '../../hooks'
8
9
  import { signOut } from '../SignOutForm/signOut'
9
10
  import { WaitForCustomer } from '../WaitForCustomer/WaitForCustomer'
10
11
  import { DeleteCustomerDocument } from './DeleteCustomer.gql'
11
12
 
12
13
  export function AccountDeleteForm() {
13
14
  const client = useApolloClient()
15
+ const router = useRouter()
14
16
 
15
- const dashboard = useCustomerQuery(CustomerDocument, {
16
- fetchPolicy: 'cache-and-network',
17
- })
17
+ const dashboard = useCustomerQuery(CustomerDocument, { fetchPolicy: 'cache-and-network' })
18
18
  const customer = dashboard.data?.customer
19
19
 
20
20
  const [deleteAccount, { called, error, loading }] = useMutation(DeleteCustomerDocument)
@@ -24,6 +24,15 @@ export function AccountDeleteForm() {
24
24
  const { control, handleSubmit, setError } = form
25
25
 
26
26
  const submitHandler = handleSubmit(async (data) => {
27
+ const currentToken = client.cache.readQuery({ query: CustomerTokenDocument })?.customerToken
28
+ if (currentToken) {
29
+ client.cache.writeQuery({
30
+ query: CustomerTokenDocument,
31
+ broadcast: true,
32
+ data: { customerToken: { ...currentToken, token: 'Force Reauthentication' } },
33
+ })
34
+ }
35
+
27
36
  if (data.email !== customer?.email) {
28
37
  setError('email', {
29
38
  message: t`The given email does not match the account email`,
@@ -31,6 +40,7 @@ export function AccountDeleteForm() {
31
40
  } else {
32
41
  await deleteAccount()
33
42
  signOut(client)
43
+ await router.push('/')
34
44
  }
35
45
  })
36
46
 
@@ -1,8 +1,7 @@
1
1
  import { SectionContainer } from '@graphcommerce/next-ui'
2
- import React from 'react'
3
2
  import type { AccountOrdersFragment } from '../AccountOrders/AccountOrders.gql'
4
3
  import { NoOrdersFound } from '../NoOrdersFound/NoOrdersFound'
5
- import { OrderCard } from '../OrderCard/OrderCard'
4
+ import { OrderCard } from '../Order'
6
5
 
7
6
  export type AccountLatestOrderProps = AccountOrdersFragment & {
8
7
  loading: boolean
@@ -3,7 +3,7 @@ import type { SxProps, Theme } from '@mui/material'
3
3
  import { Box, Link } from '@mui/material'
4
4
  import React from 'react'
5
5
  import { NoOrdersFound } from '../NoOrdersFound/NoOrdersFound'
6
- import { OrderCard } from '../OrderCard/OrderCard'
6
+ import { OrderCard } from '../Order'
7
7
  import type { AccountOrdersFragment } from './AccountOrders.gql'
8
8
 
9
9
  export type AccountOrdersProps = AccountOrdersFragment & { sx?: SxProps<Theme> }
@@ -14,12 +14,12 @@ import { Trans } from '@lingui/macro'
14
14
  import type { AccordionProps } from '@mui/material'
15
15
  import { Accordion, AccordionDetails, AccordionSummary, Alert, Box } from '@mui/material'
16
16
  import { canCancelOrder } from '../../utils'
17
- import type { OrderDetailsFragment } from '../OrderDetails/OrderDetails.gql'
18
17
  import type { CancelOrderMutation, CancelOrderMutationVariables } from './CancelOrder.gql'
19
18
  import { CancelOrderDocument } from './CancelOrder.gql'
19
+ import type { CancelOrderFragment } from './CancelOrderFragment.gql'
20
20
 
21
21
  export type CancelOrderFormProps = {
22
- order: OrderDetailsFragment
22
+ order: CancelOrderFragment
23
23
  } & Omit<AccordionProps, 'children'>
24
24
 
25
25
  export function CancelOrderForm(props: CancelOrderFormProps) {
@@ -0,0 +1,5 @@
1
+ fragment CancelOrderFragment on CustomerOrder {
2
+ id
3
+ ...OrderStateLabel
4
+ ...OrderDetails
5
+ }
@@ -11,6 +11,7 @@ export type ChangeNameFormProps = {
11
11
  lastname: string
12
12
  }
13
13
 
14
+ /** @deprecated Use UpdateCustomerForm when using Magento 2.4.7 and higher */
14
15
  export function ChangeNameForm(props: ChangeNameFormProps) {
15
16
  const { prefix, firstname, lastname } = props
16
17
  const form = useFormGqlMutation(
@@ -0,0 +1,3 @@
1
+ fragment ContactUsConfig on StoreConfig @inject(into: ["StoreConfigFragment"]) {
2
+ contact_enabled
3
+ }
@@ -0,0 +1,43 @@
1
+ fragment CreditMemo on CreditMemo {
2
+ id
3
+ number
4
+ items {
5
+ ...CreditMemoItem
6
+ }
7
+ total {
8
+ subtotal {
9
+ ...Money
10
+ }
11
+ adjustment {
12
+ ...Money
13
+ }
14
+ shipping_handling {
15
+ ...ShippingHandling
16
+ }
17
+ total_shipping {
18
+ ...Money
19
+ }
20
+ discounts {
21
+ amount {
22
+ ...Money
23
+ }
24
+ label
25
+ }
26
+ base_grand_total {
27
+ ...Money
28
+ }
29
+ grand_total {
30
+ ...Money
31
+ }
32
+ taxes {
33
+ ...TaxItem
34
+ }
35
+ total_tax {
36
+ ...Money
37
+ }
38
+ }
39
+ comments {
40
+ message
41
+ timestamp
42
+ }
43
+ }
@@ -0,0 +1,12 @@
1
+ fragment CreditMemoCard on CreditMemo {
2
+ id
3
+ number
4
+ comments {
5
+ ...SalesCommentItem
6
+ }
7
+ total {
8
+ grand_total {
9
+ ...Money
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,66 @@
1
+ import { Money } from '@graphcommerce/magento-store'
2
+ import { breakpointVal, iconChevronRight, IconSvg, NextLink, sxx } from '@graphcommerce/next-ui'
3
+ import { Trans } from '@lingui/macro'
4
+ import type { SxProps, Theme } from '@mui/material'
5
+ import { Box, lighten } from '@mui/material'
6
+ import type { CreditMemoCardFragment } from './CreditMemoCard.gql'
7
+
8
+ export type CreditMemoCardProps = {
9
+ orderNumber: string
10
+ creditMemo: CreditMemoCardFragment
11
+ sx?: SxProps<Theme>
12
+ }
13
+
14
+ export function CreditMemoCard(props: CreditMemoCardProps) {
15
+ const { creditMemo, orderNumber, sx = [] } = props
16
+ const { number, total } = creditMemo
17
+
18
+ return (
19
+ <Box
20
+ component={NextLink}
21
+ href={`/account/orders/credit-memo?orderNumber=${orderNumber}&creditMemoNumber=${number}`}
22
+ sx={sxx(
23
+ (theme) => ({
24
+ textDecoration: 'none',
25
+ color: 'text.primary',
26
+ px: theme.spacings.xxs,
27
+ py: theme.spacings.xxs,
28
+ gap: theme.spacings.sm,
29
+ background:
30
+ theme.palette.mode === 'light'
31
+ ? theme.palette.background.default
32
+ : lighten(theme.palette.background.default, 0.15),
33
+ ...breakpointVal(
34
+ 'borderRadius',
35
+ theme.shape.borderRadius * 2,
36
+ theme.shape.borderRadius * 3,
37
+ theme.breakpoints.values,
38
+ ),
39
+ '&:hover': {
40
+ backgroundColor: theme.palette.action.hover,
41
+ },
42
+ display: 'grid',
43
+ gridTemplate: `
44
+ "number total action" / 1fr auto auto
45
+ `,
46
+ rowGap: 0.5,
47
+ columnGap: 1,
48
+ }),
49
+ sx,
50
+ )}
51
+ >
52
+ <Box sx={{ gridArea: 'number', typography: 'body1' }}>
53
+ <Trans>Credit Memo #{number}</Trans>
54
+ </Box>
55
+ <Box sx={{ gridArea: 'total', alignSelf: 'center' }}>
56
+ <Money {...total?.grand_total} />
57
+ </Box>
58
+
59
+ <IconSvg
60
+ src={iconChevronRight}
61
+ size='medium'
62
+ sx={{ gridArea: 'action', alignSelf: 'center' }}
63
+ />
64
+ </Box>
65
+ )
66
+ }
@@ -0,0 +1,94 @@
1
+ import {
2
+ breakpointVal,
3
+ DateTimeFormat,
4
+ extendableComponent,
5
+ SectionContainer,
6
+ } from '@graphcommerce/next-ui'
7
+ import { Trans } from '@lingui/macro'
8
+ import type { SxProps, Theme } from '@mui/material'
9
+ import { Box, lighten, Typography } from '@mui/material'
10
+ import type { CreditMemoFragment } from './CreditMemo.gql'
11
+
12
+ export type CreditMemoDetailsProps = {
13
+ creditMemo: CreditMemoFragment
14
+ sx?: SxProps<Theme>
15
+ }
16
+
17
+ const componentName = 'CreditMemoDetails'
18
+ const parts = [
19
+ 'sectionContainer',
20
+ 'creditMemoDetailTitle',
21
+ 'creditMemoDetailContainer',
22
+ 'creditMemoDetailRow',
23
+ ] as const
24
+ const { classes } = extendableComponent(componentName, parts)
25
+
26
+ export function CreditMemoDetails(props: CreditMemoDetailsProps) {
27
+ const { creditMemo, sx = [] } = props
28
+ const { number, id } = creditMemo
29
+
30
+ return (
31
+ <SectionContainer
32
+ labelLeft={<Trans>Credit Memo details</Trans>}
33
+ sx={[
34
+ (theme) => ({
35
+ padding: theme.spacings.sm,
36
+ marginBottom: theme.spacings.md,
37
+ background:
38
+ theme.palette.mode === 'light'
39
+ ? theme.palette.background.default
40
+ : lighten(theme.palette.background.default, 0.15),
41
+ ...breakpointVal(
42
+ 'borderRadius',
43
+ theme.shape.borderRadius * 2,
44
+ theme.shape.borderRadius * 3,
45
+ theme.breakpoints.values,
46
+ ),
47
+ '& .SectionHeader-root': {
48
+ mt: 0,
49
+ mb: theme.spacings.xs,
50
+ },
51
+ }),
52
+ ...(Array.isArray(sx) ? sx : [sx]),
53
+ ]}
54
+ >
55
+ <Box
56
+ className={classes.creditMemoDetailContainer}
57
+ sx={[
58
+ (theme) => ({
59
+ gridColumnGap: theme.spacings.xxl,
60
+ gridRowGap: theme.spacings.md,
61
+ display: 'grid',
62
+ [theme.breakpoints.up('sm')]: {
63
+ gridTemplateColumns: '1fr 1fr',
64
+ marginTop: theme.spacings.xxs,
65
+ },
66
+ }),
67
+ ...(Array.isArray(sx) ? sx : [sx]),
68
+ ]}
69
+ >
70
+ <Box className={classes.creditMemoDetailRow}>
71
+ <SectionContainer
72
+ variantLeft='h5'
73
+ labelLeft={<Trans>Credit Memo number</Trans>}
74
+ className={classes.creditMemoDetailTitle}
75
+ sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
76
+ >
77
+ <Typography>{number}</Typography>
78
+ </SectionContainer>
79
+ </Box>
80
+
81
+ <Box className={classes.creditMemoDetailRow}>
82
+ {/* <SectionContainer
83
+ variantLeft='h5'
84
+ labelLeft={<Trans>Credit Memo ID</Trans>}
85
+ className={classes.creditMemoDetailTitle}
86
+ sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '4px' } }}
87
+ >
88
+ <Typography>{id}</Typography>
89
+ </SectionContainer> */}
90
+ </Box>
91
+ </Box>
92
+ </SectionContainer>
93
+ )
94
+ }
@@ -0,0 +1,26 @@
1
+ fragment CreditMemoItem on CreditMemoItemInterface {
2
+ __typename
3
+ id
4
+ product_name
5
+ product_sku
6
+ quantity_refunded
7
+ product_sale_price {
8
+ ...Money
9
+ }
10
+
11
+ discounts {
12
+ amount {
13
+ ...Money
14
+ }
15
+ label
16
+ }
17
+ order_item {
18
+ id
19
+ product {
20
+ uid
21
+ thumbnail {
22
+ ...ProductImage
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,125 @@
1
+ import { Image } from '@graphcommerce/image'
2
+ import { Money, PriceModifiersList, type PriceModifier } from '@graphcommerce/magento-store'
3
+ import { ActionCard, actionCardImageSizes, type ActionCardProps } from '@graphcommerce/next-ui'
4
+ import { Trans } from '@lingui/react'
5
+ import { Box } from '@mui/material'
6
+ import type { CreditMemoItemFragment } from './CreditMemoItem.gql'
7
+
8
+ export type CreditMemoItemProps = Omit<ActionCardProps, 'value' | 'image' | 'title'> & {
9
+ item: CreditMemoItemFragment
10
+ priceModifiers?: PriceModifier[]
11
+ }
12
+
13
+ export function CreditMemoItem(props: CreditMemoItemProps) {
14
+ const { item, priceModifiers, size = 'responsive', ...rest } = props
15
+ const {
16
+ product_name,
17
+ product_sku,
18
+ quantity_refunded,
19
+ product_sale_price,
20
+ discounts,
21
+ id,
22
+ order_item,
23
+ } = item
24
+
25
+ return (
26
+ <ActionCard
27
+ {...rest}
28
+ value={id}
29
+ sx={(theme) => ({
30
+ '&.ActionCard-root': {
31
+ px: 0,
32
+ py: theme.spacings.xs,
33
+ },
34
+ '& .ActionCard-rootInner': {
35
+ justifyContent: 'space-between',
36
+ alignItems: 'stretch',
37
+ },
38
+ '&.sizeSmall': {
39
+ px: 0,
40
+ },
41
+ '&.sizeResponsive': {
42
+ [theme.breakpoints.down('md')]: { px: 0 },
43
+ },
44
+ '& .ActionCard-end': {
45
+ justifyContent: 'space-between',
46
+ },
47
+ '& .ActionCard-action': {
48
+ pr: 0,
49
+ },
50
+ '& .ActionCard-image': {
51
+ alignSelf: 'flex-start',
52
+ },
53
+ '& .ActionCard-secondaryAction': {
54
+ display: 'grid',
55
+ rowGap: theme.spacings.xs,
56
+ justifyItems: 'start',
57
+ },
58
+ '& .ActionCard-price': {
59
+ pr: 0,
60
+ mb: { xs: 0.5, sm: 0 },
61
+ },
62
+ })}
63
+ size={size}
64
+ image={
65
+ order_item?.product?.thumbnail?.url && (
66
+ <Image
67
+ layout='fill'
68
+ src={order_item.product.thumbnail.url}
69
+ alt={order_item?.product.thumbnail?.label ?? ''}
70
+ sx={{
71
+ width: actionCardImageSizes[size],
72
+ height: actionCardImageSizes[size],
73
+ display: 'block',
74
+ borderRadius: 1,
75
+ objectFit: 'contain',
76
+ backgroundColor: 'background.image',
77
+ }}
78
+ sizes={actionCardImageSizes[size]}
79
+ />
80
+ )
81
+ }
82
+ title={product_name}
83
+ price={
84
+ <Money
85
+ currency={product_sale_price.currency}
86
+ value={(product_sale_price.value ?? 0) * (quantity_refunded ?? 1)}
87
+ />
88
+ }
89
+ action={<>&nbsp;</>}
90
+ secondaryAction={
91
+ <>
92
+ <Box
93
+ sx={{
94
+ display: 'flex',
95
+ alignItems: 'center',
96
+ color: 'text.secondary',
97
+ mt: 1,
98
+ gap: '10px',
99
+ justifyContent: 'start',
100
+ }}
101
+ >
102
+ {quantity_refunded}
103
+ {' ⨉ '}
104
+ <Money {...product_sale_price} />
105
+ </Box>
106
+
107
+ {rest.secondaryAction}
108
+ </>
109
+ }
110
+ details={
111
+ <>
112
+ {priceModifiers && priceModifiers.length > 0 && (
113
+ <PriceModifiersList
114
+ label={<Trans id='Base Price'>Base price</Trans>}
115
+ modifiers={[...priceModifiers]}
116
+ total={product_sale_price.value ?? 0}
117
+ currency={product_sale_price.currency}
118
+ />
119
+ )}
120
+ {rest.details}
121
+ </>
122
+ }
123
+ />
124
+ )
125
+ }
@@ -0,0 +1,78 @@
1
+ import {
2
+ ActionCardLayout,
3
+ breakpointVal,
4
+ extendableComponent,
5
+ nonNullable,
6
+ SectionContainer,
7
+ } from '@graphcommerce/next-ui'
8
+ import { Trans } from '@lingui/macro'
9
+ import type { SxProps, Theme } from '@mui/material'
10
+ import { Box } from '@mui/material'
11
+ import type { CreditMemoFragment } from './CreditMemo.gql'
12
+ import { CreditMemoItem } from './CreditMemoItem'
13
+
14
+ export type CreditMemoItemsProps = {
15
+ creditMemo: CreditMemoFragment
16
+ sx?: SxProps<Theme>
17
+ layout?: 'list' | 'grid'
18
+ size?: 'small' | 'medium' | 'large'
19
+ }
20
+
21
+ const componentName = 'CreditMemoItems'
22
+ const parts = ['root', 'items', 'actionCard'] as const
23
+ const { classes } = extendableComponent(componentName, parts)
24
+
25
+ export function CreditMemoItems(props: CreditMemoItemsProps) {
26
+ const { creditMemo, sx = [], layout = 'list', size } = props
27
+
28
+ const items = (creditMemo.items ?? []).filter(nonNullable)
29
+ if (!items.length) return null
30
+
31
+ return (
32
+ <Box
33
+ className={classes.root}
34
+ sx={[
35
+ (theme) => ({
36
+ my: theme.spacings.md,
37
+ padding: `${theme.spacings.sm} ${theme.spacings.sm}`,
38
+ border: `1px ${theme.palette.divider} solid`,
39
+ ...breakpointVal(
40
+ 'borderRadius',
41
+ theme.shape.borderRadius * 2,
42
+ theme.shape.borderRadius * 3,
43
+ theme.breakpoints.values,
44
+ ),
45
+ }),
46
+ ...(Array.isArray(sx) ? sx : [sx]),
47
+ ]}
48
+ >
49
+ <SectionContainer
50
+ sx={{ '& .SectionHeader-root': { mt: 0 } }}
51
+ labelLeft={<Trans>Refunded items</Trans>}
52
+ variantLeft='h6'
53
+ className={classes.items}
54
+ >
55
+ <ActionCardLayout
56
+ sx={(theme) => ({
57
+ marginBottom: theme.spacings.md,
58
+ '&.layoutStack': {
59
+ gap: 0,
60
+ },
61
+ })}
62
+ className={classes.actionCard}
63
+ layout={layout}
64
+ >
65
+ {items.map((item) => (
66
+ <CreditMemoItem
67
+ key={item.id}
68
+ item={item}
69
+ size={size}
70
+ layout={layout}
71
+ variant='default'
72
+ />
73
+ ))}
74
+ </ActionCardLayout>
75
+ </SectionContainer>
76
+ </Box>
77
+ )
78
+ }