@akinon/pz-masterpass 1.102.0-rc.78 → 1.102.0

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
@@ -1,23 +1,6 @@
1
1
  # @akinon/pz-masterpass
2
2
 
3
- ## 1.102.0-rc.78
4
-
5
- ## 1.102.0-rc.77
6
-
7
- ### Minor Changes
8
-
9
- - d8be48fb: ZERO-3422: Update fetch method to use dynamic request method in wallet complete redirection middleware
10
- - ad0bec92: ZERO-3364 :Update readme file for masterpass
11
- - 16aff543: ZERO-3431: Add test script for redirect utility in package.json
12
- - 64699d3ff: ZERO-2761: Fix invalid import for plugin module
13
- - e974d8e8: ZERO-3406: Fix rc build
14
- - b31333ed: ZERO-3357 :Add components with renderer properties for customizable UI elements in pz-masterpass
15
- - 7eb51ca9: ZERO-3424 :Update package versions
16
- - 7727ae55f: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
17
- - 8b1d24eb: ZERO-3422: Update fetch method to use dynamic request method in wallet complete redirection middleware
18
- - 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
19
- - 08c3caec: ZERO-3607 :Enhance the DeleteButton component with additional features and improve the OTP modal functionality by adding minutes and seconds
20
- - e9af4e2: ZERO-3607 :Enhance the DeleteButton component with additional features and improve the OTP modal functionality by adding minutes and seconds
3
+ ## 1.102.0
21
4
 
22
5
  ## 1.101.0
23
6
 
@@ -49,8 +32,6 @@
49
32
 
50
33
  ## 1.91.0
51
34
 
52
- > > > > > > > origin/ZERO-3418
53
-
54
35
  ## 1.90.0
55
36
 
56
37
  ## 1.89.0
package/README.md CHANGED
@@ -12,14 +12,10 @@ npx @akinon/projectzero@latest --plugins
12
12
 
13
13
  ## Available Props
14
14
 
15
- ## Masterpass Provider
15
+ ### Masterpass Provider
16
16
 
17
17
  ##### File Path: src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx
18
18
 
19
- ### Usage Examples
20
-
21
- ##### Default Usage
22
-
23
19
  ```javascript
24
20
  <PluginModule
25
21
  component={Component.MasterpassProvider}
@@ -33,7 +29,7 @@ npx @akinon/projectzero@latest --plugins
33
29
  </PluginModule>
34
30
  ```
35
31
 
36
- ##### Customized Usage with Additional Params
32
+ ### Additional Params
37
33
 
38
34
  ##### To add extra parameters, it can be added by passing additional Params property to the Masterpass Provider.
39
35
 
@@ -55,30 +51,8 @@ npx @akinon/projectzero@latest --plugins
55
51
 
56
52
  ### Delete Confirmation Modal
57
53
 
58
- #### Props
59
-
60
- | Props | Type | Required | Description |
61
- | --- | --- | --- | --- |
62
- | translations | typeof defaultTranslations | Optional | Used to customize the default texts. |
63
- | renderer | RendererProps | Optional | Renderer functions that can be used to customize all subcomponents. |
64
-
65
- #### RendererProps
66
-
67
- | Props | Type | Description |
68
- | --- | --- | --- |
69
- | open | boolean | It is information whether the modal is open or not. |
70
- | setOpen | (open: boolean) => void | Used to manage modal on/off operation. |
71
- | onConfirm | () => void | This is the function that will perform the deletion operation. |
72
- | onCancel | () => void | This is the function that will be run if the user cancels the deletion process. |
73
- | loading | boolean | Indicates the loading status during the deletion process. |
74
- | error | string / null | Error message to be displayed if an error occurs during deletion. |
75
-
76
54
  ##### File Path: src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx
77
55
 
78
- ### Usage Examples
79
-
80
- ##### Default Usage
81
-
82
56
  ```javascript
83
57
  <PluginModule
84
58
  component={Component.MasterpassDeleteConfirmationModal}
@@ -92,70 +66,10 @@ npx @akinon/projectzero@latest --plugins
92
66
  />
93
67
  ```
94
68
 
95
- ##### Customized Usage with Renderer
96
-
97
- ```javascript
98
- <PluginModule
99
- component={Component.MasterpassDeleteConfirmationModal}
100
- props={{
101
- renderer: {
102
- Content: ({ open, setOpen, onConfirm, onCancel, loading, error }) => (
103
- <Modal
104
- open={open}
105
- setOpen={setOpen}
106
- className="w-full sm:w-[28rem]"
107
- portalId="masterpass-remove-card-modal"
108
- >
109
- <div className="flex flex-col items-center p-5">
110
- <div className="text-xs mb-3">
111
- Are you sure you want to delete your card?
112
- </div>
113
- <Button onClick={onConfirm} className="bg-red-600 text-black">
114
- {loading ? 'Deletion...' : 'Delete'}
115
- </Button>
116
- <Button appearance="outlined" onClick={onCancel}>
117
- Cancel
118
- </Button>
119
- {error && (
120
- <p className="text-red-500 text-sm mt-2 text-center">
121
- 🚨 {error}
122
- </p>
123
- )}
124
- </div>
125
- </Modal>
126
- )
127
- }
128
- }}
129
- />
130
- ```
131
-
132
69
  ### OTP Modal
