@akinon/next 1.14.1 → 1.16.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/.gitattributes ADDED
@@ -0,0 +1,15 @@
1
+ *.js text eol=lf
2
+ *.jsx text eol=lf
3
+ *.ts text eol=lf
4
+ *.tsx text eol=lf
5
+ *.json text eol=lf
6
+ *.md text eol=lf
7
+
8
+ .eslintignore text eol=lf
9
+ .eslintrc text eol=lf
10
+ .gitignore text eol=lf
11
+ .prettierrc text eol=lf
12
+ .yarnrc text eol=lf
13
+
14
+ * text=auto
15
+
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 1.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a2458ad: ZERO-2414: Add OpenTelemetry instrumentation for tracing
8
+ - a2458ad: ZERO-2415: Refactor plugins
9
+
10
+ ## 1.15.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 96dd05f: ZERO-2373: Add credit payment
15
+ - 96dd05f: ZERO-2385: Add gitattributes file
16
+ - 96dd05f: ZERO-2404: Add gpay middleware
17
+
3
18
  ## 1.14.1
4
19
 
5
20
  ### Patch Changes
@@ -1,29 +1,29 @@
1
- .checkout-payment-iframe-wrapper {
2
- position: fixed;
3
- top: 0;
4
- left: 0;
5
- width: 100%;
6
- height: 100%;
7
- border: none;
8
- z-index: 1000;
9
- background-color: white;
10
-
11
- iframe {
12
- width: 100%;
13
- height: 100%;
14
- border: none;
15
- background-color: white;
16
- }
17
-
18
- .close-button {
19
- position: fixed;
20
- top: 16px;
21
- right: 16px;
22
- width: 32px;
23
- height: 32px;
24
- display: flex;
25
- align-items: center;
26
- justify-content: center;
27
- z-index: 1001;
28
- }
1
+ .checkout-payment-iframe-wrapper {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ border: none;
8
+ z-index: 1000;
9
+ background-color: white;
10
+
11
+ iframe {
12
+ width: 100%;
13
+ height: 100%;
14
+ border: none;
15
+ background-color: white;
16
+ }
17
+
18
+ .close-button {
19
+ position: fixed;
20
+ top: 16px;
21
+ right: 16px;
22
+ width: 32px;
23
+ height: 32px;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ z-index: 1001;
28
+ }
29
29
  }
@@ -10,14 +10,17 @@ let plugins;
10
10
 
11
11
  try {
12
12
  plugins = require(path.resolve(rootDir, './src/plugins.js'));
13
- } catch (error) {}
13
+ } catch (error) {
14
+ console.error('No plugins.js file found, skipping plugin installation.');
15
+ process.exit(0);
16
+ }
14
17
 
15
18
  let installCmd = [];
16
19
 
17
20
  availablePlugins
18
21
  .filter((p) => plugins?.includes(p))
19
22
  .forEach((name) => {
20
- installCmd.push(`git+https://bitbucket.org/akinonteam/${name}`);
23
+ installCmd.push(`@akinon/${name}`);
21
24
  });
22
25
 
23
26
  spawn.sync('yarn', ['cache clean']);
@@ -46,6 +46,12 @@ interface ImageProps extends NextImageProps {
46
46
  */
47
47
  sizes?: string;
48
48
  imageClassName?: string;
49
+
50
+ /**
51
+ * Swiper removed and we use react-multi-carousel at the moment.
52
+ * We need to use this prop to make the image draggable or not.
53
+ */
54
+ draggable?: boolean;
49
55
  }
50
56
 
51
57
  const DEFAULT_QUALITY = 70;
@@ -87,6 +93,7 @@ export const Image = (props: ImageProps) => {
87
93
  aspectRatio,
88
94
  quality = DEFAULT_QUALITY,
89
95
  crop = 'center',
96
+ draggable,
90
97
  className,
91
98
  imageClassName,
92
99
  ...restImage
@@ -127,6 +134,7 @@ export const Image = (props: ImageProps) => {
127
134
  }}
128
135
  className={imageClassName}
129
136
  {...(hasGif && { unoptimized: true })}
137
+ {...(draggable !== undefined && { draggable })}
130
138
  />
131
139
  </div>
132
140
  );
@@ -7,6 +7,7 @@ export * from './input';
7
7
  export * from './lazy-component';
8
8
  export * from './loader-spinner';
9
9
  export * from './mobile-app-toggler';
10
+ export * from './modal';
10
11
  export * from './oauth-login';
11
12
  export * from './plugin-module';
