sales-frontend-components 0.0.81 → 0.0.83

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.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { FieldValues, UseControllerProps } from 'react-hook-form';
3
3
  import { CheckboxButtonProps, CheckboxProps, DatePickerSingleHtmlProps, DatePickerRangeHtmlProps, FormField, SegmentGroupHtmlProps, SelectProps, OptionProps } from 'sales-frontend-design-system';
4
4
  import * as sales_frontend_api_method from 'sales-frontend-api/method';
5
- import { OccupationResponseDto, AddressStandardizationResponseDto, AddressResponseDto, OrganizationProfileResponse, EmployeeProfileResponseDto, CustomerSearchProps } from 'sales-frontend-api/method';
5
+ import { OccupationResponseDto, AddressStandardizationResponseDto, AddressResponseDto, OrganizationProfileResponse, EmployeeProfileResponseDto, CustomerSearchProps, RemoteIdentityVerificationSystemTokenRequestDto, ApiConfig } from 'sales-frontend-api/method';
6
6
  import * as React$1 from 'react';
7
7
  import React__default from 'react';
8
8
 
@@ -266,5 +266,78 @@ declare const JobSearchModal: React__default.FC<JobSearchModalProps>;
266
266
 
267
267
  declare const CustomerSearch: ({ onSelect }: CustomerSearchProps) => react_jsx_runtime.JSX.Element;
268
268
 
269
- export { Attachment, BankStockSearchModal, CustomerSearch, EmployeeSearchModal, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSearchJobField, FormSegmentGroup, FormSelect, FormTextField, JobSearchModal, OrganizationSearchModal, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useBankStockSearch, useCamera, useCanvasPaint, useJobVehicleSearchModal, useSearchAddress };
270
- export type { AttachedPhoto, AttachmentProps, BankStockItem, BankStockSearchModalProps, DownloadProps, PaintProps, Pen, StepIndicatorProps, StepItem, cameraItemType, cameraOptions };
269
+ interface VerificationResponse {
270
+ command: 'webClose';
271
+ args: {
272
+ result: 'Y' | 'N';
273
+ code: string;
274
+ };
275
+ }
276
+ interface RivUrlParams {
277
+ /** 유입환경구분코드(0: 모바일웹, 1: PC, 2: App) */
278
+ envDvsnCode?: string;
279
+ /** 완료페이지 스킵여부(0: Skip Off, 1: Skip On) */
280
+ skipFinalPage?: string;
281
+ /** 시작페이지 스킵여부(0: Skip Off, 1: Skip On) */
282
+ skipFirstPage?: string;
283
+ /** 국적타입(D: 내국인, F: 외국인) */
284
+ nationalityType?: 'D' | 'F';
285
+ }
286
+ interface RemoteIdentityVerificationSuccess {
287
+ rivsRqstId: string;
288
+ }
289
+ interface UseRemoteIdentityVerificationProps {
290
+ rivEnv?: 'prd' | 'stg' | 'dev';
291
+ rivOrigin?: string;
292
+ tokenRequestParams: RemoteIdentityVerificationSystemTokenRequestDto;
293
+ rivSearchParams?: RivUrlParams;
294
+ apiConfig?: ApiConfig;
295
+ onSuccess?: (result: VerificationResponse['args'], remoteIdentityVerificationSuccess: RemoteIdentityVerificationSuccess) => void;
296
+ onError?: (result: VerificationResponse['args']) => void;
297
+ onCancel?: (result: VerificationResponse['args']) => void;
298
+ }
299
+
300
+ /**
301
+ * 비대면인증시스템 기본 로직
302
+ * @param config
303
+ */
304
+ declare const useRemoteIdentityVerification: ({ rivEnv, rivOrigin, tokenRequestParams, apiConfig, onCancel, onError, onSuccess, rivSearchParams }: UseRemoteIdentityVerificationProps) => {
305
+ createRemoteIdentityVerificationUrl: () => Promise<{
306
+ fullUrl: string;
307
+ rivsRqstId: string;
308
+ }>;
309
+ createMessageHandler: ({ rivsRqstId }: RemoteIdentityVerificationSuccess, cleanup?: () => void) => (event: MessageEvent) => void;
310
+ };
311
+ /**
312
+ * Iframe용 비대면인증시스템 훅
313
+ * @param config
314
+ * @returns
315
+ */
316
+ declare const useRemoteIdentityVerificationIframe: (config: UseRemoteIdentityVerificationProps) => {
317
+ RivModalIframe: ({ width, height, loadingComponent, ...iframeProps }: React.IframeHTMLAttributes<HTMLIFrameElement> & {
318
+ width?: string;
319
+ height?: string;
320
+ loadingComponent?: React.ReactNode;
321
+ }) => react_jsx_runtime.JSX.Element;
322
+ RivIframe: ({ width, height, ...iframeProps }: React.IframeHTMLAttributes<HTMLIFrameElement> & {
323
+ width?: string;
324
+ height?: string;
325
+ }) => react_jsx_runtime.JSX.Element | null;
326
+ openRivIframe: () => Promise<void>;
327
+ closeRivIframe: () => void;
328
+ remoteIdentityVerificationUrl: string;
329
+ isCreatingUrl: boolean;
330
+ isFullyLoaded: boolean;
331
+ };
332
+ /**
333
+ * 팝업용 비대면인증시스템 훅
334
+ * @param config
335
+ * @returns
336
+ */
337
+ declare const useRemoteIdentityVerificationPopup: (config: UseRemoteIdentityVerificationProps) => {
338
+ openPopup: (target?: string, features?: string) => Promise<void>;
339
+ isCreatingUrl: boolean;
340
+ };
341
+
342
+ export { Attachment, BankStockSearchModal, CustomerSearch, EmployeeSearchModal, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSearchJobField, FormSegmentGroup, FormSelect, FormTextField, JobSearchModal, OrganizationSearchModal, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useBankStockSearch, useCamera, useCanvasPaint, useJobVehicleSearchModal, useRemoteIdentityVerification, useRemoteIdentityVerificationIframe, useRemoteIdentityVerificationPopup, useSearchAddress };
343
+ export type { AttachedPhoto, AttachmentProps, BankStockItem, BankStockSearchModalProps, DownloadProps, PaintProps, Pen, RemoteIdentityVerificationSuccess, RivUrlParams, StepIndicatorProps, StepItem, UseRemoteIdentityVerificationProps, VerificationResponse, cameraItemType, cameraOptions };
package/dist/index.esm.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { useController } from 'react-hook-form';
3
- import { CheckboxButton, Checkbox, DatePicker, DateRangePicker, Accordion, Radio, Table, Button, FormField, Select, Tab, useModalState, Modal, SegmentGroup, ModalUtils, FormCore, RadioGroup, useDropDown, List, ListItem } from 'sales-frontend-design-system';
3
+ import { CheckboxButton, Checkbox, DatePicker, DateRangePicker, Accordion, Radio, Table, Button, FormField, Select, Tab, useModalState, Modal, SegmentGroup, ModalUtils, FormCore, RadioGroup, useDropDown, List, ListItem, Loading } from 'sales-frontend-design-system';
4
4
  import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