133
70
 
134
- #### Props
135
-
136
- | Props | Type | Required | Description |
137
- | --- | --- | --- | --- |
138
- | translations | { [key: string]: string } | Optional | Translation object to customize all texts. Overrides default texts. |
139
- | renderer | RendererProps | Optional | Renderer functions that can be used to customize all subcomponents. |
140
-
141
- #### RendererProps
142
-
143
- | Props | Type | Description |
144
- | --- | --- | --- |
145
- | open | boolean | It is information whether the modal is open or not. |
146
- | setOpen | (open: boolean) => void | Used to manage modal on/off operation. |
147
- | onSubmit | (data: { otp_code: string }) => void | Sends the OTP code entered by the user. |
148
- | loading | boolean | Indicates the loading status during validation. |
149
- | error | string / null | Error message to be displayed if there is an error. |
150
- | resendSms | () => void | Function triggered when the user requests SMS again. |
151
- | resendSmsFetching | boolean | Indicates the loading status during the resending process. |
152
- | targetDate | number | When the countdown will end (as a timestamp). |
153
- | otpRef | string / null | Transaction reference number, if applicable. |
154
-
155
71
  ##### File Path: src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx
156
72
 
157
- ##### Default Usage
158
-
159
73
  ```javascript
160
74
  <PluginModule
161
75
  component={Component.MasterpassOtpModal}
@@ -172,123 +86,10 @@ npx @akinon/projectzero@latest --plugins
172
86
  />
173
87
  ```
174
88
 
175
- ##### Customized Usage with Renderer
176
-
177
- ```javascript
178
- <PluginModule
179
- component={Component.MasterpassOtpModal}
180
- props={{
181
- renderer: {
182
- Content: ({
183
- open,
184
- setOpen,
185
- onSubmit,
186
- loading,
187
- error,
188
- resendSms,
189
- resendSmsFetching,
190
- targetDate,
191
- otpRef,
192
- minutes,
193
- seconds,
194
- control,
195
- formError
196
- }) => {
197
- const [code, setCode] = useState('');
198
- return (
199
- <Modal
200
- portalId="otp-masterpass"
201
- open={open}
202
- setOpen={setOpen}
203
- className="w-[330px] bottom-auto top-1/4 mx-auto px-0 pb-0 md:pb-0 md:rounded-none md:pt-0 md:px-0 md:bottom-auto"
204
- iconSize={20}
205
- >
206
- <div className="py-4 px-14 pt-12 pb-9 flex flex-col justify-center items-center">
207
- <div className="text-lg leading-5 font-semibold text-secondary text-center pb-7">
208
- Telefon doğrulama kodunu gir
209
- </div>
210
- <form
211
- onSubmit={(e) => {
212
- e.preventDefault();
213
- onSubmit({ otp_code: code });
214
- }}
215
- >
216
- <div className="mt-2 flex flex-col items-center justify-between">
217
- <div>
218
- <label className="text-xs leading-[14px] font-normal text-secondary">
219
- SMS kodu
220
- </label>
221
- <Input
222
- id="otp_code"
223
- autoComplete="off"
224
- minLength={6}
225
- maxLength={6}
226
- max="999999"
227
- min="000000"
228
- control={control}
229
- className="h-9 rounded-full border-gray-620 mt-2"
230
- onChange={(e) =>
231
- setCode((e.target as HTMLInputElement).value)
232
- }
233
- />
234
- </div>
235
- <Button className="w-full capitalize bg-secondary rounded-full text-base h-auto py-1.5 mt-2 border-none">
236
- Doğrula
237
- </Button>
238
- {formError && (
239
- <p className="mt-2 text-error text-xs text-center">
240
- {formError}
241
- </p>
242
- )}
243
- </div>
244
- </form>
245
- {minutes + seconds > 0 ? (
246
- <div className="flex mt-2 flex justify-center">
247
- {`0${minutes}`} :{' '}
248
- {`${seconds < 10 ? '0' : ''}${seconds}`}
249
- </div>
250
- ) : (
251
- <Button
252
- onClick={() => resendSms()}
253
- className="w-full capitalize bg-secondary rounded-full text-base h-auto py-1.5 mt-2 border-none text-white"
254
- >
255
- {!resendSmsFetching ? 'resend code' : <LoaderSpinner />}
256
- </Button>
257
- )}
258
- </div>
259
- </Modal>
260
- );
261
- }
262
- }
263
- }}
264
- />
265
- ```
266
-
267
89
  ### Link Modal
268
90
 
269
- #### Props
270
-
271
- | Props | Type | Required | Description |
272
- | --- | --- | --- | --- |
273
- | translations | { [key: string]: string } | Optional | Translation object to customize all texts. Overrides default texts. |
274
- | renderer | RendererProps | Optional | Renderer functions that can be used to customize all subcomponents. |
275
-
276
- #### RendererProps
277
-
278
- | Props | Type | Description |
279
- | --- | --- | --- |
280
- | open | boolean | It is information whether the modal is open or not. |
281
- | setOpen | (open: boolean) => void | Used to manage modal on/off operation. |
282
- | onClick | () => void | It is the function that is called when the user clicks the "Use" button. |
283
- | loading | boolean | This is the loading status that will be displayed during the API request. |
284
- | error | string | If there is an error in the API response, a message is displayed in this field. |
285
-
286
91
  ##### File Path: src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx
