@graphcommerce/magento-customer 4.3.1 → 4.4.1
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 +34 -0
- package/components/CustomerFab/CustomerFab.tsx +12 -11
- package/components/CustomerMenuFabItem/CustomerMenuFabItem.tsx +9 -10
- package/hooks/index.ts +3 -2
- package/hooks/useCustomerSession.ts +6 -9
- package/hooks/useFormIsEmailAvailable.tsx +11 -13
- package/hooks/useGuestQuery.ts +11 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 4.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1487](https://github.com/graphcommerce-org/graphcommerce/pull/1487) [`238aa4d34`](https://github.com/graphcommerce-org/graphcommerce/commit/238aa4d3478773b8cb0973f4112c9829e59e16d6) Thanks [@paales](https://github.com/paales)! - When @injecting mandatory fields into the CustomerTokenFragment it would throw a typescript error.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`afc67103d`](https://github.com/graphcommerce-org/graphcommerce/commit/afc67103d0e00583e274465036fd287537f95e79)]:
|
|
10
|
+
- @graphcommerce/next-ui@4.8.3
|
|
11
|
+
- @graphcommerce/ecommerce-ui@1.0.15
|
|
12
|
+
- @graphcommerce/magento-store@4.2.7
|
|
13
|
+
|
|
14
|
+
## 4.4.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- [#1485](https://github.com/graphcommerce-org/graphcommerce/pull/1485) [`d6262de71`](https://github.com/graphcommerce-org/graphcommerce/commit/d6262de71d2254a2b0b492e1a60f9e141767470e) Thanks [@paales](https://github.com/paales)! - move to useCustomerSession instead of using the tokenquery directly and fix ssr issues
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`c8c246b8a`](https://github.com/graphcommerce-org/graphcommerce/commit/c8c246b8aaab0621b68a2fca2a1c529a56fad962)]:
|
|
23
|
+
- @graphcommerce/next-ui@4.8.2
|
|
24
|
+
- @graphcommerce/ecommerce-ui@1.0.14
|
|
25
|
+
- @graphcommerce/magento-store@4.2.6
|
|
26
|
+
|
|
27
|
+
## 4.3.2
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [[`a9df81310`](https://github.com/graphcommerce-org/graphcommerce/commit/a9df81310c051876dd82fb2819105dece47cc213), [`f167f9963`](https://github.com/graphcommerce-org/graphcommerce/commit/f167f99630966a7de43717937d43669e66132494)]:
|
|
32
|
+
- @graphcommerce/next-ui@4.8.1
|
|
33
|
+
- @graphcommerce/ecommerce-ui@1.0.13
|
|
34
|
+
- @graphcommerce/magento-store@4.2.5
|
|
35
|
+
- @graphcommerce/image@3.1.6
|
|
36
|
+
|
|
3
37
|
## 4.3.1
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useQuery } from '@graphcommerce/graphql'
|
|
2
1
|
import {
|
|
3
2
|
iconPerson,
|
|
4
3
|
DesktopHeaderBadge,
|
|
@@ -9,14 +8,15 @@ import { i18n } from '@lingui/core'
|
|
|
9
8
|
import { Fab, FabProps as FabPropsType, NoSsr, SxProps, Theme } from '@mui/material'
|
|
10
9
|
import PageLink from 'next/link'
|
|
11
10
|
import React from 'react'
|
|
12
|
-
import {
|
|
11
|
+
import { useCustomerSession, UseCustomerSessionReturn } from '../../hooks'
|
|
13
12
|
|
|
14
|
-
type CustomerFabContentProps =
|
|
13
|
+
type CustomerFabContentProps = {
|
|
15
14
|
icon?: React.ReactNode
|
|
16
15
|
authHref: string
|
|
17
16
|
guestHref: string
|
|
18
17
|
FabProps?: Omit<FabPropsType, 'children'>
|
|
19
18
|
sx?: SxProps<Theme>
|
|
19
|
+
session?: UseCustomerSessionReturn
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const name = 'CustomerFab'
|
|
@@ -24,11 +24,10 @@ const parts = ['root'] as const
|
|
|
24
24
|
const { classes } = extendableComponent(name, parts)
|
|
25
25
|
|
|
26
26
|
function CustomerFabContent(props: CustomerFabContentProps) {
|
|
27
|
-
const {
|
|
28
|
-
const { requireAuth } = useCustomerSession()
|
|
27
|
+
const { session, icon, guestHref, authHref, FabProps, sx } = props
|
|
29
28
|
|
|
30
29
|
return (
|
|
31
|
-
<PageLink href={requireAuth ? guestHref : authHref} passHref>
|
|
30
|
+
<PageLink href={session?.requireAuth ? guestHref : authHref} passHref>
|
|
32
31
|
<Fab
|
|
33
32
|
color='inherit'
|
|
34
33
|
id='account'
|
|
@@ -39,8 +38,8 @@ function CustomerFabContent(props: CustomerFabContentProps) {
|
|
|
39
38
|
sx={sx}
|
|
40
39
|
>
|
|
41
40
|
<DesktopHeaderBadge
|
|
42
|
-
badgeContent={
|
|
43
|
-
color={
|
|
41
|
+
badgeContent={session?.token ? 1 : 0}
|
|
42
|
+
color={session?.valid ? 'primary' : 'error'}
|
|
44
43
|
variant='dot'
|
|
45
44
|
overlap='circular'
|
|
46
45
|
>
|
|
@@ -51,12 +50,14 @@ function CustomerFabContent(props: CustomerFabContentProps) {
|
|
|
51
50
|
)
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
export
|
|
55
|
-
|
|
53
|
+
export type CustomerFabProps = Omit<CustomerFabContentProps, 'session'>
|
|
54
|
+
|
|
55
|
+
export function CustomerFab(props: CustomerFabProps) {
|
|
56
|
+
const session = useCustomerSession()
|
|
56
57
|
|
|
57
58
|
return (
|
|
58
59
|
<NoSsr fallback={<CustomerFabContent {...props} />}>
|
|
59
|
-
<CustomerFabContent
|
|
60
|
+
<CustomerFabContent session={session} {...props} />
|
|
60
61
|
</NoSsr>
|
|
61
62
|
)
|
|
62
63
|
}
|
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
import { useQuery } from '@graphcommerce/graphql'
|
|
2
1
|
import { MenuFabSecondaryItem, iconPerson, IconSvg } from '@graphcommerce/next-ui'
|
|
3
2
|
import { Badge, NoSsr, SxProps, Theme } from '@mui/material'
|
|
4
3
|
import React from 'react'
|
|
5
|
-
import {
|
|
4
|
+
import { useCustomerSession, UseCustomerSessionReturn } from '../../hooks/useCustomerSession'
|
|
6
5
|
|
|
7
|
-
type CustomerMenuFabItemProps =
|
|
6
|
+
type CustomerMenuFabItemProps = {
|
|
8
7
|
icon?: React.ReactNode
|
|
9
8
|
children: React.ReactNode
|
|
10
9
|
authHref: string
|
|
11
10
|
guestHref: string
|
|
12
11
|
sx?: SxProps<Theme>
|
|
12
|
+
session?: UseCustomerSessionReturn
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function CustomerMenuFabItemContent(props: CustomerMenuFabItemProps) {
|
|
16
|
-
const {
|
|
17
|
-
const requireAuth = Boolean(!customerToken || !customerToken.valid)
|
|
16
|
+
const { session, icon, children, guestHref, authHref, sx = [] } = props
|
|
18
17
|
|
|
19
18
|
return (
|
|
20
19
|
<MenuFabSecondaryItem
|
|
21
20
|
sx={sx}
|
|
22
21
|
icon={
|
|
23
22
|
<Badge
|
|
24
|
-
badgeContent={
|
|
25
|
-
color={
|
|
23
|
+
badgeContent={session?.token ? 1 : 0}
|
|
24
|
+
color={session?.valid ? 'primary' : 'error'}
|
|
26
25
|
variant='dot'
|
|
27
26
|
overlap='circular'
|
|
28
27
|
>
|
|
29
28
|
{icon ?? <IconSvg src={iconPerson} size='medium' />}
|
|
30
29
|
</Badge>
|
|
31
30
|
}
|
|
32
|
-
href={requireAuth ? guestHref : authHref}
|
|
31
|
+
href={session?.requireAuth ? guestHref : authHref}
|
|
33
32
|
>
|
|
34
33
|
{children}
|
|
35
34
|
</MenuFabSecondaryItem>
|
|
@@ -37,11 +36,11 @@ function CustomerMenuFabItemContent(props: CustomerMenuFabItemProps) {
|
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
export function CustomerMenuFabItem(props: CustomerMenuFabItemProps) {
|
|
40
|
-
const
|
|
39
|
+
const session = useCustomerSession()
|
|
41
40
|
|
|
42
41
|
return (
|
|
43
42
|
<NoSsr fallback={<CustomerMenuFabItemContent {...props} />}>
|
|
44
|
-
<CustomerMenuFabItemContent
|
|
43
|
+
<CustomerMenuFabItemContent session={session} {...props} />
|
|
45
44
|
</NoSsr>
|
|
46
45
|
)
|
|
47
46
|
}
|
package/hooks/index.ts
CHANGED
|
@@ -2,7 +2,8 @@ export * from './Customer.gql'
|
|
|
2
2
|
export * from './CustomerInfo.gql'
|
|
3
3
|
export * from './CustomerToken.gql'
|
|
4
4
|
export * from './IsEmailAvailable.gql'
|
|
5
|
-
export * from './useExtractCustomerErrors'
|
|
6
|
-
export * from './useFormIsEmailAvailable'
|
|
7
5
|
export * from './useCustomerQuery'
|
|
8
6
|
export * from './useCustomerSession'
|
|
7
|
+
export * from './useExtractCustomerErrors'
|
|
8
|
+
export * from './useFormIsEmailAvailable'
|
|
9
|
+
export * from './useGuestQuery'
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { useQuery } from '@graphcommerce/graphql'
|
|
2
|
-
import { CustomerTokenDocument } from './CustomerToken.gql'
|
|
3
|
-
import { CustomerTokenFragment } from './CustomerTokenFragment.gql'
|
|
2
|
+
import { CustomerTokenDocument, CustomerTokenQuery } from './CustomerToken.gql'
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
| (CustomerTokenFragment & {
|
|
7
|
-
loggedIn: boolean
|
|
8
|
-
requireAuth: boolean
|
|
9
|
-
})
|
|
10
|
-
| (Partial<CustomerTokenFragment> & { loggedIn: false; requireAuth: true })
|
|
4
|
+
type TokenResponse = Omit<NonNullable<CustomerTokenQuery['customerToken']>, '__typename'>
|
|
11
5
|
|
|
12
|
-
export
|
|
6
|
+
export type UseCustomerSessionReturn =
|
|
7
|
+
| Partial<TokenResponse> & { loggedIn: boolean; requireAuth: boolean }
|
|
8
|
+
|
|
9
|
+
export function useCustomerSession(): UseCustomerSessionReturn {
|
|
13
10
|
const token = useQuery(CustomerTokenDocument, { ssr: false, fetchPolicy: 'cache-only' }).data
|
|
14
11
|
?.customerToken
|
|
15
12
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { useQuery } from '@graphcommerce/graphql'
|
|
2
1
|
import { useFormAutoSubmit, useFormGqlQuery, useFormPersist } from '@graphcommerce/react-hook-form'
|
|
3
2
|
import { useEffect, useState } from 'react'
|
|
4
3
|
import { CustomerDocument } from './Customer.gql'
|
|
5
|
-
import { CustomerTokenDocument } from './CustomerToken.gql'
|
|
6
4
|
import { IsEmailAvailableDocument } from './IsEmailAvailable.gql'
|
|
7
5
|
import { useCustomerQuery } from './useCustomerQuery'
|
|
6
|
+
import { useCustomerSession } from './useCustomerSession'
|
|
8
7
|
|
|
9
8
|
export type UseFormIsEmailAvailableProps = {
|
|
10
9
|
email?: string | null
|
|
@@ -13,32 +12,31 @@ export type UseFormIsEmailAvailableProps = {
|
|
|
13
12
|
|
|
14
13
|
export function useFormIsEmailAvailable(props: UseFormIsEmailAvailableProps) {
|
|
15
14
|
const { email, onSubmitted } = props
|
|
16
|
-
const {
|
|
15
|
+
const { loggedIn, requireAuth } = useCustomerSession()
|
|
17
16
|
const customerQuery = useCustomerQuery(CustomerDocument)
|
|
18
17
|
|
|
19
18
|
const form = useFormGqlQuery(
|
|
20
19
|
IsEmailAvailableDocument,
|
|
21
20
|
{ mode: 'onChange', defaultValues: { email: email ?? '' } },
|
|
22
|
-
{ fetchPolicy: 'cache-and-network' },
|
|
21
|
+
// { fetchPolicy: 'cache-and-network' },
|
|
23
22
|
)
|
|
24
23
|
const { formState, data, handleSubmit } = form
|
|
25
24
|
|
|
26
25
|
const submit = handleSubmit(onSubmitted || (() => {}))
|
|
27
|
-
const autoSubmitting = useFormAutoSubmit({ form, submit })
|
|
26
|
+
const autoSubmitting = useFormAutoSubmit({ form, submit, forceInitialSubmit: true })
|
|
28
27
|
|
|
29
28
|
const hasAccount = data?.isEmailAvailable?.is_email_available === false
|
|
30
|
-
const { isDirty, isSubmitSuccessful, isSubmitted, isSubmitting, isValid } = formState
|
|
31
29
|
|
|
32
|
-
const
|
|
30
|
+
const { isDirty, isSubmitSuccessful, isSubmitted, isSubmitting, isValid } = formState
|
|
33
31
|
|
|
34
32
|
const [mode, setMode] = useState<'email' | 'signin' | 'signup' | 'signedin' | 'session-expired'>(
|
|
35
|
-
|
|
33
|
+
loggedIn ? 'signedin' : 'email',
|
|
36
34
|
)
|
|
37
35
|
|
|
38
36
|
useFormPersist({ form, name: 'IsEmailAvailable' })
|
|
39
37
|
|
|
40
38
|
useEffect(() => {
|
|
41
|
-
if (
|
|
39
|
+
if (loggedIn) {
|
|
42
40
|
setMode('signedin')
|
|
43
41
|
return
|
|
44
42
|
}
|
|
@@ -47,19 +45,19 @@ export function useFormIsEmailAvailable(props: UseFormIsEmailAvailableProps) {
|
|
|
47
45
|
if (!isDirty && isSubmitted && isSubmitSuccessful && isValid)
|
|
48
46
|
setMode(hasAccount ? 'signin' : 'signup')
|
|
49
47
|
|
|
50
|
-
if (customerQuery.data?.customer &&
|
|
48
|
+
if (customerQuery.data?.customer && requireAuth)
|
|
51
49
|
setMode(isSubmitSuccessful ? 'signin' : 'session-expired')
|
|
52
50
|
}, [
|
|
53
51
|
customerQuery.data?.customer,
|
|
54
52
|
hasAccount,
|
|
55
53
|
isDirty,
|
|
56
|
-
isLoggedIn,
|
|
57
54
|
isSubmitSuccessful,
|
|
58
55
|
isSubmitted,
|
|
59
56
|
isSubmitting,
|
|
60
57
|
isValid,
|
|
61
|
-
|
|
58
|
+
loggedIn,
|
|
59
|
+
requireAuth,
|
|
62
60
|
])
|
|
63
61
|
|
|
64
|
-
return { mode, form,
|
|
62
|
+
return { mode, form, submit, autoSubmitting, hasAccount }
|
|
65
63
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useQuery, TypedDocumentNode, QueryHookOptions } from '@graphcommerce/graphql'
|
|
2
|
+
import { useCustomerSession } from './useCustomerSession'
|
|
3
|
+
|
|
4
|
+
/** Will only execute when the customer is not signed in. */
|
|
5
|
+
export function useGuestQuery<Q, V>(
|
|
6
|
+
document: TypedDocumentNode<Q, V>,
|
|
7
|
+
queryOptions: QueryHookOptions<Q, V> = {},
|
|
8
|
+
) {
|
|
9
|
+
const { token } = useCustomerSession()
|
|
10
|
+
return useQuery(document, { ...queryOptions, ssr: false, skip: !!token })
|
|
11
|
+
}
|
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": "4.
|
|
5
|
+
"version": "4.4.1",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
"@playwright/test": "^1.21.1"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@graphcommerce/ecommerce-ui": "1.0.
|
|
21
|
+
"@graphcommerce/ecommerce-ui": "1.0.15",
|
|
22
22
|
"@graphcommerce/graphql": "3.1.3",
|
|
23
23
|
"@graphcommerce/graphql-mesh": "4.1.3",
|
|
24
|
-
"@graphcommerce/image": "3.1.
|
|
24
|
+
"@graphcommerce/image": "3.1.6",
|
|
25
25
|
"@graphcommerce/magento-graphql": "3.0.12",
|
|
26
|
-
"@graphcommerce/magento-store": "4.2.
|
|
27
|
-
"@graphcommerce/next-ui": "4.8.
|
|
26
|
+
"@graphcommerce/magento-store": "4.2.7",
|
|
27
|
+
"@graphcommerce/next-ui": "4.8.3",
|
|
28
28
|
"@graphcommerce/react-hook-form": "3.1.3"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|