@riosst100/pwa-marketplace 3.3.2 → 3.3.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@riosst100/pwa-marketplace",
3
3
  "author": "riosst100@gmail.com",
4
- "version": "3.3.2",
4
+ "version": "3.3.3",
5
5
  "main": "src/index.js",
6
6
  "pwa-studio": {
7
7
  "targets": {
@@ -1,4 +1,5 @@
1
1
  module.exports = componentOverrideMapping = {
2
+ ['@magento/peregrine/lib/Apollo/links/storeLink.js']: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/Apollo/links/storeLink.js',
2
3
  ['@magento/peregrine/lib/talons/CreateAccount/useCreateAccount.js']: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/CreateAccount/useCreateAccount.js',
3
4
  ['@magento/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js']: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js',
4
5
  ['@magento/venia-ui/lib/components/CartPage/PriceAdjustments/CouponCode/couponCode.js']: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/CartPage/PriceAdjustments/CouponCode/couponCode.js',
@@ -38,10 +38,12 @@ const AgeVerificationModal = props => {
38
38
  <div className={modalClasses.backdrop} />
39
39
  <div className={modalClasses.dialog}>
40
40
  <div className={modalClasses.body}>
41
- <div><Icon src={AlertTriangle} attrs={{ width: 20 }} /></div>
41
+ <div><Icon src={AlertTriangle} classes={{
42
+ icon: modalClasses.icon
43
+ }} attrs={{ width: 40 }} /></div>
42
44
  <h2 className={modalClasses.title}>Are you over 18 years old?</h2>
43
- <p>You must be at least 18 years old to access this page. Please verify your age.</p>
44
- <label>Your Birthday</label>
45
+ <p style={{"paddingTop": "10px"}}>You must be at least 18 years old to access this page. Please verify your age.</p>
46
+ <label className={modalClasses.formLabel}>Your Birthday:</label>
45
47
  <div className={modalClasses.birthday}>
46
48
  {/* Month */}
47
49
  <select onChange={(e) => setMonth(e.target.value)}>
@@ -67,7 +69,7 @@ const AgeVerificationModal = props => {
67
69
  ))}
68
70
  </select>
69
71
  </div>
70
- {ageVerificationErrorMessage && <div>{ageVerificationErrorMessage}</div>}
72
+ {ageVerificationErrorMessage && <div className={modalClasses.error}>{ageVerificationErrorMessage}</div>}
71
73
  <div className={modalClasses.actions}>
72
74
  <button className={modalClasses.btnUnder} onClick={handleUnderAge}>I'm under 18 years old</button>
73
75
  <button className={modalClasses.btnOver} onClick={handleOverAge}>I'm 18 years old</button>
@@ -6,6 +6,13 @@
6
6
  text-align: left;
7
7
  }
8
8
 
9
+ .formLabel {
10
+ font-weight: 500;
11
+ padding-top: 30px;
12
+ font-size: 13px;
13
+ padding-bottom: 10px;
14
+ }
15
+
9
16
  /* Birthday selects */
10
17
  .birthday {
11
18
  display: flex;
@@ -28,7 +35,7 @@
28
35
 
29
36
  .btnUnder {
30
37
  flex: 1;
31
- padding: 10px;
38
+ /* padding: 10px; */
32
39
  border: none;
33
40
  border-radius: 6px;
34
41
  color: white;
@@ -38,7 +45,7 @@
38
45
 
39
46
  .btnOver {
40
47
  flex: 1;
41
- padding: 10px;
48
+ /* padding: 10px; */
42
49
  border: none;
43
50
  border-radius: 6px;
44
51
  color: white;
@@ -98,7 +105,7 @@
98
105
  font-size:20px;
99
106
  font-weight:600;
100
107
  margin:0;
101
- color:#333
108
+ color:red;
102
109
  }
103
110
  .closeBtn{
104
111
  background:none;
@@ -110,12 +117,24 @@
110
117
  padding:4px 8px;
111
118
  border-radius:6px
112
119
  }
120
+ .error {
121
+ color: red;
122
+ padding: 10px;
123
+ font-size: 13px;
124
+ margin-top: -20px;
125
+ margin-bottom: 20px;
126
+ }
113
127
  .closeBtn:hover{
114
128
  background:#f5f5f5;
115
129
  color:#222
116
130
  }
131
+ .icon {
132
+ --stroke: red;
133
+ stroke: red;
134
+ color: red;
135
+ }
117
136
  .body{
118
- padding: 20px 50px;
137
+ padding: 30px 50px;
119
138
  overflow: auto;
120
139
  display: flex;
121
140
  flex-direction: column;
@@ -0,0 +1 @@
1
+ export { default } from './loadingRequest';
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import modalClasses from './loadingRequest.module.css';
4
+
5
+ // Simple portal root fallback
6
+ const getPortalRoot = () => {
7
+ let root = document.getElementById('loading-request-portal');
8
+ if (!root) {
9
+ root = document.createElement('div');
10
+ root.id = 'loading-request-portal';
11
+ document.body.appendChild(root);
12
+ }
13
+ return root;
14
+ };
15
+
16
+ const LoadingRequest = props => {
17
+
18
+ const {
19
+ isLoading
20
+ } = props;
21
+
22
+ const modal = isLoading ? (
23
+ <div className={modalClasses.overlay} role="dialog" aria-modal="true" aria-label="Modal">
24
+ <div className={modalClasses.backdrop} />
25
+ <div className={modalClasses.dialog}>
26
+ <div className={modalClasses.body}>
27
+ <img src={process.env.MAGENTO_BACKEND_URL + "/media/images/spinner2.gif"} style={{"width":"15%"}} />
28
+ <div style={{
29
+ "marginTop": "10px",
30
+ "color": "white"
31
+ }}>Please wait...</div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ ) : null;
36
+
37
+ return <>{isLoading ? ReactDOM.createPortal(modal, getPortalRoot()) : null}</>;
38
+ };
39
+
40
+ export default LoadingRequest;
@@ -0,0 +1,150 @@
1
+ .modal label {
2
+ display: block;
3
+ font-size: 14px;
4
+ font-weight: bold;
5
+ margin-bottom: 8px;
6
+ text-align: left;
7
+ }
8
+
9
+ /* Birthday selects */
10
+ .birthday {
11
+ display: flex;
12
+ gap: 10px;
13
+ margin-bottom: 20px;
14
+ }
15
+
16
+ .birthday select {
17
+ flex: 1;
18
+ padding: 8px;
19
+ border-radius: 6px;
20
+ border: 1px solid #ccc;
21
+ }
22
+
23
+ /* Buttons */
24
+ .actions {
25
+ display: flex;
26
+ gap: 10px;
27
+ }
28
+
29
+ .btnUnder {
30
+ flex: 1;
31
+ padding: 10px;
32
+ border: none;
33
+ border-radius: 6px;
34
+ color: white;
35
+ font-size: 14px;
36
+ cursor: pointer;
37
+ }
38
+
39
+ .btnOver {
40
+ flex: 1;
41
+ padding: 10px;
42
+ border: none;
43
+ border-radius: 6px;
44
+ color: white;
45
+ font-size: 14px;
46
+ cursor: pointer;
47
+ }
48
+
49
+ .btnUnder {
50
+ background: #ef4444;
51
+ }
52
+
53
+ .btnOver {
54
+ background: #22c55e;
55
+ }
56
+
57
+ .btnOver:hover {
58
+ opacity: 0.9;
59
+ }
60
+
61
+ .btnUnder:hover {
62
+ opacity: 0.9;
63
+ }
64
+
65
+ .overlay{
66
+ position:fixed;
67
+ inset:0;
68
+ display:flex;
69
+ padding:5vh 24px;
70
+ font-family:inherit;
71
+ align-items: center;
72
+ justify-content: center;
73
+ z-index: 9999;
74
+ }
75
+ .backdrop{
76
+ position:absolute;
77
+ inset:0;
78
+ background: rgba(0, 0, 0, 0.64);
79
+ backdrop-filter: blur(8px);
80
+ }
81
+ .dialog{
82
+ position:relative;
83
+ width:clamp(320px,80vw,500px);
84
+ display:flex;
85
+ flex-direction:column
86
+ }
87
+ .header{
88
+ display:flex;
89
+ align-items:center;
90
+ justify-content:space-between;
91
+ padding:16px 20px;
92
+ border-bottom:1px solid #eee
93
+ }
94
+ .title{
95
+ font-size:20px;
96
+ font-weight:600;
97
+ margin:0;
98
+ color:#333
99
+ }
100
+ .closeBtn{
101
+ background:none;
102
+ border:none;
103
+ font-size:24px;
104
+ line-height:1;
105
+ cursor:pointer;
106
+ color:#777;
107
+ padding:4px 8px;
108
+ border-radius:6px
109
+ }
110
+ .closeBtn:hover{
111
+ background:#f5f5f5;
112
+ color:#222
113
+ }
114
+ .body{
115
+ padding: 20px 50px;
116
+ overflow: auto;
117
+ display: flex;
118
+ flex-direction: column;
119
+ text-align: center;
120
+ flex-wrap: wrap;
121
+ align-content: center;
122
+ }
123
+ .triggerBtn{
124
+ background:#f76b1c;
125
+ color:#fff;
126
+ border:none;
127
+ padding:10px 18px;
128
+ border-radius:8px;
129
+ font-weight:600;
130
+ cursor:pointer
131
+ }
132
+ .triggerBtn:hover{
133
+ background:#f26313
134
+ }
135
+ /* Vertical stack wrapper for existing sellerCoupon card styles */
136
+ .stack{
137
+ display:flex;
138
+ flex-direction:column;
139
+ gap:16px;
140
+ padding:4px 2px 12px;
141
+ }
142
+ @media (max-width:640px){
143
+ .dialog{
144
+ width:92vw;
145
+ padding-bottom:8px
146
+ }
147
+ .grid{
148
+ grid-template-columns:repeat(auto-fill,minmax(160px,1fr))
149
+ }
150
+ }
@@ -1,13 +1,7 @@
1
1
  import React, {useState} from 'react';
2
- import Button from '@magento/venia-ui/lib/components/Button';
3
- import Image from '@magento/venia-ui/lib/components/Image';
4
- import GoogleIcon from './img/google.svg';
5
- import FacebookIcon from './img/facebook.svg';
6
- import InstagramIcon from './img/instagram.svg';
7
- import WechatIcon from './img/wechat.svg';
8
- import WeiboIcon from './img/weibo.svg';
9
2
  import GoogleSignInButton from './googleSignInButton'
10
3
  import { useSocialLogin } from '@riosst100/pwa-marketplace/src/talons/SocialLogin/useSocialLogin';
4
+ import LoadingRequest from '@riosst100/pwa-marketplace/src/components/LoadingRequest';
11
5
 
12
6
  const SocialLogin = () => {
13
7
  const [jwtToken, setJwtToken] = useState(null);
@@ -16,58 +10,14 @@ const SocialLogin = () => {
16
10
  jwtToken
17
11
  });
18
12
 
19
- // const {
20
- // errors,
21
- // handleCreateAccount,
22
- // handleEnterKeyPress,
23
- // signinHandleEnterKeyPress,
24
- // handleForgotPassword,
25
- // forgotPasswordHandleEnterKeyPress,
26
- // handleSubmit,
27
- // isBusy,
28
- // setFormApi,
29
- // recaptchaWidgetProps
30
- // } = talonProps;
13
+ const {
14
+ isLoading
15
+ } = talonProps;
31
16
 
32
17
  return (
33
18
  <div className='relative flex w-full justify-center items-center'>
19
+ <LoadingRequest isLoading={isLoading} />
34
20
  <GoogleSignInButton setToken={setJwtToken} />
35
- {/* <Button
36
- className="shadow-type-1 p-[14px] rounded-full w-[52px] h-[52px]"
37
- >
38
- <Image
39
- alt='facebook'
40
- className="relative"
41
- src={FacebookIcon}
42
- />
43
- </Button>
44
- <Button
45
- className="shadow-type-1 p-[14px] rounded-full w-[52px] h-[52px]"
46
- >
47
- <Image
48
- alt='instagram'
49
- className="relative"
50
- src={InstagramIcon}
51
- />
52
- </Button>
53
- <Button
54
- className="shadow-type-1 p-[14px] rounded-full w-[52px] h-[52px]"
55
- >
56
- <Image
57
- alt='wechat'
58
- className="relative"
59
- src={WechatIcon}
60
- />
61
- </Button>
62
- <Button
63
- className="shadow-type-1 p-[14px] rounded-full w-[52px] h-[52px]"
64
- >
65
- <Image
66
- alt='weibo'
67
- className="relative"
68
- src={WeiboIcon}
69
- />
70
- </Button> */}
71
21
  </div>
72
22
  )
73
23
  }
@@ -0,0 +1,34 @@
1
+ import { setContext } from '@apollo/client/link/context';
2
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
3
+
4
+ const storage = new BrowserPersistence();
5
+
6
+ export default function createStoreLink() {
7
+ return setContext((_, { headers }) => {
8
+ const websiteCodes = [];
9
+
10
+ AVAILABLE_WEBSITES.forEach(store => {
11
+ websiteCodes.push(store.website_code);
12
+ });
13
+
14
+ const { location } = globalThis;
15
+ const match = location && location.pathname.split("/")[1];
16
+ const websiteCodeInUrl = websiteCodes.find((str) => str === match);
17
+
18
+ let prefix = websiteCodeInUrl ? websiteCodeInUrl + '_' : '';
19
+
20
+ const storeCurrency = storage.getItem(prefix + 'store_view_currency') || null;
21
+ const storeCode = storage.getItem(prefix + 'store_view_code') || STORE_VIEW_CODE;
22
+
23
+ // return the headers to the context so httpLink can read them
24
+ return {
25
+ headers: {
26
+ ...headers,
27
+ store: storeCode,
28
+ ...(storeCurrency && {
29
+ 'Content-Currency': storeCurrency
30
+ })
31
+ }
32
+ };
33
+ });
34
+ }
@@ -66,10 +66,22 @@ const CartContextProvider = props => {
66
66
  const [removeSplitCart] = useMutation(REMOVE_SPLIT_CART_MUTATION);
67
67
  const fetchCartDetails = useAwaitQuery(CART_DETAILS_QUERY);
68
68
 
69
+ const websiteCodes = [];
70
+
71
+ AVAILABLE_WEBSITES.forEach(store => {
72
+ websiteCodes.push(store.website_code);
73
+ });
74
+
75
+ const { location } = globalThis;
76
+ const match = location && location.pathname.split("/")[1];
77
+ const websiteCodeInUrl = websiteCodes.find((str) => str === match);
78
+
79
+ let prefix = websiteCodeInUrl ? websiteCodeInUrl + '_' : '';
80
+
69
81
  // Storage listener to force a state update if cartId changes from another browser tab.
70
82
  const storageListener = useCallback(() => {
71
83
  const storage = new BrowserPersistence();
72
- const currentCartId = storage.getItem('cartId');
84
+ const currentCartId = storage.getItem(prefix + 'cartId');
73
85
  const { cartId } = cartState;
74
86
  if (cartId && currentCartId && cartId !== currentCartId) {
75
87
  globalThis.location && globalThis.location.reload();
@@ -475,6 +475,18 @@ export const getCartDetails = payload => {
475
475
  };
476
476
  };
477
477
 
478
+ const websiteCodes = [];
479
+
480
+ AVAILABLE_WEBSITES.forEach(store => {
481
+ websiteCodes.push(store.website_code);
482
+ });
483
+
484
+ const { location } = globalThis;
485
+ const match = location && location.pathname.split("/")[1];
486
+ const websiteCodeInUrl = websiteCodes.find((str) => str === match);
487
+
488
+ const prefix = websiteCodeInUrl ? websiteCodeInUrl + '_' : '';
489
+
478
490
  export const removeCart = () =>
479
491
  async function thunk(dispatch) {
480
492
  // Clear the cartId from local storage.
@@ -507,15 +519,15 @@ export async function clearSellerCartId() {
507
519
  }
508
520
 
509
521
  export async function retrieveCartId() {
510
- return storage.getItem('cartId');
522
+ return storage.getItem(prefix + 'cartId');
511
523
  }
512
524
 
513
525
  export async function saveCartId(id) {
514
- return storage.setItem('cartId', id);
526
+ return storage.setItem(prefix + 'cartId', id);
515
527
  }
516
528
 
517
529
  export async function clearCartId() {
518
- return storage.removeItem('cartId');
530
+ return storage.removeItem(prefix + 'cartId');
519
531
  }
520
532
 
521
533
  async function retrieveImageCache() {
@@ -32,9 +32,11 @@ export const useAdapter = props => {
32
32
  const match = location && location.pathname.split("/")[1];
33
33
  let websiteCodeInUrl = websiteCodes.find((str) => str === match);
34
34
 
35
+ let prefix = websiteCodeInUrl ? websiteCodeInUrl + '_' : '';
36
+
35
37
  let isBaseWebsite = false;
36
38
 
37
- let websiteCode = storage.getItem('website_code');
39
+ let websiteCode = storage.getItem(prefix + 'website_code');
38
40
 
39
41
  if (!websiteCodeInUrl) {
40
42
  isBaseWebsite = true;
@@ -86,7 +88,7 @@ export const useAdapter = props => {
86
88
 
87
89
  const clearCacheData = useCallback(
88
90
  async (client, cacheType) => {
89
- const storeCode = storage.getItem('store_view_code') || 'default';
91
+ const storeCode = storage.getItem(prefix + 'store_view_code') || 'default';
90
92
 
91
93
  // Clear current store
92
94
  if (cacheType === 'cart') {
@@ -135,11 +137,11 @@ export const useAdapter = props => {
135
137
  }
136
138
  }
137
139
  },
138
- [apolloLink, createApolloClient, createCachePersistor]
140
+ [apolloLink, prefix, createApolloClient, createCachePersistor]
139
141
  );
140
142
 
141
143
  const apolloClient = useMemo(() => {
142
- const storeCode = storage.getItem('store_view_code') || 'default';
144
+ const storeCode = storage.getItem(prefix + 'store_view_code') || 'default';
143
145
  const client = createApolloClient(preInstantiatedCache, apolloLink);
144
146
  const persistor = isServer
145
147
  ? null
@@ -154,6 +156,7 @@ export const useAdapter = props => {
154
156
  apiBase,
155
157
  apolloLink,
156
158
  clearCacheData,
159
+ prefix,
157
160
  createApolloClient,
158
161
  createCachePersistor
159
162
  ]);
@@ -12,6 +12,8 @@ import DEFAULT_OPERATIONS from '@magento/peregrine/lib/talons/SignIn/signIn.gql'
12
12
  import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
13
13
  import { BrowserPersistence } from '@magento/peregrine/lib/util';
14
14
 
15
+ import { useToasts } from '@magento/peregrine/lib/Toasts';
16
+
15
17
  const storage = new BrowserPersistence();
16
18
 
17
19
  export const useSignIn = props => {
@@ -20,7 +22,8 @@ export const useSignIn = props => {
20
22
  getCartDetailsQuery,
21
23
  setDefaultUsername,
22
24
  showCreateAccount,
23
- showForgotPassword
25
+ showForgotPassword,
26
+ setIsLoading
24
27
  } = props;
25
28
 
26
29
  const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
@@ -67,11 +70,14 @@ export const useSignIn = props => {
67
70
  const fetchUserDetails = useAwaitQuery(getCustomerQuery);
68
71
  const fetchCartDetails = useAwaitQuery(getCartDetailsQuery);
69
72
 
73
+ const [, { addToast }] = useToasts();
74
+
70
75
  const formApiRef = useRef(null);
71
76
  const setFormApi = useCallback(api => (formApiRef.current = api), []);
72
77
 
73
78
  const handleSubmit = useCallback(
74
79
  async ({ email, password }) => {
80
+ setIsLoading(true)
75
81
  setIsSigningIn(true);
76
82
  // handleTriggerClick();
77
83
  try {
@@ -135,6 +141,17 @@ export const useSignIn = props => {
135
141
  });
136
142
 
137
143
  getCartDetails({ fetchCartId, fetchCartDetails });
144
+
145
+ addToast({
146
+ type: 'success',
147
+ message: formatMessage({
148
+ id: 'signIn.signInSuccessToast',
149
+ defaultMessage: "You have successfully signed in."
150
+ }),
151
+ timeout: 5000
152
+ });
153
+
154
+ setIsLoading(false);
138
155
  } catch (error) {
139
156
  if (process.env.NODE_ENV !== 'production') {
140
157
  console.error(error);
@@ -157,6 +174,7 @@ export const useSignIn = props => {
157
174
  fetchUserDetails,
158
175
  getCartDetails,
159
176
  fetchCartDetails,
177
+ setIsLoading,
160
178
  dispatch,
161
179
  handleTriggerClick
162
180
  ]
@@ -0,0 +1,132 @@
1
+ import { BrowserPersistence } from '@magento/peregrine/lib/util';
2
+
3
+ const storage = new BrowserPersistence();
4
+
5
+ // If the root template supplies the backend URL at runtime, use it directly
6
+ const { documentElement: htmlElement } = globalThis.document || {};
7
+ const { imageOptimizingOrigin } = htmlElement ? htmlElement.dataset : {};
8
+ const alreadyOptimized = imageOptimizingOrigin === 'backend';
9
+
10
+ const websiteCodes = [];
11
+
12
+ AVAILABLE_WEBSITES.forEach(store => {
13
+ websiteCodes.push(store.website_code);
14
+ });
15
+
16
+ const { location } = globalThis;
17
+ const match = location && location.pathname.split("/")[1];
18
+ const websiteCodeInUrl = websiteCodes.find((str) => str === match);
19
+
20
+ let prefix = websiteCodeInUrl ? websiteCodeInUrl + '_' : '';
21
+
22
+ // Protect against potential falsy values for `mediaBackend`.
23
+ const storeCode = storage.getItem(prefix + 'store_view_code') || STORE_VIEW_CODE;
24
+ const storeSecureBaseMediaUrl = {};
25
+
26
+ // Fallback to global secure_base_media_url set at build time
27
+ AVAILABLE_STORE_VIEWS.forEach(store => {
28
+ storeSecureBaseMediaUrl[store.store_code] = store.secure_base_media_url;
29
+ });
30
+
31
+ let mediaBackend =
32
+ storage.getItem(prefix + 'store_view_secure_base_media_url') ||
33
+ storeSecureBaseMediaUrl[storeCode];
34
+ if (!mediaBackend) {
35
+ console.warn('A media backend URL should be defined in your config.');
36
+ mediaBackend = 'https://backend.test/media/';
37
+ }
38
+
39
+ // Tests if a URL begins with `http:` or `https:` or `data:`
40
+ const absoluteUrl = /^(data|http|https)?:/i;
41
+
42
+ // Simple path joiner that guarantees one and only one slash between segments
43
+ const joinUrls = (base, url) =>
44
+ (base.endsWith('/') ? base.slice(0, -1) : base) +
45
+ '/' +
46
+ (url.startsWith('/') ? url.slice(1) : url);
47
+
48
+ const mediaBases = new Map()
49
+ .set('image-product', 'catalog/product/')
50
+ .set('image-category', 'catalog/category/')
51
+ .set('image-swatch', 'attribute/swatch/');
52
+
53
+ const getFileType = url => {
54
+ const fileName = url.pathname.split('/').reverse()[0];
55
+ const fileType = fileName.split('.').reverse()[0];
56
+
57
+ return fileType;
58
+ };
59
+
60
+ /**
61
+ * Creates an "optimized" url for a provided relative url based on
62
+ * requested media type and width. Any image URLs (whose type begins with
63
+ * "image-" will also be optimized.)
64
+ *
65
+ * If a `type` is provided the `path` will be joined with the associated media
66
+ * base.
67
+ * - `catalog/product/path/to/img.jpg`
68
+ *
69
+ * If a `width` is provided, "resize parameters" are added to the URL for
70
+ * middlewares (either onboard or backend) to return using the desired width
71
+ * and original media url.
72
+ * - `catalog/product/path/to/img.jpg?width=500&auto=webp&format=pjpg
73
+ *
74
+ * If only `path` is provided it is returned unaltered.
75
+ *
76
+ * @param {string} path - absolute or relative url to resource.
77
+ * @param {Object} props - properties describing desired optimizations
78
+ * @param {string} props.type - "image-product" or "image-category"
79
+ * @param {number} props.width - the desired resize width of the image
80
+ * @param {number} props.height - the desired resize height of the image
81
+ * @param {number} props.quality - the desired quality of the image
82
+ * @param {bool} props.crop - should the image be cropped
83
+ * @param {string} props.fit - how should the image be fit with the dimensions: bounds, cover, crop
84
+ */
85
+ const makeOptimizedUrl = (path, { type, ...opts } = {}) => {
86
+ // Immediate return if there's no image optimization to attempt
87
+ if (!type || !type.startsWith('image-')) {
88
+ return path;
89
+ }
90
+
91
+ const { origin } = globalThis.location || {};
92
+ const isAbsolute = absoluteUrl.test(path);
93
+ const magentoBackendURL = process.env.MAGENTO_BACKEND_URL;
94
+ let baseURL = new URL(path, mediaBackend);
95
+
96
+ // If URL is relative and has a supported type, prepend media base onto path
97
+ if (!isAbsolute && mediaBases.has(type)) {
98
+ const mediaBase = mediaBases.get(type);
99
+ if (!baseURL.pathname.includes(mediaBase)) {
100
+ baseURL = new URL(joinUrls(mediaBase, path), mediaBackend);
101
+ }
102
+ }
103
+
104
+ if (baseURL.href.startsWith(magentoBackendURL) && !alreadyOptimized) {
105
+ // Replace URL base so optimization middleware can handle request
106
+ baseURL = new URL(baseURL.href.slice(magentoBackendURL.length), origin);
107
+ }
108
+
109
+ // Append image optimization parameters
110
+ const params = new URLSearchParams(baseURL.search);
111
+ params.set('auto', 'webp'); // Use the webp format if available
112
+
113
+ const imageFileType = getFileType(baseURL);
114
+ if (imageFileType === 'png') {
115
+ params.set('format', 'png'); // use png if webp is not available
116
+ } else {
117
+ params.set('format', 'pjpg'); // Use progressive JPG if webp is not available
118
+ }
119
+
120
+ Object.entries(opts).forEach(([key, value]) => {
121
+ if (value !== undefined && value !== null) {
122
+ params.set(key, value);
123
+ }
124
+ });
125
+ baseURL.search = params.toString();
126
+ if (baseURL.origin === origin) {
127
+ return baseURL.href.slice(baseURL.origin.length);
128
+ }
129
+ return baseURL.href;
130
+ };
131
+
132
+ export default makeOptimizedUrl;
@@ -106,63 +106,67 @@ const Adapter = props => {
106
106
  // await removeCart();
107
107
 
108
108
  // klo enabled jd redirect tros
109
- storage.removeItem('cartId');
110
-
111
- storage.setItem('store_view_code', storeCodeInUrl);
112
- storage.setItem('website_code', websiteCodeInUrl);
113
- storage.setItem(
114
- 'store_view_currency',
115
- storeCurrencies[storeCodeInUrl]
116
- );
117
- storage.setItem(
118
- 'store_view_secure_base_media_url',
119
- storeSecureBaseMediaUrl[storeCodeInUrl]
120
- );
109
+ // storage.removeItem('cartId');
110
+
111
+ // storage.setItem('store_view_code', storeCodeInUrl);
112
+ // storage.setItem('website_code', websiteCodeInUrl);
113
+ // storage.setItem(
114
+ // 'store_view_currency',
115
+ // storeCurrencies[storeCodeInUrl]
116
+ // );
117
+ // storage.setItem(
118
+ // 'store_view_secure_base_media_url',
119
+ // storeSecureBaseMediaUrl[storeCodeInUrl]
120
+ // );
121
121
 
122
122
  // We're required to reload the page as the basename doesn't
123
123
  // change entirely without a full page reload.
124
124
  // history.go(0);
125
125
  }
126
126
 
127
- console.log('currentWebsiteCode',currentWebsiteCode)
128
-
129
- if (!websiteCodeInUrl && getWebsiteByUserIp) {
130
- setVerifyUserIp(false);
131
-
132
- const search = location.search;
133
-
134
- const query = new URLSearchParams(search);
135
- const isAccessBaseWebsite = query.get('access_base_website') || (
136
- storage.getItem('access_base_website') || null
137
- );
127
+ // console.log('currentWebsiteCode',currentWebsiteCode)
138
128
 
139
- // const websiteCode = getWebsiteByUserIp.countryCode && !isAccessBaseWebsite ? getWebsiteByUserIp.countryCode.toLowerCase() : process.env.WEBSITE_CODE;
129
+ if (!websiteCodeInUrl) {
140
130
  const websiteCode = process.env.WEBSITE_CODE;
131
+ // if (websiteCode != storage.getItem('website_code')) {
132
+ setVerifyUserIp(false);
133
+
134
+ const search = location.search;
135
+
136
+ const query = new URLSearchParams(search);
137
+ const isAccessBaseWebsite = query.get('access_base_website') || (
138
+ storage.getItem('access_base_website') || null
139
+ );
141
140
 
142
- if (websiteCodes.find((str) => str === websiteCode)) {
143
- routerProps.basename = websiteCode != process.env.WEBSITE_CODE && !isAccessBaseWebsite ? '/'+websiteCode : '/';
141
+ // const websiteCode = getWebsiteByUserIp.countryCode && !isAccessBaseWebsite ? getWebsiteByUserIp.countryCode.toLowerCase() : process.env.WEBSITE_CODE;
144
142
 
145
- setNewRouterProps(routerProps);
143
+ if (websiteCodes.find((str) => str === websiteCode)) {
144
+ routerProps.basename = websiteCode != process.env.WEBSITE_CODE && !isAccessBaseWebsite ? '/'+websiteCode : '/';
146
145
 
147
- if (isAccessBaseWebsite) {
148
- storage.setItem('access_base_website', 1);
149
- }
146
+ setNewRouterProps(routerProps);
150
147
 
151
- let storeCodeInUrl = websiteStores[websiteCode];
148
+ if (isAccessBaseWebsite) {
149
+ storage.setItem('access_base_website', 1);
150
+ }
152
151
 
153
- storage.removeItem('cartId');
152
+ let storeCodeInUrl = websiteStores[websiteCode];
154
153
 
155
- storage.setItem('store_view_code', storeCodeInUrl);
156
- storage.setItem('website_code', websiteCode);
157
- storage.setItem(
158
- 'store_view_currency',
159
- storeCurrencies[storeCodeInUrl]
160
- );
161
- storage.setItem(
162
- 'store_view_secure_base_media_url',
163
- storeSecureBaseMediaUrl[storeCodeInUrl]
164
- );
165
- }
154
+ if (websiteCode != storage.getItem('website_code')) {
155
+ storage.removeItem('cartId');
156
+ }
157
+
158
+ storage.setItem('store_view_code', storeCodeInUrl);
159
+ storage.setItem('website_code', websiteCode);
160
+ storage.setItem(
161
+ 'store_view_currency',
162
+ storeCurrencies[storeCodeInUrl]
163
+ );
164
+ storage.setItem(
165
+ 'store_view_secure_base_media_url',
166
+ storeSecureBaseMediaUrl[storeCodeInUrl]
167
+ );
168
+ }
169
+ // }
166
170
  }
167
171
  }, [websiteCodeInUrl, currentWebsiteCode]);
168
172
 
@@ -27,6 +27,7 @@ const SignIn = props => {
27
27
  showCreateAccount,
28
28
  showForgotPassword,
29
29
  initialValues,
30
+ setIsLoading,
30
31
  showSocialLogin = true,
31
32
  } = props;
32
33
 
@@ -36,7 +37,8 @@ const SignIn = props => {
36
37
  getCartDetailsQuery: GET_CART_DETAILS_QUERY,
37
38
  setDefaultUsername,
38
39
  showCreateAccount,
39
- showForgotPassword
40
+ showForgotPassword,
41
+ setIsLoading
40
42
  });
41
43
 
42
44
  const {
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { shape, string } from 'prop-types';
3
3
  import { FormattedMessage, useIntl } from 'react-intl';
4
4
 
@@ -9,37 +9,43 @@ import SignIn from '@magento/venia-ui/lib/components/SignIn';
9
9
  import cn from 'classnames';
10
10
 
11
11
  import defaultClasses from './signInPage.module.css';
12
+ import LoadingRequest from '@riosst100/pwa-marketplace/src/components/LoadingRequest';
12
13
 
13
14
  const SignInPage = props => {
14
15
  const classes = useStyle(defaultClasses, props.classes);
15
16
  const { signInProps } = useSignInPage(props);
16
17
  const { formatMessage } = useIntl();
17
18
 
19
+ const [isLoading, setIsLoading] = useState(false);
20
+
18
21
  return (
19
- <div className={classes.signInRootContainer}>
20
- <div className={cn(classes.root, '!py-[60px]')}>
21
- <StoreTitle>
22
- {formatMessage({
23
- id: 'signInPage.title',
24
- defaultMessage: 'Sign In'
25
- })}
26
- </StoreTitle>
27
- <div className={cn(classes.leftContentContainer, '')}>
28
- <div class="auth-left">
29
- <img src="https://img.freepik.com/premium-vector/sign-concept-illustration_114360-125.jpg" width="50%" />
30
- <p style={{
31
- "fontSize": "20px",
32
- "fontWeight": 500
33
- }}>Sign in to start shopping or sell your collectibles.</p>
22
+ <>
23
+ <LoadingRequest isLoading={isLoading} />
24
+ <div className={classes.signInRootContainer}>
25
+ <div className={cn(classes.root, '!py-[60px]')}>
26
+ <StoreTitle>
27
+ {formatMessage({
28
+ id: 'signInPage.title',
29
+ defaultMessage: 'Sign In'
30
+ })}
31
+ </StoreTitle>
32
+ <div className={cn(classes.leftContentContainer, '')}>
33
+ <div class="auth-left">
34
+ <img src="https://img.freepik.com/premium-vector/sign-concept-illustration_114360-125.jpg" width="50%" />
35
+ <p style={{
36
+ "fontSize": "20px",
37
+ "fontWeight": 500
38
+ }}>Sign in to start shopping or sell your collectibles.</p>
39
+ </div>
34
40
  </div>
35
41
  </div>
36
- </div>
37
- <div className={cn(classes.root, '!py-[60px]')}>
38
- <div className={cn(classes.contentContainer, 'border border-gray-100 rounded-lg')}>
39
- <SignIn {...signInProps} />
42
+ <div className={cn(classes.root, '!py-[60px]')}>
43
+ <div className={cn(classes.contentContainer, 'border border-gray-100 rounded-lg')}>
44
+ <SignIn setIsLoading={setIsLoading} {...signInProps} />
45
+ </div>
40
46
  </div>
41
47
  </div>
42
- </div>
48
+ </>
43
49
  );
44
50
  };
45
51
 
@@ -1,8 +1,5 @@
1
1
  import { useEffect, useMemo } from 'react';
2
- import { useHistory } from 'react-router-dom';
3
2
  import { BrowserPersistence } from '@magento/peregrine/lib/util';
4
- import { useCartContext } from '@magento/peregrine/lib/context/cart';
5
- import { useApolloClient, useQuery } from '@apollo/client';
6
3
 
7
4
  const storage = new BrowserPersistence();
8
5
 
@@ -12,7 +9,6 @@ const storage = new BrowserPersistence();
12
9
  * and reloads the page so that they are used in the graphQL headers.
13
10
  */
14
11
  const StoreCodeRoute = () => {
15
- const history = useHistory();
16
12
 
17
13
  const websiteCodes = [];
18
14
  const websiteStores = useMemo(() => ({}), []);
@@ -34,61 +30,32 @@ const StoreCodeRoute = () => {
34
30
  // ie `https://example.com/fr/foo/baz.html` => `fr`.
35
31
  const { location } = globalThis;
36
32
  const match = location && location.pathname.split("/")[1];
33
+ const defaultWebsiteCode = process.env.WEBSITE_CODE;
37
34
  let websiteCodeInUrl = websiteCodes.find((str) => str === match);
38
35
 
39
36
  // Determine what the current store code is using the configured basename.
40
- const currentWebsiteCode = storage && storage.getItem('website_code') || process.env.WEBSITE_CODE;
41
-
42
-
43
37
 
44
38
  // If we find a store code in the url that is not the current one, update
45
39
  // the storage value and refresh so that we start using the new code.
46
40
  useEffect(() => {
47
- if (!websiteCodeInUrl) {
48
- history.replace(location.pathname + location.search)
49
- } else if (websiteCodeInUrl && websiteCodeInUrl !== currentWebsiteCode) {
50
- const storeCodeInUrl = websiteStores[websiteCodeInUrl];
51
-
52
- // alert(storeCodeInUrl)
53
-
54
- // update store/website saat url berubah, misal /id ke /sg
55
-
56
- // issue store view code gk berubah, klo di graphql aman
57
-
58
- // ini update di graphql dan di cookie, tapi di cookie beda klo ga di hardcode
41
+ if (websiteCodeInUrl) {
42
+ let prefix = '';
43
+ let storeCodeInUrl = websiteStores[websiteCodeInUrl];
59
44
 
60
- // ini oke, store di graphql dari sini
61
- // storeCodeInUrl = 'id_id_store_view';
62
- // console.log('storeCodeInUrl',storeCodeInUrl)
63
-
64
- // await apolloClient.clearCacheData(apolloClient, 'cart');
65
- // await removeCart();
66
- alert('22ok')
67
- storage.removeItem('cartId');
68
-
69
- storage.setItem('store_view_code', storeCodeInUrl);
70
- storage.setItem('website_code', websiteCodeInUrl);
45
+ storage.setItem(prefix + 'store_view_code', storeCodeInUrl);
46
+ storage.setItem(prefix + 'website_code', websiteCodeInUrl);
71
47
  storage.setItem(
72
- 'store_view_currency',
48
+ prefix + 'store_view_currency',
73
49
  storeCurrencies[storeCodeInUrl]
74
50
  );
51
+
75
52
  storage.setItem(
76
- 'store_view_secure_base_media_url',
53
+ prefix + 'store_view_secure_base_media_url',
77
54
  storeSecureBaseMediaUrl[storeCodeInUrl]
78
55
  );
79
-
80
- // We're required to reload the page as the basename doesn't
81
- // change entirely without a full page reload.
82
- // history.go(0);
83
56
  }
84
57
  }, [
85
- websiteCodeInUrl,
86
- // currentWebsiteCode,
87
- history
88
- // , apolloClient, removeCart
89
- // storeCodeInUrl,
90
- // storeCurrencies,
91
- // storeSecureBaseMediaUrl
58
+ websiteCodeInUrl
92
59
  ]);
93
60
 
94
61
  return null;
@@ -31,6 +31,7 @@ export const useSocialLogin = props => {
31
31
 
32
32
  const apolloClient = useApolloClient();
33
33
  const [isSigningIn, setIsSigningIn] = useState(false);
34
+ const [isLoading, setIsLoading] = useState(false);
34
35
 
35
36
  const [
36
37
  { cartId },
@@ -60,6 +61,7 @@ export const useSocialLogin = props => {
60
61
 
61
62
  useEffect(async () => {
62
63
  if (jwtToken) {
64
+ setIsLoading(true);
63
65
  setIsSigningIn(true);
64
66
  try {
65
67
  // Get source cart id (guest cart id).
@@ -124,6 +126,8 @@ export const useSocialLogin = props => {
124
126
  }),
125
127
  timeout: 5000
126
128
  });
129
+
130
+ setIsLoading(false);
127
131
  } catch (error) {
128
132
  if (process.env.NODE_ENV !== 'production') {
129
133
  console.error(error);
@@ -162,6 +166,7 @@ export const useSocialLogin = props => {
162
166
 
163
167
  return {
164
168
  errors,
169
+ isLoading,
165
170
  // isBusy: isGettingDetails || isSigningIn || recaptchaLoading,
166
171
  isBusy: isGettingDetails || isSigningIn,
167
172
  setFormApi