287
92
 
288
- ### Usage Examples
289
-
290
- ##### Default Usage
291
-
292
93
  ```javascript
293
94
  <PluginModule
294
95
  component={Component.MasterpassLinkModal}
@@ -302,67 +103,10 @@ npx @akinon/projectzero@latest --plugins
302
103
  />
303
104
  ```
304
105
 
305
- ##### Customized Usage with Renderer
306
-
307
- ```javascript
308
- <PluginModule
309
- component={Component.MasterpassLinkModal}
310
- props={{
311
- renderer: {
312
- Content: ({ open, setOpen, onClick, loading, error }) => (
313
- <Modal
314
- open={open}
315
- setOpen={setOpen}
316
- className="w-full sm:w-[28rem]"
317
- portalId="masterpass-check-user"
318
- >
319
- <div className="p-10">
320
- <p className="text-sm text-center">
321
- You have cards registered to your Masterpass account. Do you want
322
- to use your cards?
323
- </p>
324
- <Button
325
- onClick={onClick}
326
- disabled={loading}
327
- className="bg-green-600 text-error w-full py-2 mt-4"
328
- >
329
- {loading ? 'Loading...' : 'Use'}
330
- </Button>
331
- {error && <p className="text-error text-sm">{error}</p>}
332
- </div>
333
- </Modal>
334
- )
335
- }
336
- }}
337
- />
338
- ```
339
-
340
106
  ### Card List
341
107
 
342
- #### Props
343
-
344
- | Props | Type | Required | Description |
345
- | --- | --- | --- | --- |
346
- | className | string | Optional | Gives an additional style class to the component's outer container. |
347
- | translations | { [key: string]: string } | Optional | Translation object to customize all texts. Overrides default texts. |
348
- | renderer | RendererProps | Optional | Renderer functions that can be used to customize all subcomponents. |
349
-
350
- #### RendererProps
351
-
352
- | Props | Type | Description |
353
- | --- | --- | --- |
354
- | Header | JSX.Element | Used to customize the title area at the top of the card list. |
355
- | CardItem | (params: { card, selectedCard, onSelect, DeleteButton }) => JSX.Element | It allows you to fully customize the card element. |
356
- | Loader | () => JSX.Element | Used to define a custom loader component to be displayed when loading cards. |
357
- | ErrorFallback | (params: { error: string; onRetry: () => void }) => JSX.Element | Custom widget to be shown if an error occurs while loading cards. |
358
- | SwitchPaymentButton | (props: { onClick: () => void; label: string }) => JSX.Element | Used to customize the "Pay with a new card" option. |
359
-
360
108
  ##### File Path: src/views/checkout/steps/payment/options/credit-card/index.tsx
361
109
 
362
- ### Usage Examples
363
-
364
- ##### Default Usage
365
-
366
110
  ```javascript
367
111
  <PluginModule
368
112
  component={Component.MasterpassCardList}
@@ -377,131 +121,10 @@ npx @akinon/projectzero@latest --plugins
377
121
  />
378
122
  ```
379
123
 
380
- ##### Customized Usage with Renderer
381
-
382
- ```javascript
383
- <PluginModule
384
- component={Component.MasterpassCardList}
385
- props={{
386
- className: 'px-10',
387
- form: {
388
- control,
389
- register,
390
- errors,
391
- setFormValue,
392
- clearErrors
393
- },
394
- renderer: {
395
- Header: () => (
396
- <div className="flex items-center gap-2 mt-4 px-10 text-success">
397
- Select a card to pay
398
- </div>
399
- ),
400
- Loader: () => (
401
- <div className="flex justify-center items-center p-10">
402
- <span className="text-lg font-bold text-error">
403
- Loading your cards...
404
- </span>
405
- </div>
406
- ),
407
- ErrorFallback: ({ error, onRetry }) => (
408
- <div className="text-center p-8">
409
- <h2 className="text-red-500 text-xl mb-4">Oops! {error}</h2>
410
- <Button onClick={onRetry}>Try Again</Button>
411
- </div>
412
- ),
413
- CardItem: ({ card, onSelect, DeleteButton, selectedCard }) => (
414
- <li
415
- key={card.UniqueId}
416
- className="p-4 cursor-pointer rounded-[10px] border-gray border space-x-5 pl-5 mb-6 md:mb-2.5"
417
- onClick={() => onSelect(card)}
418
- >
419
- <div className="flex justify-between items-center">
420
- <div className="flex items-center">
421
- <Checkbox
422
- key={
423
- selectedCard?.UniqueId === card.UniqueId
424
- ? 'selected'
425
- : 'not-selected'
426
- }
427
- checked={selectedCard?.UniqueId === card.UniqueId}
428
- onChange={() => onSelect(card)}
429
- className="mr-2"
430
- />
431
- <div>
432
- <h3 className="font-semibold">{card.Name}</h3>
433
- <p className="text-xs text-gray-500">{card.Value1}</p>
434
- </div>
435
- </div>
436
- <DeleteButton
437
- cardAliasName={card.Name}
438
- content={<Icon name="close" size={12} />}
439
- className="mb-8"
440
- />
441
- </div>
442
- </li>
443
- ),
444
- SwitchPaymentButton: ({ onClick, label }) => (
445
- <div className="px-10">
446
- <button
447
- onClick={onClick}
448
- className="p-4 w-full text-left cursor-pointer rounded-[10px] border-gray border space-x-5 pl-5 mb-6 md:mb-2.5"
449
- >
450
- {label}
451
- </button>
452
- </div>
453
- )
454
- }
455
- }}
456
- />
457
- ```
458
-
459
124
  ### Card Registration
