@graphcommerce/magento-store 3.0.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 +123 -0
- package/Money.gql.ts +4 -0
- package/Money.graphql +4 -0
- package/Money.tsx +27 -0
- package/PageMeta.tsx +37 -0
- package/StoreConfig.gql.ts +10 -0
- package/StoreConfig.graphql +29 -0
- package/config-to-env/EnvConfig.d.ts +7 -0
- package/config-to-env/EnvConfig.gql.ts +10 -0
- package/config-to-env/EnvConfig.graphql +33 -0
- package/config-to-env/index.ts +38 -0
- package/hooks/useFindCountry.ts +10 -0
- package/hooks/useFindRegion.ts +18 -0
- package/index.ts +20 -0
- package/localeToStore.ts +19 -0
- package/next-env.d.ts +4 -0
- package/package.json +35 -0
- package/queries/CountryRegions.gql.ts +10 -0
- package/queries/CountryRegions.graphql +12 -0
- package/switcher/CountryLocale.gql.ts +4 -0
- package/switcher/CountryLocale.graphql +5 -0
- package/switcher/StoreLocale.gql.ts +4 -0
- package/switcher/StoreLocale.graphql +8 -0
- package/switcher/StoreSwitcherButton.tsx +34 -0
- package/switcher/StoreSwitcherList.gql.ts +10 -0
- package/switcher/StoreSwitcherList.graphql +10 -0
- package/switcher/StoreSwitcherList.tsx +120 -0
- package/tsconfig.json +5 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [3.0.1](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-store@3.0.0...@graphcommerce/magento-store@3.0.1) (2021-09-27)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @graphcommerce/magento-store
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0 (2021-09-27)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* canonical urls ([9ff8d3f](https://github.com/ho-nl/m2-pwa/commit/9ff8d3f950098fb28440f31f5dd93a835dce0bda))
|
|
20
|
+
* change href's from faq to service ([cb9875b](https://github.com/ho-nl/m2-pwa/commit/cb9875bce43db5953f227ee60f8d5dfe339f50b5))
|
|
21
|
+
* code consistency ([a310f0e](https://github.com/ho-nl/m2-pwa/commit/a310f0e548907c044b016b9473641ecd378b313f))
|
|
22
|
+
* **country-switcher:** navigate back to correct locale ([579d146](https://github.com/ho-nl/m2-pwa/commit/579d146e1b658a343b1514d8e8a45c01a507c084))
|
|
23
|
+
* duplicated (meta) tags in document head ([d52e962](https://github.com/ho-nl/m2-pwa/commit/d52e9629036ccab1f266ddd01600a0bd45930149))
|
|
24
|
+
* footer country flag ([8c6bf20](https://github.com/ho-nl/m2-pwa/commit/8c6bf206f85d44289a8d11d9bcd2178af6cc3445))
|
|
25
|
+
* get more data from store locale ([455245c](https://github.com/ho-nl/m2-pwa/commit/455245cf88d4a0cfbe197c97739306af8d8ff211))
|
|
26
|
+
* ignore md files from triggering version updates ([4f98392](https://github.com/ho-nl/m2-pwa/commit/4f9839250b3a32d3070da5290e5efcc5e2243fba))
|
|
27
|
+
* implement next-ui barrel imports ([75bea70](https://github.com/ho-nl/m2-pwa/commit/75bea703dba898f18a2a1dfa3243ebd0a4e6f0e1))
|
|
28
|
+
* lint error ([be542af](https://github.com/ho-nl/m2-pwa/commit/be542afc466209c79cb776aac494abb7cab24bf7))
|
|
29
|
+
* **magento-store:** move useCountry/useRegion to magento-store and rename to useFindCountry/useFindRegion ([3fed1c5](https://github.com/ho-nl/m2-pwa/commit/3fed1c53f975977e2681a9b80bb283332d9ad5ec))
|
|
30
|
+
* make storeswitcher a button ([a7dc452](https://github.com/ho-nl/m2-pwa/commit/a7dc45297e565be9c5d72c03e3d8c4a61c415c8a))
|
|
31
|
+
* prices wouldn’t render if the price wasn’t an integer ([0866881](https://github.com/ho-nl/m2-pwa/commit/08668813699065b168e3d9b1fe2410c5cd073c89))
|
|
32
|
+
* prop types ([caccb1a](https://github.com/ho-nl/m2-pwa/commit/caccb1ab4c459642b64498dde22c372fd890f0c7))
|
|
33
|
+
* remove button from store-switcher in footer ([43f6d52](https://github.com/ho-nl/m2-pwa/commit/43f6d5227edff809effa46b658afc0d3c4268f3f))
|
|
34
|
+
* remove canonical metatag when no canonical is given ([167b7f0](https://github.com/ho-nl/m2-pwa/commit/167b7f080f98a10ff35cbd760b24b8198aac6518))
|
|
35
|
+
* search not submitting after empying the field ([a15b5cf](https://github.com/ho-nl/m2-pwa/commit/a15b5cf94f4619e0087c8871a98617ab160f671a))
|
|
36
|
+
* secure base link url in store config ([ecba5c2](https://github.com/ho-nl/m2-pwa/commit/ecba5c2b2c109b027916872ca860c566b031d8a4))
|
|
37
|
+
* since all links are of next/link we need to add passHref for custom components ([16fb931](https://github.com/ho-nl/m2-pwa/commit/16fb93100d367203ea79bb4f93357221253f2ecd))
|
|
38
|
+
* yarn workspace packages hot reload ([d03fc9f](https://github.com/ho-nl/m2-pwa/commit/d03fc9fdda3486476761786f2b56a934cc92befc))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Features
|
|
42
|
+
|
|
43
|
+
* add getFilterTypes to shared client, faster generation ([beccfde](https://github.com/ho-nl/m2-pwa/commit/beccfde6ebc8aaf6223f0e8b33fabf4f5039efed))
|
|
44
|
+
* added footer buttons ([65610cc](https://github.com/ho-nl/m2-pwa/commit/65610cc1db2929b9203a3b7b25375a8324bc8ce9))
|
|
45
|
+
* added store switcher route ([64b04b3](https://github.com/ho-nl/m2-pwa/commit/64b04b3c1488c93395b228ac04c9d3c3912391a2))
|
|
46
|
+
* better 404 handling and simplified getStaticProps ([321ace1](https://github.com/ho-nl/m2-pwa/commit/321ace1850642ee3eddfa674c37e6fca8adcdb74))
|
|
47
|
+
* canonical urls using abstract page meta component ([5f09b6f](https://github.com/ho-nl/m2-pwa/commit/5f09b6f89f4c39f5465869b86468c384de73faba))
|
|
48
|
+
* created stacked-pages package ([d86008e](https://github.com/ho-nl/m2-pwa/commit/d86008ee659ccb25b194a41d624b394a1ddbd088))
|
|
49
|
+
* **graphql:** introduced new graphql package that holds all generated files ([a3e7aa0](https://github.com/ho-nl/m2-pwa/commit/a3e7aa05540540533b5ced9a95f1f802ecbe499f))
|
|
50
|
+
* i18n routing added (/ and /fr for demo) ([bb3b339](https://github.com/ho-nl/m2-pwa/commit/bb3b339fbc9fceddd264a891ad81f00327a241ae))
|
|
51
|
+
* **image:** introduced completely rewritten Image component ([e3413b3](https://github.com/ho-nl/m2-pwa/commit/e3413b3a57392d6571ea64cb8d9c8dca05ea31df))
|
|
52
|
+
* introduces framer-next-pages and framer-sheet to next-ui and soxbase package ([e04ad8a](https://github.com/ho-nl/m2-pwa/commit/e04ad8a94cd1fd5a7c5575c9db7916b6e8a88f16))
|
|
53
|
+
* major performance refactor ([03f8e2f](https://github.com/ho-nl/m2-pwa/commit/03f8e2fa16ef919bd6bd6eadd36922d0245ed960))
|
|
54
|
+
* move to category_uid instead of category_id ([a2efe8d](https://github.com/ho-nl/m2-pwa/commit/a2efe8daac6ebe949070108fc4bcf8cc0919c1c7))
|
|
55
|
+
* next.js 11 ([7d61407](https://github.com/ho-nl/m2-pwa/commit/7d614075a778f488045034f74be4f75b93f63c43))
|
|
56
|
+
* **playwright:** added new playwright package to enable browser testing ([6f49ec7](https://github.com/ho-nl/m2-pwa/commit/6f49ec7595563775b96ebf21c27e39da1282e8d9))
|
|
57
|
+
* renamed all packages to use [@graphcommerce](https://github.com/graphcommerce) instead of [@reachdigital](https://github.com/reachdigital) ([491e4ce](https://github.com/ho-nl/m2-pwa/commit/491e4cec9a2686472dac36b79f999257c0811ffe))
|
|
58
|
+
* support reviews store config variables ([532e849](https://github.com/ho-nl/m2-pwa/commit/532e84926c97affcd21ade56773bc06a02060b3a))
|
|
59
|
+
* upgrade to node 14 ([d079a75](https://github.com/ho-nl/m2-pwa/commit/d079a751e9bfd8dc7f5009d2c9f31c336a0c96ab))
|
|
60
|
+
* upgraded to nextjs 11 ([0053beb](https://github.com/ho-nl/m2-pwa/commit/0053beb7ef597c190add7264256a0eaec35868da))
|
|
61
|
+
* useFormMutationCart and simpler imports ([012f090](https://github.com/ho-nl/m2-pwa/commit/012f090e8f54d09f35d393c61ad1e2319f5a90ff))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Reverts
|
|
65
|
+
|
|
66
|
+
* Revert "chore: upgrade @apollo/client" ([55ff24e](https://github.com/ho-nl/m2-pwa/commit/55ff24ede0e56c85b8095edadadd1ec5e0b1b8d2))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## 2.0.8 (2020-10-28)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Bug Fixes
|
|
74
|
+
|
|
75
|
+
* make sure themes extensions are found ([5aa18db](https://github.com/ho-nl/m2-pwa/commit/5aa18db514fd2e2f50681367e39523f8e742ece0))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
### Features
|
|
79
|
+
|
|
80
|
+
* added generated graphql.ts files ([3e44415](https://github.com/ho-nl/m2-pwa/commit/3e44415b018e74b502e9e98479aa5e84041f337d))
|
|
81
|
+
* split into packages ([2ee7fd6](https://github.com/ho-nl/m2-pwa/commit/2ee7fd6c0056f467d114f04d92c6c0ddf622d151))
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### BREAKING CHANGES
|
|
85
|
+
|
|
86
|
+
* huge folder structure refactor, please read README to reinstall
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Change Log
|
|
93
|
+
|
|
94
|
+
All notable changes to this project will be documented in this file. See
|
|
95
|
+
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
96
|
+
|
|
97
|
+
# [2.102.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-store@2.101.9...@graphcommerce/magento-store@2.102.0) (2021-08-12)
|
|
98
|
+
|
|
99
|
+
### Features
|
|
100
|
+
|
|
101
|
+
- upgraded to nextjs 11
|
|
102
|
+
([0053beb](https://github.com/ho-nl/m2-pwa/commit/0053beb7ef597c190add7264256a0eaec35868da))
|
|
103
|
+
|
|
104
|
+
## [2.101.9](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-store@2.101.8...@graphcommerce/magento-store@2.101.9) (2021-08-09)
|
|
105
|
+
|
|
106
|
+
### Reverts
|
|
107
|
+
|
|
108
|
+
- Revert "chore: upgrade @apollo/client"
|
|
109
|
+
([55ff24e](https://github.com/ho-nl/m2-pwa/commit/55ff24ede0e56c85b8095edadadd1ec5e0b1b8d2))
|
|
110
|
+
|
|
111
|
+
# [2.101.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-store@2.100.18...@graphcommerce/magento-store@2.101.0) (2021-07-26)
|
|
112
|
+
|
|
113
|
+
### Features
|
|
114
|
+
|
|
115
|
+
- **playwright:** added new playwright package to enable browser testing
|
|
116
|
+
([6f49ec7](https://github.com/ho-nl/m2-pwa/commit/6f49ec7595563775b96ebf21c27e39da1282e8d9))
|
|
117
|
+
|
|
118
|
+
## [2.100.11](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-store@2.100.10...@graphcommerce/magento-store@2.100.11) (2021-07-20)
|
|
119
|
+
|
|
120
|
+
### Bug Fixes
|
|
121
|
+
|
|
122
|
+
- ignore md files from triggering version updates
|
|
123
|
+
([4f98392](https://github.com/ho-nl/m2-pwa/commit/4f9839250b3a32d3070da5290e5efcc5e2243fba))
|
package/Money.gql.ts
ADDED
package/Money.graphql
ADDED
package/Money.tsx
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import React, { useMemo } from 'react'
|
|
3
|
+
import { MoneyFragment } from './Money.gql'
|
|
4
|
+
import { StoreConfigDocument } from './StoreConfig.gql'
|
|
5
|
+
|
|
6
|
+
export type MoneyProps = MoneyFragment & { round?: boolean }
|
|
7
|
+
|
|
8
|
+
export default function Money({ currency, value, round = false }: MoneyProps) {
|
|
9
|
+
const { data: config } = useQuery(StoreConfigDocument)
|
|
10
|
+
const locale = config?.storeConfig?.locale
|
|
11
|
+
|
|
12
|
+
const digits = round && (value ?? 0) % 1 === 0
|
|
13
|
+
|
|
14
|
+
const numberFormatter = useMemo(() => {
|
|
15
|
+
if (!locale) return undefined
|
|
16
|
+
|
|
17
|
+
return new Intl.NumberFormat(locale.replace('_', '-'), {
|
|
18
|
+
style: 'currency',
|
|
19
|
+
currency: currency ?? config?.storeConfig?.base_currency_code ?? '',
|
|
20
|
+
...(digits && { minimumFractionDigits: 0 }),
|
|
21
|
+
})
|
|
22
|
+
}, [config?.storeConfig?.base_currency_code, currency, digits, locale])
|
|
23
|
+
|
|
24
|
+
if (!numberFormatter || !value) return null
|
|
25
|
+
|
|
26
|
+
return <>{numberFormatter.format(value)}</>
|
|
27
|
+
}
|
package/PageMeta.tsx
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import {
|
|
3
|
+
PageMeta as NextPageMeta,
|
|
4
|
+
PageMetaProps as NextPageMetaProps,
|
|
5
|
+
} from '@graphcommerce/next-ui'
|
|
6
|
+
import { StoreConfigDocument } from './StoreConfig.gql'
|
|
7
|
+
|
|
8
|
+
type PageMetaProps = Pick<NextPageMetaProps, 'title' | 'metaDescription' | 'metaRobots'> & {
|
|
9
|
+
canonical?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function PageMeta(props: PageMetaProps) {
|
|
13
|
+
const { title, canonical = '', ...pageMetaProps } = props
|
|
14
|
+
const config = useQuery(StoreConfigDocument)
|
|
15
|
+
|
|
16
|
+
const prefix = config.data?.storeConfig?.title_prefix ?? ''
|
|
17
|
+
const separator = config.data?.storeConfig?.title_separator ?? ''
|
|
18
|
+
const defaultTitle = config.data?.storeConfig?.default_title ?? ''
|
|
19
|
+
const suffix = config.data?.storeConfig?.title_suffix ?? ''
|
|
20
|
+
|
|
21
|
+
let pageTitle = prefix ?? ''
|
|
22
|
+
if (title ?? defaultTitle) pageTitle += ` ${title ?? defaultTitle}`
|
|
23
|
+
if (separator && suffix) pageTitle += ` ${separator}`
|
|
24
|
+
if (suffix) pageTitle += ` ${suffix}`
|
|
25
|
+
|
|
26
|
+
const urlPath = ((canonical ?? '').startsWith('/') && canonical?.substr(1)) || canonical
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<NextPageMeta
|
|
30
|
+
title={pageTitle ?? ''}
|
|
31
|
+
canonical={
|
|
32
|
+
urlPath ? `${config.data?.storeConfig?.secure_base_link_url ?? ''}${urlPath}` : undefined
|
|
33
|
+
}
|
|
34
|
+
{...pageMetaProps}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as Types from '@graphcommerce/graphql';
|
|
3
|
+
|
|
4
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
5
|
+
|
|
6
|
+
export const StoreConfigDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StoreConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storeConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"store_code"}},{"kind":"Field","name":{"kind":"Name","value":"store_name"}},{"kind":"Field","name":{"kind":"Name","value":"locale"}},{"kind":"Field","name":{"kind":"Name","value":"base_currency_code"}},{"kind":"Field","name":{"kind":"Name","value":"default_display_currency_code"}},{"kind":"Field","name":{"kind":"Name","value":"title_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"title_prefix"}},{"kind":"Field","name":{"kind":"Name","value":"title_separator"}},{"kind":"Field","name":{"kind":"Name","value":"default_title"}},{"kind":"Field","name":{"kind":"Name","value":"cms_home_page"}},{"kind":"Field","name":{"kind":"Name","value":"catalog_default_sort_by"}},{"kind":"Field","name":{"kind":"Name","value":"category_url_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"product_url_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"secure_base_link_url"}},{"kind":"Field","name":{"kind":"Name","value":"root_category_uid"}},{"kind":"Field","name":{"kind":"Name","value":"weight_unit"}},{"kind":"Field","name":{"kind":"Name","value":"product_reviews_enabled"}},{"kind":"Field","name":{"kind":"Name","value":"allow_guests_to_write_product_reviews"}}]}}]}}]} as unknown as DocumentNode<StoreConfigQuery, StoreConfigQueryVariables>;
|
|
7
|
+
export type StoreConfigQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export type StoreConfigQuery = { storeConfig?: Types.Maybe<{ store_code?: Types.Maybe<string>, store_name?: Types.Maybe<string>, locale?: Types.Maybe<string>, base_currency_code?: Types.Maybe<string>, default_display_currency_code?: Types.Maybe<string>, title_suffix?: Types.Maybe<string>, title_prefix?: Types.Maybe<string>, title_separator?: Types.Maybe<string>, default_title?: Types.Maybe<string>, cms_home_page?: Types.Maybe<string>, catalog_default_sort_by?: Types.Maybe<string>, category_url_suffix?: Types.Maybe<string>, product_url_suffix?: Types.Maybe<string>, secure_base_link_url?: Types.Maybe<string>, root_category_uid?: Types.Maybe<string>, weight_unit?: Types.Maybe<string>, product_reviews_enabled?: Types.Maybe<string>, allow_guests_to_write_product_reviews?: Types.Maybe<string> }> };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
query StoreConfig {
|
|
2
|
+
storeConfig {
|
|
3
|
+
store_code
|
|
4
|
+
store_name
|
|
5
|
+
|
|
6
|
+
locale
|
|
7
|
+
base_currency_code
|
|
8
|
+
default_display_currency_code
|
|
9
|
+
|
|
10
|
+
title_suffix
|
|
11
|
+
title_prefix
|
|
12
|
+
title_separator
|
|
13
|
+
default_title
|
|
14
|
+
|
|
15
|
+
cms_home_page
|
|
16
|
+
|
|
17
|
+
catalog_default_sort_by
|
|
18
|
+
category_url_suffix
|
|
19
|
+
product_url_suffix
|
|
20
|
+
secure_base_link_url
|
|
21
|
+
|
|
22
|
+
root_category_uid
|
|
23
|
+
|
|
24
|
+
weight_unit
|
|
25
|
+
|
|
26
|
+
product_reviews_enabled
|
|
27
|
+
allow_guests_to_write_product_reviews
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as Types from '@graphcommerce/graphql';
|
|
3
|
+
|
|
4
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
5
|
+
|
|
6
|
+
export const EnvConfigDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EnvConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"envConfig"},"name":{"kind":"Name","value":"availableStores"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"absolute_footer"}},{"kind":"Field","name":{"kind":"Name","value":"allow_guests_to_write_product_reviews"}},{"kind":"Field","name":{"kind":"Name","value":"allow_items"}},{"kind":"Field","name":{"kind":"Name","value":"allow_order"}},{"kind":"Field","name":{"kind":"Name","value":"autocomplete_on_storefront"}},{"kind":"Field","name":{"kind":"Name","value":"base_currency_code"}},{"kind":"Field","name":{"kind":"Name","value":"store_code"}},{"kind":"Field","name":{"kind":"Name","value":"store_name"}},{"kind":"Field","name":{"kind":"Name","value":"locale"}},{"kind":"Field","name":{"kind":"Name","value":"default_display_currency_code"}},{"kind":"Field","name":{"kind":"Name","value":"title_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"title_prefix"}},{"kind":"Field","name":{"kind":"Name","value":"title_separator"}},{"kind":"Field","name":{"kind":"Name","value":"default_title"}},{"kind":"Field","name":{"kind":"Name","value":"cms_home_page"}},{"kind":"Field","name":{"kind":"Name","value":"catalog_default_sort_by"}},{"kind":"Field","name":{"kind":"Name","value":"category_url_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"product_url_suffix"}},{"kind":"Field","name":{"kind":"Name","value":"base_link_url"}},{"kind":"Field","name":{"kind":"Name","value":"root_category_uid"}},{"kind":"Field","name":{"kind":"Name","value":"weight_unit"}}]}}]}}]} as unknown as DocumentNode<EnvConfigQuery, EnvConfigQueryVariables>;
|
|
7
|
+
export type EnvConfigQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export type EnvConfigQuery = { envConfig?: Types.Maybe<Array<Types.Maybe<{ absolute_footer?: Types.Maybe<string>, allow_guests_to_write_product_reviews?: Types.Maybe<string>, allow_items?: Types.Maybe<string>, allow_order?: Types.Maybe<string>, autocomplete_on_storefront?: Types.Maybe<boolean>, base_currency_code?: Types.Maybe<string>, store_code?: Types.Maybe<string>, store_name?: Types.Maybe<string>, locale?: Types.Maybe<string>, default_display_currency_code?: Types.Maybe<string>, title_suffix?: Types.Maybe<string>, title_prefix?: Types.Maybe<string>, title_separator?: Types.Maybe<string>, default_title?: Types.Maybe<string>, cms_home_page?: Types.Maybe<string>, catalog_default_sort_by?: Types.Maybe<string>, category_url_suffix?: Types.Maybe<string>, product_url_suffix?: Types.Maybe<string>, base_link_url?: Types.Maybe<string>, root_category_uid?: Types.Maybe<string>, weight_unit?: Types.Maybe<string> }>>> };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
query EnvConfig {
|
|
2
|
+
envConfig: availableStores {
|
|
3
|
+
absolute_footer
|
|
4
|
+
allow_guests_to_write_product_reviews
|
|
5
|
+
allow_items
|
|
6
|
+
allow_order
|
|
7
|
+
autocomplete_on_storefront
|
|
8
|
+
base_currency_code
|
|
9
|
+
|
|
10
|
+
store_code
|
|
11
|
+
store_name
|
|
12
|
+
|
|
13
|
+
locale
|
|
14
|
+
base_currency_code
|
|
15
|
+
default_display_currency_code
|
|
16
|
+
|
|
17
|
+
title_suffix
|
|
18
|
+
title_prefix
|
|
19
|
+
title_separator
|
|
20
|
+
default_title
|
|
21
|
+
|
|
22
|
+
cms_home_page
|
|
23
|
+
|
|
24
|
+
catalog_default_sort_by
|
|
25
|
+
category_url_suffix
|
|
26
|
+
product_url_suffix
|
|
27
|
+
base_link_url
|
|
28
|
+
|
|
29
|
+
root_category_uid
|
|
30
|
+
|
|
31
|
+
weight_unit
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import { FetchResult } from '@apollo/client'
|
|
4
|
+
import { config } from 'dotenv'
|
|
5
|
+
import { print } from 'graphql'
|
|
6
|
+
import fetch from 'node-fetch'
|
|
7
|
+
import { EnvConfigDocument, EnvConfigQuery } from './EnvConfig.gql'
|
|
8
|
+
|
|
9
|
+
config()
|
|
10
|
+
|
|
11
|
+
async function configToPublicEnv() {
|
|
12
|
+
const req = await fetch('http://localhost:3001/api/graphql', {
|
|
13
|
+
headers: {
|
|
14
|
+
accept: '*/*',
|
|
15
|
+
'content-type': 'application/json',
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
operationName: null,
|
|
19
|
+
variables: null,
|
|
20
|
+
query: print(EnvConfigDocument),
|
|
21
|
+
}),
|
|
22
|
+
// '{"operationName":null,"variables":{},"query":"{\\n availableStores {\\n absolute_footer\\n allow_guests_to_write_product_reviews\\n allow_items\\n allow_order\\n autocomplete_on_storefront\\n base_currency_code\\n store_code\\n store_name\\n locale\\n base_currency_code\\n default_display_currency_code\\n title_suffix\\n title_prefix\\n title_separator\\n default_title\\n cms_home_page\\n catalog_default_sort_by\\n category_url_suffix\\n product_url_suffix\\n base_link_url\\n root_category_uid\\n weight_unit\\n }\\n}\\n"}',
|
|
23
|
+
method: 'POST',
|
|
24
|
+
})
|
|
25
|
+
const response = ((await req.json()) || {}) as FetchResult<EnvConfigQuery>
|
|
26
|
+
|
|
27
|
+
const data = Object.fromEntries(
|
|
28
|
+
(response.data!.envConfig || []).map((entry) => [entry!.store_code, entry]),
|
|
29
|
+
)
|
|
30
|
+
fs.writeFile('./global-manifest.json', JSON.stringify(data), (err) => {
|
|
31
|
+
if (err) throw err
|
|
32
|
+
console.info('Global data manifest written to file')
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
37
|
+
// eslint-disable-next-line no-console
|
|
38
|
+
configToPublicEnv().then(console.log).catch(console.error)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import { Country, Maybe } from '@graphcommerce/graphql'
|
|
3
|
+
import { CountryRegionsDocument } from '../queries/CountryRegions.gql'
|
|
4
|
+
|
|
5
|
+
export function useFindCountry(countryCode?: Maybe<string>): Maybe<Country> | undefined {
|
|
6
|
+
const countryRegions = useQuery(CountryRegionsDocument)
|
|
7
|
+
return countryRegions.data?.countries?.filter(
|
|
8
|
+
(c) => c?.two_letter_abbreviation === countryCode,
|
|
9
|
+
)?.[0]
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Maybe, Region } from '@graphcommerce/graphql'
|
|
2
|
+
import { useFindCountry } from './useFindCountry'
|
|
3
|
+
|
|
4
|
+
export function useFindRegion(
|
|
5
|
+
countryCode?: Maybe<string>,
|
|
6
|
+
regionId?: Maybe<number>,
|
|
7
|
+
): Region | undefined {
|
|
8
|
+
const country = useFindCountry(countryCode)
|
|
9
|
+
|
|
10
|
+
if (!country || !regionId) return undefined
|
|
11
|
+
|
|
12
|
+
const region =
|
|
13
|
+
country.available_regions && country.available_regions.filter((r) => r?.id === regionId)[0]
|
|
14
|
+
|
|
15
|
+
if (!region) return undefined
|
|
16
|
+
|
|
17
|
+
return region
|
|
18
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { default as PageMeta } from './PageMeta'
|
|
2
|
+
export * from './StoreConfig.gql'
|
|
3
|
+
export * from './localeToStore'
|
|
4
|
+
|
|
5
|
+
export { default as StoreSwitcherButton } from './switcher/StoreSwitcherButton'
|
|
6
|
+
export * from './switcher/StoreSwitcherButton'
|
|
7
|
+
|
|
8
|
+
export { default as StoreSwitcherList } from './switcher/StoreSwitcherList'
|
|
9
|
+
export * from './switcher/StoreSwitcherList'
|
|
10
|
+
export * from './switcher/StoreSwitcherList.gql'
|
|
11
|
+
|
|
12
|
+
export * from './Money'
|
|
13
|
+
export { default as Money } from './Money'
|
|
14
|
+
|
|
15
|
+
export * from './Money.gql'
|
|
16
|
+
|
|
17
|
+
export * from './queries/CountryRegions.gql'
|
|
18
|
+
|
|
19
|
+
export * from './hooks/useFindCountry'
|
|
20
|
+
export * from './hooks/useFindRegion'
|
package/localeToStore.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
if (!process.env.NEXT_PUBLIC_LOCALE_STORES) {
|
|
2
|
+
throw Error('Please provide NEXT_PUBLIC_LOCALE_STORES in your .env')
|
|
3
|
+
}
|
|
4
|
+
const localeStores = JSON.parse(process.env.NEXT_PUBLIC_LOCALE_STORES) as {
|
|
5
|
+
[index: string]: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function localeToStore(locale?: string | null | undefined) {
|
|
9
|
+
if (!locale) return Object.values(localeStores)?.[0]
|
|
10
|
+
return localeStores?.[locale]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function defaultLocale(): string {
|
|
14
|
+
return Object.keys(localeStores)?.[0]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function storeToLocale(store?: string | null | undefined) {
|
|
18
|
+
return Object.entries(localeStores).find(([, s]) => s === store)?.[0]
|
|
19
|
+
}
|
package/next-env.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@graphcommerce/magento-store",
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
6
|
+
"browserslist": [
|
|
7
|
+
"extends @graphcommerce/browserslist-config-pwa"
|
|
8
|
+
],
|
|
9
|
+
"eslintConfig": {
|
|
10
|
+
"extends": "@graphcommerce/eslint-config-pwa",
|
|
11
|
+
"parserOptions": {
|
|
12
|
+
"project": "./tsconfig.json"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@graphcommerce/browserslist-config-pwa": "^3.0.1",
|
|
17
|
+
"@graphcommerce/eslint-config-pwa": "^3.0.1",
|
|
18
|
+
"@graphcommerce/prettier-config-pwa": "^3.0.1",
|
|
19
|
+
"@graphcommerce/typescript-config-pwa": "^3.0.1",
|
|
20
|
+
"@playwright/test": "^1.14.1"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@apollo/client": "^3.3.21",
|
|
24
|
+
"@graphcommerce/graphql": "^2.103.1",
|
|
25
|
+
"@graphcommerce/image": "^2.104.1",
|
|
26
|
+
"@graphcommerce/next-ui": "^3.0.1",
|
|
27
|
+
"@graphql-typed-document-node/core": "^3.1.0",
|
|
28
|
+
"@material-ui/core": "^4.12.3",
|
|
29
|
+
"@material-ui/lab": "^4.0.0-alpha.60",
|
|
30
|
+
"next": "^11.1.2",
|
|
31
|
+
"react": "^17.0.2",
|
|
32
|
+
"react-dom": "^17.0.2",
|
|
33
|
+
"type-fest": "^2.1.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as Types from '@graphcommerce/graphql';
|
|
3
|
+
|
|
4
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
5
|
+
|
|
6
|
+
export const CountryRegionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CountryRegions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"countries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"full_name_locale"}},{"kind":"Field","name":{"kind":"Name","value":"two_letter_abbreviation"}},{"kind":"Field","name":{"kind":"Name","value":"three_letter_abbreviation"}},{"kind":"Field","name":{"kind":"Name","value":"available_regions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<CountryRegionsQuery, CountryRegionsQueryVariables>;
|
|
7
|
+
export type CountryRegionsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export type CountryRegionsQuery = { countries?: Types.Maybe<Array<Types.Maybe<{ full_name_locale?: Types.Maybe<string>, two_letter_abbreviation?: Types.Maybe<string>, three_letter_abbreviation?: Types.Maybe<string>, available_regions?: Types.Maybe<Array<Types.Maybe<{ code?: Types.Maybe<string>, id?: Types.Maybe<number>, name?: Types.Maybe<string> }>>> }>>> };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as Types from '@graphcommerce/graphql';
|
|
3
|
+
|
|
4
|
+
export type StoreLocaleFragment = { code?: Types.Maybe<string>, store_name?: Types.Maybe<string>, locale?: Types.Maybe<string>, base_currency_code?: Types.Maybe<string>, store_group_name?: Types.Maybe<string>, store_group_code?: Types.Maybe<string> };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import { Button, makeStyles } from '@material-ui/core'
|
|
3
|
+
import { FlagAvatar, UseStyles } from '@graphcommerce/next-ui'
|
|
4
|
+
import PageLink from 'next/link'
|
|
5
|
+
import React from 'react'
|
|
6
|
+
import { StoreConfigDocument } from '../StoreConfig.gql'
|
|
7
|
+
|
|
8
|
+
const useStyles = makeStyles(
|
|
9
|
+
() => ({
|
|
10
|
+
avatar: {
|
|
11
|
+
height: 20,
|
|
12
|
+
width: 20,
|
|
13
|
+
marginRight: 10,
|
|
14
|
+
},
|
|
15
|
+
}),
|
|
16
|
+
{ name: 'StoreSwitcherButton' },
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export type StoreSwitcherButtonProps = UseStyles<typeof useStyles>
|
|
20
|
+
|
|
21
|
+
export default function StoreSwitcherButton(props) {
|
|
22
|
+
const config = useQuery(StoreConfigDocument)
|
|
23
|
+
const country = config.data?.storeConfig?.store_code?.split('_')?.[1].toLowerCase() ?? ''
|
|
24
|
+
|
|
25
|
+
const classes = useStyles(props)
|
|
26
|
+
return (
|
|
27
|
+
<PageLink href='/switch-stores' passHref>
|
|
28
|
+
<Button variant='text' size='medium'>
|
|
29
|
+
<FlagAvatar country={country} classes={{ root: classes.avatar }} />
|
|
30
|
+
{config.data?.storeConfig?.store_name} - {config.data?.storeConfig?.base_currency_code}
|
|
31
|
+
</Button>
|
|
32
|
+
</PageLink>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as Types from '@graphcommerce/graphql';
|
|
3
|
+
|
|
4
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
5
|
+
|
|
6
|
+
export const StoreSwitcherListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StoreSwitcherList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"availableStores"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"store_name"}},{"kind":"Field","name":{"kind":"Name","value":"store_code"}},{"kind":"Field","name":{"kind":"Name","value":"locale"}},{"kind":"Field","name":{"kind":"Name","value":"base_currency_code"}},{"kind":"Field","name":{"kind":"Name","value":"store_group_name"}},{"kind":"Field","name":{"kind":"Name","value":"store_group_code"}}]}}]}}]} as unknown as DocumentNode<StoreSwitcherListQuery, StoreSwitcherListQueryVariables>;
|
|
7
|
+
export type StoreSwitcherListQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export type StoreSwitcherListQuery = { availableStores?: Types.Maybe<Array<Types.Maybe<{ store_name?: Types.Maybe<string>, store_code?: Types.Maybe<string>, locale?: Types.Maybe<string>, base_currency_code?: Types.Maybe<string>, store_group_name?: Types.Maybe<string>, store_group_code?: Types.Maybe<string> }>>> };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
List,
|
|
3
|
+
ListItem,
|
|
4
|
+
ListItemText,
|
|
5
|
+
makeStyles,
|
|
6
|
+
Theme,
|
|
7
|
+
Collapse,
|
|
8
|
+
ListItemAvatar,
|
|
9
|
+
} from '@material-ui/core'
|
|
10
|
+
import { FlagAvatar, UseStyles } from '@graphcommerce/next-ui'
|
|
11
|
+
import PageLink from 'next/link'
|
|
12
|
+
import React from 'react'
|
|
13
|
+
import { localeToStore, storeToLocale } from '../localeToStore'
|
|
14
|
+
import { StoreSwitcherListQuery } from './StoreSwitcherList.gql'
|
|
15
|
+
|
|
16
|
+
const useStyles = makeStyles(
|
|
17
|
+
(theme: Theme) => ({
|
|
18
|
+
list: {},
|
|
19
|
+
listItem: {
|
|
20
|
+
borderTop: '1px solid #efefef',
|
|
21
|
+
cursor: 'pointer',
|
|
22
|
+
},
|
|
23
|
+
listItemIndented: {
|
|
24
|
+
paddingLeft: 30,
|
|
25
|
+
cursor: 'pointer',
|
|
26
|
+
},
|
|
27
|
+
groupIcon: {
|
|
28
|
+
fontSize: 29,
|
|
29
|
+
lineHeight: 1,
|
|
30
|
+
minWidth: 40,
|
|
31
|
+
color: theme.palette.text.primary,
|
|
32
|
+
},
|
|
33
|
+
avatar: {
|
|
34
|
+
width: 30,
|
|
35
|
+
height: 30,
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
{ name: 'StoreSwitcherList' },
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
type Store = NonNullable<NonNullable<StoreSwitcherListQuery['availableStores']>[0]>
|
|
42
|
+
|
|
43
|
+
export type StoreSwitcherListProps = { locale: string | undefined } & StoreSwitcherListQuery &
|
|
44
|
+
UseStyles<typeof useStyles>
|
|
45
|
+
|
|
46
|
+
export default function StoreSwitcherList(props: StoreSwitcherListProps) {
|
|
47
|
+
const { availableStores, locale } = props
|
|
48
|
+
const classes = useStyles(props)
|
|
49
|
+
|
|
50
|
+
const groupedStores = Object.entries(
|
|
51
|
+
(availableStores ?? []).reduce<{
|
|
52
|
+
[group: string]: { name: Store['store_group_name']; stores: Store[] }
|
|
53
|
+
}>((storesGrouped, store) => {
|
|
54
|
+
const code = store?.store_group_code
|
|
55
|
+
if (!store?.store_group_code || !code) return storesGrouped
|
|
56
|
+
|
|
57
|
+
if (!storesGrouped[code]) storesGrouped[code] = { name: store.store_group_name, stores: [] }
|
|
58
|
+
|
|
59
|
+
storesGrouped[code].stores.push(store)
|
|
60
|
+
return storesGrouped
|
|
61
|
+
}, {}),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<List className={classes.list}>
|
|
66
|
+
{groupedStores.map(([code, group]) => (
|
|
67
|
+
<React.Fragment key={code}>
|
|
68
|
+
<PageLink
|
|
69
|
+
key={group.stores[0].store_code}
|
|
70
|
+
href='/switch-stores'
|
|
71
|
+
locale={storeToLocale(group.stores[0].store_code)}
|
|
72
|
+
replace
|
|
73
|
+
passHref
|
|
74
|
+
>
|
|
75
|
+
<ListItem
|
|
76
|
+
button
|
|
77
|
+
component='a'
|
|
78
|
+
selected={
|
|
79
|
+
group.stores.length <= 1 && localeToStore(locale) === group.stores[0].store_code
|
|
80
|
+
}
|
|
81
|
+
color='inherit'
|
|
82
|
+
className={classes.listItem}
|
|
83
|
+
>
|
|
84
|
+
<ListItemAvatar>
|
|
85
|
+
<FlagAvatar country={code} classes={{ root: classes.avatar }} />
|
|
86
|
+
</ListItemAvatar>
|
|
87
|
+
<ListItemText>
|
|
88
|
+
{group.name}
|
|
89
|
+
{group.stores.length <= 1 && ` — ${group.stores[0].store_name}`}
|
|
90
|
+
</ListItemText>
|
|
91
|
+
</ListItem>
|
|
92
|
+
</PageLink>
|
|
93
|
+
{group.stores.length > 1 && (
|
|
94
|
+
<Collapse in timeout='auto'>
|
|
95
|
+
{group.stores.map((store) => (
|
|
96
|
+
<PageLink
|
|
97
|
+
key={store.store_code}
|
|
98
|
+
href='/switch-stores'
|
|
99
|
+
locale={storeToLocale(store.store_code)}
|
|
100
|
+
replace
|
|
101
|
+
passHref
|
|
102
|
+
>
|
|
103
|
+
<ListItem
|
|
104
|
+
button
|
|
105
|
+
component='a'
|
|
106
|
+
selected={localeToStore(locale) === store.store_code}
|
|
107
|
+
color='inherit'
|
|
108
|
+
className={classes.listItemIndented}
|
|
109
|
+
>
|
|
110
|
+
<ListItemText inset>{store.store_name}</ListItemText>
|
|
111
|
+
</ListItem>
|
|
112
|
+
</PageLink>
|
|
113
|
+
))}
|
|
114
|
+
</Collapse>
|
|
115
|
+
)}
|
|
116
|
+
</React.Fragment>
|
|
117
|
+
))}
|
|
118
|
+
</List>
|
|
119
|
+
)
|
|
120
|
+
}
|