@graphcommerce/magento-cart 3.1.0 → 3.1.4

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
@@ -3,6 +3,42 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.1.4](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart@3.1.3...@graphcommerce/magento-cart@3.1.4) (2021-10-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * conditional hook in CartSummary ([780c5c1](https://github.com/ho-nl/m2-pwa/commit/780c5c140e03ea5f77ea9cf5409498ed853e772c))
12
+ * issue where the cart shippingMethod didn't have a value defined ([a1f27d1](https://github.com/ho-nl/m2-pwa/commit/a1f27d1bff01921ff2cf783394c2bb4a65285d17))
13
+
14
+
15
+
16
+
17
+
18
+ ## [3.1.3](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart@3.1.2...@graphcommerce/magento-cart@3.1.3) (2021-10-07)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **cart:** agreements didn't handle state updates properly ([4401ff9](https://github.com/ho-nl/m2-pwa/commit/4401ff96a410379805d89bb2fa711df2d8a8fad0))
24
+ * make sure if no payment method is filled in we get an error shown ([a203e57](https://github.com/ho-nl/m2-pwa/commit/a203e570caad0732427a178e8e8b10b4a15d676b))
25
+ * make sure the CartAgreementsForm validates immediately ([eceacbb](https://github.com/ho-nl/m2-pwa/commit/eceacbb4803dd6e2701bf1835aa601c06ba4d6a3))
26
+
27
+
28
+
29
+
30
+
31
+ ## [3.1.1](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart@3.1.0...@graphcommerce/magento-cart@3.1.1) (2021-10-06)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * **cart-fab:** box shadow in safari ([4eb316d](https://github.com/ho-nl/m2-pwa/commit/4eb316dd0f2ab7ee2806a3acdb306af1eb72854b))
37
+
38
+
39
+
40
+
41
+
6
42
  # [3.1.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart@3.0.13...@graphcommerce/magento-cart@3.1.0) (2021-10-05)
7
43
 
8
44
 
@@ -0,0 +1,6 @@
1
+ import { Page } from '@playwright/test'
2
+
3
+ export async function fillCartAgreementsForm(page: Page) {
4
+ const inputs = await page.$$('form[name=cartAgreements] input')
5
+ await Promise.all(inputs.map((input) => input.check()))
6
+ }
@@ -16,13 +16,14 @@ export default function ApolloCartErrorAlert(props: ApolloCartErrorAlertProps) {
16
16
  let action: JSX.Element | undefined
17
17
 
18
18
  const [, noSuchEntity] = graphqlErrorByCategory({ category: 'graphql-no-such-entity', error })
19
- action = noSuchEntity && clear ? <Button onClick={clear}>Reset Cart</Button> : undefined
19
+ action = noSuchEntity ? <Button onClick={clear}>Reset Cart</Button> : undefined
20
20
 
21
21
  const [, authorizationError] = graphqlErrorByCategory({
22
22
  category: 'graphql-authorization',
23
23
  error,
24
24
  mask: token?.token ? 'Please reauthenticate and try again' : 'You must sign in to continue',
25
25
  })
26
+
26
27
  action =
27
28
  authorizationError && clear ? (
28
29
  <Link href='/account/signin' passHref>
@@ -1 +1,30 @@
1
- export {}
1
+ import { graphqlErrorByCategory } from '@graphcommerce/magento-graphql'
2
+ import {
3
+ ApolloErrorFullPage,
4
+ Button,
5
+ SvgImage,
6
+ ApolloErrorFullPageProps,
7
+ iconLock,
8
+ iconSadShoppingBag,
9
+ } from '@graphcommerce/next-ui'
10
+ import React from 'react'
11
+ import { useClearCurrentCartId } from '../../hooks/useClearCurrentCartId'
12
+
13
+ export type ApolloCartErrorFullPageProps = Omit<ApolloErrorFullPageProps, 'icon'>
14
+
15
+ export default function ApolloCartErrorFullPage(props: ApolloCartErrorFullPageProps) {
16
+ const { error, ...passedProps } = props
17
+ const clear = useClearCurrentCartId()
18
+
19
+ const [, noSuchEntity] = graphqlErrorByCategory({ category: 'graphql-no-such-entity', error })
20
+ const action = noSuchEntity ? <Button onClick={clear}>Reset Cart</Button> : undefined
21
+
22
+ return (
23
+ <ApolloErrorFullPage
24
+ error={error}
25
+ icon={<SvgImage src={iconSadShoppingBag} size={148} alt='person' />}
26
+ button={action}
27
+ {...passedProps}
28
+ />
29
+ )
30
+ }
@@ -0,0 +1,11 @@
1
+ query CartAgreements {
2
+ checkoutAgreements {
3
+ agreement_id
4
+ checkbox_text
5
+ content
6
+ content_height
7
+ is_html
8
+ mode
9
+ name
10
+ }
11
+ }
@@ -0,0 +1,132 @@
1
+ import { useQuery } from '@apollo/client'
2
+ import { FormDiv } from '@graphcommerce/next-ui'
3
+ import {
4
+ Controller,
5
+ useForm,
6
+ useFormCompose,
7
+ UseFormComposeOptions,
8
+ useFormPersist,
9
+ } from '@graphcommerce/react-hook-form'
10
+ import {
11
+ Checkbox,
12
+ FormControl,
13
+ FormControlLabel,
14
+ FormHelperText,
15
+ Link,
16
+ makeStyles,
17
+ Theme,
18
+ } from '@material-ui/core'
19
+ import PageLink from 'next/link'
20
+ import React from 'react'
21
+ import { CartAgreementsDocument } from './CartAgreements.gql'
22
+
23
+ export type CartAgreementsFormProps = Pick<UseFormComposeOptions, 'step'>
24
+
25
+ const useStyles = makeStyles(
26
+ (theme: Theme) => ({
27
+ formDiv: {
28
+ paddingTop: theme.spacings.sm,
29
+ },
30
+ formInner: {
31
+ ...theme.typography.body1,
32
+ display: 'inline-block',
33
+ },
34
+ formControlRoot: {
35
+ display: 'block',
36
+ },
37
+ manualCheck: {
38
+ padding: `9px 0`,
39
+ },
40
+ }),
41
+ {
42
+ name: 'CartAgreements',
43
+ },
44
+ )
45
+
46
+ export default function CartAgreementsForm(props: CartAgreementsFormProps) {
47
+ const { step } = props
48
+ const { data } = useQuery(CartAgreementsDocument)
49
+ const classes = useStyles()
50
+
51
+ // sort conditions so checkboxes will be placed first
52
+ const sortedAgreements = data?.checkoutAgreements
53
+ ? [...data.checkoutAgreements].sort((a, b) => {
54
+ return a?.mode === 'MANUAL' ? -1 : b?.mode === 'MANUAL' ? 1 : 0
55
+ })
56
+ : []
57
+
58
+ const form = useForm({ mode: 'onChange' })
59
+
60
+ const { handleSubmit, formState, control } = form
61
+
62
+ const submit = handleSubmit(() => {})
63
+
64
+ useFormPersist({ form, name: 'PaymentAgreementsForm' })
65
+
66
+ useFormCompose({ form, step, submit, key: 'PaymentAgreementsForm' })
67
+
68
+ return (
69
+ <FormDiv classes={{ root: classes.formDiv }}>
70
+ <form noValidate onSubmit={submit} name='cartAgreements'>
71
+ <div className={classes.formInner}>
72
+ {data?.checkoutAgreements &&
73
+ sortedAgreements?.map(
74
+ (agreement) =>
75
+ agreement && (
76
+ <React.Fragment key={agreement.agreement_id}>
77
+ {agreement.mode === 'MANUAL' ? (
78
+ <>
79
+ <Controller
80
+ defaultValue={''}
81
+ name={String(agreement.agreement_id)}
82
+ control={control}
83
+ rules={{ required: 'You have to agree in order to proceed' }}
84
+ render={({
85
+ field: { onChange, value, name, ref, onBlur },
86
+ fieldState: { error },
87
+ }) => (
88
+ <FormControl
89
+ error={!!formState.errors[String(agreement.agreement_id)]}
90
+ classes={{ root: classes.formControlRoot }}
91
+ >
92
+ <FormControlLabel
93
+ control={<Checkbox color='secondary' required={true} />}
94
+ label={
95
+ <PageLink
96
+ href={`/legal/view/${agreement.name
97
+ ?.toLowerCase()
98
+ .replaceAll(' ', '-')}`}
99
+ passHref
100
+ >
101
+ <Link color='secondary'>{agreement.checkbox_text}</Link>
102
+ </PageLink>
103
+ }
104
+ checked={!!value}
105
+ inputRef={ref}
106
+ onBlur={onBlur}
107
+ name={name}
108
+ onChange={(e) => onChange(e as React.ChangeEvent<HTMLInputElement>)}
109
+ />
110
+ {error?.message && <FormHelperText>{error.message}</FormHelperText>}
111
+ </FormControl>
112
+ )}
113
+ />
114
+ </>
115
+ ) : (
116
+ <div className={classes.manualCheck}>
117
+ <PageLink
118
+ href={`/legal/view/${agreement.name?.toLowerCase().replaceAll(' ', '-')}`}
119
+ passHref
120
+ >
121
+ <Link color='secondary'>{agreement.checkbox_text}</Link>
122
+ </PageLink>
123
+ </div>
124
+ )}
125
+ </React.Fragment>
126
+ ),
127
+ )}
128
+ </div>
129
+ </form>
130
+ </FormDiv>
131
+ )
132
+ }
@@ -2,6 +2,7 @@ import {
2
2
  iconShoppingBag,
3
3
  StyledBadge,
4
4
  SvgImageSimple,
5
+ FixedFab,
5
6
  useFixedFabAnimation,
6
7
  } from '@graphcommerce/next-ui'
7
8
  import { Fab, FabProps, NoSsr } from '@material-ui/core'
@@ -23,12 +24,20 @@ function CartFabContent(props: CartFabContentProps) {
23
24
  const cartIcon = icon ?? (
24
25
  <SvgImageSimple src={iconShoppingBag} alt='Shopping Bag' loading='eager' size='large' />
25
26
  )
26
- const { filter } = useFixedFabAnimation()
27
+ const { boxShadow } = useFixedFabAnimation()
27
28
 
28
29
  return (
29
- <m.div style={{ filter }}>
30
+ <m.div style={{ boxShadow, width: 'inherit', borderRadius: 'inherit' }}>
30
31
  <PageLink href='/cart' passHref>
31
- <Fab aria-label='Cart' color='inherit' size='large' {...fabProps}>
32
+ <Fab
33
+ aria-label='Cart'
34
+ color='inherit'
35
+ size='large'
36
+ style={{
37
+ boxShadow: 'none',
38
+ }}
39
+ {...fabProps}
40
+ >
32
41
  {total_quantity > 0 ? (
33
42
  <StyledBadge color='primary' variant='dot'>
34
43
  {cartIcon}
@@ -60,8 +69,10 @@ export default function CartFab(props: CartFabProps) {
60
69
  const qty = data?.cart?.total_quantity ?? 0
61
70
 
62
71
  return (
63
- <NoSsr fallback={<CartFabContent {...props} total_quantity={0} />}>
64
- <CartFabContent total_quantity={qty} {...props} />
65
- </NoSsr>
72
+ <FixedFab>
73
+ <NoSsr fallback={<CartFabContent {...props} total_quantity={0} />}>
74
+ <CartFabContent total_quantity={qty} {...props} />
75
+ </NoSsr>
76
+ </FixedFab>
66
77
  )
67
78
  }
@@ -45,19 +45,15 @@ export default function CartSummary(props: CartSummaryProps) {
45
45
  const classes = useStyles(props)
46
46
  const { children, editable } = props
47
47
 
48
- const { data } = useCartQuery(GetCartSummaryDocument, {
49
- // allowUrl: true,
50
- fetchPolicy: 'network-only',
48
+ const { data } = useCartQuery(GetCartSummaryDocument, { allowUrl: true })
49
+ const { href: historyHref, onClick: historyOnClick } = useHistoryLink({
50
+ href: '/checkout',
51
51
  })
52
52
 
53
53
  if (!data?.cart) return null
54
54
 
55
55
  const { email, shipping_addresses, billing_address } = data.cart
56
56
 
57
- const { href: historyHref, onClick: historyOnClick } = useHistoryLink({
58
- href: '/checkout',
59
- })
60
-
61
57
  return (
62
58
  <div className={classes.root}>
63
59
  <div className={classes.detailsContainer}>
@@ -65,9 +65,10 @@ export default function CartTotals(props: CartTotalsProps) {
65
65
  const { containerMargin } = props
66
66
  const { shipping_addresses, prices } = data.cart
67
67
  const shippingMethod = shipping_addresses?.[0]?.selected_shipping_method
68
+
68
69
  const shippingMethodPrices = shipping_addresses?.[0]?.available_shipping_methods?.find(
69
70
  (avail) =>
70
- (shippingMethod?.amount.value ?? 0) > 0 &&
71
+ (shippingMethod?.amount?.value ?? 0) > 0 &&
71
72
  avail?.carrier_code === shippingMethod?.carrier_code &&
72
73
  avail?.method_code === shippingMethod?.method_code,
73
74
  )
@@ -1,56 +1,25 @@
1
- import { responsiveVal, SvgImage, iconSadShoppingBag } from '@graphcommerce/next-ui'
2
- import { makeStyles, Theme, Typography } from '@material-ui/core'
1
+ import { iconSadShoppingBag, FullPageMessage, SvgImageSimple } from '@graphcommerce/next-ui'
2
+ import { Button } from '@material-ui/core'
3
+ import Link from 'next/link'
3
4
  import React from 'react'
4
5
 
5
- const useStyles = makeStyles(
6
- (theme: Theme) => ({
7
- root: {
8
- textAlign: 'center',
9
- display: 'flex',
10
- justifyContent: 'center',
11
- alignItems: 'center',
12
- [theme.breakpoints.down('sm')]: {
13
- minHeight: '70vh',
14
- },
15
- [theme.breakpoints.up('md')]: {
16
- minHeight: '60vh',
17
- },
18
- },
19
- img: {
20
- display: 'block',
21
- margin: `0 auto ${theme.spacings.xxs} auto`,
22
- width: responsiveVal(120, 180),
23
- height: responsiveVal(120, 180),
24
- },
25
- }),
26
- { name: 'EmptyCart' },
27
- )
28
-
29
6
  type EmptyCartProps = { children?: React.ReactNode }
30
7
  export default function EmptyCart(props: EmptyCartProps) {
31
8
  const { children } = props
32
- const classes = useStyles()
33
9
 
34
10
  return (
35
- <div className={classes.root}>
36
- <div>
37
- <SvgImage
38
- src={iconSadShoppingBag}
39
- alt='Empty Cart'
40
- className={classes.img}
41
- loading='eager'
42
- size='large'
43
- />
44
-
45
- {children ?? (
46
- <>
47
- <Typography variant='h3' gutterBottom component='h1'>
48
- Your cart is empty
49
- </Typography>
50
- <Typography>Discover our collection and add items to your basket!</Typography>
51
- </>
52
- )}
53
- </div>
54
- </div>
11
+ <FullPageMessage
12
+ title='Your cart is empty'
13
+ icon={<SvgImageSimple src={iconSadShoppingBag} alt='Empty Cart' layout='fill' />}
14
+ button={
15
+ <Link href='/' passHref>
16
+ <Button variant='contained' color='primary' size='large'>
17
+ Continue shopping
18
+ </Button>
19
+ </Link>
20
+ }
21
+ >
22
+ {children ?? <>Discover our collection and add items to your basket!</>}
23
+ </FullPageMessage>
55
24
  )
56
25
  }
@@ -12,8 +12,8 @@ export { default as EmptyCart } from './EmptyCart/EmptyCart'
12
12
  export * from './ApolloCartError/ApolloCartErrorAlert'
13
13
  export { default as ApolloCartErrorAlert } from './ApolloCartError/ApolloCartErrorAlert'
14
14
 
15
- // export { default as ApolloCartErrorFullPage } from './ApolloCartError/ApolloCartErrorFullPage'
16
- // export * from './ApolloCartError/ApolloCartErrorFullPage'
15
+ export * from './ApolloCartError/ApolloCartErrorFullPage'
16
+ export { default as ApolloCartErrorFullPage } from './ApolloCartError/ApolloCartErrorFullPage'
17
17
 
18
18
  export * from './CartSummary'
19
19
  export { default as CartSummary } from './CartSummary'
@@ -28,3 +28,6 @@ export { default as CartAddressMultiLine } from './CartAddressMultiLine'
28
28
 
29
29
  export * from './CartAddressSingleLine'
30
30
  export { default as CartAddressSingleLine } from './CartAddressSingleLine'
31
+
32
+ export * from './CartAgreementsForm/CartAgreementsForm'
33
+ export { default as CartAgreementsForm } from './CartAgreementsForm/CartAgreementsForm'
@@ -1,14 +1,13 @@
1
1
  import { useApolloClient } from '@apollo/client'
2
2
  import { CurrentCartIdDocument } from './CurrentCartId.gql'
3
- import { useCurrentCartId } from './useCurrentCartId'
4
3
 
5
4
  export function useClearCurrentCartId() {
6
5
  const { cache } = useApolloClient()
7
- const currentCartId = useCurrentCartId()
8
-
9
- if (!currentCartId) return undefined
10
6
 
11
7
  return () => {
8
+ const id = cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId?.id
9
+ if (!id) return
10
+
12
11
  cache.writeQuery({
13
12
  query: CurrentCartIdDocument,
14
13
  data: { currentCartId: { __typename: 'CurrentCartId', id: null } },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphcommerce/magento-cart",
3
- "version": "3.1.0",
3
+ "version": "3.1.4",
4
4
  "sideEffects": false,
5
5
  "prettier": "@graphcommerce/prettier-config-pwa",
6
6
  "browserslist": [
@@ -14,21 +14,21 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@graphcommerce/browserslist-config-pwa": "^3.0.1",
17
- "@graphcommerce/eslint-config-pwa": "^3.0.4",
17
+ "@graphcommerce/eslint-config-pwa": "^3.0.5",
18
18
  "@graphcommerce/prettier-config-pwa": "^3.0.2",
19
19
  "@graphcommerce/typescript-config-pwa": "^3.1.0",
20
20
  "@playwright/test": "^1.15.0"
21
21
  },
22
22
  "dependencies": {
23
- "@apollo/client": "^3.3.21",
24
- "@graphcommerce/framer-scroller": "^0.2.5",
25
- "@graphcommerce/graphql": "^2.103.4",
26
- "@graphcommerce/image": "^2.104.5",
27
- "@graphcommerce/magento-customer": "^3.0.13",
28
- "@graphcommerce/magento-graphql": "^2.103.4",
29
- "@graphcommerce/magento-store": "^3.0.11",
30
- "@graphcommerce/next-ui": "^3.1.3",
31
- "@graphcommerce/react-hook-form": "^2.102.4",
23
+ "@apollo/client": "^3.4.16",
24
+ "@graphcommerce/framer-scroller": "^0.2.7",
25
+ "@graphcommerce/graphql": "^2.103.5",
26
+ "@graphcommerce/image": "^2.104.6",
27
+ "@graphcommerce/magento-customer": "^3.0.17",
28
+ "@graphcommerce/magento-graphql": "^2.103.5",
29
+ "@graphcommerce/magento-store": "^3.0.15",
30
+ "@graphcommerce/next-ui": "^3.1.7",
31
+ "@graphcommerce/react-hook-form": "^2.102.6",
32
32
  "@graphql-typed-document-node/core": "^3.1.0",
33
33
  "@material-ui/core": "^4.12.3",
34
34
  "@material-ui/lab": "^4.0.0-alpha.60",
@@ -38,5 +38,5 @@
38
38
  "react": "^17.0.2",
39
39
  "react-dom": "^17.0.2"
40
40
  },
41
- "gitHead": "bffc2d42dc3f1e6a95cbff7025ede389693f8a54"
41
+ "gitHead": "7c6ad9b6fdf91e48b33013218d962ad15f931db8"
42
42
  }