460
125
 
461
- #### Props
462
-
463
- | Props | Type | Required | Description |
464
- | --- | --- | --- | --- |
465
- | getValues | () => Record<string, string> | Required | Returns the values ​​of form fields. |
466
- | className | string | Optional | Gives an additional CSS class to the outer container. |
467
- | infoModalContent | React.ReactNode | Optional | Body content for the informational modal. |
468
- | infoModalIcon | React.ReactNode | Optional | Used to override the notification icon. |
469
- | translations | typeof defaultTranslations | Optional | Can be used to override default texts. |
470
- | renderer | RendererProps | Optional | Renderer functions that can be used to customize all subcomponents. |
471
-
472
- #### RendererProps
473
-
474
- | Props | Type | Description |
475
- | --- | --- | --- |
476
- | Content | (props: { isChecked, toggle, setIsInfoModalOpen, onChange, onSubmit, loading, error, showGoBackLink?, onClickGoBackLink? }) => JSX.Element | Used to render the main content. |
477
- | InfoModal | (props: { open: boolean; setOpen: (value: boolean) => void }) => JSX.Element | Can be used to override the notification modal. |
478
-
479
126
  ##### File Path: src/views/checkout/steps/payment/options/credit-card/index.tsx
480
127
 
481
- ### Usage Examples
482
-
483
- ##### Default Usage
484
-
485
- ```javascript
486
- <PluginModule
487
- component={Component.MasterpassCardRegistration}
488
- props={{
489
- // Do not remove getValues, it is used to get the form values
490
- getValues,
491
- translations: {
492
- enter_card_name: 'Enter card name',
493
- continue: 'Continue',
494
- pay_with_my_masterpass_card: 'Pay with my Masterpass card',
495
- terms_and_conditions: 'Masterpass terms and conditions',
496
- card_registration_consent:
497
- 'I want to store my card information in the Mastercard infrastructure and use it again in my next purchase.'
498
- }
499
- }}
500
- />
501
- ```
502
-
503
- ##### Customized Usage with className, infoModalContent, infoModalIcon
504
-
505
128
  ```javascript
506
129
  <PluginModule
507
130
  component={Component.MasterpassCardRegistration}
@@ -522,86 +145,3 @@ npx @akinon/projectzero@latest --plugins
522
145
  }}
523
146
  />
524
147
  ```