12
13
  export * from './price';
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+
3
+ import { ReactPortal } from './react-portal';
4
+
5
+ import { Icon } from './icon';
6
+ import { twMerge } from 'tailwind-merge';
7
+ import { useEffect } from 'react';
8
+ export interface ModalProps {
9
+ portalId: string;
10
+ children?: React.ReactNode;
11
+ open?: boolean;
12
+ setOpen?: (open: boolean) => void;
13
+ title?: React.ReactNode;
14
+ showCloseButton?: React.ReactNode;
15
+ className?: string;
16
+ }
17
+
18
+ export const Modal = (props: ModalProps) => {
19
+ const {
20
+ children,
21
+ portalId,
22
+ open,
23
+ setOpen,
24
+ title = '',
25
+ showCloseButton = true,
26
+ className
27
+ } = props;
28
+
29
+ useEffect(() => {
30
+ if (open) {
31
+ document.body.style.overflow = 'hidden';
32
+ } else {
33
+ document.body.style.overflow = 'auto';
34
+ }
35
+ }, [open]);
36
+
37
+ if (!open) return null;
38
+
39
+ return (
40
+ <ReactPortal wrapperId={portalId}>
41
+ <div className="fixed top-0 left-0 w-screen h-screen bg-primary bg-opacity-60 z-50" />
42
+ <section
43
+ className={twMerge(
44
+ 'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
45
+ className
46
+ )}
47
+ >
48
+ {(showCloseButton || title) && (
49
+ <div className="flex px-6 py-4 border-b border-gray-400">
50
+ {title && <h3 className="text-lg font-light">{title}</h3>}
51
+ {showCloseButton && (
52
+ <button
53
+ type="button"
54
+ onClick={() => setOpen(false)}
55
+ className="ml-auto"
56
+ >
57
+ <Icon name="close" size={16} />
58
+ </button>
59
+ )}
60
+ </div>
61
+ )}
62
+ {children}
63
+ </section>
64
+ </ReactPortal>
65
+ );
66
+ };
@@ -12,7 +12,7 @@ enum Plugin {
12
12
  GPay = 'pz-gpay',
13
13
  Otp = 'pz-otp',
14
14
  BKMExpress = 'pz-bkm',
15
- Masterpass = 'pz-masterpass'
15
+ CreditPayment= 'pz-credit-payment'
16
16
  }
17
17
 