5
- import { useSearchOccupationDetailQuery, useSearchOccupationQuery, useSearchAddressQuery, useSearchPostalCodeQuery, useSearchAddressStandardizationQuery, useSearchOrganizationQuery, useSearchEmployeeProfileQuery, useSearchVehicleQuery, useSearchCustomerListQuery } from 'sales-frontend-api/method';
5
+ import { useSearchOccupationDetailQuery, useSearchOccupationQuery, useSearchAddressQuery, useSearchPostalCodeQuery, useSearchAddressStandardizationQuery, useSearchOrganizationQuery, useSearchEmployeeProfileQuery, useSearchVehicleQuery, useSearchCustomerListQuery, getRemoteIdentityVerificationSystemToken } from 'sales-frontend-api/method';
6
6
  import { IconMainUiSearch, IconIllustCamera, IconGraphicsBankHsbc, IconGraphicsBankKebHana, IconGraphicsBankScJeil, IconGraphicsBankGyeongnam, IconGraphicsBankGwangju, IconGraphicsBankKukmin, IconGraphicsBankKiup, IconGraphicsBankJiyeokNonghyeop, IconGraphicsBankNhNonghyeop, IconGraphicsBankDaegu, IconGraphicsBankBusan, IconGraphicsBankSanlim, IconGraphicsBankSaneop, IconGraphicsBankSaemaulGeumgo, IconGraphicsBankSuhyeop, IconGraphicsBankSinhan, IconGraphicsBankSinhyeop, IconGraphicsBankOehwan, IconGraphicsBankWoori, IconGraphicsBankPost, IconGraphicsBankJeochuk, IconGraphicsBankJeonbuk, IconGraphicsBankJeju, IconGraphicsBankKakaoBank, IconGraphicsBankKBank, IconGraphicsBankHankookCity, IconGraphicsStockDbGeumyungTujajeungkwon, IconGraphicsStockKbJeungkwon, IconGraphicsStockNhWooriTujajeungkwon, IconGraphicsStockNhTujajeungkwon, IconGraphicsStockSkJeungkwon, IconGraphicsStockGyoboJeungkwon, IconGraphicsStockDaesinJeungkwon, IconGraphicsStockMeritzJeungkwon, IconGraphicsStockMiraeAssetJeungkwon, IconGraphicsStockBugukJeungkwon, IconGraphicsStockSamsungJeungkwon, IconGraphicsStockSinyeongJeungkwon, IconGraphicsStockSinhanTujajeungkwon, IconGraphicsStockYuantaJeungkwon, IconGraphicsStockYujinTujajeungkwon, IconGraphicsStockKiwoomJeungkwon, IconGraphicsStockHanaGeumyungTujajeungkwon, IconGraphicsStockHiTujajeungkwon, IconGraphicsStockHankookJeungkwonGeumyung, IconGraphicsStockHankookTujajeungkwon, IconGraphicsStockHanwhaTujajeungkwon, IconGraphicsStockHyundaiChaJeungkwon, IconGraphicsStockHochulEopsum, IconGraphicsFeedbackEmpty, IconIllustGrade, IconIllustJob, IconSubUiArrowRight, IconIllustVehicle } from 'sales-frontend-assets';