525
-
526
- ##### Customized Usage with Renderer
527
-
528
- ```javascript
529
- <PluginModule
530
- component={Component.MasterpassCardRegistration}
531
- props={{
532
- // Do not remove getValues, it is used to get the form values
533
- getValues,
534
- renderer: {
535
- InfoModal: ({ open, setOpen }) => (
536
- <Modal
537
- open={open}
538
- setOpen={setOpen}
539
- portalId="masterpass-info-modal"
540
- >
541
- masterpass information
542
- </Modal>
543
- ),
544
- Content: ({
545
- isChecked,
546
- toggle,
547
- setIsInfoModalOpen,
548
- onChange,
549
- onSubmit,
550
- loading,
551
- error,
552
- showGoBackLink,
553
- onClickGoBackLink
554
- }) => (
555
- <div className="bg-[#F8F8F8] mx-10 mb-5 px-2 py-1">
556
- <div className="flex items-center gap-2 pb-4 mb-4">
557
- <Checkbox checked={isChecked} onChange={toggle} />
558
- <h1>Masterpass</h1>
559
- <div>
560
- <Icon
561
- name="info"
562
- size={15}
563
- className="fill-[#000000] cursor-pointer"
564
- onClick={() => {
565
- setIsInfoModalOpen(true);
566
- }}
567
- />
568
- </div>
569
- </div>
570
- <p className="text-xs">
571
- I want to store my card information in the Mastercard infrastructure and use it again in my next purchase.
572
- </p>
573
- {isChecked && (
574
- <>
575
- <Input
576
- label="Give your card a name"
577
- onChange={(e) =>
578
- onChange((e.target as HTMLInputElement).value)
579
- }
580
- className="mt-2"
581
- />
582
- <Button
583
- onClick={onSubmit}
584
- className="bg-green-600 text-black w-full mt-3"
585
- >
586
- {loading ? 'Loading...' : 'Save'}
587
- </Button>
588
- {error && (
589
- <p className="text-xs text-red-600 mt-2">🚨 {error}</p>
590
- )}
591
- </>
592
- )}
593
- {showGoBackLink && (
594
- <div>
595
- <button
596
- onClick={onClickGoBackLink}
597
- className="text-xs text-red-600 underline mt-3"
598
- >
599
- I want to pay with my card registered to Masterpass.
600
- </button>
601
- </div>
602
- )}
603
- </div>
604
- )
605
- }
606
- }}
607
- ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/pz-masterpass",
3
- "version": "1.102.0-rc.78",
3
+ "version": "1.102.0",
4
4
  "license": "MIT",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.d.ts",
@@ -3,20 +3,14 @@
3
3
  import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
4
4
  import { Icon } from 'components';
5
5
  import { useCallback, useEffect, useMemo, useState } from 'react';
6
- import { twMerge } from 'tailwind-merge';
7
6
  import {
8
7
  setDeletionCardAliasName,
9
8
  setDeletionModalVisible
10
9
  } from '../redux/reducer';
10
+ import { CheckMasterpassResponse } from '../types';
11
11
  import { formCreator } from '../utils';
12
12
  import { useCards } from './use-cards';
13
13
 
14
- export type DeleteButtonProps = {
15
- cardAliasName: string;
16
- content?: JSX.Element;
17
- className?: string;
18
- };
19
-
20
14
  export const useDeleteCard = () => {
21
15
  const { msisdn, token, language, deletion } = useAppSelector(
22
16
  (state: any) => state.masterpass
@@ -73,27 +67,22 @@ export const useDeleteCard = () => {
73
67
 
74
68
  const DeleteButton = useMemo(
75
69
  () =>
76
- ({ cardAliasName, content, className }: DeleteButtonProps) => {
70
+ ({ cardAliasName }: { cardAliasName: string }) => {
77
71
  return (
78
72
  <span
79
- className={twMerge('cursor-pointer p-1', className)}
73
+ className="cursor-pointer p-1"
80
74
  onClick={(event: React.MouseEvent<HTMLElement>) => {
81
75
  event.stopPropagation();
82
76
  dispatch(setDeletionModalVisible(true));
83
77
  dispatch(setDeletionCardAliasName(cardAliasName));
84
78
  }}
85
79
  >
86
- {content ?? <Icon name="close" size={12} />}
80
+ <Icon name="close" size={12} />
87
81
  </span>
88
82
  );
89
83
  },
90
84
  []
91
85
  );
92
86
 
93
- return {
94
- DeleteButton,
95
- deleteCard,
96
- isLoading,
97
- error
98
- };
87
+ return { DeleteButton, deleteCard, isLoading, error };
99
88
  };
@@ -48,30 +48,6 @@ const defaultTranslations = {
48
48
  security_code_info: 'What’s CVC?'
49
49
  };
50
50
 
51
- interface RendererProps {
52
- Header?: () => JSX.Element;
53
- CardItem?: (params: {
54
- card: any;
55
- selectedCard: any;
56
- onSelect: (card: any) => Promise<void>;
57
- DeleteButton?: React.FC<{
58
- cardAliasName: string;
59
- onDelete: () => void;
60
- className?: string;
61
- content?: JSX.Element;
62
- }>;
63
- }) => JSX.Element;
64
- Loader?: () => JSX.Element;
65
- ErrorFallback?: (params: {
66
- error: string;
67
- onRetry: () => void;
68
- }) => JSX.Element;
69
- SwitchPaymentButton?: (props: {
70
- onClick: () => void;
71
- label: string;
72
- }) => JSX.Element;
73
- }
74
-
75
51
  export interface MasterpassCardListProps {
76
52
  className?: string;
77
53
  translations?: typeof defaultTranslations;
@@ -82,14 +58,12 @@ export interface MasterpassCardListProps {
82
58
  register: UseFormRegister<any>;
83
59
  setFormValue: UseFormSetValue<any>;
84
60
  };
85
- renderer?: RendererProps;
86
61
  }
87
62
 
88
63
  export const MasterpassCardList = ({
89
64
  className,
90
65
  translations,
91
- form,
92
- renderer
66
+ form
93
67
  }: MasterpassCardListProps) => {
94
68
  const { preOrder } = useAppSelector((state) => state.checkout);
95
69
  const { accountStatus, isDirectPurchase, selectedCard, cvcRequired } =
@@ -99,28 +73,7 @@ export const MasterpassCardList = ({
99
73
  const { DeleteButton } = useDeleteCard();
100
74
  const dispatch = useAppDispatch();
101
75
 
102
- const onSelectCard = async (card: any) => {
103
- if (selectedCard?.UniqueId !== card.UniqueId) {
104
- await setMasterpassBinNumber(card.Value1.substring(0, 6)).unwrap();
105
- dispatch(setSelectedCard(card));
106
- dispatch(setCvcRequired(false));
107
- if (form) {
108
- form.setFormValue('card_cvv', '');
109
- form.clearErrors('card_cvv');
110
- }
111
- }
112
- };
113
-
114
- const switchPaymentButton = renderer?.SwitchPaymentButton ? (
115
- renderer.SwitchPaymentButton({
116
- onClick: () => {
117
- dispatch(setIsDirectPurchase(true));
118
- dispatch(setInstallmentOptions([]));
119
- },
120
- label:
121
- translations?.pay_with_new_card ?? defaultTranslations.pay_with_new_card
122
- })
123
- ) : (
76
+ const switchPaymentButton = (
124
77
  <a
125
78
  href="#"
126
79
  className="text-xs underline"
@@ -139,9 +92,7 @@ export const MasterpassCardList = ({
139
92
  }
140
93
 
141
94
  if (loading) {
142
- return renderer?.Loader ? (
143
- renderer.Loader()
144
- ) : (
95
+ return (
145
96
  <div className="p-5">
146
97
  <LoaderSpinner className="w-8 h-8" />
147
98
  </div>
@@ -149,14 +100,18 @@ export const MasterpassCardList = ({
149
100
  }
150
101
 
151
102
  if (error && !isDirectPurchase) {
152
- return renderer?.ErrorFallback ? (
153
- renderer.ErrorFallback({ error, onRetry: refreshCards })
154
- ) : (
103
+ return (
155
104
  <div className="flex flex-col items-center">
156
105
  <div className="p-5">{error}</div>
157
- <Button className="w-48 mb-5" onClick={refreshCards}>
106
+ <Button
107
+ className="w-48 mb-5"
108
+ onClick={() => {
109
+ refreshCards();
110
+ }}
111
+ >
158
112
  {translations?.retryFetchCards ?? defaultTranslations.retryFetchCards}
159
113
  </Button>
114
+
160
115
  {switchPaymentButton}
161
116
  </div>
162
117
  );
@@ -171,75 +126,38 @@ export const MasterpassCardList = ({
171
126
  }
172
127
 
173
128
  return (
174
- <div className="w-full">
175
- {renderer?.Header ? (
176
- renderer.Header()
177
- ) : (
178
- <>
179
- <Image
180
- className="mb-4"
181
- width={140}
182
- height={25}
183
- src={masterpassLogo.src}
184
- alt="Masterpass Logo"
185
- />
186
- <p className="text-xs">
187
- {translations?.title ?? defaultTranslations.title}
188
- </p>
189
- </>
190
- )}
191
-
192
- <ul className={twMerge('mt-4 text-xs', className)}>
129
+ <div className={twMerge('w-full', className)}>
130
+ <Image
131
+ className="mb-4"
132
+ width={140}
133
+ height={25}
134
+ src={masterpassLogo.src}
135
+ alt="Masterpass Logo"
136
+ />
137
+ <p className="text-xs">
138
+ {translations?.title ?? defaultTranslations.title}
139
+ </p>
140
+ <ul className="mt-4 text-xs">
193
141
  {cards?.map((card) => {
194
- const cvcField =
195
- selectedCard?.UniqueId === card.UniqueId && form && cvcRequired ? (
196
- <div
197
- className={twMerge(
198
- clsx('flex items-center justify-start mt-2', {
199
- 'items-baseline': form.errors.card_cvv
200
- })
201
- )}
202
- >
203
- <label
204
- className="text-xs text-black-400 mr-1.5"
205
- htmlFor="card_cvv"
206
- >
207
- {translations?.security_code ??
208
- defaultTranslations.security_code}
209
- </label>
210
- <Input
211
- format="###"
212
- mask="_"
213
- control={form.control}
214
- allowEmptyFormatting={true}
215
- {...form.register('card_cvv')}
216
- error={form.errors.card_cvv}
217
- />
218
- <div className="group relative flex items-center justify-start text-gray-600 cursor-pointer ml-2 transition-all hover:text-secondary">
219
- <span className="text-xs underline">
220
- {translations?.security_code_info ??
221
- defaultTranslations.security_code_info}
222
- </span>
223
- <Icon name="cvc" size={16} className="leading-none ml-2" />
224
- <div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2">
225
- <Image src="/cvv.jpg" alt="Cvv" width={385} height={262} />
226
- </div>
227
- </div>
228
- </div>
229
- ) : null;
230
-
231
- return renderer?.CardItem ? (
232
- renderer.CardItem({
233
- card,
234
- selectedCard,
235
- onSelect: onSelectCard,
236
- DeleteButton
237
- })
238
- ) : (
142
+ return (
239
143
  <li
240
144
  key={card.UniqueId}
241
145
  className="p-4 mb-2 border-2 border-gray-200 flex flex-col space-x-2 cursor-pointer"
242
- onClick={() => onSelectCard(card)}
146
+ onClick={async () => {
147
+ if (selectedCard?.UniqueId !== card.UniqueId) {
148
+ await setMasterpassBinNumber(
149
+ card.Value1.substring(0, 6)
150
+ ).unwrap();
151
+
152
+ dispatch(setSelectedCard(card));
153
+ dispatch(setCvcRequired(false));
154
+
155
+ if (form) {
156
+ form.setFormValue('card_cvv', '');
157
+ form.clearErrors('card_cvv');
158
+ }
159
+ }
160
+ }}
243
161
  >
244
162
  <div className="flex justify-between items-center">
245
163
  <input
@@ -251,14 +169,12 @@ export const MasterpassCardList = ({
251
169
  className="mr-2"
252
170
  onChange={(e) => e.preventDefault()}
253
171
  />
254
-
255
172
  <label
256
173
  htmlFor={card.UniqueId}
257
174
  className="flex flex-col w-full cursor-pointer md:flex-row md:items-center md:justify-between"
258
175
  >
259
176
  <p className="w-full lg:w-1/3">{card.Name}</p>
260
177
  <p className="w-full text-[10px] lg:w-1/3">{card.Value1}</p>
261
-
262
178
  <Image
263
179
  className="w-8 h-6 object-contain flex items-center justify-center mr-4"
264
180
  width={50}
@@ -270,7 +186,46 @@ export const MasterpassCardList = ({
270
186
 
271
187
  <DeleteButton cardAliasName={card.Name} />
272
188
  </div>
273
- {cvcField}
189
+ {selectedCard?.UniqueId === card.UniqueId && form && cvcRequired && (
190
+ <div
191
+ className={twMerge(
192
+ clsx('flex items-center justify-start mt-2', {
193
+ 'items-baseline': form.errors.card_cvv
194
+ })
195
+ )}
196
+ >
197
+ <label
198
+ className="text-xs text-black-400 mr-1.5"
199
+ htmlFor="card_cvv"
200
+ >
201
+ {translations?.security_code ??
202
+ defaultTranslations.security_code}
203
+ </label>
204
+ <Input
205
+ format="###"
206
+ mask="_"
207
+ control={form.control}
208
+ allowEmptyFormatting={true}
209
+ {...form.register('card_cvv')}
210
+ error={form.errors.card_cvv}
211
+ />
212
+ <div className="group relative flex items-center justify-start text-gray-600 cursor-pointer ml-2 transition-all hover:text-secondary">
213
+ <span className="text-xs underline">
214
+ {translations?.security_code_info ??
215
+ defaultTranslations.security_code_info}
216
+ </span>
217
+ <Icon name="cvc" size={16} className="leading-none ml-2" />
218
+ <div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2">
219
+ <Image
220
+ src="/cvv.jpg"
221
+ alt="Cvv"
222
+ width={385}
223
+ height={262}
224
+ />
225
+ </div>
226
+ </div>
227
+ </div>
228
+ )}
274
229
  </li>
275
230
  );
276
231
  })}
@@ -32,31 +32,13 @@ export const MasterpassCardRegistration = ({
32
32
  className,
33
33
  infoModalContent,
34
34
  infoModalIcon,
35
- translations,
36
- renderer = {}
35
+ translations
37
36
  }: {
38
37
  getValues: () => Record<string, string | number | boolean>;
39
38
  className?: string;
40
39
  infoModalContent?: React.ReactNode;
41
40
  infoModalIcon?: React.ReactNode;
42
41
  translations?: typeof defaultTranslations;
43
- renderer?: {
44
- Content?: (props: {
45
- isChecked: boolean;
46
- toggle: () => void;
47
- setIsInfoModalOpen: (value: boolean) => void;
48
- onChange: (value: string) => void;
49
- onSubmit: () => void;
50
- loading: boolean;
51
- error: string | null;
52
- showGoBackLink?: boolean;
53
- onClickGoBackLink?: () => void;
54
- }) => JSX.Element;
55
- InfoModal?: (props: {
56
- open: boolean;
57
- setOpen: (value: boolean) => void;
58
- }) => JSX.Element;
59
- };
60
42
  }) => {
61
43
  const { preOrder } = useAppSelector((state: RootState) => state.checkout);
62
44
  const { msisdn, token, language, otp, isDirectPurchase, accountStatus } =
@@ -186,56 +168,13 @@ export const MasterpassCardRegistration = ({
186
168
  return null;
187
169
  }
188
170
 
189
- if (renderer.Content) {
190
- return (
191
- <>
192
- {renderer.InfoModal ? (
193
- <renderer.InfoModal
194
- open={isInfoModalOpen}
195
- setOpen={setIsInfoModalOpen}
196
- />
197
- ) : (
198
- <InfoModal
199
- open={isInfoModalOpen}
200
- setOpen={setIsInfoModalOpen}
201
- content={infoModalContent}
202
- />
203
- )}
204
-
205
- <renderer.Content
206
- isChecked={isAgreementChecked}
207
- toggle={() => setIsAgreementChecked(!isAgreementChecked)}
208
- setIsInfoModalOpen={setIsInfoModalOpen}
209
- onChange={(value) => setAccountAliasName(value)}
210
- onSubmit={registerCard}
211
- loading={isBusy}
212
- error={formError}
213
- showGoBackLink={
214
- accountStatus !== MasterpassStatus.NoAccount && cards?.length > 0
215
- }
216
- onClickGoBackLink={() => {
217
- dispatch(setIsDirectPurchase(false));
218
- dispatch(setInstallmentOptions([]));
219
- }}
220
- />
221
- </>
222
- );
223
- }
224
-
225
171
  return (
226
172
  <div className={twMerge('w-full', className)}>
227
- {renderer.InfoModal ? (
228
- <renderer.InfoModal
229
- open={isInfoModalOpen}
230
- setOpen={setIsInfoModalOpen}
231
- />
232
- ) : (
233
- <InfoModal
234
- open={isInfoModalOpen}
235
- setOpen={setIsInfoModalOpen}
236
- content={infoModalContent}
237
- />
238
- )}
173
+ <InfoModal
174
+ open={isInfoModalOpen}
175
+ setOpen={setIsInfoModalOpen}
176
+ content={infoModalContent}
177
+ />
239
178
 
240
179
  <div className="border border-[#ddd]">
241
180
  <div className="p-4">
@@ -15,39 +15,15 @@ const defaultTranslations = {
15
15
 
16
16
  export interface MasterpassDeleteConfirmationModalProps {
17
17
  translations?: typeof defaultTranslations;
18
- renderer?: {
19
- Content?: (props: {
20
- open: boolean;
21
- setOpen: (open: boolean) => void;
22
- onConfirm: () => void;
23
- onCancel: () => void;
24
- loading: boolean;
25
- error: string | null;
26
- }) => JSX.Element;
27
- };
28
18
  }
29
19
 
30
20
  export const MasterpassDeleteConfirmationModal = ({
31
- translations,
32
- renderer = {}
21
+ translations
33
22
  }: MasterpassDeleteConfirmationModalProps) => {
34
23
  const { deletion } = useAppSelector((state) => state.masterpass);
35
24
  const { deleteCard, isLoading, error } = useDeleteCard();
36
25
  const dispatch = useAppDispatch();
37
26
 
38
- if (renderer.Content) {
39
- return (
40
- <renderer.Content
41
- open={deletion.isModalVisible}
42
- setOpen={() => dispatch(setDeletionModalVisible(false))}
43
- onConfirm={deleteCard}
44
- onCancel={() => dispatch(setDeletionModalVisible(false))}
45
- loading={isLoading}
46
- error={error}
47
- />
48
- );
49
- }
50
-
51
27
  return (
52
28
  <Modal
53
29
  portalId="masterpass-remove-card-modal"
@@ -21,20 +21,10 @@ const defaultTranslations = {
21
21
 
22
22
  export interface MasterpassLinkModalProps {
23
23
  translations?: typeof defaultTranslations;
24
- renderer?: {
25
- Content?: (props: {
26
- open: boolean;
27
- setOpen: (open: boolean) => void;
28
- onClick: () => void;
29
- loading: boolean;
30
- error: string | null;
31
- }) => JSX.Element;
32
- };
33
24
  }
34
25
 
35
26
  export const MasterpassLinkModal = ({
36
- translations,
37
- renderer = {}
27
+ translations
38
28
  }: MasterpassLinkModalProps) => {
39
29
  const { msisdn, token, accountStatus, otp, language } = useAppSelector(
40
30
  (state) => state.masterpass
@@ -103,18 +93,6 @@ export const MasterpassLinkModal = ({
103
93
  }
104
94
  }, [otp.response]);
105
95
 
106
- if (renderer.Content) {
107
- return (
108
- <renderer.Content
109
- open={isOpen}
110
- setOpen={setIsOpen}
111
- onClick={onLinkButtonClick}
112
- loading={isLoading}
113
- error={error}
114
- />
115
- );
116
- }
117
-
118
96
  return (
119
97
  <Modal
120
98
  portalId="masterpass-check-user"
@@ -12,32 +12,15 @@ import { OtpForm, OtpFormProps, defaultTranslations } from './otp-form';
12
12
  import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
13
13
  import { setOtpModalVisible, setOtpResponse } from '../../redux/reducer';
14
14
  import { Image } from '@akinon/next/components/image';
15
- import { useCountdown } from '../../hooks/use-countdown';
16
15
 
17
16
  export interface MasterpassOtpModalProps {
18
17
  translations?: {
19
18
  5001?: string;
20
19
  } & OtpFormProps['translations'];
21
- renderer?: {
22
- Content?: (props: {
23
- open: boolean;
24
- setOpen: (open: boolean) => void;
25
- onSubmit: (data: { otp_code: string }) => void;
26
- loading: boolean;
27
- error: string | null;
28
- resendSms: () => void;
29
- resendSmsFetching: boolean;
30
- targetDate: number;
31
- otpRef: string | null;
32
- minutes?: number;
33
- seconds?: number;
34
- }) => JSX.Element;
35
- };
36
20
  }
37
21
 
38
22
  export const MasterpassOtpModal = ({
39
- translations,
40
- renderer = {}
23
+ translations
41
24
  }: MasterpassOtpModalProps) => {
42
25
  const { token, otp, language } = useAppSelector((state) => state.masterpass);
43
26
  const [isModalOpen, setIsModalOpen] = useState(false);
@@ -128,26 +111,6 @@ export const MasterpassOtpModal = ({
128
111
  }
129
112
  }, [isModalOpen]);
130
113
 
131
- if (renderer.Content) {
132
- const [minutes, seconds] = useCountdown(new Date(otpTime));
133
-
134
- return (
135
- <renderer.Content
136
- open={isModalOpen}
137
- setOpen={handleModalVisibility}
138
- onSubmit={onFormSubmit}
139
- loading={isBusy}
140
- error={otpError}
141
- resendSms={resendSms}
142
- resendSmsFetching={isBusy}
143
- targetDate={otpTime}
144
- otpRef={otpRef}
145
- minutes={minutes}
146
- seconds={seconds}
147
- />
148
- );
149
- }
150
-
151
114
  return (
152
115
  <Modal
153
116
  portalId="otp-masterpass"