18
18
  export enum Component {
@@ -24,7 +24,7 @@ export enum Component {
24
24
  GPay = 'GPayOption',
25
25
  Otp = 'Otp',
26
26
  BKMExpress = 'BKMOption',
27
- MasterpassCardList = 'MasterpassCardList'
27
+ CreditPayment= 'CreditPayment'
28
28
  }
29
29
 
30
30
  const PluginComponents = new Map([
@@ -36,7 +36,7 @@ const PluginComponents = new Map([
36
36
  [Plugin.GPay, [Component.GPay]],
37
37
  [Plugin.Otp, [Component.Otp]],
38
38
  [Plugin.BKMExpress, [Component.BKMExpress]],
39
- [Plugin.Masterpass, [Component.MasterpassCardList]]
39
+ [Plugin.CreditPayment, [Component.CreditPayment]]
40
40
  ]);
41
41
 
42
42
  const getPlugin = (component: Component) => {
@@ -56,6 +56,10 @@ export default function PluginModule({
56
56
  }) {
57
57
  const plugin = getPlugin(component);
58
58
 
59
+ if (!(plugins as string[]).includes(plugin)) {
60
+ return null;
61
+ }
62
+
59
63
  const Component = useMemo(
60
64
  () =>
61
65
  dynamic(
@@ -79,6 +83,8 @@ export default function PluginModule({
79
83
  promise = import(`${'pz-otp'}`);
80
84
  } else if (plugin === Plugin.BKMExpress) {
81
85
  promise = import(`${'pz-bkm'}`);
86
+ } else if (plugin === Plugin.CreditPayment) {
87
+ promise = import(`${'pz-credit-payment'}`);
82
88
  }
83
89
  } catch (error) {
84
90
  logger.error(error);
@@ -90,12 +96,8 @@ export default function PluginModule({
90
96
  },
91
97
  { ssr: false }
92
98
  ),
93
- [plugin, component]
99
+ [plugin]
94
100
  );
95
101
 
96
- if (!(plugins as string[]).includes(plugin)) {
97
- return null;
98
- }
99
-
100
102
  return <Component {...props} />;
101
103
  }
@@ -50,10 +50,6 @@ export default function SelectedPaymentOptionView() {
50
50
  );
51
51
  } else if (payment_option.payment_type === 'loyalty_money') {
52
52
  promise = import(`views/checkout/steps/payment/options/loyalty`);
53
- } else if (payment_option.payment_type === 'masterpass') {
54
- promise = import(
55
- `views/checkout/steps/payment/options/credit-card`
56
- );
57
53
  }
58
54
  // else if (payment_option.payment_type === 'credit_payment') {
59
55
  // promise = import(`views/checkout/steps/payment/options/credit-payment`);
@@ -1,107 +1,107 @@
1
- import { buildClientRequestUrl } from '../../utils';
2
- import { api } from './api';
3
- import { address, misc } from '../urls';
4
- import { Address, City, Country, District, Township } from '../../types';
5
-
6
- interface GetResponse<T> {
7
- count: number;
8
- next: null;
9
- previous: null;
10
- results: T[];
11
- }
12
-
13
- const addressApi = api.injectEndpoints({
14
- endpoints: (builder) => ({
15
- getAddresses: builder.query<GetResponse<Address>, void>({
16
- query: () => buildClientRequestUrl(address.getAddresses),
17
- providesTags: ['Addresses']
18
- }),
19
- getCountries: builder.query<GetResponse<Country>, void>({
20
- query: () => buildClientRequestUrl(address.countries)
21
- }),
22
- getCities: builder.query<GetResponse<City>, string>({
23
- query: (country) => buildClientRequestUrl(address.getCities(country))
24
- }),
25
- getTownships: builder.query<GetResponse<Township>, string>({
26
- query: (city) => buildClientRequestUrl(address.getTownships(city))
27
- }),
28
- getDistricts: builder.query<GetResponse<District>, string>({
29
- query: (township) => buildClientRequestUrl(address.getDistricts(township))
30
- }),
31
- getRetailStore: builder.query<GetResponse<any>, void>({
32
- query: () => buildClientRequestUrl(address.getRetailStore)
33
- }),
34
- getRetailStoreCities: builder.query<GetResponse<any>, string>({
35
- query: (country) => buildClientRequestUrl(address.getRetailStoreCities(country))
36
- }),
37
- getRetailStoreTownships: builder.query<GetResponse<any>, string>({
38
- query: (city) => buildClientRequestUrl(address.getRetailStoreTownships(city))
39
- }),
40
- addAddress: builder.mutation<Address, Partial<Address>>({
41
- query: (body) => ({
42
- url: buildClientRequestUrl(address.base, {
43
- contentType: 'application/json'
44
- }),
45
- method: 'POST',
46
- body: {
47
- ...body,
48
- type: body.is_corporate === 'true' ? 'corporate' : 'personal'
49
- }
50
- }),
51
- invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
52
- }),
53
- editAddress: builder.mutation<Address, Partial<Address>>({
54
- query: ({ pk, ...body }) => ({
55
- url: buildClientRequestUrl(address.editAddress(pk), {
56
- contentType: 'application/json'
57
- }),
58
- method: 'PATCH',
59
- body: {
60
- ...body,
61
- user: body.user?.pk,
62
- type: body.is_corporate === 'true' ? 'corporate' : 'personal'
63
- }
64
- }),
65
- invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
66
- }),
67
- removeAddress: builder.mutation<void, number>({
68
- query: (id) => ({
69
- url: buildClientRequestUrl(address.removeAddress(id)),
70
- method: 'DELETE'
71
- }),
72
- invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
73
- }),
74
- setDefaultAddress: builder.mutation<Address, Partial<Address>>({
75
- query: ({ pk, primary }) => ({
76
- url: buildClientRequestUrl(address.setDefaultAddress(pk), {
77
- contentType: 'application/json'
78
- }),
79
- method: 'PATCH',
80
- body: { primary }
81
- }),
82
- invalidatesTags: ['Addresses']
83
- }),
84
- getStores: builder.query<GetResponse<Address>, void>({
85
- query: () => ({
86
- url: buildClientRequestUrl(misc.stores)
87
- })
88
- })
89
- }),
90
- overrideExisting: true
91
- });
92
-
93
- export const {
94
- useGetAddressesQuery,
95
- useGetCountriesQuery,
96
- useGetCitiesQuery,
97
- useGetTownshipsQuery,
98
- useGetDistrictsQuery,
99
- useGetRetailStoreQuery,
100
- useGetRetailStoreCitiesQuery,
101
- useGetRetailStoreTownshipsQuery,
102
- useAddAddressMutation,
103
- useEditAddressMutation,
104
- useRemoveAddressMutation,
105
- useSetDefaultAddressMutation,
106
- useGetStoresQuery
107
- } = addressApi;
1
+ import { buildClientRequestUrl } from '../../utils';
2
+ import { api } from './api';
3
+ import { address, misc } from '../urls';
4
+ import { Address, City, Country, District, Township } from '../../types';
5
+
6
+ interface GetResponse<T> {
7
+ count: number;
8
+ next: null;
9
+ previous: null;
10
+ results: T[];
11
+ }
12
+
13
+ const addressApi = api.injectEndpoints({
14
+ endpoints: (builder) => ({
15
+ getAddresses: builder.query<GetResponse<Address>, void>({
16
+ query: () => buildClientRequestUrl(address.getAddresses),
17
+ providesTags: ['Addresses']
18
+ }),
19
+ getCountries: builder.query<GetResponse<Country>, void>({
20
+ query: () => buildClientRequestUrl(address.countries)
21
+ }),
22
+ getCities: builder.query<GetResponse<City>, string>({
23
+ query: (country) => buildClientRequestUrl(address.getCities(country))
24
+ }),
25
+ getTownships: builder.query<GetResponse<Township>, string>({
26
+ query: (city) => buildClientRequestUrl(address.getTownships(city))
27
+ }),
28
+ getDistricts: builder.query<GetResponse<District>, string>({
29
+ query: (township) => buildClientRequestUrl(address.getDistricts(township))
30
+ }),
31
+ getRetailStore: builder.query<GetResponse<any>, void>({
32
+ query: () => buildClientRequestUrl(address.getRetailStore)
33
+ }),
34
+ getRetailStoreCities: builder.query<GetResponse<any>, string>({
35
+ query: (country) => buildClientRequestUrl(address.getRetailStoreCities(country))
36
+ }),
37
+ getRetailStoreTownships: builder.query<GetResponse<any>, string>({
38
+ query: (city) => buildClientRequestUrl(address.getRetailStoreTownships(city))
39
+ }),
40
+ addAddress: builder.mutation<Address, Partial<Address>>({
41
+ query: (body) => ({
42
+ url: buildClientRequestUrl(address.base, {
43
+ contentType: 'application/json'
44
+ }),
45
+ method: 'POST',
46
+ body: {
47
+ ...body,
48
+ type: body.is_corporate === 'true' ? 'corporate' : 'personal'
49
+ }
50
+ }),
51
+ invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
52
+ }),
53
+ editAddress: builder.mutation<Address, Partial<Address>>({
54
+ query: ({ pk, ...body }) => ({
55
+ url: buildClientRequestUrl(address.editAddress(pk), {
56
+ contentType: 'application/json'
57
+ }),
58
+ method: 'PATCH',
59
+ body: {
60
+ ...body,
61
+ user: body.user?.pk,
62
+ type: body.is_corporate === 'true' ? 'corporate' : 'personal'
63
+ }
64
+ }),
65
+ invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
66
+ }),
67
+ removeAddress: builder.mutation<void, number>({
68
+ query: (id) => ({
69
+ url: buildClientRequestUrl(address.removeAddress(id)),
70
+ method: 'DELETE'
71
+ }),
72
+ invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
73
+ }),
74
+ setDefaultAddress: builder.mutation<Address, Partial<Address>>({
75
+ query: ({ pk, primary }) => ({
76
+ url: buildClientRequestUrl(address.setDefaultAddress(pk), {
77
+ contentType: 'application/json'
78
+ }),
79
+ method: 'PATCH',
80
+ body: { primary }
81
+ }),
82
+ invalidatesTags: ['Addresses']
83
+ }),
84
+ getStores: builder.query<GetResponse<Address>, void>({
85
+ query: () => ({
86
+ url: buildClientRequestUrl(misc.stores)
87
+ })
88
+ })
89
+ }),
90
+ overrideExisting: true
91
+ });
92
+
93
+ export const {
94
+ useGetAddressesQuery,
95
+ useGetCountriesQuery,
96
+ useGetCitiesQuery,
97
+ useGetTownshipsQuery,
98
+ useGetDistrictsQuery,
99
+ useGetRetailStoreQuery,
100
+ useGetRetailStoreCitiesQuery,
101
+ useGetRetailStoreTownshipsQuery,
102
+ useAddAddressMutation,
103
+ useEditAddressMutation,
104
+ useRemoveAddressMutation,
105
+ useSetDefaultAddressMutation,
106
+ useGetStoresQuery
107
+ } = addressApi;