7
7
  import styles from './modal/pre-standard/job-search-modal/job-search-modal.module.scss';
8
8
  import styles$1 from './step-indicator/step-indicator.module.scss';
@@ -14,6 +14,7 @@ import styles$6 from './modal/pre-standard/employee-search-modal/employee-search
14
14
  import styles$7 from './modal/pre-standard/job-vehicle-search-modal/job-vehicle-search-modal.module.scss';
15
15
  import styles$8 from './modal/pre-standard/vehicle-search-modal/vehicle-search-modal.module.scss';
16
16
  import styles$9 from './modal/standard/customer-search/customer-search.module.scss';
17
+ import { MessageEventManager } from 'sales-frontend-utils';
17
18
 
18
19
  const FormCheckboxButton = ({
19
20
  name,
@@ -2577,5 +2578,203 @@ const CustomerSearch = ({ onSelect }) => {
2577
2578
  ] });
2578
2579
  };
2579
2580
 
2580
- export { Attachment, BankStockSearchModal, CustomerSearch, EmployeeSearchModal, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSearchJobField, FormSegmentGroup, FormSelect, FormTextField, JobSearchModal, OrganizationSearchModal, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useBankStockSearch, useCamera, useCanvasPaint, useJobVehicleSearchModal, useSearchAddress };
2581
+ const VERIFICATION_CODES = {
2582
+ SUCCESS: "0000",
2583
+ USER_CANCEL: "9000",
2584
+ TOKEN_ERROR: "9001",
2585
+ CAMERA_PERMISSION: "9002",
2586
+ ATTEMPT_EXCEEDED: "9003",
2587
+ SERVER_ERROR: "9999"
2588
+ };
2589
+ const useRemoteIdentityVerification = ({
2590
+ rivEnv,
2591
+ rivOrigin,
2592
+ tokenRequestParams,
2593
+ apiConfig,
2594
+ onCancel,
2595
+ onError,
2596
+ onSuccess,
2597
+ rivSearchParams
2598
+ }) => {
2599
+ const rivHost = rivOrigin ?? `https://${rivEnv === "prd" ? "" : rivEnv === "stg" ? "qa" : "dev"}riv.hanwhalife.com`;
2600
+ const createRemoteIdentityVerificationUrl = async () => {
2601
+ const response = await getRemoteIdentityVerificationSystemToken(tokenRequestParams, apiConfig);
2602
+ const { accessToken, remoteIdentityVerificationSystemRequestId } = response.data;
2603
+ const urlParams = new URLSearchParams({
2604
+ authorization: accessToken,
2605
+ rivsRqstId: remoteIdentityVerificationSystemRequestId,
2606
+ ...rivSearchParams
2607
+ });
2608
+ return { fullUrl: `${rivHost}/?${urlParams.toString()}`, rivsRqstId: remoteIdentityVerificationSystemRequestId };
2609
+ };
2610
+ const createMessageHandler = ({ rivsRqstId }, cleanup) => {
2611
+ return (event) => {
2612
+ try {
2613
+ const response = typeof event.data === "string" ? JSON.parse(decodeURIComponent(event.data)) : event.data;
2614
+ if (response.command !== "webClose") {
2615
+ return;
2616
+ }
2617
+ const { result, code } = response.args;
2618
+ switch (code) {
2619
+ case VERIFICATION_CODES.USER_CANCEL:
2620
+ console.log("=====\uC0AC\uC6A9\uC790 \uC885\uB8CC!=====", { result, code });
2621
+ onCancel?.({ result, code });
2622
+ cleanup?.();
2623
+ break;
2624
+ case VERIFICATION_CODES.TOKEN_ERROR:
2625
+ case VERIFICATION_CODES.CAMERA_PERMISSION:
2626
+ case VERIFICATION_CODES.ATTEMPT_EXCEEDED:
2627
+ case VERIFICATION_CODES.SERVER_ERROR:
2628
+ console.log("=====\uBE44\uB300\uBA74\uC778\uC99D \uC2E4\uD328!=====", { result, code });
2629
+ onError?.({ result, code });
2630
+ cleanup?.();
2631
+ break;
2632
+ case VERIFICATION_CODES.SUCCESS:
2633
+ console.log("=====\uBE44\uB300\uBA74\uC778\uC99D \uC131\uACF5!=====", { result, code });
2634
+ onSuccess?.({ result, code }, { rivsRqstId });
2635
+ cleanup?.();
2636
+ break;
2637
+ default:
2638
+ console.warn("Unknown verification code:", code);
2639
+ }
2640
+ } catch (error) {
2641
+ console.error("Failed to parse postMessage:", error);
2642
+ }
2643
+ };
2644
+ };
2645
+ return {
2646
+ createRemoteIdentityVerificationUrl,
2647
+ createMessageHandler
2648
+ };
2649
+ };
2650
+ const useRemoteIdentityVerificationIframe = (config) => {
2651
+ const { createMessageHandler, createRemoteIdentityVerificationUrl } = useRemoteIdentityVerification(config);
2652
+ const { isOpen, openModal, closeModal } = useModalState();
2653
+ const [remoteIdentityVerificationUrl, setRemoteIdentityVerificationUrl] = useState("");
2654
+ const [rivsRqstId, setRivsRqstId] = useState("");
2655
+ const [isCreatingUrl, setIsCreatingUrl] = useState(false);
2656
+ const [isIframeLoaded, setIsIframeLoaded] = useState(false);
2657
+ const createIframeUrl = async () => {
2658
+ if (remoteIdentityVerificationUrl || isCreatingUrl) {
2659
+ return;
2660
+ }
2661
+ setIsCreatingUrl(true);
2662
+ setIsIframeLoaded(false);
2663
+ try {
2664
+ const { fullUrl, rivsRqstId: rivsRqstId2 } = await createRemoteIdentityVerificationUrl();
2665
+ setRemoteIdentityVerificationUrl(fullUrl);
2666
+ setRivsRqstId(rivsRqstId2);
2667
+ } catch (error) {
2668
+ console.error("Failed to create URL:", error);
2669
+ throw error;
2670
+ } finally {
2671
+ setIsCreatingUrl(false);
2672
+ }
2673
+ };
2674
+ const openRivIframe = async () => {
2675
+ try {
2676
+ await createIframeUrl();
2677
+ openModal();
2678
+ } catch (error) {
2679
+ console.error("openRivIframe error::", error);
2680
+ await ModalUtils.alert("\uBE44\uB300\uBA74 \uC778\uC99D URL \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
2681
+ }
2682
+ };
2683
+ const closeRivIframe = () => {
2684
+ setRemoteIdentityVerificationUrl("");
2685
+ setRivsRqstId("");
2686
+ setIsIframeLoaded(false);
2687
+ closeModal();
2688
+ };
2689
+ useEffect(() => {
2690
+ if (!remoteIdentityVerificationUrl) {
2691
+ return;
2692
+ }
2693
+ const messageHandler = createMessageHandler({ rivsRqstId }, closeRivIframe);
2694
+ MessageEventManager.getInstance().registerHandler("riv-iframe-handler", messageHandler);
2695
+ return () => MessageEventManager.getInstance().unregisterHandler("riv-iframe-handler");
2696
+ }, [remoteIdentityVerificationUrl, rivsRqstId]);
2697
+ const RivIframe = ({
2698
+ width = "100%",
2699
+ height = "100%",
2700
+ ...iframeProps
2701
+ }) => {
2702
+ if (!remoteIdentityVerificationUrl) {
2703
+ return null;
2704
+ }
2705
+ return /* @__PURE__ */ jsx(
2706
+ "iframe",
2707
+ {
2708
+ src: remoteIdentityVerificationUrl,
2709
+ width,
2710
+ height,
2711
+ allow: "camera *;",
2712
+ onLoad: () => setIsIframeLoaded(true),
2713
+ ...iframeProps
2714
+ }
2715
+ );
2716
+ };
2717
+ const RivModalIframe = ({
2718
+ width = "100%",
2719
+ height = "100%",
2720
+ loadingComponent,
2721
+ ...iframeProps
2722
+ }) => {
2723
+ const isLoading = isCreatingUrl || !!remoteIdentityVerificationUrl && !isIframeLoaded;
2724
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Modal.Root, { isOpen, children: [
2725
+ isLoading && (loadingComponent || /* @__PURE__ */ jsx(Loading.Wait, { bodyText: "\uBD88\uB7EC\uC624\uB294 \uC911" })),
2726
+ /* @__PURE__ */ jsx(RivIframe, { width, height, allow: "camera *;", ...iframeProps })
2727
+ ] }) });
2728
+ };
2729
+ return {
2730
+ RivModalIframe,
2731
+ RivIframe,
2732
+ openRivIframe,
2733
+ closeRivIframe,
2734
+ remoteIdentityVerificationUrl,
2735
+ isCreatingUrl,
2736
+ isFullyLoaded: isIframeLoaded
2737
+ };
2738
+ };
2739
+ const useRemoteIdentityVerificationPopup = (config) => {
2740
+ const { createRemoteIdentityVerificationUrl, createMessageHandler } = useRemoteIdentityVerification(config);
2741
+ const [isCreatingUrl, setIsCreatingUrl] = useState(false);
2742
+ const [rivsRqstId, setRivsRqstId] = useState("");
2743
+ const popupRef = useRef(null);
2744
+ const openPopup = async (target = "_blank", features) => {
2745
+ if (popupRef.current && !popupRef.current.closed) {
2746
+ popupRef.current.close();
2747
+ }
2748
+ setIsCreatingUrl(true);
2749
+ try {
2750
+ const { fullUrl, rivsRqstId: rivsRqstId2 } = await createRemoteIdentityVerificationUrl();
2751
+ const popup = window.open(fullUrl, target, features);
2752
+ if (!popup) {
2753
+ await ModalUtils.alert("\uD31D\uC5C5\uC774 \uCC28\uB2E8\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD31D\uC5C5\uC744 \uD5C8\uC6A9\uD574\uC8FC\uC138\uC694.");
2754
+ return;
2755
+ }
2756
+ setRivsRqstId(rivsRqstId2);
2757
+ popupRef.current = popup;
2758
+ } catch (error) {
2759
+ console.error("openPopup error::", error);
2760
+ await ModalUtils.alert("\uBE44\uB300\uBA74 \uC778\uC99D URL \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
2761
+ } finally {
2762
+ setIsCreatingUrl(false);
2763
+ }
2764
+ };
2765
+ const cleanPopup = () => {
2766
+ popupRef.current = null;
2767
+ };
2768
+ useEffect(() => {
2769
+ const messageHandler = createMessageHandler({ rivsRqstId }, cleanPopup);
2770
+ MessageEventManager.getInstance().registerHandler("riv-popup-handler", messageHandler);
2771
+ return () => MessageEventManager.getInstance().unregisterHandler("riv-popup-handler");
2772
+ }, [rivsRqstId]);
2773
+ return {
2774
+ openPopup,
2775
+ isCreatingUrl
2776
+ };
2777
+ };
2778
+
2779
+ export { Attachment, BankStockSearchModal, CustomerSearch, EmployeeSearchModal, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSearchJobField, FormSegmentGroup, FormSelect, FormTextField, JobSearchModal, OrganizationSearchModal, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useBankStockSearch, useCamera, useCanvasPaint, useJobVehicleSearchModal, useRemoteIdentityVerification, useRemoteIdentityVerificationIframe, useRemoteIdentityVerificationPopup, useSearchAddress };
2581
2780
  //# sourceMappingURL=index.esm.js.map