@infosoftas/s4-orders-js-sdk 0.0.1-alpha1b → 0.0.1-alpha1d
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/.release-it.json +6 -0
- package/lib/package.json +42 -0
- package/lib/script.js +2 -0
- package/lib/script.js.LICENSE.txt +39 -0
- package/package.json +6 -5
- package/src/App.scss +2 -2
- package/src/App.tsx +97 -18
- package/src/api/OrdersApi.ts +15 -2
- package/src/api/SubscribeApi.ts +5 -1
- package/src/assets/styles/forms.scss +1 -1
- package/src/assets/styles/general.scss +2 -2
- package/src/components/Alert/alert.scss +1 -1
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Button/button.scss +1 -1
- package/src/components/FormFields/AddressField.tsx +52 -0
- package/src/components/FormFields/EmailField.tsx +5 -1
- package/src/components/FormFields/FormFields.helper.ts +5 -1
- package/src/components/FormFields/FormFieldsMapper.ts +9 -3
- package/src/components/FormFields/InputField.tsx +51 -0
- package/src/components/FormFields/NameField.tsx +5 -1
- package/src/components/FormFields/PhoneField.tsx +5 -1
- package/src/components/Loader/loader.scss +1 -1
- package/src/components/MainIframe/MainIframe.tsx +1 -1
- package/src/components/OrderForm/OrderForm.tsx +73 -17
- package/src/components/OrderForm/orderForm.scss +1 -1
- package/src/constants/index.ts +1 -1
- package/src/enums/general.ts +2 -0
- package/src/hooks/useMessageEvent.tsx +3 -2
- package/src/index.tsx +2 -2
- package/src/types/api.ts +1 -1
- package/src/types/general.ts +6 -1
- package/src/types/order.ts +6 -1
- package/src/utils/fetcher.ts +11 -7
- package/src/utils/helper.ts +29 -1
- package/src/utils/order.helper.ts +29 -9
- package/tsconfig.json +41 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-dom.production.min.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @license React
|
|
13
|
+
* react-jsx-runtime.production.min.js
|
|
14
|
+
*
|
|
15
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the MIT license found in the
|
|
18
|
+
* LICENSE file in the root directory of this source tree.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @license React
|
|
23
|
+
* react.production.min.js
|
|
24
|
+
*
|
|
25
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
26
|
+
*
|
|
27
|
+
* This source code is licensed under the MIT license found in the
|
|
28
|
+
* LICENSE file in the root directory of this source tree.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @license React
|
|
33
|
+
* scheduler.production.min.js
|
|
34
|
+
*
|
|
35
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
36
|
+
*
|
|
37
|
+
* This source code is licensed under the MIT license found in the
|
|
38
|
+
* LICENSE file in the root directory of this source tree.
|
|
39
|
+
*/
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infosoftas/s4-orders-js-sdk",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-alpha1d",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"build": "rimraf
|
|
5
|
+
"build": "rimraf lib && webpack --env mode=production"
|
|
6
6
|
},
|
|
7
7
|
"eslintConfig": {
|
|
8
8
|
"extends": [
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"prop-types": "^15.8.1",
|
|
14
14
|
"react": "^18.3.1",
|
|
15
15
|
"react-dom": "^18.3.1",
|
|
16
|
-
"react-hook-form": "^7.53.0"
|
|
17
|
-
"rimraf": "^6.0.1"
|
|
16
|
+
"react-hook-form": "^7.53.0"
|
|
18
17
|
},
|
|
19
18
|
"devDependencies": {
|
|
20
19
|
"@babel/core": "^7.24.3",
|
|
@@ -25,6 +24,7 @@
|
|
|
25
24
|
"@types/react-dom": "^18.0.6",
|
|
26
25
|
"babel-loader": "^8.3.0",
|
|
27
26
|
"css-loader": "^7.1.2",
|
|
27
|
+
"copy-webpack-plugin": "^12.0.2",
|
|
28
28
|
"dotenv-webpack": "^8.1.0",
|
|
29
29
|
"mini-css-extract-plugin": "^2.9.1",
|
|
30
30
|
"sass": "^1.79.2",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"ts-loader": "^9.5.1",
|
|
34
34
|
"typescript": "^5.6.2",
|
|
35
35
|
"webpack": "^5.95.0",
|
|
36
|
-
"webpack-cli": "^5.1.4"
|
|
36
|
+
"webpack-cli": "^5.1.4",
|
|
37
|
+
"rimraf": "^6.0.1"
|
|
37
38
|
},
|
|
38
39
|
"publishConfig": {
|
|
39
40
|
"access": "restricted"
|
package/src/App.scss
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { FC, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import { MessageEventTypeEnum, PaymentMethodEnum } from '
|
|
4
|
-
import useMessageEvent from '
|
|
5
|
-
import OrderForm from '
|
|
6
|
-
import Loader from '
|
|
7
|
-
import MainIframe from '
|
|
8
|
-
import Alert from '
|
|
9
|
-
import { ConfigType } from '
|
|
10
|
-
import { CompleteOrderParamsType, OrderInfoType } from '
|
|
11
|
-
import { orderComplete } from '
|
|
12
|
-
import { prepareErrorMessage } from '
|
|
3
|
+
import { MessageEventTypeEnum, PaymentMethodEnum } from './enums/general';
|
|
4
|
+
import useMessageEvent from './hooks/useMessageEvent';
|
|
5
|
+
import OrderForm from './components/OrderForm/OrderForm';
|
|
6
|
+
import Loader from './components/Loader/Loader';
|
|
7
|
+
import MainIframe from './components/MainIframe/MainIframe';
|
|
8
|
+
import Alert from './components/Alert/Alert';
|
|
9
|
+
import { ConfigType, ErrorsMsg } from './types/general';
|
|
10
|
+
import { CompleteOrderParamsType, OrderInfoType } from './types/order';
|
|
11
|
+
import { orderComplete, orderDelete } from './api/OrdersApi';
|
|
12
|
+
import { prepareErrorMessage, prepareErrorsArrayMessage } from './utils/helper';
|
|
13
13
|
|
|
14
14
|
import ErrorBoundary from './ErrorBoundary';
|
|
15
15
|
|
|
@@ -18,6 +18,7 @@ import './App.scss';
|
|
|
18
18
|
const App: FC<ConfigType> = ({
|
|
19
19
|
moduleTitle,
|
|
20
20
|
apiKey,
|
|
21
|
+
apiUrl,
|
|
21
22
|
templatePackageId,
|
|
22
23
|
subscriberId,
|
|
23
24
|
userId,
|
|
@@ -42,6 +43,7 @@ const App: FC<ConfigType> = ({
|
|
|
42
43
|
const [isConfirmed, setIsConfirmed] = useState<boolean>(false);
|
|
43
44
|
const [isFailed, setIsFailed] = useState<boolean>(false);
|
|
44
45
|
const [failedMsg, setFailedMsg] = useState<string>('');
|
|
46
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
45
47
|
const [orderInfo, setOrderInfo] = useState<OrderInfoType | null>(null);
|
|
46
48
|
|
|
47
49
|
useEffect(() => {
|
|
@@ -50,6 +52,12 @@ const App: FC<ConfigType> = ({
|
|
|
50
52
|
}
|
|
51
53
|
}, [apiKey]);
|
|
52
54
|
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (apiUrl) {
|
|
57
|
+
sessionStorage.setItem('sdk_api_url', apiUrl);
|
|
58
|
+
}
|
|
59
|
+
}, [apiUrl]);
|
|
60
|
+
|
|
53
61
|
const messageCallback = async (
|
|
54
62
|
data: CompleteOrderParamsType
|
|
55
63
|
): Promise<void> => {
|
|
@@ -57,6 +65,8 @@ const App: FC<ConfigType> = ({
|
|
|
57
65
|
setIframeSrc(null);
|
|
58
66
|
setShowOrderForm(false);
|
|
59
67
|
setIsFailed(false);
|
|
68
|
+
setFailedMsg('');
|
|
69
|
+
setErrorsMsg([]);
|
|
60
70
|
try {
|
|
61
71
|
await orderComplete(orderId || data.orderId || '');
|
|
62
72
|
setIsConfirmed(true);
|
|
@@ -73,23 +83,83 @@ const App: FC<ConfigType> = ({
|
|
|
73
83
|
}
|
|
74
84
|
} catch (error) {
|
|
75
85
|
console.log(error);
|
|
86
|
+
if (
|
|
87
|
+
(error as { status: number }).status === 409 &&
|
|
88
|
+
(data.paymentMethod === PaymentMethodEnum.Vipps ||
|
|
89
|
+
data.paymentMethod === PaymentMethodEnum.MobilePay)
|
|
90
|
+
) {
|
|
91
|
+
handleOrderDelete(orderId || data.orderId);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
76
95
|
setFailedMsg(
|
|
77
96
|
prepareErrorMessage(error as Error, settings?.failureText)
|
|
78
97
|
);
|
|
98
|
+
setErrorsMsg(
|
|
99
|
+
prepareErrorsArrayMessage(
|
|
100
|
+
(
|
|
101
|
+
error as {
|
|
102
|
+
errors: ErrorsMsg;
|
|
103
|
+
}
|
|
104
|
+
)?.errors
|
|
105
|
+
)
|
|
106
|
+
);
|
|
79
107
|
setIsFailed(true);
|
|
80
108
|
setLoading(false);
|
|
81
109
|
setShowOrderForm(true);
|
|
82
110
|
}
|
|
83
111
|
};
|
|
84
112
|
|
|
85
|
-
const
|
|
113
|
+
const handleOrderDelete = async (id: string) => {
|
|
114
|
+
try {
|
|
115
|
+
await orderDelete(id);
|
|
116
|
+
if (window === top) {
|
|
117
|
+
top.postMessage(
|
|
118
|
+
{
|
|
119
|
+
type: MessageEventTypeEnum.ORDER_FLOW_CANCEL,
|
|
120
|
+
isCanceled: true,
|
|
121
|
+
orderInfo: orderInfo,
|
|
122
|
+
},
|
|
123
|
+
top?.location?.origin || '*'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
setIsFailed(false);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(error);
|
|
129
|
+
setFailedMsg(
|
|
130
|
+
prepareErrorMessage(error as Error, settings?.failureText)
|
|
131
|
+
);
|
|
132
|
+
setErrorsMsg(
|
|
133
|
+
prepareErrorsArrayMessage(
|
|
134
|
+
(
|
|
135
|
+
error as {
|
|
136
|
+
errors: ErrorsMsg;
|
|
137
|
+
}
|
|
138
|
+
)?.errors
|
|
139
|
+
)
|
|
140
|
+
);
|
|
141
|
+
setIsFailed(true);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setLoading(false);
|
|
145
|
+
setShowOrderForm(true);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const handleMessageEvent = async (type: MessageEventTypeEnum) => {
|
|
86
149
|
if (type === MessageEventTypeEnum.CANCEL) {
|
|
150
|
+
try {
|
|
151
|
+
if (orderId) {
|
|
152
|
+
await handleOrderDelete(orderId);
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.log(error);
|
|
156
|
+
}
|
|
157
|
+
|
|
87
158
|
setLoading(false);
|
|
88
159
|
setOrderId(null);
|
|
89
160
|
setOrderInfo(null);
|
|
90
161
|
setIframeSrc(null);
|
|
91
162
|
setIsConfirmed(false);
|
|
92
|
-
setIsFailed(false);
|
|
93
163
|
setShowOrderForm(true);
|
|
94
164
|
}
|
|
95
165
|
};
|
|
@@ -106,6 +176,16 @@ const App: FC<ConfigType> = ({
|
|
|
106
176
|
setIsFailed(false);
|
|
107
177
|
setOrderId(data?.orderId || null);
|
|
108
178
|
setOrderInfo(data || null);
|
|
179
|
+
if (window === top) {
|
|
180
|
+
top.postMessage(
|
|
181
|
+
{
|
|
182
|
+
type: MessageEventTypeEnum.ORDER_UPDATE_INFO,
|
|
183
|
+
isUpdate: true,
|
|
184
|
+
orderInfo: data || null,
|
|
185
|
+
},
|
|
186
|
+
top?.location?.origin || '*'
|
|
187
|
+
);
|
|
188
|
+
}
|
|
109
189
|
if (url) {
|
|
110
190
|
if (
|
|
111
191
|
showIframe &&
|
|
@@ -155,12 +235,8 @@ const App: FC<ConfigType> = ({
|
|
|
155
235
|
errorInvalidEmailMsg={settings?.errorInvalidEmailMsg}
|
|
156
236
|
errorInvalidPhoneMsg={settings?.errorInvalidPhoneMsg}
|
|
157
237
|
defaultValues={settings?.orderDefaultValues}
|
|
158
|
-
redirectUrl={
|
|
159
|
-
|
|
160
|
-
? window.location.href.split('?')[0]
|
|
161
|
-
: redirectUrl ||
|
|
162
|
-
window.location.href.split('?')[0]
|
|
163
|
-
}
|
|
238
|
+
redirectUrl={redirectUrl}
|
|
239
|
+
showIframe={showIframe}
|
|
164
240
|
paymentMethodsOptions={paymentMethodsOptions}
|
|
165
241
|
language={language}
|
|
166
242
|
merchantAgreementUrl={merchantAgreementUrl}
|
|
@@ -176,6 +252,9 @@ const App: FC<ConfigType> = ({
|
|
|
176
252
|
)}
|
|
177
253
|
|
|
178
254
|
{isFailed && <Alert className="mt-2" msg={failedMsg} />}
|
|
255
|
+
{isFailed &&
|
|
256
|
+
errorsMsg?.length > 0 &&
|
|
257
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
179
258
|
</div>
|
|
180
259
|
</ErrorBoundary>
|
|
181
260
|
);
|
package/src/api/OrdersApi.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AgreementsType } from '
|
|
2
|
-
import fetcher from '
|
|
1
|
+
import { AgreementsType } from '../types/order';
|
|
2
|
+
import fetcher from '../utils/fetcher';
|
|
3
3
|
|
|
4
4
|
type RequestOrderStartType = {
|
|
5
5
|
subscriberId?: string;
|
|
@@ -42,3 +42,16 @@ export const orderComplete = (id: string): Promise<OrderResponseType> =>
|
|
|
42
42
|
},
|
|
43
43
|
body: null,
|
|
44
44
|
}) as Promise<OrderResponseType>;
|
|
45
|
+
|
|
46
|
+
export const orderDelete = (id: string): Promise<OrderResponseType> =>
|
|
47
|
+
fetcher<OrderResponseType, null>({
|
|
48
|
+
method: 'DELETE',
|
|
49
|
+
url: `/order/${id}`,
|
|
50
|
+
headers: {
|
|
51
|
+
'S4-ORDERS-API-KEY':
|
|
52
|
+
sessionStorage.getItem('sdk_api_key') ||
|
|
53
|
+
process.env.API_KEY ||
|
|
54
|
+
'',
|
|
55
|
+
},
|
|
56
|
+
body: null,
|
|
57
|
+
}) as Promise<OrderResponseType>;
|
package/src/api/SubscribeApi.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import fetcher from '
|
|
1
|
+
import fetcher from '../utils/fetcher';
|
|
2
2
|
|
|
3
3
|
type CreateSubscriberRequestType = {
|
|
4
4
|
name?: string;
|
|
5
5
|
email?: string;
|
|
6
6
|
phone?: string;
|
|
7
|
+
country?: string;
|
|
8
|
+
city?: string;
|
|
9
|
+
addressLines?: string[];
|
|
10
|
+
zip?: string;
|
|
7
11
|
};
|
|
8
12
|
|
|
9
13
|
type CreateSubscriberResponseType = {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
readOnly: boolean;
|
|
10
|
+
label?: string;
|
|
11
|
+
errorReqMsg?: string;
|
|
12
|
+
errors?: {
|
|
13
|
+
address?: {
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const AddressField: FC<Props> = ({
|
|
20
|
+
required = false,
|
|
21
|
+
readOnly = false,
|
|
22
|
+
label = 'Address',
|
|
23
|
+
errorReqMsg = 'This field is required!',
|
|
24
|
+
errors,
|
|
25
|
+
}) => {
|
|
26
|
+
const { register } = useFormContext();
|
|
27
|
+
const id = uuidv4();
|
|
28
|
+
return (
|
|
29
|
+
<div className="field-wrapper" data-testid="sdk-address-field-id">
|
|
30
|
+
<textarea
|
|
31
|
+
id={id}
|
|
32
|
+
autoComplete="address"
|
|
33
|
+
placeholder=" "
|
|
34
|
+
readOnly={readOnly}
|
|
35
|
+
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
36
|
+
{...register('address', {
|
|
37
|
+
required: required ? errorReqMsg : false,
|
|
38
|
+
})}
|
|
39
|
+
/>
|
|
40
|
+
<label className="label-control" htmlFor={id}>
|
|
41
|
+
{label} {required && <span className="text-error">*</span>}
|
|
42
|
+
</label>
|
|
43
|
+
{errors && errors.address && (
|
|
44
|
+
<div className="text-error caption">
|
|
45
|
+
{errors.address.message}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default AddressField;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -24,9 +26,11 @@ const EmailField: FC<Props> = ({
|
|
|
24
26
|
errors,
|
|
25
27
|
}) => {
|
|
26
28
|
const { register } = useFormContext();
|
|
29
|
+
const id = uuidv4();
|
|
27
30
|
return (
|
|
28
31
|
<div className="field-wrapper" data-testid="sdk-email-field-id">
|
|
29
32
|
<input
|
|
33
|
+
id={id}
|
|
30
34
|
autoComplete="email"
|
|
31
35
|
placeholder=" "
|
|
32
36
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
@@ -40,7 +44,7 @@ const EmailField: FC<Props> = ({
|
|
|
40
44
|
},
|
|
41
45
|
})}
|
|
42
46
|
/>
|
|
43
|
-
<label className="label-control">
|
|
47
|
+
<label className="label-control" htmlFor={id}>
|
|
44
48
|
{label} {required && <span className="text-error">*</span>}
|
|
45
49
|
</label>
|
|
46
50
|
{errors && errors.email && (
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { OrderFormFiledType } from '
|
|
1
|
+
import { OrderFormFiledType } from '../../types/general';
|
|
2
2
|
|
|
3
3
|
export const FIELD_TYPES = {
|
|
4
4
|
PHONE: 'phoneNumber',
|
|
5
5
|
EMAIL: 'email',
|
|
6
6
|
NAME: 'name',
|
|
7
|
+
COUNTRY: 'country',
|
|
8
|
+
CITY: 'city',
|
|
9
|
+
ADDRESS: 'address',
|
|
10
|
+
ZIP: 'zip',
|
|
7
11
|
};
|
|
8
12
|
|
|
9
13
|
export const DEFAULT_ORDER_FORM_FIELDS: OrderFormFiledType[] = [
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import EmailField from '
|
|
2
|
-
import PhoneField from '
|
|
3
|
-
import NameField from '
|
|
1
|
+
import EmailField from './EmailField';
|
|
2
|
+
import PhoneField from './PhoneField';
|
|
3
|
+
import NameField from './NameField';
|
|
4
|
+
import AddressField from './AddressField';
|
|
5
|
+
import InputField from './InputField';
|
|
4
6
|
|
|
5
7
|
import { FIELD_TYPES } from './FormFields.helper';
|
|
6
8
|
|
|
@@ -8,6 +10,10 @@ const formFieldsMapper = {
|
|
|
8
10
|
[FIELD_TYPES.PHONE]: PhoneField,
|
|
9
11
|
[FIELD_TYPES.NAME]: NameField,
|
|
10
12
|
[FIELD_TYPES.EMAIL]: EmailField,
|
|
13
|
+
[FIELD_TYPES.ADDRESS]: AddressField,
|
|
14
|
+
[FIELD_TYPES.COUNTRY]: InputField,
|
|
15
|
+
[FIELD_TYPES.CITY]: InputField,
|
|
16
|
+
[FIELD_TYPES.ZIP]: InputField,
|
|
11
17
|
};
|
|
12
18
|
|
|
13
19
|
export default formFieldsMapper;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
readOnly: boolean;
|
|
10
|
+
label?: string;
|
|
11
|
+
errorReqMsg?: string;
|
|
12
|
+
errors?: {
|
|
13
|
+
[key: string]: {
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const NameField: FC<Props> = ({
|
|
20
|
+
name,
|
|
21
|
+
required = false,
|
|
22
|
+
readOnly = false,
|
|
23
|
+
label = '',
|
|
24
|
+
errorReqMsg = 'This field is required!',
|
|
25
|
+
errors,
|
|
26
|
+
}) => {
|
|
27
|
+
const { register } = useFormContext();
|
|
28
|
+
const id = uuidv4();
|
|
29
|
+
return (
|
|
30
|
+
<div className="field-wrapper" data-testid={`sdk-${name}-field-id`}>
|
|
31
|
+
<input
|
|
32
|
+
id={id}
|
|
33
|
+
autoComplete={name}
|
|
34
|
+
placeholder=" "
|
|
35
|
+
readOnly={readOnly}
|
|
36
|
+
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
37
|
+
{...register(name, {
|
|
38
|
+
required: required ? errorReqMsg : false,
|
|
39
|
+
})}
|
|
40
|
+
/>
|
|
41
|
+
<label className="label-control" htmlFor={id}>
|
|
42
|
+
{label} {required && <span className="text-error">*</span>}
|
|
43
|
+
</label>
|
|
44
|
+
{errors && errors[name] && (
|
|
45
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default NameField;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -22,9 +24,11 @@ const NameField: FC<Props> = ({
|
|
|
22
24
|
errors,
|
|
23
25
|
}) => {
|
|
24
26
|
const { register } = useFormContext();
|
|
27
|
+
const id = uuidv4();
|
|
25
28
|
return (
|
|
26
29
|
<div className="field-wrapper" data-testid="sdk-name-field-id">
|
|
27
30
|
<input
|
|
31
|
+
id={id}
|
|
28
32
|
autoComplete="name"
|
|
29
33
|
placeholder=" "
|
|
30
34
|
readOnly={readOnly}
|
|
@@ -33,7 +37,7 @@ const NameField: FC<Props> = ({
|
|
|
33
37
|
required: required ? errorReqMsg : false,
|
|
34
38
|
})}
|
|
35
39
|
/>
|
|
36
|
-
<label className="label-control">
|
|
40
|
+
<label className="label-control" htmlFor={id}>
|
|
37
41
|
{label} {required && <span className="text-error">*</span>}
|
|
38
42
|
</label>
|
|
39
43
|
{errors && errors.name && (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -24,9 +26,11 @@ const PhoneFiled: FC<Props> = ({
|
|
|
24
26
|
errors,
|
|
25
27
|
}) => {
|
|
26
28
|
const { register } = useFormContext();
|
|
29
|
+
const id = uuidv4();
|
|
27
30
|
return (
|
|
28
31
|
<div className="field-wrapper" data-testid="sdk-phone-field-id">
|
|
29
32
|
<input
|
|
33
|
+
id={id}
|
|
30
34
|
autoComplete="tel"
|
|
31
35
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
32
36
|
placeholder=" "
|
|
@@ -40,7 +44,7 @@ const PhoneFiled: FC<Props> = ({
|
|
|
40
44
|
},
|
|
41
45
|
})}
|
|
42
46
|
/>
|
|
43
|
-
<label className="label-control">
|
|
47
|
+
<label className="label-control" htmlFor={id}>
|
|
44
48
|
{label} {required && <span className="text-error">*</span>}
|
|
45
49
|
</label>
|
|
46
50
|
{errors && errors.phoneNumber && (
|