sales-frontend-solution 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +479 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +78 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +471 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
- package/readme.md +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
declare enum KeypadModeEnum {
|
|
5
|
+
QWERTY_SMART = "qwertysmart",
|
|
6
|
+
NUMBER = "number"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type KeypadSessionType = {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
secToken: string;
|
|
12
|
+
input: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type KeypadType = ReactElement<KeypadFieldType>;
|
|
16
|
+
|
|
17
|
+
type Props = {
|
|
18
|
+
value: KeypadSessionType | null;
|
|
19
|
+
inputElement: KeypadType;
|
|
20
|
+
mode: KeypadModeEnum;
|
|
21
|
+
onChange: (value: KeypadSessionType | null) => void;
|
|
22
|
+
maxLength: number;
|
|
23
|
+
};
|
|
24
|
+
declare function Keypad({ value, onChange, mode, maxLength, inputElement }: Props): react_jsx_runtime.JSX.Element;
|
|
25
|
+
|
|
26
|
+
type KeypadResponseType = {
|
|
27
|
+
length: number;
|
|
28
|
+
element: HTMLInputElement;
|
|
29
|
+
sessionInfo: KeypadSessionType;
|
|
30
|
+
keyType: string;
|
|
31
|
+
name: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type KeypadFieldType = {
|
|
35
|
+
ref: React.Ref<any>;
|
|
36
|
+
value: string;
|
|
37
|
+
onClick: () => void;
|
|
38
|
+
onFocus: () => void;
|
|
39
|
+
isKeypadActive?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type NxlOneProps = {
|
|
43
|
+
bizCode: string;
|
|
44
|
+
tmplCode: string;
|
|
45
|
+
ncsrInfoUuid?: string;
|
|
46
|
+
nlcCtfnId?: string;
|
|
47
|
+
t?: string;
|
|
48
|
+
env?: 'dev' | 'stg' | 'prod';
|
|
49
|
+
};
|
|
50
|
+
type NxlOneResponse = {
|
|
51
|
+
action?: 'error' | 'close' | 'complete';
|
|
52
|
+
redirectUrl?: string;
|
|
53
|
+
nlcCtfnId?: string;
|
|
54
|
+
};
|
|
55
|
+
type OpenOptionType = {
|
|
56
|
+
popupWidth?: number;
|
|
57
|
+
popupHeight?: number;
|
|
58
|
+
popupLeft?: number;
|
|
59
|
+
popupTop?: number;
|
|
60
|
+
windowName?: string;
|
|
61
|
+
};
|
|
62
|
+
declare function useNxlOne({ bizCode, tmplCode, ncsrInfoUuid, nlcCtfnId, t, env }: NxlOneProps): {
|
|
63
|
+
redirect: () => void;
|
|
64
|
+
open: (options?: OpenOptionType) => Promise<NxlOneResponse>;
|
|
65
|
+
Iframe: ({ height, className, style, allow, sandbox, onSuccess, onError, onClose, strictOrigin }: {
|
|
66
|
+
height?: number | string;
|
|
67
|
+
className?: string;
|
|
68
|
+
style?: React.CSSProperties;
|
|
69
|
+
allow?: string;
|
|
70
|
+
sandbox?: string;
|
|
71
|
+
onSuccess?: (response: NxlOneResponse) => void;
|
|
72
|
+
onError?: (response: NxlOneResponse) => void;
|
|
73
|
+
onClose: (response: NxlOneResponse) => void;
|
|
74
|
+
strictOrigin?: boolean;
|
|
75
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export { Keypad, type KeypadFieldType, KeypadModeEnum, type KeypadResponseType, type KeypadSessionType, type KeypadType, type NxlOneProps, type NxlOneResponse, useNxlOne };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import React, { useRef, useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/Keypad.tsx
|
|
5
|
+
|
|
6
|
+
// src/utils/load-script.ts
|
|
7
|
+
async function loadScript(url2) {
|
|
8
|
+
await new Promise((resolve, reject) => {
|
|
9
|
+
const script = document.createElement("script");
|
|
10
|
+
script.src = url2;
|
|
11
|
+
script.async = true;
|
|
12
|
+
script.addEventListener("load", () => {
|
|
13
|
+
resolve({ loaded: true, error: false });
|
|
14
|
+
});
|
|
15
|
+
script.addEventListener("error", () => {
|
|
16
|
+
reject({
|
|
17
|
+
loaded: false,
|
|
18
|
+
error: true,
|
|
19
|
+
message: "\uD30C\uC77C \uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4."
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
document.body.appendChild(script);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/libs/xkeyboard.ts
|
|
27
|
+
var getPath = (service, env) => `https://nxl-${`${service}-${env}` }.hanwhalife.com`;
|
|
28
|
+
var getEnv = () => {
|
|
29
|
+
return "stg";
|
|
30
|
+
};
|
|
31
|
+
var XKeyboardMobileInstance = (() => {
|
|
32
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const env = getEnv();
|
|
36
|
+
const keypadServicePath = `${getPath("xkp", env)}/xkp/xkscriptservice`;
|
|
37
|
+
const keypadContentsPath = `${getPath("nlc", env)}/cnts-files/xkeyboard`;
|
|
38
|
+
window.XKConfigMobile = {
|
|
39
|
+
version: "1.0.5.1",
|
|
40
|
+
server: keypadServicePath,
|
|
41
|
+
contextRoot: `${keypadContentsPath}/js`,
|
|
42
|
+
cssPath: `${keypadContentsPath}/css/xkp_mobile.css`,
|
|
43
|
+
logoImgPath: `${keypadContentsPath}/img/logo.png`,
|
|
44
|
+
inputObjectBackgroundColor: "#E4E4E4",
|
|
45
|
+
inputObjectBorderStyle: "1px solid #9E9E9E",
|
|
46
|
+
invalidSessionErrorMessage: "\uBCF4\uC548\uC138\uC158\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n'\uD655\uC778'\uC744 \uB204\uB974\uBA74 \uD0A4\uD328\uB4DC\uAC00 \uAC31\uC2E0 \uB429\uB2C8\uB2E4.",
|
|
47
|
+
invalidSessionAutoRefresh: true,
|
|
48
|
+
enableAccessibility: true,
|
|
49
|
+
useCustomAlert: false,
|
|
50
|
+
functionKeyButtonStyle: "text",
|
|
51
|
+
maxInputSize: 56,
|
|
52
|
+
textInputView: 0,
|
|
53
|
+
touchOption: 0
|
|
54
|
+
};
|
|
55
|
+
document.oncontextmenu = () => false;
|
|
56
|
+
document.ondragstart = () => false;
|
|
57
|
+
document.onselectstart = () => false;
|
|
58
|
+
const headTag = document.head;
|
|
59
|
+
const scriptsToLoad = ["xkeypad_mobile.js"];
|
|
60
|
+
const urls = scriptsToLoad.map(
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
|
+
(x) => `${window.XKConfigMobile.contextRoot}/${x}`
|
|
63
|
+
);
|
|
64
|
+
Promise.all(urls.map((x) => loadScript(x))).then(() => {
|
|
65
|
+
const existingLink = document.getElementById("xkStyle");
|
|
66
|
+
if (existingLink?.parentNode) {
|
|
67
|
+
existingLink.parentNode.removeChild(existingLink);
|
|
68
|
+
}
|
|
69
|
+
const linkElement = document.createElement("link");
|
|
70
|
+
linkElement.id = "xkStyle";
|
|
71
|
+
linkElement.rel = "stylesheet";
|
|
72
|
+
linkElement.type = "text/css";
|
|
73
|
+
linkElement.href = window.XKConfigMobile.cssPath;
|
|
74
|
+
headTag.appendChild(linkElement);
|
|
75
|
+
});
|
|
76
|
+
const keypads = {};
|
|
77
|
+
const getKeypad = (name) => keypads[name];
|
|
78
|
+
const setKeypad = (name, keypad) => {
|
|
79
|
+
keypads[name] = keypad;
|
|
80
|
+
return keypad;
|
|
81
|
+
};
|
|
82
|
+
const removeKeypad = (name) => {
|
|
83
|
+
delete keypads[name];
|
|
84
|
+
};
|
|
85
|
+
const closeAll = () => {
|
|
86
|
+
Object.keys(keypads).forEach((id) => {
|
|
87
|
+
const keypad = keypads[id];
|
|
88
|
+
if (keypad && keypad.isOpen()) {
|
|
89
|
+
keypad.close();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
const newKeypad = (name) => {
|
|
94
|
+
return setKeypad(name, new window.XKModule());
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
keypads,
|
|
98
|
+
getKeypad,
|
|
99
|
+
setKeypad,
|
|
100
|
+
newKeypad,
|
|
101
|
+
removeKeypad,
|
|
102
|
+
closeAll
|
|
103
|
+
};
|
|
104
|
+
})();
|
|
105
|
+
|
|
106
|
+
// src/types/keypad-message.enum.ts
|
|
107
|
+
var KeypadMessageTypeEnum = /* @__PURE__ */ ((KeypadMessageTypeEnum2) => {
|
|
108
|
+
KeypadMessageTypeEnum2[KeypadMessageTypeEnum2["NotSupportDevice"] = -1] = "NotSupportDevice";
|
|
109
|
+
KeypadMessageTypeEnum2[KeypadMessageTypeEnum2["Already"] = -2] = "Already";
|
|
110
|
+
return KeypadMessageTypeEnum2;
|
|
111
|
+
})(KeypadMessageTypeEnum || {});
|
|
112
|
+
var keypad_message_enum_default = KeypadMessageTypeEnum;
|
|
113
|
+
|
|
114
|
+
// src/types/keypad-mode.enum.ts
|
|
115
|
+
var KeypadModeEnum = /* @__PURE__ */ ((KeypadModeEnum2) => {
|
|
116
|
+
KeypadModeEnum2["QWERTY_SMART"] = "qwertysmart";
|
|
117
|
+
KeypadModeEnum2["NUMBER"] = "number";
|
|
118
|
+
return KeypadModeEnum2;
|
|
119
|
+
})(KeypadModeEnum || {});
|
|
120
|
+
var keypad_mode_enum_default = KeypadModeEnum;
|
|
121
|
+
|
|
122
|
+
// src/utils/uuid.ts
|
|
123
|
+
var uuidv4 = () => {
|
|
124
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
125
|
+
const r = Math.random() * 16 || 0, v = c === "x" ? r : r && 3 || 8;
|
|
126
|
+
return v.toString(16);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/hooks/use-keypad.ts
|
|
131
|
+
function useKeypad() {
|
|
132
|
+
const [isShow, setIsShow] = useState(false);
|
|
133
|
+
const show = useCallback(
|
|
134
|
+
(inputRef, onInputChange, onKeypadClose, keyType = keypad_mode_enum_default.QWERTY_SMART, maxLength, numberKeyRowCount) => {
|
|
135
|
+
const name = uuidv4();
|
|
136
|
+
if (!XKeyboardMobileInstance) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
let keypad = XKeyboardMobileInstance.getKeypad(name);
|
|
140
|
+
if (!keypad) {
|
|
141
|
+
keypad = XKeyboardMobileInstance.newKeypad(name);
|
|
142
|
+
} else {
|
|
143
|
+
keypad.refresh();
|
|
144
|
+
}
|
|
145
|
+
if (onInputChange && typeof onInputChange === "function") {
|
|
146
|
+
onInputChange(0);
|
|
147
|
+
}
|
|
148
|
+
const keyPadParam = {
|
|
149
|
+
name: `xk-pad-${name}`,
|
|
150
|
+
editBox: inputRef,
|
|
151
|
+
keyType,
|
|
152
|
+
width: 100,
|
|
153
|
+
position: { top: 10, left: null },
|
|
154
|
+
viewType: "half",
|
|
155
|
+
closeDelay: 0,
|
|
156
|
+
autoKeyResize: true,
|
|
157
|
+
isE2E: true,
|
|
158
|
+
onlyMobile: false,
|
|
159
|
+
hasPressEffect: true,
|
|
160
|
+
maxLength,
|
|
161
|
+
numberKeyRowCount,
|
|
162
|
+
onInputChange: (newLength) => {
|
|
163
|
+
if (onInputChange && typeof onInputChange === "function") {
|
|
164
|
+
onInputChange(newLength);
|
|
165
|
+
}
|
|
166
|
+
if (!keypad) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (keyPadParam.maxLength && keyPadParam.maxLength > 0 && newLength >= keyPadParam.maxLength && keypad.isOpend()) {
|
|
170
|
+
keypad.close();
|
|
171
|
+
setIsShow(false);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
onKeypadClose: () => {
|
|
176
|
+
if (!keypad) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!XKeyboardMobileInstance) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (onKeypadClose && typeof onKeypadClose === "function") {
|
|
183
|
+
const sessionInfo = keypad.get_sessionInfo();
|
|
184
|
+
let length = 0;
|
|
185
|
+
if (sessionInfo.input && sessionInfo.input.indexOf(",") >= 0) {
|
|
186
|
+
length = sessionInfo.input.split(",").length;
|
|
187
|
+
}
|
|
188
|
+
const res = {
|
|
189
|
+
length,
|
|
190
|
+
element: inputRef,
|
|
191
|
+
sessionInfo: {
|
|
192
|
+
input: sessionInfo.input,
|
|
193
|
+
sessionId: sessionInfo.sessionId,
|
|
194
|
+
secToken: sessionInfo.secToken
|
|
195
|
+
},
|
|
196
|
+
keyType,
|
|
197
|
+
name
|
|
198
|
+
};
|
|
199
|
+
setIsShow(false);
|
|
200
|
+
onKeypadClose(res);
|
|
201
|
+
}
|
|
202
|
+
XKeyboardMobileInstance.removeKeypad(name);
|
|
203
|
+
if (!onKeypadClose) {
|
|
204
|
+
throw new Error("not found onKeypadClose");
|
|
205
|
+
}
|
|
206
|
+
if (typeof onKeypadClose !== "function") {
|
|
207
|
+
throw new Error("not found onKeypadClose");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const aRet = keypad.initialize(keyPadParam);
|
|
212
|
+
if (aRet === keypad_message_enum_default.NotSupportDevice) {
|
|
213
|
+
alert("\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uAE30\uAE30 \uC785\uB2C8\uB2E4.");
|
|
214
|
+
return;
|
|
215
|
+
} else if (aRet === keypad_message_enum_default.Already) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
setIsShow(true);
|
|
219
|
+
},
|
|
220
|
+
[]
|
|
221
|
+
);
|
|
222
|
+
const getValue = (name) => {
|
|
223
|
+
if (!XKeyboardMobileInstance) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const targetKeypad = XKeyboardMobileInstance.keypads[name];
|
|
227
|
+
if (!targetKeypad) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
return targetKeypad.get_sessionInfo();
|
|
231
|
+
};
|
|
232
|
+
const find = (name) => {
|
|
233
|
+
if (!XKeyboardMobileInstance) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (name) {
|
|
237
|
+
return XKeyboardMobileInstance.keypads[name];
|
|
238
|
+
} else {
|
|
239
|
+
const keypadIds = Object.keys(XKeyboardMobileInstance.keypads);
|
|
240
|
+
for (const keypadId of keypadIds) {
|
|
241
|
+
const targetKeypad = XKeyboardMobileInstance.keypads[keypadId];
|
|
242
|
+
if (targetKeypad && targetKeypad.isOpen()) {
|
|
243
|
+
return targetKeypad;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
const isOpen = (name) => {
|
|
249
|
+
const targetKeypad = find(name);
|
|
250
|
+
return !!targetKeypad;
|
|
251
|
+
};
|
|
252
|
+
const close = (name) => {
|
|
253
|
+
const targetKeypad = find(name);
|
|
254
|
+
if (targetKeypad) {
|
|
255
|
+
targetKeypad.close();
|
|
256
|
+
setIsShow(false);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const clear = (name) => {
|
|
260
|
+
const _xkmodule = find(name);
|
|
261
|
+
if (_xkmodule) {
|
|
262
|
+
_xkmodule.clear();
|
|
263
|
+
setIsShow(false);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
const refresh = (name) => {
|
|
267
|
+
const targetKeypad = find(name);
|
|
268
|
+
if (targetKeypad) {
|
|
269
|
+
targetKeypad.refresh();
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
const handleMouseDown = (event) => {
|
|
274
|
+
if (!XKeyboardMobileInstance) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const keypadAlertDivTag = document.querySelector("#xkalert");
|
|
278
|
+
const keypadDivTag = keypadAlertDivTag?.parentElement;
|
|
279
|
+
if (keypadDivTag && !keypadDivTag.contains(event.target)) {
|
|
280
|
+
XKeyboardMobileInstance.closeAll();
|
|
281
|
+
setIsShow(false);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
285
|
+
return () => {
|
|
286
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
287
|
+
};
|
|
288
|
+
}, []);
|
|
289
|
+
return {
|
|
290
|
+
show,
|
|
291
|
+
close,
|
|
292
|
+
clear,
|
|
293
|
+
refresh,
|
|
294
|
+
getValue,
|
|
295
|
+
isOpen,
|
|
296
|
+
find,
|
|
297
|
+
isShow
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function Keypad({ value, onChange, mode, maxLength, inputElement }) {
|
|
301
|
+
const { show, isShow } = useKeypad();
|
|
302
|
+
const inputRef = useRef(null);
|
|
303
|
+
const [maskedValue, setMaskedValue] = useState("");
|
|
304
|
+
const onCloseBack = useCallback(
|
|
305
|
+
(res) => {
|
|
306
|
+
onChange(res.sessionInfo);
|
|
307
|
+
},
|
|
308
|
+
[onChange]
|
|
309
|
+
);
|
|
310
|
+
const onChangeBack = useCallback(
|
|
311
|
+
(length) => {
|
|
312
|
+
if (length === 0) {
|
|
313
|
+
onChange(null);
|
|
314
|
+
}
|
|
315
|
+
setMaskedValue("".padStart(length, "*"));
|
|
316
|
+
},
|
|
317
|
+
[onChange, setMaskedValue]
|
|
318
|
+
);
|
|
319
|
+
const handleKeypad = useCallback(() => {
|
|
320
|
+
show(inputRef.current, onChangeBack, onCloseBack, mode, maxLength, 3);
|
|
321
|
+
}, [show, inputRef, onChangeBack, onCloseBack, mode, maxLength]);
|
|
322
|
+
const enhancedOnClick = (existingClickHandler, newClickHandler) => {
|
|
323
|
+
return () => {
|
|
324
|
+
if (existingClickHandler) {
|
|
325
|
+
existingClickHandler();
|
|
326
|
+
}
|
|
327
|
+
newClickHandler();
|
|
328
|
+
};
|
|
329
|
+
};
|
|
330
|
+
const cloneElement = React.cloneElement(inputElement, {
|
|
331
|
+
ref: inputRef,
|
|
332
|
+
value: maskedValue,
|
|
333
|
+
onClick: enhancedOnClick(inputElement.props.onClick, handleKeypad),
|
|
334
|
+
isKeypadActive: isShow
|
|
335
|
+
});
|
|
336
|
+
useEffect(() => {
|
|
337
|
+
const length = value?.input && value.input.length > 0 ? value.input.split(",").length : 0;
|
|
338
|
+
setMaskedValue("".padStart(length, "*"));
|
|
339
|
+
}, [value]);
|
|
340
|
+
useEffect(() => {
|
|
341
|
+
if (inputRef.current && !(inputRef.current instanceof HTMLInputElement)) {
|
|
342
|
+
throw new Error("Input \uD0DC\uADF8\uAC00 \uC815\uC758\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
343
|
+
}
|
|
344
|
+
}, []);
|
|
345
|
+
return /* @__PURE__ */ jsx(Fragment, { children: cloneElement });
|
|
346
|
+
}
|
|
347
|
+
var url = (() => {
|
|
348
|
+
const url2 = typeof window !== "undefined" ? window.location.href : "";
|
|
349
|
+
if (url2.includes("localhost") || url2.includes("dev")) {
|
|
350
|
+
return "https://nxl-nlc-dev.hanwhalife.com";
|
|
351
|
+
} else if (url2.includes("stg")) {
|
|
352
|
+
return "https://nxl-nlc-stg.hanwhalife.com";
|
|
353
|
+
} else {
|
|
354
|
+
return "https://nxl-nlc.hanwhalife.com";
|
|
355
|
+
}
|
|
356
|
+
})();
|
|
357
|
+
function useNxlOne({ bizCode, tmplCode, ncsrInfoUuid, nlcCtfnId, t, env }) {
|
|
358
|
+
const baseUrl = env === "prod" ? "https://nxl-nlc.hanwhalife.com" : env === "stg" ? "https://nxl-nlc-stg.hanwhalife.com" : env === "dev" ? "https://nxl-nlc-dev.hanwhalife.com" : void 0;
|
|
359
|
+
const buildUrl = useCallback(() => {
|
|
360
|
+
const targetUrl = new URL("/auth/v1", baseUrl || url);
|
|
361
|
+
targetUrl.searchParams.set("bizCode", bizCode);
|
|
362
|
+
targetUrl.searchParams.set("tmplCode", tmplCode);
|
|
363
|
+
if (nlcCtfnId) {
|
|
364
|
+
targetUrl.searchParams.set("nlcCtfnId", nlcCtfnId);
|
|
365
|
+
}
|
|
366
|
+
if (t) {
|
|
367
|
+
targetUrl.searchParams.set("t", t);
|
|
368
|
+
}
|
|
369
|
+
if (ncsrInfoUuid) {
|
|
370
|
+
targetUrl.searchParams.set("ncsrInfoUuid", ncsrInfoUuid);
|
|
371
|
+
}
|
|
372
|
+
return targetUrl.toString();
|
|
373
|
+
}, [bizCode, tmplCode, t, ncsrInfoUuid, nlcCtfnId]);
|
|
374
|
+
const redirect = () => {
|
|
375
|
+
const targetUrl = buildUrl();
|
|
376
|
+
location.href = targetUrl;
|
|
377
|
+
};
|
|
378
|
+
const open = async (options) => {
|
|
379
|
+
return new Promise((resolve, reject) => {
|
|
380
|
+
const targetUrl = buildUrl();
|
|
381
|
+
const width = options && options.popupWidth || 744;
|
|
382
|
+
const height = options && options.popupHeight || 720;
|
|
383
|
+
const left = options && options.popupLeft || window.screenX + (window.outerWidth - width) / 2;
|
|
384
|
+
const top = options && options.popupTop || window.screenX + (window.outerWidth - width) / 2;
|
|
385
|
+
const popupFeatures = `width=${width},height=${height},left=${left},top=${top}`;
|
|
386
|
+
const popup = window.open(targetUrl, options && options.windowName || "self_cert", popupFeatures);
|
|
387
|
+
if (!popup) {
|
|
388
|
+
reject(new Error("\uCC28\uB2E8\uB418\uAC70\uB098 \uC5F4\uB9AC\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
let isSettled = false;
|
|
392
|
+
const handleMessage = (event) => {
|
|
393
|
+
if (event.origin !== new URL(targetUrl).origin) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (!isSettled) {
|
|
397
|
+
isSettled = true;
|
|
398
|
+
if (event.data) {
|
|
399
|
+
resolve(event.data);
|
|
400
|
+
} else {
|
|
401
|
+
reject("\uC778\uC99D\uC774 \uCDE8\uC18C\uB418\uAC70\uB098 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
402
|
+
}
|
|
403
|
+
popup?.close();
|
|
404
|
+
window.removeEventListener("message", handleMessage);
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
window.addEventListener("message", handleMessage);
|
|
408
|
+
});
|
|
409
|
+
};
|
|
410
|
+
const Iframe = function({
|
|
411
|
+
height = 720,
|
|
412
|
+
className,
|
|
413
|
+
style,
|
|
414
|
+
allow,
|
|
415
|
+
sandbox = "allow-scripts allow-forms allow-same-origin",
|
|
416
|
+
onSuccess,
|
|
417
|
+
onError,
|
|
418
|
+
onClose,
|
|
419
|
+
strictOrigin = true
|
|
420
|
+
}) {
|
|
421
|
+
const targetUrl = buildUrl();
|
|
422
|
+
useEffect(() => {
|
|
423
|
+
if (!onSuccess && !onError) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const handler = (e) => {
|
|
427
|
+
if (strictOrigin && e.origin !== url) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const d = e.data;
|
|
431
|
+
if (d) {
|
|
432
|
+
if (d.action === "close") {
|
|
433
|
+
onClose(d);
|
|
434
|
+
return;
|
|
435
|
+
} else if (onError && d.action === "error") {
|
|
436
|
+
onError(d);
|
|
437
|
+
return;
|
|
438
|
+
} else if (onSuccess && d.action === "complete") {
|
|
439
|
+
onSuccess(d);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
} else if (onError) {
|
|
443
|
+
onError({
|
|
444
|
+
action: "error",
|
|
445
|
+
nlcCtfnId: "",
|
|
446
|
+
redirectUrl: ""
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
window.addEventListener("message", handler);
|
|
451
|
+
return () => window.removeEventListener("message", handler);
|
|
452
|
+
}, [onClose, onError, onSuccess, strictOrigin]);
|
|
453
|
+
return /* @__PURE__ */ jsx(
|
|
454
|
+
"iframe",
|
|
455
|
+
{
|
|
456
|
+
src: targetUrl,
|
|
457
|
+
width: "100%",
|
|
458
|
+
height: typeof height === "number" ? `${height}px` : height,
|
|
459
|
+
style: { border: 0, ...style },
|
|
460
|
+
className,
|
|
461
|
+
sandbox,
|
|
462
|
+
...allow ? { allow } : {}
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
};
|
|
466
|
+
return { redirect, open, Iframe };
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export { Keypad, keypad_mode_enum_default as KeypadModeEnum, useNxlOne };
|
|
470
|
+
//# sourceMappingURL=index.js.map
|
|
471
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/load-script.ts","../src/libs/xkeyboard.ts","../src/types/keypad-message.enum.ts","../src/types/keypad-mode.enum.ts","../src/utils/uuid.ts","../src/hooks/use-keypad.ts","../src/components/Keypad.tsx","../src/hooks/use-nxl-one.tsx"],"names":["url","KeypadMessageTypeEnum","KeypadModeEnum","useState","useCallback","useEffect","jsx"],"mappings":"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","file":"index.js","sourcesContent":["export async function loadScript(url: string) {\r\n await new Promise((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = url;\r\n script.async = true;\r\n script.addEventListener('load', () => {\r\n resolve({ loaded: true, error: false });\r\n });\r\n\r\n script.addEventListener('error', () => {\r\n reject({\r\n loaded: false,\r\n error: true,\r\n message: '파일 로드에 실패하였습니다.'\r\n });\r\n });\r\n\r\n document.body.appendChild(script);\r\n });\r\n}\r\n","import { KeypadActionType } from '../types/keypad-action.type';\r\nimport { loadScript } from '../utils/load-script';\r\n\r\ntype ENV = 'dev' | 'stg' | 'prod';\r\n\r\nconst getPath = (service: string, env: ENV) =>\r\n `https://nxl-${env !== 'prod' ? `${service}-${env}` : service}.hanwhalife.com`;\r\n\r\nconst getEnv: () => ENV = () => {\r\n const host = window.location.hostname;\r\n\r\n // if (host.includes('-dev.') || host.includes('localhost')) {\r\n // return 'dev';\r\n // } else if (host.includes('-stg.')) {\r\n // return 'stg';\r\n // } else {\r\n // return 'prod';\r\n // }\r\n\r\n return 'stg';\r\n};\r\n\r\ninterface KeypadConfig {\r\n version: string;\r\n server: string;\r\n contextRoot: string;\r\n cssPath: string;\r\n logoImgPath: string;\r\n inputObjectBackgroundColor: string;\r\n inputObjectBorderStyle: string;\r\n invalidSessionErrorMessage: string;\r\n invalidSessionAutoRefresh: boolean;\r\n enableAccessibility: boolean;\r\n useCustomAlert: boolean;\r\n functionKeyButtonStyle: string;\r\n maxInputSize: number;\r\n textInputView: number;\r\n touchOption: number;\r\n}\r\n\r\nexport const XKeyboardMobileInstance = (() => {\r\n if (typeof window === 'undefined' || typeof document === 'undefined') {\r\n return null;\r\n }\r\n\r\n const env = getEnv();\r\n\r\n const keypadServicePath = `${getPath('xkp', env)}/xkp/xkscriptservice`;\r\n const keypadContentsPath = `${getPath('nlc', env)}/cnts-files/xkeyboard`;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (window as any).XKConfigMobile = {\r\n version: '1.0.5.1',\r\n server: keypadServicePath,\r\n contextRoot: `${keypadContentsPath}/js`,\r\n cssPath: `${keypadContentsPath}/css/xkp_mobile.css`,\r\n logoImgPath: `${keypadContentsPath}/img/logo.png`,\r\n inputObjectBackgroundColor: '#E4E4E4',\r\n inputObjectBorderStyle: '1px solid #9E9E9E',\r\n invalidSessionErrorMessage: \"보안세션이 만료되었습니다.\\n'확인'을 누르면 키패드가 갱신 됩니다.\",\r\n invalidSessionAutoRefresh: true,\r\n enableAccessibility: true,\r\n useCustomAlert: false,\r\n functionKeyButtonStyle: 'text',\r\n maxInputSize: 56,\r\n textInputView: 0,\r\n touchOption: 0\r\n } as KeypadConfig;\r\n\r\n document.oncontextmenu = () => false;\r\n document.ondragstart = () => false;\r\n document.onselectstart = () => false;\r\n\r\n const headTag = document.head;\r\n const scriptsToLoad = ['xkeypad_mobile.js'];\r\n\r\n const urls = scriptsToLoad.map(\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (x) => `${(window as any).XKConfigMobile.contextRoot}/${x}`\r\n );\r\n\r\n Promise.all(urls.map((x) => loadScript(x))).then(() => {\r\n const existingLink = document.getElementById('xkStyle');\r\n\r\n if (existingLink?.parentNode) {\r\n existingLink.parentNode.removeChild(existingLink);\r\n }\r\n\r\n const linkElement = document.createElement('link');\r\n linkElement.id = 'xkStyle';\r\n linkElement.rel = 'stylesheet';\r\n linkElement.type = 'text/css';\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n linkElement.href = (window as any).XKConfigMobile.cssPath;\r\n\r\n headTag.appendChild(linkElement);\r\n });\r\n\r\n const keypads: { [key: string]: KeypadActionType | undefined } = {};\r\n\r\n const getKeypad = (name: string) => keypads[name];\r\n\r\n const setKeypad = (name: string, keypad: KeypadActionType) => {\r\n keypads[name] = keypad;\r\n\r\n return keypad;\r\n };\r\n\r\n const removeKeypad = (name: string) => {\r\n delete keypads[name];\r\n };\r\n\r\n const closeAll = () => {\r\n Object.keys(keypads).forEach((id) => {\r\n const keypad = keypads[id];\r\n if (keypad && keypad.isOpen()) {\r\n keypad.close();\r\n }\r\n });\r\n };\r\n\r\n const newKeypad = (name: string) => {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return setKeypad(name, new (window as any).XKModule());\r\n };\r\n\r\n return {\r\n keypads,\r\n getKeypad,\r\n setKeypad,\r\n newKeypad,\r\n removeKeypad,\r\n closeAll\r\n };\r\n})();\r\n","enum KeypadMessageTypeEnum {\r\n NotSupportDevice = -1,\r\n Already = -2\r\n}\r\n\r\nexport default KeypadMessageTypeEnum;\r\n","enum KeypadModeEnum {\r\n QWERTY_SMART = 'qwertysmart',\r\n NUMBER = 'number'\r\n}\r\n\r\nexport default KeypadModeEnum;","export const uuidv4 = (): string => {\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\r\n const r = Math.random() * 16 || 0,\r\n v = c === 'x' ? r : (r && 0x3) || 0x8;\r\n\r\n return v.toString(16);\r\n });\r\n};\r\n","import { useCallback, useEffect, useState } from 'react';\r\n\r\nimport { XKeyboardMobileInstance } from '../libs/xkeyboard';\r\nimport KeypadMessageTypeEnum from '../types/keypad-message.enum';\r\nimport KeypadModeEnum from '../types/keypad-mode.enum';\r\nimport KeypadResponseType from '../types/keypad-response.type';\r\nimport { uuidv4 } from '../utils/uuid';\r\n\r\nexport default function useKeypad() {\r\n const [isShow, setIsShow] = useState<boolean>(false);\r\n\r\n const show = useCallback(\r\n (\r\n inputRef: HTMLInputElement,\r\n onInputChange: (length: number) => void,\r\n onKeypadClose: (res: KeypadResponseType) => void,\r\n keyType: KeypadModeEnum = KeypadModeEnum.QWERTY_SMART,\r\n maxLength: number,\r\n numberKeyRowCount: number\r\n ) => {\r\n const name = uuidv4();\r\n\r\n if (!XKeyboardMobileInstance) {\r\n return;\r\n }\r\n\r\n let keypad = XKeyboardMobileInstance.getKeypad(name);\r\n\r\n if (!keypad) {\r\n keypad = XKeyboardMobileInstance.newKeypad(name);\r\n } else {\r\n keypad.refresh();\r\n }\r\n\r\n if (onInputChange && typeof onInputChange === 'function') {\r\n onInputChange(0);\r\n }\r\n\r\n const keyPadParam = {\r\n name: `xk-pad-${name}`,\r\n editBox: inputRef,\r\n keyType,\r\n width: 100,\r\n position: { top: 10, left: null },\r\n viewType: 'half',\r\n closeDelay: 0,\r\n autoKeyResize: true,\r\n isE2E: true,\r\n onlyMobile: false,\r\n hasPressEffect: true,\r\n maxLength,\r\n numberKeyRowCount,\r\n onInputChange: (newLength: number) => {\r\n if (onInputChange && typeof onInputChange === 'function') {\r\n onInputChange(newLength);\r\n }\r\n\r\n // 키패드가 존재하지 않을 경우, 종료\r\n if (!keypad) {\r\n return;\r\n }\r\n\r\n //키패드 입력 길이가 최대 입력 길이가 됐을 때 키패드 닫기\r\n if (\r\n keyPadParam.maxLength &&\r\n keyPadParam.maxLength > 0 &&\r\n newLength >= keyPadParam.maxLength &&\r\n keypad.isOpend()\r\n ) {\r\n keypad.close();\r\n setIsShow(false);\r\n\r\n return;\r\n }\r\n },\r\n onKeypadClose: () => {\r\n if (!keypad) {\r\n return;\r\n }\r\n\r\n if (!XKeyboardMobileInstance) {\r\n return;\r\n }\r\n\r\n if (onKeypadClose && typeof onKeypadClose === 'function') {\r\n const sessionInfo = keypad.get_sessionInfo();\r\n let length = 0;\r\n if (sessionInfo.input && sessionInfo.input.indexOf(',') >= 0) {\r\n length = sessionInfo.input.split(',').length;\r\n }\r\n\r\n const res = {\r\n length,\r\n element: inputRef,\r\n sessionInfo: {\r\n input: sessionInfo.input,\r\n sessionId: sessionInfo.sessionId,\r\n secToken: sessionInfo.secToken\r\n },\r\n keyType,\r\n name\r\n };\r\n\r\n setIsShow(false);\r\n onKeypadClose(res);\r\n }\r\n\r\n XKeyboardMobileInstance.removeKeypad(name);\r\n\r\n if (!onKeypadClose) {\r\n throw new Error('not found onKeypadClose');\r\n }\r\n\r\n if (typeof onKeypadClose !== 'function') {\r\n throw new Error('not found onKeypadClose');\r\n }\r\n }\r\n };\r\n\r\n const aRet = keypad.initialize(keyPadParam);\r\n\r\n if (aRet === KeypadMessageTypeEnum.NotSupportDevice) {\r\n // 안내 메세지 세팅\r\n alert('지원하지 않는 기기 입니다.');\r\n\r\n return;\r\n } else if (aRet === KeypadMessageTypeEnum.Already) {\r\n // alert('이미 키패드가 실행 중입니다.');\r\n return;\r\n }\r\n\r\n setIsShow(true);\r\n },\r\n []\r\n );\r\n\r\n const getValue = (name: string) => {\r\n if (!XKeyboardMobileInstance) {\r\n return;\r\n }\r\n\r\n const targetKeypad = XKeyboardMobileInstance.keypads[name];\r\n\r\n if (!targetKeypad) {\r\n return null;\r\n }\r\n\r\n return targetKeypad.get_sessionInfo();\r\n };\r\n\r\n /**\r\n * 활성화 되어있는 키패드 찾는다\r\n * @returns\r\n */\r\n const find = (name?: string) => {\r\n if (!XKeyboardMobileInstance) {\r\n return;\r\n }\r\n\r\n if (name) {\r\n return XKeyboardMobileInstance.keypads[name];\r\n } else {\r\n // 키패드가 출력되어있으면, 확인하여 키패드를 닫는다.\r\n const keypadIds = Object.keys(XKeyboardMobileInstance.keypads);\r\n\r\n for (const keypadId of keypadIds) {\r\n const targetKeypad = XKeyboardMobileInstance.keypads[keypadId];\r\n\r\n if (targetKeypad && targetKeypad.isOpen()) {\r\n return targetKeypad;\r\n }\r\n }\r\n }\r\n };\r\n\r\n const isOpen = (name?: string) => {\r\n const targetKeypad = find(name);\r\n\r\n return !!targetKeypad;\r\n };\r\n\r\n const close = (name?: string) => {\r\n const targetKeypad = find(name);\r\n if (targetKeypad) {\r\n targetKeypad.close();\r\n setIsShow(false);\r\n }\r\n };\r\n\r\n const clear = (name?: string) => {\r\n const _xkmodule = find(name);\r\n if (_xkmodule) {\r\n _xkmodule.clear();\r\n setIsShow(false);\r\n }\r\n };\r\n\r\n const refresh = (name?: string) => {\r\n const targetKeypad = find(name);\r\n if (targetKeypad) {\r\n targetKeypad.refresh();\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n const handleMouseDown = (event: MouseEvent) => {\r\n if (!XKeyboardMobileInstance) {\r\n return;\r\n }\r\n\r\n const keypadAlertDivTag = document.querySelector('#xkalert');\r\n\r\n const keypadDivTag = keypadAlertDivTag?.parentElement;\r\n if (keypadDivTag && !keypadDivTag.contains(event.target as Node)) {\r\n XKeyboardMobileInstance.closeAll();\r\n setIsShow(false);\r\n }\r\n };\r\n document.addEventListener('mousedown', handleMouseDown);\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleMouseDown);\r\n };\r\n }, []);\r\n\r\n return {\r\n show,\r\n close,\r\n clear,\r\n refresh,\r\n getValue,\r\n isOpen,\r\n find,\r\n isShow\r\n };\r\n}\r\n","import React, { useEffect, useRef, useState, useCallback } from 'react';\r\n\r\nimport useXKeypad from '../hooks/use-keypad';\r\nimport KeypadModeEnum from '../types/keypad-mode.enum';\r\nimport KeypadResponseType from '../types/keypad-response.type';\r\nimport KeypadSessionType from '../types/keypad-session.type';\r\nimport KeypadType from '../types/keypad.type';\r\n\r\ntype Props = {\r\n value: KeypadSessionType | null;\r\n inputElement: KeypadType;\r\n mode: KeypadModeEnum;\r\n onChange: (value: KeypadSessionType | null) => void;\r\n maxLength: number;\r\n};\r\n\r\nexport default function Keypad({ value, onChange, mode, maxLength, inputElement }: Props) {\r\n const { show, isShow } = useXKeypad();\r\n\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n const [maskedValue, setMaskedValue] = useState<string>('');\r\n\r\n const onCloseBack = useCallback(\r\n (res: KeypadResponseType) => {\r\n onChange(res.sessionInfo);\r\n },\r\n [onChange]\r\n );\r\n\r\n const onChangeBack = useCallback(\r\n (length: number) => {\r\n if (length === 0) {\r\n onChange(null);\r\n }\r\n setMaskedValue(''.padStart(length, '*'));\r\n },\r\n [onChange, setMaskedValue]\r\n );\r\n\r\n const handleKeypad = useCallback(() => {\r\n show(inputRef.current as HTMLInputElement, onChangeBack, onCloseBack, mode, maxLength, 3);\r\n }, [show, inputRef, onChangeBack, onCloseBack, mode, maxLength]);\r\n\r\n const enhancedOnClick = (existingClickHandler: () => void, newClickHandler: () => void) => {\r\n return () => {\r\n if (existingClickHandler) {\r\n existingClickHandler();\r\n }\r\n newClickHandler();\r\n };\r\n };\r\n\r\n const cloneElement = React.cloneElement(inputElement, {\r\n ref: inputRef,\r\n value: maskedValue,\r\n onClick: enhancedOnClick(inputElement.props.onClick, handleKeypad),\r\n isKeypadActive: isShow\r\n });\r\n\r\n useEffect(() => {\r\n const length = value?.input && value.input.length > 0 ? value.input.split(',').length : 0;\r\n setMaskedValue(''.padStart(length, '*'));\r\n }, [value]);\r\n\r\n useEffect(() => {\r\n if (inputRef.current && !(inputRef.current instanceof HTMLInputElement)) {\r\n throw new Error('Input 태그가 정의되지 않았습니다.');\r\n }\r\n }, []);\r\n\r\n return <>{cloneElement}</>;\r\n}\r\n","import { useCallback, useEffect, useState } from 'react';\r\n\r\nexport type NxlOneProps = {\r\n bizCode: string;\r\n tmplCode: string;\r\n ncsrInfoUuid?: string;\r\n nlcCtfnId?: string;\r\n // TYPE\r\n t?: string;\r\n env?: 'dev' | 'stg' | 'prod';\r\n};\r\n\r\nexport type NxlOneResponse = {\r\n action?: 'error' | 'close' | 'complete';\r\n redirectUrl?: string;\r\n nlcCtfnId?: string;\r\n};\r\n\r\nconst url = (() => {\r\n const url = typeof window !== 'undefined' ? window.location.href : '';\r\n\r\n if (url.includes('localhost') || url.includes('dev')) {\r\n return 'https://nxl-nlc-dev.hanwhalife.com';\r\n } else if (url.includes('stg')) {\r\n return 'https://nxl-nlc-stg.hanwhalife.com';\r\n } else {\r\n return 'https://nxl-nlc.hanwhalife.com';\r\n }\r\n})();\r\n\r\ntype OpenOptionType = {\r\n popupWidth?: number;\r\n popupHeight?: number;\r\n popupLeft?: number;\r\n popupTop?: number;\r\n windowName?: string;\r\n};\r\n\r\nexport default function useNxlOne({ bizCode, tmplCode, ncsrInfoUuid, nlcCtfnId, t, env }: NxlOneProps) {\r\n const baseUrl =\r\n env === 'prod'\r\n ? 'https://nxl-nlc.hanwhalife.com'\r\n : env === 'stg'\r\n ? 'https://nxl-nlc-stg.hanwhalife.com'\r\n : env === 'dev'\r\n ? 'https://nxl-nlc-dev.hanwhalife.com'\r\n : undefined;\r\n\r\n const buildUrl = useCallback(() => {\r\n const targetUrl = new URL('/auth/v1', baseUrl || url);\r\n targetUrl.searchParams.set('bizCode', bizCode);\r\n targetUrl.searchParams.set('tmplCode', tmplCode);\r\n\r\n if (nlcCtfnId) {\r\n targetUrl.searchParams.set('nlcCtfnId', nlcCtfnId);\r\n }\r\n\r\n if (t) {\r\n targetUrl.searchParams.set('t', t);\r\n }\r\n\r\n if (ncsrInfoUuid) {\r\n targetUrl.searchParams.set('ncsrInfoUuid', ncsrInfoUuid);\r\n }\r\n\r\n return targetUrl.toString();\r\n }, [bizCode, tmplCode, t, ncsrInfoUuid, nlcCtfnId]);\r\n\r\n /**\r\n * NEXTLAB ONE 인증 페이지로 이동합니다.\r\n * 인증이 완료 후, 관리자 페이지에서 정의한 프로세스 완료 URL로 이동합니다.\r\n */\r\n const redirect = () => {\r\n const targetUrl = buildUrl();\r\n\r\n location.href = targetUrl;\r\n };\r\n\r\n /**\r\n * NEXTLAB ONE 인증 페이지를 팝업으로 엽니다.\r\n * @param options 팝업의 크기, 위치, 창 이름을 정의합니다.\r\n * @returns 완료 URL에 인증 ID가 Query String 이 함께 정의된 형태로 반환됩니다.\r\n *\r\n * @example\r\n * const { open } = useNxlOne();\r\n *\r\n * const handleClick = async () => {\r\n * try {\r\n * const result = await open({ popupWidth: 500, popupHeight: 500 });\r\n * console.log('이동 시킬 URL : ' + result);\r\n * } catch (e) {\r\n * console.error('팝업 프로세스 실패');\r\n * }\r\n * }\r\n *\r\n * @note 팝업은 반드시 사용자 이벤트 핸들러 내에서 직접 호출해야 브라우저 차단을 피할 수 있습니다.\r\n */\r\n const open = async (options?: OpenOptionType) => {\r\n return new Promise<NxlOneResponse>((resolve, reject) => {\r\n const targetUrl = buildUrl();\r\n\r\n const width = (options && options.popupWidth) || 744;\r\n const height = (options && options.popupHeight) || 720;\r\n\r\n const left = (options && options.popupLeft) || window.screenX + (window.outerWidth - width) / 2;\r\n const top = (options && options.popupTop) || window.screenX + (window.outerWidth - width) / 2;\r\n\r\n const popupFeatures = `width=${width},height=${height},left=${left},top=${top}`;\r\n const popup = window.open(targetUrl, (options && options.windowName) || 'self_cert', popupFeatures);\r\n\r\n if (!popup) {\r\n reject(new Error('차단되거나 열리지 않았습니다.'));\r\n\r\n return;\r\n }\r\n\r\n let isSettled = false;\r\n\r\n const handleMessage = (event: MessageEvent) => {\r\n if (event.origin !== new URL(targetUrl).origin) {\r\n return;\r\n }\r\n\r\n if (!isSettled) {\r\n isSettled = true;\r\n\r\n if (event.data) {\r\n resolve(event.data);\r\n } else {\r\n reject('인증이 취소되거나 실패했습니다.');\r\n }\r\n\r\n popup?.close();\r\n window.removeEventListener('message', handleMessage);\r\n }\r\n };\r\n\r\n window.addEventListener('message', handleMessage);\r\n });\r\n };\r\n\r\n const Iframe = function ({\r\n height = 720,\r\n className,\r\n style,\r\n allow,\r\n sandbox = 'allow-scripts allow-forms allow-same-origin',\r\n onSuccess,\r\n onError,\r\n onClose,\r\n strictOrigin = true\r\n }: {\r\n height?: number | string;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n allow?: string;\r\n sandbox?: string;\r\n onSuccess?: (response: NxlOneResponse) => void;\r\n onError?: (response: NxlOneResponse) => void;\r\n onClose: (response: NxlOneResponse) => void;\r\n strictOrigin?: boolean;\r\n }) {\r\n const targetUrl = buildUrl();\r\n\r\n useEffect(() => {\r\n if (!onSuccess && !onError) {\r\n return;\r\n }\r\n\r\n const handler = (e: MessageEvent) => {\r\n if (strictOrigin && e.origin !== url) {\r\n return;\r\n }\r\n\r\n const d = e.data as NxlOneResponse;\r\n if (d) {\r\n if (d.action === 'close') {\r\n onClose(d);\r\n\r\n return;\r\n } else if (onError && d.action === 'error') {\r\n onError(d);\r\n\r\n return;\r\n } else if (onSuccess && d.action === 'complete') {\r\n onSuccess(d);\r\n\r\n return;\r\n }\r\n } else if (onError) {\r\n onError({\r\n action: 'error',\r\n nlcCtfnId: '',\r\n redirectUrl: ''\r\n });\r\n }\r\n };\r\n\r\n window.addEventListener('message', handler as EventListener);\r\n\r\n return () => window.removeEventListener('message', handler as EventListener);\r\n }, [onClose, onError, onSuccess, strictOrigin]);\r\n\r\n return (\r\n <iframe\r\n src={targetUrl}\r\n width=\"100%\"\r\n height={typeof height === 'number' ? `${height}px` : height}\r\n style={{ border: 0, ...style }}\r\n className={className}\r\n sandbox={sandbox}\r\n {...(allow ? { allow } : {})}\r\n />\r\n );\r\n };\r\n\r\n return { redirect, open, Iframe };\r\n}\r\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sales-frontend-solution",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.cjs.js"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": ">=18.0.0",
|
|
25
|
+
"react-dom": ">=18.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.14.0",
|
|
29
|
+
"@types/react": "19.1.0",
|
|
30
|
+
"@types/react-dom": "19.1.1",
|
|
31
|
+
"react": "^19.1.0",
|
|
32
|
+
"tsup": "^8.4.0",
|
|
33
|
+
"typescript": "5.8.2",
|
|
34
|
+
"eslint-config-sales-frontend-eslint-config-v8": "^0.0.6",
|
|
35
|
+
"sales-frontend-typescript-config": "0.0.2"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"lint": "eslint . --max-warnings 0",
|
|
39
|
+
"generate:component": "turbo gen react-component",
|
|
40
|
+
"check-types": "tsc --noEmit",
|
|
41
|
+
"storybook": "tsup --watch",
|
|
42
|
+
"build": "tsup"
|
|
43
|
+
}
|
|
44
|
+
}
|