@bwg-ui/core 1.1.23 → 1.1.25

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.
Files changed (161) hide show
  1. package/dist/chunks/AuthContext-CXng9fj0.cjs.map +1 -1
  2. package/dist/chunks/{AuthContext-Ei2P-z4d.js → AuthContext-DrEpBrpB.js} +7 -3
  3. package/dist/chunks/AuthContext-DrEpBrpB.js.map +1 -0
  4. package/dist/chunks/{BwgSwitch-CAI-kEaM.cjs → BwgSwitch-DOlc57wi.cjs} +2 -2
  5. package/dist/chunks/BwgSwitch-DOlc57wi.cjs.map +1 -0
  6. package/dist/chunks/{BwgSwitch-B79pseQM.js → BwgSwitch-D_scwi9_.js} +18 -18
  7. package/dist/chunks/BwgSwitch-D_scwi9_.js.map +1 -0
  8. package/dist/chunks/{BwgUploader-DaNV2URT.cjs → BwgUploader-CkXwkcUL.cjs} +2 -2
  9. package/dist/chunks/BwgUploader-CkXwkcUL.cjs.map +1 -0
  10. package/dist/chunks/{BwgUploader-BcVlE61B.js → BwgUploader-DBFF9BPF.js} +327 -327
  11. package/dist/chunks/BwgUploader-DBFF9BPF.js.map +1 -0
  12. package/dist/chunks/LoadingOverlay-DAZJF5wg.js.map +1 -1
  13. package/dist/chunks/LoadingOverlay-DcmKvoZA.cjs.map +1 -1
  14. package/dist/chunks/{SSOHandler-DiW4Ft9i.cjs → SSOHandler-BY6LXMLc.cjs} +32 -32
  15. package/dist/chunks/SSOHandler-BY6LXMLc.cjs.map +1 -0
  16. package/dist/chunks/{SSOHandler-CkPcSHIm.js → SSOHandler-CxvxEBaH.js} +1977 -1930
  17. package/dist/chunks/SSOHandler-CxvxEBaH.js.map +1 -0
  18. package/dist/chunks/ScreenProtectContext-3my4PHFa.js.map +1 -1
  19. package/dist/chunks/ScreenProtectContext-CVuXrJm6.cjs.map +1 -1
  20. package/dist/chunks/SearchBoxContext-DwFDOyYG.cjs.map +1 -1
  21. package/dist/chunks/{SearchBoxContext-BCvEYyFk.js → SearchBoxContext-gWM7FHIw.js} +3 -5
  22. package/dist/chunks/SearchBoxContext-gWM7FHIw.js.map +1 -0
  23. package/dist/chunks/ViewContainer-Bhq22_B3.cjs.map +1 -1
  24. package/dist/chunks/{ViewContainer-CjpJqoGG.js → ViewContainer-D9SKBnrn.js} +40 -28
  25. package/dist/chunks/ViewContainer-D9SKBnrn.js.map +1 -0
  26. package/dist/chunks/apiUtils-BZ6s0_NI.cjs.map +1 -1
  27. package/dist/chunks/{apiUtils-DxzLqPhU.js → apiUtils-DSwE62oG.js} +14 -5
  28. package/dist/chunks/apiUtils-DSwE62oG.js.map +1 -0
  29. package/dist/chunks/{codeStore-CfI4Wh5M.js → codeStore-vPj4Y0TK.js} +2 -2
  30. package/dist/chunks/{codeStore-CfI4Wh5M.js.map → codeStore-vPj4Y0TK.js.map} +1 -1
  31. package/dist/chunks/{core-bHd8azE6.js → core-Dl0PdDdT.js} +2 -2
  32. package/dist/chunks/{core-bHd8azE6.js.map → core-Dl0PdDdT.js.map} +1 -1
  33. package/dist/chunks/{enc-base64-BQYwLKgk.js → enc-base64-D7t4BoUA.js} +3 -3
  34. package/dist/chunks/{enc-base64-BQYwLKgk.js.map → enc-base64-D7t4BoUA.js.map} +1 -1
  35. package/dist/chunks/{favoriteStore-Cemc-26t.js → favoriteStore-Bh1FuZm9.js} +2 -2
  36. package/dist/chunks/{favoriteStore-Cemc-26t.js.map → favoriteStore-Bh1FuZm9.js.map} +1 -1
  37. package/dist/chunks/{popupStore-Bi6o78lP.js → popupStore-BRRmB4zH.js} +2 -2
  38. package/dist/chunks/{popupStore-Bi6o78lP.js.map → popupStore-BRRmB4zH.js.map} +1 -1
  39. package/dist/chunks/{sha256-BZfJs28k.js → sha256-C2-s1oZe.js} +3 -3
  40. package/dist/chunks/{sha256-BZfJs28k.js.map → sha256-C2-s1oZe.js.map} +1 -1
  41. package/dist/chunks/usePopup-D2JEuDrO.cjs.map +1 -1
  42. package/dist/chunks/{usePopup-BSqsnSz7.js → usePopup-DarKTbRC.js} +3 -3
  43. package/dist/chunks/usePopup-DarKTbRC.js.map +1 -0
  44. package/dist/components/common/BookmarkMngModal.d.ts +1 -1
  45. package/dist/components/common/BookmarkMngModal.d.ts.map +1 -1
  46. package/dist/components/common/BookmarkPopver.d.ts +2 -2
  47. package/dist/components/common/BookmarkPopver.d.ts.map +1 -1
  48. package/dist/components/common/BwgButtonGroup.d.ts +5 -5
  49. package/dist/components/common/BwgButtonGroup.d.ts.map +1 -1
  50. package/dist/components/common/BwgCmptArea.d.ts +7 -7
  51. package/dist/components/common/BwgCmptArea.d.ts.map +1 -1
  52. package/dist/components/common/BwgCol.d.ts +2 -1
  53. package/dist/components/common/BwgCol.d.ts.map +1 -1
  54. package/dist/components/common/BwgConfigProvider.d.ts +2 -2
  55. package/dist/components/common/BwgConfigProvider.d.ts.map +1 -1
  56. package/dist/components/common/BwgDetail.d.ts +2 -1
  57. package/dist/components/common/BwgDetail.d.ts.map +1 -1
  58. package/dist/components/common/BwgDraggable.d.ts +5 -5
  59. package/dist/components/common/BwgDraggable.d.ts.map +1 -1
  60. package/dist/components/common/BwgDrawer.d.ts +2 -1
  61. package/dist/components/common/BwgDrawer.d.ts.map +1 -1
  62. package/dist/components/common/BwgEditor.d.ts +5 -5
  63. package/dist/components/common/BwgEditor.d.ts.map +1 -1
  64. package/dist/components/common/BwgGrid.d.ts +8 -8
  65. package/dist/components/common/BwgGrid.d.ts.map +1 -1
  66. package/dist/components/common/BwgInfoArea.d.ts +4 -4
  67. package/dist/components/common/BwgInfoArea.d.ts.map +1 -1
  68. package/dist/components/common/BwgPopup.d.ts +3 -3
  69. package/dist/components/common/BwgPopup.d.ts.map +1 -1
  70. package/dist/components/common/BwgRow.d.ts +2 -1
  71. package/dist/components/common/BwgRow.d.ts.map +1 -1
  72. package/dist/components/common/BwgTitleBox.d.ts +5 -4
  73. package/dist/components/common/BwgTitleBox.d.ts.map +1 -1
  74. package/dist/components/common/BwgView.d.ts +4 -4
  75. package/dist/components/common/BwgView.d.ts.map +1 -1
  76. package/dist/components/common/ContentBox.d.ts +3 -3
  77. package/dist/components/common/ContentBox.d.ts.map +1 -1
  78. package/dist/components/common/ContentLayOut.d.ts +6 -5
  79. package/dist/components/common/ContentLayOut.d.ts.map +1 -1
  80. package/dist/components/common/GlobalConfigProvider.d.ts +2 -2
  81. package/dist/components/common/GlobalConfigProvider.d.ts.map +1 -1
  82. package/dist/components/common/QuickServiceToggle.d.ts +4 -4
  83. package/dist/components/common/QuickServiceToggle.d.ts.map +1 -1
  84. package/dist/components/common/SSOHandler.d.ts +2 -1
  85. package/dist/components/common/SSOHandler.d.ts.map +1 -1
  86. package/dist/components/common/SearchBox.d.ts +5 -4
  87. package/dist/components/common/SearchBox.d.ts.map +1 -1
  88. package/dist/components/common/index.cjs +1 -1
  89. package/dist/components/common/index.js +1 -1
  90. package/dist/components/core/BwgButton.d.ts +3 -2
  91. package/dist/components/core/BwgButton.d.ts.map +1 -1
  92. package/dist/components/core/BwgDatePicker.d.ts +3 -3
  93. package/dist/components/core/BwgDatePicker.d.ts.map +1 -1
  94. package/dist/components/core/BwgDownload.d.ts +2 -2
  95. package/dist/components/core/BwgDownload.d.ts.map +1 -1
  96. package/dist/components/core/BwgForm.d.ts +2 -1
  97. package/dist/components/core/BwgForm.d.ts.map +1 -1
  98. package/dist/components/core/BwgFormItem.d.ts +3 -3
  99. package/dist/components/core/BwgFormItem.d.ts.map +1 -1
  100. package/dist/components/core/BwgInput.d.ts +2 -2
  101. package/dist/components/core/BwgInput.d.ts.map +1 -1
  102. package/dist/components/core/BwgLargeUploader.d.ts +2 -2
  103. package/dist/components/core/BwgLargeUploader.d.ts.map +1 -1
  104. package/dist/components/core/BwgMaskedInput.d.ts +2 -2
  105. package/dist/components/core/BwgMaskedInput.d.ts.map +1 -1
  106. package/dist/components/core/BwgMaskedPicker.d.ts +2 -2
  107. package/dist/components/core/BwgMaskedPicker.d.ts.map +1 -1
  108. package/dist/components/core/BwgRangePicker.d.ts +3 -3
  109. package/dist/components/core/BwgRangePicker.d.ts.map +1 -1
  110. package/dist/components/core/BwgSearch.d.ts +1 -1
  111. package/dist/components/core/BwgSearch.d.ts.map +1 -1
  112. package/dist/components/core/BwgUploader.d.ts +2 -2
  113. package/dist/components/core/BwgUploader.d.ts.map +1 -1
  114. package/dist/components/core/index.cjs +1 -1
  115. package/dist/components/core/index.js +2 -2
  116. package/dist/components/layout/ErrorBound.d.ts +3 -3
  117. package/dist/components/layout/ErrorBound.d.ts.map +1 -1
  118. package/dist/components/layout/LoadingOverlay.d.ts +3 -2
  119. package/dist/components/layout/LoadingOverlay.d.ts.map +1 -1
  120. package/dist/components/layout/PrivateProtectedOverlay.d.ts +3 -2
  121. package/dist/components/layout/PrivateProtectedOverlay.d.ts.map +1 -1
  122. package/dist/components/layout/ProgressOverlay.d.ts +2 -2
  123. package/dist/components/layout/ProgressOverlay.d.ts.map +1 -1
  124. package/dist/components/layout/ViewContainer.d.ts +3 -3
  125. package/dist/components/layout/ViewContainer.d.ts.map +1 -1
  126. package/dist/components/layout/index.js +1 -1
  127. package/dist/components/popup/MenuReport.d.ts +2 -2
  128. package/dist/components/popup/MenuReport.d.ts.map +1 -1
  129. package/dist/index.cjs +1 -1
  130. package/dist/index.js +11 -11
  131. package/dist/provider/contexts/AuthContext.d.ts +3 -2
  132. package/dist/provider/contexts/AuthContext.d.ts.map +1 -1
  133. package/dist/provider/contexts/CommonCodeContext.d.ts +2 -2
  134. package/dist/provider/contexts/CommonCodeContext.d.ts.map +1 -1
  135. package/dist/provider/contexts/ScreenProtectContext.d.ts +5 -5
  136. package/dist/provider/contexts/ScreenProtectContext.d.ts.map +1 -1
  137. package/dist/provider/contexts/SearchBoxContext.d.ts +3 -3
  138. package/dist/provider/contexts/SearchBoxContext.d.ts.map +1 -1
  139. package/dist/provider/contexts/ServiceCodeContext.d.ts +2 -2
  140. package/dist/provider/contexts/ServiceCodeContext.d.ts.map +1 -1
  141. package/dist/provider/index.js +3 -3
  142. package/dist/stores/index.cjs.map +1 -1
  143. package/dist/stores/index.d.ts +0 -1
  144. package/dist/stores/index.d.ts.map +1 -1
  145. package/dist/stores/index.js +6 -6
  146. package/dist/stores/index.js.map +1 -1
  147. package/dist/stores/menuViewStore.d.ts +6 -5
  148. package/dist/stores/menuViewStore.d.ts.map +1 -1
  149. package/dist/utils/index.js +2 -2
  150. package/package.json +1 -1
  151. package/dist/chunks/AuthContext-Ei2P-z4d.js.map +0 -1
  152. package/dist/chunks/BwgSwitch-B79pseQM.js.map +0 -1
  153. package/dist/chunks/BwgSwitch-CAI-kEaM.cjs.map +0 -1
  154. package/dist/chunks/BwgUploader-BcVlE61B.js.map +0 -1
  155. package/dist/chunks/BwgUploader-DaNV2URT.cjs.map +0 -1
  156. package/dist/chunks/SSOHandler-CkPcSHIm.js.map +0 -1
  157. package/dist/chunks/SSOHandler-DiW4Ft9i.cjs.map +0 -1
  158. package/dist/chunks/SearchBoxContext-BCvEYyFk.js.map +0 -1
  159. package/dist/chunks/ViewContainer-CjpJqoGG.js.map +0 -1
  160. package/dist/chunks/apiUtils-DxzLqPhU.js.map +0 -1
  161. package/dist/chunks/usePopup-BSqsnSz7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenProtectContext-3my4PHFa.js","sources":["../../src/provider/contexts/ScreenProtectContext.tsx"],"sourcesContent":["import { Input } from \"antd\";\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\n\r\n/**\r\n * ScreenProtectProvider\r\n * - 전역용(기본값): window 활동감지 + fixed 전체 오버레이\r\n * - 탭스코프용(옵션): eventTarget 활동감지 + absolute 탭 영역 오버레이\r\n */\r\n\r\n// ===================== Lock Context =====================\r\ntype LockContextValue = {\r\n locked: boolean;\r\n lock: () => void;\r\n unlock: (pin?: string) => Promise<void> | void;\r\n setIdleMs: (ms: number) => void;\r\n};\r\n\r\nconst LockContext = createContext<LockContextValue | null>(null);\r\n\r\nexport const useLock = () => {\r\n const ctx = useContext(LockContext);\r\n if (!ctx)\r\n throw new Error(\"useLock must be used within ScreenProtectProvider\");\r\n return ctx;\r\n};\r\n\r\n// ===================== Provider =====================\r\nexport const ScreenProtectProvider: React.FC<{\r\n children: React.ReactNode;\r\n idleMs?: number;\r\n onUnlock?: (pin?: string) => Promise<boolean> | boolean;\r\n persistLocked?: boolean;\r\n storageKey?: string;\r\n\r\n /** ▼ 탭 스코프용 확장 옵션 */\r\n eventTarget?: EventTarget | null; // 활동 감지/가드 대상 (기본: window)\r\n overlayScope?: \"global\" | \"scoped\"; // 캡처가드 범위\r\n overlayId?: string; // 오버레이 DOM id\r\n overlayPosition?: \"fixed\" | \"absolute\"; // 오버레이 위치 (전역: fixed, 탭: absolute)\r\n}> = ({\r\n children,\r\n idleMs = 10_000,\r\n onUnlock,\r\n persistLocked = true,\r\n storageKey = \"inactivityLocked\",\r\n eventTarget,\r\n overlayScope = \"global\",\r\n overlayId = \"lock-overlay-root\",\r\n overlayPosition = \"fixed\",\r\n}) => {\r\n const initialLocked =\r\n persistLocked &&\r\n typeof window !== \"undefined\" &&\r\n window.localStorage.getItem(storageKey) === \"1\";\r\n\r\n const [locked, setLocked] = useState(initialLocked);\r\n const [idle, setIdle] = useState(idleMs);\r\n const isIdleEnabled = Number.isFinite(idle) && idle > 0;\r\n const timerRef = useRef<number | null>(null);\r\n\r\n const lock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, \"1\");\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const unlock = async (pin?: string) => {\r\n if (onUnlock) {\r\n const ok = await onUnlock(pin);\r\n if (!ok) return;\r\n }\r\n try {\r\n if (persistLocked) window.localStorage.removeItem(storageKey);\r\n } catch {}\r\n setLocked(false);\r\n if (isIdleEnabled) resetTimer();\r\n };\r\n\r\n const doLock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, \"1\");\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const resetTimer = () => {\r\n if (!isIdleEnabled) return;\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n timerRef.current = window.setTimeout(() => {\r\n doLock();\r\n }, idle);\r\n };\r\n\r\n // 활동 감지: window → target(옵션)으로 스코프 전환 가능\r\n useEffect(() => {\r\n if (!isIdleEnabled) return;\r\n const onActivity = () => {\r\n if (!locked) resetTimer();\r\n };\r\n const opts = { passive: true } as AddEventListenerOptions;\r\n const evts = [\r\n \"pointermove\",\r\n \"pointerdown\",\r\n \"keydown\",\r\n \"wheel\",\r\n \"touchstart\",\r\n ];\r\n\r\n const target = (eventTarget ?? window) as any;\r\n evts.forEach((e) => target.addEventListener(e, onActivity, opts));\r\n resetTimer();\r\n\r\n return () => {\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n evts.forEach((e) => target.removeEventListener(e, onActivity as any));\r\n };\r\n }, [idle, locked, eventTarget, isIdleEnabled]);\r\n\r\n // 잠금 중 캡처가드: 전역(global) 또는 스코프(scoped)로 범위 선택\r\n useEffect(() => {\r\n if (!locked) return;\r\n\r\n const stop = (e: Event) => {\r\n const overlay = document.getElementById(overlayId);\r\n if (overlay && overlay.contains(e.target as Node)) return; // 오버레이 내부는 통과\r\n e.stopPropagation();\r\n e.preventDefault();\r\n };\r\n\r\n const opts = { capture: true } as AddEventListenerOptions;\r\n const evs = [\r\n \"pointerdown\",\r\n \"pointerup\",\r\n \"pointermove\",\r\n \"click\",\r\n \"wheel\",\r\n \"keydown\",\r\n \"keyup\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n ];\r\n\r\n // 전역이면 window, 스코프면 eventTarget(없으면 window)\r\n const guardTarget = (\r\n overlayScope === \"scoped\" ? eventTarget ?? window : window\r\n ) as any;\r\n evs.forEach((t) => guardTarget.addEventListener(t, stop, opts));\r\n return () =>\r\n evs.forEach((t) => guardTarget.removeEventListener(t, stop as any, opts));\r\n }, [locked, overlayScope, overlayId, eventTarget]);\r\n\r\n const value = useMemo(\r\n () => ({ locked, lock, unlock, setIdleMs: setIdle }),\r\n [locked]\r\n );\r\n\r\n return (\r\n <LockContext.Provider value={value}>\r\n <div\r\n style={{ width: \"100%\", height: \"100%\" }}\r\n {...(locked ? ({ inert: \"\" } as any) : {})}\r\n {...(locked ? { \"aria-hidden\": true } : {})}\r\n >\r\n {children}\r\n </div>\r\n {locked && (\r\n <LockOverlay\r\n onUnlock={unlock}\r\n overlayId={overlayId}\r\n overlayPosition={overlayPosition}\r\n />\r\n )}\r\n </LockContext.Provider>\r\n );\r\n};\r\n\r\nconst LockOverlay: React.FC<{\r\n onUnlock: (pin?: string) => void;\r\n overlayId?: string;\r\n overlayPosition?: \"fixed\" | \"absolute\";\r\n}> = ({\r\n onUnlock,\r\n overlayId = \"lock-overlay-root\",\r\n overlayPosition = \"fixed\",\r\n}) => {\r\n const [pinLen] = useState(4);\r\n const [val, setVal] = useState(\"\");\r\n\r\n return (\r\n <div\r\n id={overlayId}\r\n aria-modal=\"true\"\r\n role=\"dialog\"\r\n aria-label=\"Locked screen\"\r\n style={{\r\n position: overlayPosition,\r\n inset: 0,\r\n background: \"rgba(12, 14, 18, 0.85)\",\r\n backdropFilter: \"blur(4px)\",\r\n display: \"grid\",\r\n placeItems: \"center\",\r\n zIndex: 9999,\r\n }}\r\n >\r\n <div className=\"lockscreen-form\" style={{ width: 420, maxWidth: \"92vw\" }}>\r\n <div className=\"lock-icon-wrap\">\r\n <span className=\"lock-icon-box\"></span>\r\n </div>\r\n <h2>잠금됨</h2>\r\n <p>PIN 번호를 입력하세요</p>\r\n <div\r\n className=\"lock-ipt-wrap\"\r\n style={{ display: \"flex\", justifyContent: \"center\" }}\r\n >\r\n <Input.OTP\r\n mask={\"*\"}\r\n autoFocus\r\n length={pinLen}\r\n value={val}\r\n onChange={(v) => {\r\n const next = (v ?? \"\").replace(/\\D/g, \"\").slice(0, pinLen);\r\n setVal(next);\r\n if (next.length === pinLen) onUnlock(next);\r\n }}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["LockContext","createContext","useLock","ctx","useContext","ScreenProtectProvider","children","idleMs","onUnlock","persistLocked","storageKey","eventTarget","overlayScope","overlayId","overlayPosition","initialLocked","locked","setLocked","useState","idle","setIdle","isIdleEnabled","timerRef","useRef","lock","unlock","pin","resetTimer","doLock","useEffect","onActivity","opts","evts","target","stop","overlay","evs","guardTarget","t","value","useMemo","jsxs","jsx","LockOverlay","pinLen","val","setVal","Input","v","next"],"mappings":"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"}
1
+ {"version":3,"file":"ScreenProtectContext-3my4PHFa.js","sources":["../../src/provider/contexts/ScreenProtectContext.tsx"],"sourcesContent":["import { Input } from \"antd\";\r\nimport {\r\n createContext,\r\n FC,\r\n ReactNode,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from 'react';\r\n\r\n/**\r\n * ScreenProtectProvider\r\n * - 전역용(기본값): window 활동감지 + fixed 전체 오버레이\r\n * - 탭스코프용(옵션): eventTarget 활동감지 + absolute 탭 영역 오버레이\r\n */\r\n\r\n// ===================== Lock Context =====================\r\ntype LockContextValue = {\r\n locked: boolean;\r\n lock: () => void;\r\n unlock: (pin?: string) => Promise<void> | void;\r\n setIdleMs: (ms: number) => void;\r\n};\r\n\r\nconst LockContext = createContext<LockContextValue | null>(null);\r\n\r\nexport const useLock = () => {\r\n const ctx = useContext(LockContext);\r\n if (!ctx)\r\n throw new Error('useLock must be used within ScreenProtectProvider');\r\n return ctx;\r\n};\r\n\r\n// ===================== Provider =====================\r\nexport const ScreenProtectProvider: FC<{\r\n children: ReactNode;\r\n idleMs?: number;\r\n onUnlock?: (pin?: string) => Promise<boolean> | boolean;\r\n persistLocked?: boolean;\r\n storageKey?: string;\r\n\r\n /** ▼ 탭 스코프용 확장 옵션 */\r\n eventTarget?: EventTarget | null; // 활동 감지/가드 대상 (기본: window)\r\n overlayScope?: 'global' | 'scoped'; // 캡처가드 범위\r\n overlayId?: string; // 오버레이 DOM id\r\n overlayPosition?: 'fixed' | 'absolute'; // 오버레이 위치 (전역: fixed, 탭: absolute)\r\n}> = ({\r\n children,\r\n idleMs = 10_000,\r\n onUnlock,\r\n persistLocked = true,\r\n storageKey = 'inactivityLocked',\r\n eventTarget,\r\n overlayScope = 'global',\r\n overlayId = 'lock-overlay-root',\r\n overlayPosition = 'fixed',\r\n}) => {\r\n const initialLocked =\r\n persistLocked &&\r\n typeof window !== 'undefined' &&\r\n window.localStorage.getItem(storageKey) === '1';\r\n\r\n const [locked, setLocked] = useState(initialLocked);\r\n const [idle, setIdle] = useState(idleMs);\r\n const isIdleEnabled = Number.isFinite(idle) && idle > 0;\r\n const timerRef = useRef<number | null>(null);\r\n\r\n const lock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, '1');\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const unlock = async (pin?: string) => {\r\n if (onUnlock) {\r\n const ok = await onUnlock(pin);\r\n if (!ok) return;\r\n }\r\n try {\r\n if (persistLocked) window.localStorage.removeItem(storageKey);\r\n } catch {}\r\n setLocked(false);\r\n if (isIdleEnabled) resetTimer();\r\n };\r\n\r\n const doLock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, '1');\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const resetTimer = () => {\r\n if (!isIdleEnabled) return;\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n timerRef.current = window.setTimeout(() => {\r\n doLock();\r\n }, idle);\r\n };\r\n\r\n // 활동 감지: window → target(옵션)으로 스코프 전환 가능\r\n useEffect(() => {\r\n if (!isIdleEnabled) return;\r\n const onActivity = () => {\r\n if (!locked) resetTimer();\r\n };\r\n const opts = { passive: true } as AddEventListenerOptions;\r\n const evts = [\r\n 'pointermove',\r\n 'pointerdown',\r\n 'keydown',\r\n 'wheel',\r\n 'touchstart',\r\n ];\r\n\r\n const target = (eventTarget ?? window) as any;\r\n evts.forEach(e => target.addEventListener(e, onActivity, opts));\r\n resetTimer();\r\n\r\n return () => {\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n evts.forEach(e => target.removeEventListener(e, onActivity as any));\r\n };\r\n }, [idle, locked, eventTarget, isIdleEnabled]);\r\n\r\n // 잠금 중 캡처가드: 전역(global) 또는 스코프(scoped)로 범위 선택\r\n useEffect(() => {\r\n if (!locked) return;\r\n\r\n const stop = (e: Event) => {\r\n const overlay = document.getElementById(overlayId);\r\n if (overlay && overlay.contains(e.target as Node)) return; // 오버레이 내부는 통과\r\n e.stopPropagation();\r\n e.preventDefault();\r\n };\r\n\r\n const opts = { capture: true } as AddEventListenerOptions;\r\n const evs = [\r\n 'pointerdown',\r\n 'pointerup',\r\n 'pointermove',\r\n 'click',\r\n 'wheel',\r\n 'keydown',\r\n 'keyup',\r\n 'touchstart',\r\n 'touchmove',\r\n ];\r\n\r\n // 전역이면 window, 스코프면 eventTarget(없으면 window)\r\n const guardTarget = (\r\n overlayScope === 'scoped' ? eventTarget ?? window : window\r\n ) as any;\r\n evs.forEach(t => guardTarget.addEventListener(t, stop, opts));\r\n return () =>\r\n evs.forEach(t => guardTarget.removeEventListener(t, stop as any, opts));\r\n }, [locked, overlayScope, overlayId, eventTarget]);\r\n\r\n const value = useMemo(\r\n () => ({ locked, lock, unlock, setIdleMs: setIdle }),\r\n [locked]\r\n );\r\n\r\n return (\r\n <LockContext.Provider value={value}>\r\n <div\r\n style={{ width: '100%', height: '100%' }}\r\n {...(locked ? ({ inert: '' } as any) : {})}\r\n {...(locked ? { 'aria-hidden': true } : {})}\r\n >\r\n {children}\r\n </div>\r\n {locked && (\r\n <LockOverlay\r\n onUnlock={unlock}\r\n overlayId={overlayId}\r\n overlayPosition={overlayPosition}\r\n />\r\n )}\r\n </LockContext.Provider>\r\n );\r\n};\r\n\r\nconst LockOverlay: FC<{\r\n onUnlock: (pin?: string) => void;\r\n overlayId?: string;\r\n overlayPosition?: 'fixed' | 'absolute';\r\n}> = ({\r\n onUnlock,\r\n overlayId = 'lock-overlay-root',\r\n overlayPosition = 'fixed',\r\n}) => {\r\n const [pinLen] = useState(4);\r\n const [val, setVal] = useState('');\r\n\r\n return (\r\n <div\r\n id={overlayId}\r\n aria-modal='true'\r\n role='dialog'\r\n aria-label='Locked screen'\r\n style={{\r\n position: overlayPosition,\r\n inset: 0,\r\n background: 'rgba(12, 14, 18, 0.85)',\r\n backdropFilter: 'blur(4px)',\r\n display: 'grid',\r\n placeItems: 'center',\r\n zIndex: 9999,\r\n }}\r\n >\r\n <div className='lockscreen-form' style={{ width: 420, maxWidth: '92vw' }}>\r\n <div className='lock-icon-wrap'>\r\n <span className='lock-icon-box'></span>\r\n </div>\r\n <h2>잠금됨</h2>\r\n <p>PIN 번호를 입력하세요</p>\r\n <div\r\n className='lock-ipt-wrap'\r\n style={{ display: 'flex', justifyContent: 'center' }}\r\n >\r\n <Input.OTP\r\n mask={'*'}\r\n autoFocus\r\n length={pinLen}\r\n value={val}\r\n onChange={v => {\r\n const next = (v ?? '').replace(/\\D/g, '').slice(0, pinLen);\r\n setVal(next);\r\n if (next.length === pinLen) onUnlock(next);\r\n }}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["LockContext","createContext","useLock","ctx","useContext","ScreenProtectProvider","children","idleMs","onUnlock","persistLocked","storageKey","eventTarget","overlayScope","overlayId","overlayPosition","initialLocked","locked","setLocked","useState","idle","setIdle","isIdleEnabled","timerRef","useRef","lock","unlock","pin","resetTimer","doLock","useEffect","onActivity","opts","evts","target","stop","overlay","evs","guardTarget","t","value","useMemo","jsxs","jsx","LockOverlay","pinLen","val","setVal","Input","v","next"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenProtectContext-CVuXrJm6.cjs","sources":["../../src/provider/contexts/ScreenProtectContext.tsx"],"sourcesContent":["import { Input } from \"antd\";\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\n\r\n/**\r\n * ScreenProtectProvider\r\n * - 전역용(기본값): window 활동감지 + fixed 전체 오버레이\r\n * - 탭스코프용(옵션): eventTarget 활동감지 + absolute 탭 영역 오버레이\r\n */\r\n\r\n// ===================== Lock Context =====================\r\ntype LockContextValue = {\r\n locked: boolean;\r\n lock: () => void;\r\n unlock: (pin?: string) => Promise<void> | void;\r\n setIdleMs: (ms: number) => void;\r\n};\r\n\r\nconst LockContext = createContext<LockContextValue | null>(null);\r\n\r\nexport const useLock = () => {\r\n const ctx = useContext(LockContext);\r\n if (!ctx)\r\n throw new Error(\"useLock must be used within ScreenProtectProvider\");\r\n return ctx;\r\n};\r\n\r\n// ===================== Provider =====================\r\nexport const ScreenProtectProvider: React.FC<{\r\n children: React.ReactNode;\r\n idleMs?: number;\r\n onUnlock?: (pin?: string) => Promise<boolean> | boolean;\r\n persistLocked?: boolean;\r\n storageKey?: string;\r\n\r\n /** ▼ 탭 스코프용 확장 옵션 */\r\n eventTarget?: EventTarget | null; // 활동 감지/가드 대상 (기본: window)\r\n overlayScope?: \"global\" | \"scoped\"; // 캡처가드 범위\r\n overlayId?: string; // 오버레이 DOM id\r\n overlayPosition?: \"fixed\" | \"absolute\"; // 오버레이 위치 (전역: fixed, 탭: absolute)\r\n}> = ({\r\n children,\r\n idleMs = 10_000,\r\n onUnlock,\r\n persistLocked = true,\r\n storageKey = \"inactivityLocked\",\r\n eventTarget,\r\n overlayScope = \"global\",\r\n overlayId = \"lock-overlay-root\",\r\n overlayPosition = \"fixed\",\r\n}) => {\r\n const initialLocked =\r\n persistLocked &&\r\n typeof window !== \"undefined\" &&\r\n window.localStorage.getItem(storageKey) === \"1\";\r\n\r\n const [locked, setLocked] = useState(initialLocked);\r\n const [idle, setIdle] = useState(idleMs);\r\n const isIdleEnabled = Number.isFinite(idle) && idle > 0;\r\n const timerRef = useRef<number | null>(null);\r\n\r\n const lock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, \"1\");\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const unlock = async (pin?: string) => {\r\n if (onUnlock) {\r\n const ok = await onUnlock(pin);\r\n if (!ok) return;\r\n }\r\n try {\r\n if (persistLocked) window.localStorage.removeItem(storageKey);\r\n } catch {}\r\n setLocked(false);\r\n if (isIdleEnabled) resetTimer();\r\n };\r\n\r\n const doLock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, \"1\");\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const resetTimer = () => {\r\n if (!isIdleEnabled) return;\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n timerRef.current = window.setTimeout(() => {\r\n doLock();\r\n }, idle);\r\n };\r\n\r\n // 활동 감지: window → target(옵션)으로 스코프 전환 가능\r\n useEffect(() => {\r\n if (!isIdleEnabled) return;\r\n const onActivity = () => {\r\n if (!locked) resetTimer();\r\n };\r\n const opts = { passive: true } as AddEventListenerOptions;\r\n const evts = [\r\n \"pointermove\",\r\n \"pointerdown\",\r\n \"keydown\",\r\n \"wheel\",\r\n \"touchstart\",\r\n ];\r\n\r\n const target = (eventTarget ?? window) as any;\r\n evts.forEach((e) => target.addEventListener(e, onActivity, opts));\r\n resetTimer();\r\n\r\n return () => {\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n evts.forEach((e) => target.removeEventListener(e, onActivity as any));\r\n };\r\n }, [idle, locked, eventTarget, isIdleEnabled]);\r\n\r\n // 잠금 중 캡처가드: 전역(global) 또는 스코프(scoped)로 범위 선택\r\n useEffect(() => {\r\n if (!locked) return;\r\n\r\n const stop = (e: Event) => {\r\n const overlay = document.getElementById(overlayId);\r\n if (overlay && overlay.contains(e.target as Node)) return; // 오버레이 내부는 통과\r\n e.stopPropagation();\r\n e.preventDefault();\r\n };\r\n\r\n const opts = { capture: true } as AddEventListenerOptions;\r\n const evs = [\r\n \"pointerdown\",\r\n \"pointerup\",\r\n \"pointermove\",\r\n \"click\",\r\n \"wheel\",\r\n \"keydown\",\r\n \"keyup\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n ];\r\n\r\n // 전역이면 window, 스코프면 eventTarget(없으면 window)\r\n const guardTarget = (\r\n overlayScope === \"scoped\" ? eventTarget ?? window : window\r\n ) as any;\r\n evs.forEach((t) => guardTarget.addEventListener(t, stop, opts));\r\n return () =>\r\n evs.forEach((t) => guardTarget.removeEventListener(t, stop as any, opts));\r\n }, [locked, overlayScope, overlayId, eventTarget]);\r\n\r\n const value = useMemo(\r\n () => ({ locked, lock, unlock, setIdleMs: setIdle }),\r\n [locked]\r\n );\r\n\r\n return (\r\n <LockContext.Provider value={value}>\r\n <div\r\n style={{ width: \"100%\", height: \"100%\" }}\r\n {...(locked ? ({ inert: \"\" } as any) : {})}\r\n {...(locked ? { \"aria-hidden\": true } : {})}\r\n >\r\n {children}\r\n </div>\r\n {locked && (\r\n <LockOverlay\r\n onUnlock={unlock}\r\n overlayId={overlayId}\r\n overlayPosition={overlayPosition}\r\n />\r\n )}\r\n </LockContext.Provider>\r\n );\r\n};\r\n\r\nconst LockOverlay: React.FC<{\r\n onUnlock: (pin?: string) => void;\r\n overlayId?: string;\r\n overlayPosition?: \"fixed\" | \"absolute\";\r\n}> = ({\r\n onUnlock,\r\n overlayId = \"lock-overlay-root\",\r\n overlayPosition = \"fixed\",\r\n}) => {\r\n const [pinLen] = useState(4);\r\n const [val, setVal] = useState(\"\");\r\n\r\n return (\r\n <div\r\n id={overlayId}\r\n aria-modal=\"true\"\r\n role=\"dialog\"\r\n aria-label=\"Locked screen\"\r\n style={{\r\n position: overlayPosition,\r\n inset: 0,\r\n background: \"rgba(12, 14, 18, 0.85)\",\r\n backdropFilter: \"blur(4px)\",\r\n display: \"grid\",\r\n placeItems: \"center\",\r\n zIndex: 9999,\r\n }}\r\n >\r\n <div className=\"lockscreen-form\" style={{ width: 420, maxWidth: \"92vw\" }}>\r\n <div className=\"lock-icon-wrap\">\r\n <span className=\"lock-icon-box\"></span>\r\n </div>\r\n <h2>잠금됨</h2>\r\n <p>PIN 번호를 입력하세요</p>\r\n <div\r\n className=\"lock-ipt-wrap\"\r\n style={{ display: \"flex\", justifyContent: \"center\" }}\r\n >\r\n <Input.OTP\r\n mask={\"*\"}\r\n autoFocus\r\n length={pinLen}\r\n value={val}\r\n onChange={(v) => {\r\n const next = (v ?? \"\").replace(/\\D/g, \"\").slice(0, pinLen);\r\n setVal(next);\r\n if (next.length === pinLen) onUnlock(next);\r\n }}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["LockContext","createContext","useLock","ctx","useContext","ScreenProtectProvider","children","idleMs","onUnlock","persistLocked","storageKey","eventTarget","overlayScope","overlayId","overlayPosition","initialLocked","locked","setLocked","useState","idle","setIdle","isIdleEnabled","timerRef","useRef","lock","unlock","pin","resetTimer","doLock","useEffect","onActivity","opts","evts","target","stop","overlay","evs","guardTarget","t","value","useMemo","jsxs","jsx","LockOverlay","pinLen","val","setVal","Input","v","next"],"mappings":"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"}
1
+ {"version":3,"file":"ScreenProtectContext-CVuXrJm6.cjs","sources":["../../src/provider/contexts/ScreenProtectContext.tsx"],"sourcesContent":["import { Input } from \"antd\";\r\nimport {\r\n createContext,\r\n FC,\r\n ReactNode,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from 'react';\r\n\r\n/**\r\n * ScreenProtectProvider\r\n * - 전역용(기본값): window 활동감지 + fixed 전체 오버레이\r\n * - 탭스코프용(옵션): eventTarget 활동감지 + absolute 탭 영역 오버레이\r\n */\r\n\r\n// ===================== Lock Context =====================\r\ntype LockContextValue = {\r\n locked: boolean;\r\n lock: () => void;\r\n unlock: (pin?: string) => Promise<void> | void;\r\n setIdleMs: (ms: number) => void;\r\n};\r\n\r\nconst LockContext = createContext<LockContextValue | null>(null);\r\n\r\nexport const useLock = () => {\r\n const ctx = useContext(LockContext);\r\n if (!ctx)\r\n throw new Error('useLock must be used within ScreenProtectProvider');\r\n return ctx;\r\n};\r\n\r\n// ===================== Provider =====================\r\nexport const ScreenProtectProvider: FC<{\r\n children: ReactNode;\r\n idleMs?: number;\r\n onUnlock?: (pin?: string) => Promise<boolean> | boolean;\r\n persistLocked?: boolean;\r\n storageKey?: string;\r\n\r\n /** ▼ 탭 스코프용 확장 옵션 */\r\n eventTarget?: EventTarget | null; // 활동 감지/가드 대상 (기본: window)\r\n overlayScope?: 'global' | 'scoped'; // 캡처가드 범위\r\n overlayId?: string; // 오버레이 DOM id\r\n overlayPosition?: 'fixed' | 'absolute'; // 오버레이 위치 (전역: fixed, 탭: absolute)\r\n}> = ({\r\n children,\r\n idleMs = 10_000,\r\n onUnlock,\r\n persistLocked = true,\r\n storageKey = 'inactivityLocked',\r\n eventTarget,\r\n overlayScope = 'global',\r\n overlayId = 'lock-overlay-root',\r\n overlayPosition = 'fixed',\r\n}) => {\r\n const initialLocked =\r\n persistLocked &&\r\n typeof window !== 'undefined' &&\r\n window.localStorage.getItem(storageKey) === '1';\r\n\r\n const [locked, setLocked] = useState(initialLocked);\r\n const [idle, setIdle] = useState(idleMs);\r\n const isIdleEnabled = Number.isFinite(idle) && idle > 0;\r\n const timerRef = useRef<number | null>(null);\r\n\r\n const lock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, '1');\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const unlock = async (pin?: string) => {\r\n if (onUnlock) {\r\n const ok = await onUnlock(pin);\r\n if (!ok) return;\r\n }\r\n try {\r\n if (persistLocked) window.localStorage.removeItem(storageKey);\r\n } catch {}\r\n setLocked(false);\r\n if (isIdleEnabled) resetTimer();\r\n };\r\n\r\n const doLock = () => {\r\n try {\r\n if (persistLocked) window.localStorage.setItem(storageKey, '1');\r\n } catch {}\r\n setLocked(true);\r\n };\r\n\r\n const resetTimer = () => {\r\n if (!isIdleEnabled) return;\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n timerRef.current = window.setTimeout(() => {\r\n doLock();\r\n }, idle);\r\n };\r\n\r\n // 활동 감지: window → target(옵션)으로 스코프 전환 가능\r\n useEffect(() => {\r\n if (!isIdleEnabled) return;\r\n const onActivity = () => {\r\n if (!locked) resetTimer();\r\n };\r\n const opts = { passive: true } as AddEventListenerOptions;\r\n const evts = [\r\n 'pointermove',\r\n 'pointerdown',\r\n 'keydown',\r\n 'wheel',\r\n 'touchstart',\r\n ];\r\n\r\n const target = (eventTarget ?? window) as any;\r\n evts.forEach(e => target.addEventListener(e, onActivity, opts));\r\n resetTimer();\r\n\r\n return () => {\r\n if (timerRef.current) window.clearTimeout(timerRef.current);\r\n evts.forEach(e => target.removeEventListener(e, onActivity as any));\r\n };\r\n }, [idle, locked, eventTarget, isIdleEnabled]);\r\n\r\n // 잠금 중 캡처가드: 전역(global) 또는 스코프(scoped)로 범위 선택\r\n useEffect(() => {\r\n if (!locked) return;\r\n\r\n const stop = (e: Event) => {\r\n const overlay = document.getElementById(overlayId);\r\n if (overlay && overlay.contains(e.target as Node)) return; // 오버레이 내부는 통과\r\n e.stopPropagation();\r\n e.preventDefault();\r\n };\r\n\r\n const opts = { capture: true } as AddEventListenerOptions;\r\n const evs = [\r\n 'pointerdown',\r\n 'pointerup',\r\n 'pointermove',\r\n 'click',\r\n 'wheel',\r\n 'keydown',\r\n 'keyup',\r\n 'touchstart',\r\n 'touchmove',\r\n ];\r\n\r\n // 전역이면 window, 스코프면 eventTarget(없으면 window)\r\n const guardTarget = (\r\n overlayScope === 'scoped' ? eventTarget ?? window : window\r\n ) as any;\r\n evs.forEach(t => guardTarget.addEventListener(t, stop, opts));\r\n return () =>\r\n evs.forEach(t => guardTarget.removeEventListener(t, stop as any, opts));\r\n }, [locked, overlayScope, overlayId, eventTarget]);\r\n\r\n const value = useMemo(\r\n () => ({ locked, lock, unlock, setIdleMs: setIdle }),\r\n [locked]\r\n );\r\n\r\n return (\r\n <LockContext.Provider value={value}>\r\n <div\r\n style={{ width: '100%', height: '100%' }}\r\n {...(locked ? ({ inert: '' } as any) : {})}\r\n {...(locked ? { 'aria-hidden': true } : {})}\r\n >\r\n {children}\r\n </div>\r\n {locked && (\r\n <LockOverlay\r\n onUnlock={unlock}\r\n overlayId={overlayId}\r\n overlayPosition={overlayPosition}\r\n />\r\n )}\r\n </LockContext.Provider>\r\n );\r\n};\r\n\r\nconst LockOverlay: FC<{\r\n onUnlock: (pin?: string) => void;\r\n overlayId?: string;\r\n overlayPosition?: 'fixed' | 'absolute';\r\n}> = ({\r\n onUnlock,\r\n overlayId = 'lock-overlay-root',\r\n overlayPosition = 'fixed',\r\n}) => {\r\n const [pinLen] = useState(4);\r\n const [val, setVal] = useState('');\r\n\r\n return (\r\n <div\r\n id={overlayId}\r\n aria-modal='true'\r\n role='dialog'\r\n aria-label='Locked screen'\r\n style={{\r\n position: overlayPosition,\r\n inset: 0,\r\n background: 'rgba(12, 14, 18, 0.85)',\r\n backdropFilter: 'blur(4px)',\r\n display: 'grid',\r\n placeItems: 'center',\r\n zIndex: 9999,\r\n }}\r\n >\r\n <div className='lockscreen-form' style={{ width: 420, maxWidth: '92vw' }}>\r\n <div className='lock-icon-wrap'>\r\n <span className='lock-icon-box'></span>\r\n </div>\r\n <h2>잠금됨</h2>\r\n <p>PIN 번호를 입력하세요</p>\r\n <div\r\n className='lock-ipt-wrap'\r\n style={{ display: 'flex', justifyContent: 'center' }}\r\n >\r\n <Input.OTP\r\n mask={'*'}\r\n autoFocus\r\n length={pinLen}\r\n value={val}\r\n onChange={v => {\r\n const next = (v ?? '').replace(/\\D/g, '').slice(0, pinLen);\r\n setVal(next);\r\n if (next.length === pinLen) onUnlock(next);\r\n }}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["LockContext","createContext","useLock","ctx","useContext","ScreenProtectProvider","children","idleMs","onUnlock","persistLocked","storageKey","eventTarget","overlayScope","overlayId","overlayPosition","initialLocked","locked","setLocked","useState","idle","setIdle","isIdleEnabled","timerRef","useRef","lock","unlock","pin","resetTimer","doLock","useEffect","onActivity","opts","evts","target","stop","overlay","evs","guardTarget","t","value","useMemo","jsxs","jsx","LockOverlay","pinLen","val","setVal","Input","v","next"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchBoxContext-DwFDOyYG.cjs","sources":["../../src/provider/contexts/ServiceCodeContext.tsx","../../src/provider/contexts/SearchBoxContext.tsx"],"sourcesContent":["import React, { createContext, useContext, ReactNode, useEffect } from 'react';\r\nimport { ServiceCodeKey, setServiceCodeOverrides } from '../../utils/serviceConfig';\r\n\r\n// 서비스코드 설정을 위한 Context 타입\r\ninterface ServiceCodeContextType {\r\n serviceCodes: Partial<Record<ServiceCodeKey, string>>;\r\n getServiceCode: (key: ServiceCodeKey) => string;\r\n}\r\n\r\n// 기본 서비스코드 정의\r\nconst DEFAULT_SERVICE_CODES = {\r\n // 권한 관련\r\n AUTH_BTNS: 'SCMSIGN00202', // 버튼 권한 조회\r\n AUTH_MENU: 'SCMSIGN00201', // 메뉴 권한 조회\r\n SRCH_CODE: 'SCMSIGN00301', // 코드 조회\r\n \r\n // 팝업 관련\r\n SRCH_POPU: 'SCMPOPU00101', // 팝업 조회\r\n \r\n // 즐겨찾기 관련\r\n AUTH_BMRK: 'SCMBMRK00101', // 즐겨찾기 관리\r\n} as const;\r\n\r\n// Context 생성\r\nconst ServiceCodeContext = createContext<ServiceCodeContextType | null>(null);\r\n\r\n// Provider Props 타입\r\ninterface ServiceCodeProviderProps {\r\n children: ReactNode;\r\n /**\r\n * 서비스코드 오버라이드 설정\r\n * 외부 프로젝트에서 기본 서비스코드를 재정의할 수 있습니다.\r\n * \r\n * @example\r\n * ```tsx\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * SRCH_CODE: 'CUSTOM_SRCH_CODE',\r\n * SRCH_POPU: 'CUSTOM_SRCH_POPU_CODE',\r\n * AUTH_BMRK: 'CUSTOM_AUTH_BMRK_CODE',\r\n * }}\r\n * >\r\n * {children}\r\n * </ServiceCodeProvider>\r\n * ```\r\n * \r\n * @description\r\n * - AUTH_BTNS: 버튼 권한 조회 서비스코드\r\n * - AUTH_MENU: 메뉴 권한 조회 서비스코드 \r\n * - SRCH_CODE: 코드 조회 서비스코드\r\n * - SRCH_POPU: 팝업 조회 서비스코드\r\n * - AUTH_BMRK: 즐겨찾기 관리 서비스코드\r\n * \r\n * 설정하지 않은 서비스코드는 기본값을 사용합니다.\r\n */\r\n serviceCodes?: Partial<Record<ServiceCodeKey, string>>;\r\n}\r\n\r\n/**\r\n * 서비스코드 Provider 컴포넌트\r\n * 외부 프로젝트에서 서비스코드를 설정할 수 있도록 함\r\n * \r\n * @example\r\n * ```tsx\r\n * import { ServiceCodeProvider } from '@bwg/core/provider';\r\n * \r\n * function App() {\r\n * return (\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </ServiceCodeProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const ServiceCodeProvider: React.FC<ServiceCodeProviderProps> = ({\r\n children,\r\n serviceCodes = {},\r\n}) => {\r\n // serviceCodes가 변경될 때마다 serviceConfig.ts의 오버라이드를 업데이트\r\n useEffect(() => {\r\n setServiceCodeOverrides(serviceCodes);\r\n }, [serviceCodes]);\r\n\r\n // 서비스코드 가져오기 함수\r\n const getServiceCode = (key: ServiceCodeKey): string => {\r\n // 1. Provider에서 설정된 값 우선 확인\r\n if (serviceCodes[key] && serviceCodes[key]!.trim() !== '') {\r\n console.log(`🔧 Provider 설정 사용: ${key} = ${serviceCodes[key]}`);\r\n return serviceCodes[key]!;\r\n }\r\n\r\n // 2. 기본값 사용\r\n const defaultValue = DEFAULT_SERVICE_CODES[key];\r\n console.log(`🔧 기본값 사용: ${key} = ${defaultValue}`);\r\n return defaultValue;\r\n };\r\n\r\n const contextValue: ServiceCodeContextType = {\r\n serviceCodes,\r\n getServiceCode,\r\n };\r\n\r\n return (\r\n <ServiceCodeContext.Provider value={contextValue}>\r\n {children}\r\n </ServiceCodeContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * 서비스코드 Context를 사용하는 Hook\r\n * \r\n * @example\r\n * ```tsx\r\n * const { getServiceCode, serviceCodes } = useServiceCode();\r\n * const authBtnsCode = getServiceCode('AUTH_BTNS');\r\n * ```\r\n */\r\nexport const useServiceCode = (): ServiceCodeContextType => {\r\n const context = useContext(ServiceCodeContext);\r\n if (!context) {\r\n throw new Error('useServiceCode must be used within a ServiceCodeProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * 특정 서비스코드를 가져오는 Hook\r\n * \r\n * @param key - 서비스코드 키\r\n * @returns 실제 서비스코드 값\r\n * \r\n * @example\r\n * ```tsx\r\n * const authBtnsCode = useServiceCodeValue('AUTH_BTNS');\r\n * const authMenuCode = useServiceCodeValue('AUTH_MENU');\r\n * ```\r\n */\r\nexport const useServiceCodeValue = (key: ServiceCodeKey): string => {\r\n const { getServiceCode } = useServiceCode();\r\n return getServiceCode(key);\r\n};\r\n\r\n/**\r\n * 모든 서비스코드를 가져오는 Hook\r\n * \r\n * @returns 모든 서비스코드 객체\r\n * \r\n * @example\r\n * ```tsx\r\n * const allServiceCodes = useAllServiceCodes();\r\n * console.log(allServiceCodes.AUTH_BTNS); // 'SCMSIGN00202' 또는 커스텀 값\r\n * ```\r\n */\r\nexport const useAllServiceCodes = (): Record<ServiceCodeKey, string> => {\r\n const { getServiceCode } = useServiceCode();\r\n const result = {} as Record<ServiceCodeKey, string>;\r\n \r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n result[key] = getServiceCode(key);\r\n }\r\n \r\n return result;\r\n};\r\n\r\n/**\r\n * 서비스코드 설정을 로그로 출력하는 Hook\r\n * 개발 시 현재 설정된 서비스코드를 확인할 수 있습니다.\r\n * \r\n * @example\r\n * ```tsx\r\n * useLogServiceCodeConfig();\r\n * // 콘솔에 현재 설정된 모든 서비스코드가 출력됩니다.\r\n * ```\r\n */\r\nexport const useLogServiceCodeConfig = (): void => {\r\n const { getServiceCode } = useServiceCode();\r\n \r\n console.log('🔧 bwg-core 서비스코드 설정:');\r\n console.log('📋 Provider 설정 > 기본값 순서로 확인');\r\n \r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n const value = getServiceCode(key);\r\n console.log(` ${key}: ${value}`);\r\n }\r\n};\r\n\r\n// 타입 내보내기\r\nexport type { ServiceCodeKey };\r\n","import React, { createContext, useContext, useRef, ReactNode } from 'react';\r\nimport { SearchBoxRef } from '../../components/common/SearchBox';\r\n\r\n// SearchBox Context 타입\r\ninterface SearchBoxContextType {\r\n searchBoxRef: React.RefObject<SearchBoxRef> | null;\r\n getFormData: () => any;\r\n setFormData: (data: any) => void;\r\n resetForm: () => void;\r\n validateForm: () => Promise<any>;\r\n}\r\n\r\n// Context 생성\r\nconst SearchBoxContext = createContext<SearchBoxContextType | null>(null);\r\n\r\n// Provider Props\r\ninterface SearchBoxProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n// Provider 컴포넌트\r\nexport const SearchBoxProvider: React.FC<SearchBoxProviderProps> = ({\r\n children,\r\n}) => {\r\n const searchBoxRef = useRef<SearchBoxRef>(null);\r\n\r\n const getFormData = () => {\r\n return searchBoxRef.current?.getFormData() || {};\r\n };\r\n\r\n const setFormData = (data: any) => {\r\n searchBoxRef.current?.setFormData(data);\r\n };\r\n\r\n const resetForm = () => {\r\n searchBoxRef.current?.resetForm();\r\n };\r\n\r\n const validateForm = async () => {\r\n return (\r\n (await searchBoxRef.current?.validateForm()) || {\r\n success: false,\r\n error: null,\r\n }\r\n );\r\n };\r\n\r\n const value: SearchBoxContextType = {\r\n searchBoxRef,\r\n getFormData,\r\n setFormData,\r\n resetForm,\r\n validateForm,\r\n };\r\n\r\n return (\r\n <SearchBoxContext.Provider value={value}>\r\n {children}\r\n </SearchBoxContext.Provider>\r\n );\r\n};\r\n\r\n// Hook\r\nexport const useSearchBox = () => {\r\n const context = useContext(SearchBoxContext);\r\n if (!context) {\r\n throw new Error('useSearchBox must be used within a SearchBoxProvider');\r\n }\r\n return context;\r\n};\r\n"],"names":["DEFAULT_SERVICE_CODES","ServiceCodeContext","createContext","ServiceCodeProvider","children","serviceCodes","useEffect","setServiceCodeOverrides","contextValue","key","defaultValue","useServiceCode","context","useContext","useServiceCodeValue","getServiceCode","useAllServiceCodes","result","useLogServiceCodeConfig","value","SearchBoxContext","SearchBoxProvider","searchBoxRef","useRef","data","jsx","useSearchBox"],"mappings":"mHAUMA,EAAwB,CAE5B,UAAW,eACX,UAAW,eACX,UAAW,eAGX,UAAW,eAGX,UAAW,cACb,EAGMC,EAAqBC,EAAAA,cAA6C,IAAI,EA0D/DC,EAA0D,CAAC,CACtE,SAAAC,EACA,aAAAC,EAAe,CAAA,CACjB,IAAM,CAEJC,EAAAA,UAAU,IAAM,CACdC,EAAAA,wBAAwBF,CAAY,CACtC,EAAG,CAACA,CAAY,CAAC,EAgBjB,MAAMG,EAAuC,CAC3C,aAAAH,EACA,eAfsBI,GAAgC,CAEtD,GAAIJ,EAAaI,CAAG,GAAKJ,EAAaI,CAAG,EAAG,KAAA,IAAW,GACrD,eAAQ,IAAI,sBAAsBA,CAAG,MAAMJ,EAAaI,CAAG,CAAC,EAAE,EACvDJ,EAAaI,CAAG,EAIzB,MAAMC,EAAeV,EAAsBS,CAAG,EAC9C,eAAQ,IAAI,cAAcA,CAAG,MAAMC,CAAY,EAAE,EAC1CA,CACT,CAIE,EAGF,+BACGT,EAAmB,SAAnB,CAA4B,MAAOO,EACjC,SAAAJ,EACH,CAEJ,EAWaO,EAAiB,IAA8B,CAC1D,MAAMC,EAAUC,EAAAA,WAAWZ,CAAkB,EAC7C,GAAI,CAACW,EACH,MAAM,IAAI,MAAM,0DAA0D,EAE5E,OAAOA,CACT,EAcaE,EAAuBL,GAAgC,CAClE,KAAM,CAAE,eAAAM,CAAA,EAAmBJ,EAAA,EAC3B,OAAOI,EAAeN,CAAG,CAC3B,EAaaO,EAAqB,IAAsC,CACtE,KAAM,CAAE,eAAAD,CAAA,EAAmBJ,EAAA,EACrBM,EAAS,CAAA,EAEf,UAAWR,KAAO,OAAO,KAAKT,CAAqB,EACjDiB,EAAOR,CAAG,EAAIM,EAAeN,CAAG,EAGlC,OAAOQ,CACT,EAYaC,EAA0B,IAAY,CACjD,KAAM,CAAE,eAAAH,CAAA,EAAmBJ,EAAA,EAE3B,QAAQ,IAAI,uBAAuB,EACnC,QAAQ,IAAI,6BAA6B,EAEzC,UAAWF,KAAO,OAAO,KAAKT,CAAqB,EAAuB,CACxE,MAAMmB,EAAQJ,EAAeN,CAAG,EAChC,QAAQ,IAAI,KAAKA,CAAG,KAAKU,CAAK,EAAE,CAClC,CACF,ECpLMC,EAAmBlB,EAAAA,cAA2C,IAAI,EAQ3DmB,EAAsD,CAAC,CAClE,SAAAjB,CACF,IAAM,CACJ,MAAMkB,EAAeC,EAAAA,OAAqB,IAAI,EAuBxCJ,EAA8B,CAClC,aAAAG,EACA,YAvBkB,IACXA,EAAa,SAAS,YAAA,GAAiB,CAAA,EAuB9C,YApBmBE,GAAc,CACjCF,EAAa,SAAS,YAAYE,CAAI,CACxC,EAmBE,UAjBgB,IAAM,CACtBF,EAAa,SAAS,UAAA,CACxB,EAgBE,aAdmB,SAEhB,MAAMA,EAAa,SAAS,gBAAmB,CAC9C,QAAS,GACT,MAAO,IAAA,CAUX,EAGF,OACEG,EAAAA,kBAAAA,IAACL,EAAiB,SAAjB,CAA0B,MAAAD,EACxB,SAAAf,CAAA,CACH,CAEJ,EAGasB,EAAe,IAAM,CAChC,MAAMd,EAAUC,EAAAA,WAAWO,CAAgB,EAC3C,GAAI,CAACR,EACH,MAAM,IAAI,MAAM,sDAAsD,EAExE,OAAOA,CACT"}
1
+ {"version":3,"file":"SearchBoxContext-DwFDOyYG.cjs","sources":["../../src/provider/contexts/ServiceCodeContext.tsx","../../src/provider/contexts/SearchBoxContext.tsx"],"sourcesContent":["import { createContext, FC, ReactNode, useContext, useEffect } from 'react';\r\nimport {\r\n ServiceCodeKey,\r\n setServiceCodeOverrides,\r\n} from '../../utils/serviceConfig';\r\n\r\n// 서비스코드 설정을 위한 Context 타입\r\ninterface ServiceCodeContextType {\r\n serviceCodes: Partial<Record<ServiceCodeKey, string>>;\r\n getServiceCode: (key: ServiceCodeKey) => string;\r\n}\r\n\r\n// 기본 서비스코드 정의\r\nconst DEFAULT_SERVICE_CODES = {\r\n // 권한 관련\r\n AUTH_BTNS: 'SCMSIGN00202', // 버튼 권한 조회\r\n AUTH_MENU: 'SCMSIGN00201', // 메뉴 권한 조회\r\n SRCH_CODE: 'SCMSIGN00301', // 코드 조회\r\n\r\n // 팝업 관련\r\n SRCH_POPU: 'SCMPOPU00101', // 팝업 조회\r\n\r\n // 즐겨찾기 관련\r\n AUTH_BMRK: 'SCMBMRK00101', // 즐겨찾기 관리\r\n} as const;\r\n\r\n// Context 생성\r\nconst ServiceCodeContext = createContext<ServiceCodeContextType | null>(null);\r\n\r\n// Provider Props 타입\r\ninterface ServiceCodeProviderProps {\r\n children: ReactNode;\r\n /**\r\n * 서비스코드 오버라이드 설정\r\n * 외부 프로젝트에서 기본 서비스코드를 재정의할 수 있습니다.\r\n *\r\n * @example\r\n * ```tsx\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * SRCH_CODE: 'CUSTOM_SRCH_CODE',\r\n * SRCH_POPU: 'CUSTOM_SRCH_POPU_CODE',\r\n * AUTH_BMRK: 'CUSTOM_AUTH_BMRK_CODE',\r\n * }}\r\n * >\r\n * {children}\r\n * </ServiceCodeProvider>\r\n * ```\r\n *\r\n * @description\r\n * - AUTH_BTNS: 버튼 권한 조회 서비스코드\r\n * - AUTH_MENU: 메뉴 권한 조회 서비스코드\r\n * - SRCH_CODE: 코드 조회 서비스코드\r\n * - SRCH_POPU: 팝업 조회 서비스코드\r\n * - AUTH_BMRK: 즐겨찾기 관리 서비스코드\r\n *\r\n * 설정하지 않은 서비스코드는 기본값을 사용합니다.\r\n */\r\n serviceCodes?: Partial<Record<ServiceCodeKey, string>>;\r\n}\r\n\r\n/**\r\n * 서비스코드 Provider 컴포넌트\r\n * 외부 프로젝트에서 서비스코드를 설정할 수 있도록 함\r\n *\r\n * @example\r\n * ```tsx\r\n * import { ServiceCodeProvider } from '@bwg/core/provider';\r\n *\r\n * function App() {\r\n * return (\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </ServiceCodeProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const ServiceCodeProvider: FC<ServiceCodeProviderProps> = ({\r\n children,\r\n serviceCodes = {},\r\n}) => {\r\n // serviceCodes가 변경될 때마다 serviceConfig.ts의 오버라이드를 업데이트\r\n useEffect(() => {\r\n setServiceCodeOverrides(serviceCodes);\r\n }, [serviceCodes]);\r\n\r\n // 서비스코드 가져오기 함수\r\n const getServiceCode = (key: ServiceCodeKey): string => {\r\n // 1. Provider에서 설정된 값 우선 확인\r\n if (serviceCodes[key] && serviceCodes[key]!.trim() !== '') {\r\n console.log(`🔧 Provider 설정 사용: ${key} = ${serviceCodes[key]}`);\r\n return serviceCodes[key]!;\r\n }\r\n\r\n // 2. 기본값 사용\r\n const defaultValue = DEFAULT_SERVICE_CODES[key];\r\n console.log(`🔧 기본값 사용: ${key} = ${defaultValue}`);\r\n return defaultValue;\r\n };\r\n\r\n const contextValue: ServiceCodeContextType = {\r\n serviceCodes,\r\n getServiceCode,\r\n };\r\n\r\n return (\r\n <ServiceCodeContext.Provider value={contextValue}>\r\n {children}\r\n </ServiceCodeContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * 서비스코드 Context를 사용하는 Hook\r\n *\r\n * @example\r\n * ```tsx\r\n * const { getServiceCode, serviceCodes } = useServiceCode();\r\n * const authBtnsCode = getServiceCode('AUTH_BTNS');\r\n * ```\r\n */\r\nexport const useServiceCode = (): ServiceCodeContextType => {\r\n const context = useContext(ServiceCodeContext);\r\n if (!context) {\r\n throw new Error('useServiceCode must be used within a ServiceCodeProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * 특정 서비스코드를 가져오는 Hook\r\n *\r\n * @param key - 서비스코드 키\r\n * @returns 실제 서비스코드 값\r\n *\r\n * @example\r\n * ```tsx\r\n * const authBtnsCode = useServiceCodeValue('AUTH_BTNS');\r\n * const authMenuCode = useServiceCodeValue('AUTH_MENU');\r\n * ```\r\n */\r\nexport const useServiceCodeValue = (key: ServiceCodeKey): string => {\r\n const { getServiceCode } = useServiceCode();\r\n return getServiceCode(key);\r\n};\r\n\r\n/**\r\n * 모든 서비스코드를 가져오는 Hook\r\n *\r\n * @returns 모든 서비스코드 객체\r\n *\r\n * @example\r\n * ```tsx\r\n * const allServiceCodes = useAllServiceCodes();\r\n * console.log(allServiceCodes.AUTH_BTNS); // 'SCMSIGN00202' 또는 커스텀 값\r\n * ```\r\n */\r\nexport const useAllServiceCodes = (): Record<ServiceCodeKey, string> => {\r\n const { getServiceCode } = useServiceCode();\r\n const result = {} as Record<ServiceCodeKey, string>;\r\n\r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n result[key] = getServiceCode(key);\r\n }\r\n\r\n return result;\r\n};\r\n\r\n/**\r\n * 서비스코드 설정을 로그로 출력하는 Hook\r\n * 개발 시 현재 설정된 서비스코드를 확인할 수 있습니다.\r\n *\r\n * @example\r\n * ```tsx\r\n * useLogServiceCodeConfig();\r\n * // 콘솔에 현재 설정된 모든 서비스코드가 출력됩니다.\r\n * ```\r\n */\r\nexport const useLogServiceCodeConfig = (): void => {\r\n const { getServiceCode } = useServiceCode();\r\n\r\n console.log('🔧 bwg-core 서비스코드 설정:');\r\n console.log('📋 Provider 설정 > 기본값 순서로 확인');\r\n\r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n const value = getServiceCode(key);\r\n console.log(` ${key}: ${value}`);\r\n }\r\n};\r\n\r\n// 타입 내보내기\r\nexport type { ServiceCodeKey };\r\n","import {\r\n createContext,\r\n FC,\r\n ReactNode,\r\n RefObject,\r\n useContext,\r\n useRef,\r\n} from 'react';\r\nimport { SearchBoxRef } from '../../components/common/SearchBox';\r\n\r\n// SearchBox Context 타입\r\ninterface SearchBoxContextType {\r\n searchBoxRef: RefObject<SearchBoxRef> | null;\r\n getFormData: () => any;\r\n setFormData: (data: any) => void;\r\n resetForm: () => void;\r\n validateForm: () => Promise<any>;\r\n}\r\n\r\n// Context 생성\r\nconst SearchBoxContext = createContext<SearchBoxContextType | null>(null);\r\n\r\n// Provider Props\r\ninterface SearchBoxProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n// Provider 컴포넌트\r\nexport const SearchBoxProvider: FC<SearchBoxProviderProps> = ({ children }) => {\r\n const searchBoxRef = useRef<SearchBoxRef>(null);\r\n\r\n const getFormData = () => {\r\n return searchBoxRef.current?.getFormData() || {};\r\n };\r\n\r\n const setFormData = (data: any) => {\r\n searchBoxRef.current?.setFormData(data);\r\n };\r\n\r\n const resetForm = () => {\r\n searchBoxRef.current?.resetForm();\r\n };\r\n\r\n const validateForm = async () => {\r\n return (\r\n (await searchBoxRef.current?.validateForm()) || {\r\n success: false,\r\n error: null,\r\n }\r\n );\r\n };\r\n\r\n const value: SearchBoxContextType = {\r\n searchBoxRef,\r\n getFormData,\r\n setFormData,\r\n resetForm,\r\n validateForm,\r\n };\r\n\r\n return (\r\n <SearchBoxContext.Provider value={value}>\r\n {children}\r\n </SearchBoxContext.Provider>\r\n );\r\n};\r\n\r\n// Hook\r\nexport const useSearchBox = () => {\r\n const context = useContext(SearchBoxContext);\r\n if (!context) {\r\n throw new Error('useSearchBox must be used within a SearchBoxProvider');\r\n }\r\n return context;\r\n};\r\n"],"names":["DEFAULT_SERVICE_CODES","ServiceCodeContext","createContext","ServiceCodeProvider","children","serviceCodes","useEffect","setServiceCodeOverrides","contextValue","key","defaultValue","useServiceCode","context","useContext","useServiceCodeValue","getServiceCode","useAllServiceCodes","result","useLogServiceCodeConfig","value","SearchBoxContext","SearchBoxProvider","searchBoxRef","useRef","data","jsx","useSearchBox"],"mappings":"mHAaMA,EAAwB,CAE5B,UAAW,eACX,UAAW,eACX,UAAW,eAGX,UAAW,eAGX,UAAW,cACb,EAGMC,EAAqBC,EAAAA,cAA6C,IAAI,EA0D/DC,EAAoD,CAAC,CAChE,SAAAC,EACA,aAAAC,EAAe,CAAA,CACjB,IAAM,CAEJC,EAAAA,UAAU,IAAM,CACdC,EAAAA,wBAAwBF,CAAY,CACtC,EAAG,CAACA,CAAY,CAAC,EAgBjB,MAAMG,EAAuC,CAC3C,aAAAH,EACA,eAfsBI,GAAgC,CAEtD,GAAIJ,EAAaI,CAAG,GAAKJ,EAAaI,CAAG,EAAG,KAAA,IAAW,GACrD,eAAQ,IAAI,sBAAsBA,CAAG,MAAMJ,EAAaI,CAAG,CAAC,EAAE,EACvDJ,EAAaI,CAAG,EAIzB,MAAMC,EAAeV,EAAsBS,CAAG,EAC9C,eAAQ,IAAI,cAAcA,CAAG,MAAMC,CAAY,EAAE,EAC1CA,CACT,CAIE,EAGF,+BACGT,EAAmB,SAAnB,CAA4B,MAAOO,EACjC,SAAAJ,EACH,CAEJ,EAWaO,EAAiB,IAA8B,CAC1D,MAAMC,EAAUC,EAAAA,WAAWZ,CAAkB,EAC7C,GAAI,CAACW,EACH,MAAM,IAAI,MAAM,0DAA0D,EAE5E,OAAOA,CACT,EAcaE,EAAuBL,GAAgC,CAClE,KAAM,CAAE,eAAAM,CAAA,EAAmBJ,EAAA,EAC3B,OAAOI,EAAeN,CAAG,CAC3B,EAaaO,EAAqB,IAAsC,CACtE,KAAM,CAAE,eAAAD,CAAA,EAAmBJ,EAAA,EACrBM,EAAS,CAAA,EAEf,UAAWR,KAAO,OAAO,KAAKT,CAAqB,EACjDiB,EAAOR,CAAG,EAAIM,EAAeN,CAAG,EAGlC,OAAOQ,CACT,EAYaC,EAA0B,IAAY,CACjD,KAAM,CAAE,eAAAH,CAAA,EAAmBJ,EAAA,EAE3B,QAAQ,IAAI,uBAAuB,EACnC,QAAQ,IAAI,6BAA6B,EAEzC,UAAWF,KAAO,OAAO,KAAKT,CAAqB,EAAuB,CACxE,MAAMmB,EAAQJ,EAAeN,CAAG,EAChC,QAAQ,IAAI,KAAKA,CAAG,KAAKU,CAAK,EAAE,CAClC,CACF,EChLMC,EAAmBlB,EAAAA,cAA2C,IAAI,EAQ3DmB,EAAgD,CAAC,CAAE,SAAAjB,KAAe,CAC7E,MAAMkB,EAAeC,EAAAA,OAAqB,IAAI,EAuBxCJ,EAA8B,CAClC,aAAAG,EACA,YAvBkB,IACXA,EAAa,SAAS,YAAA,GAAiB,CAAA,EAuB9C,YApBmBE,GAAc,CACjCF,EAAa,SAAS,YAAYE,CAAI,CACxC,EAmBE,UAjBgB,IAAM,CACtBF,EAAa,SAAS,UAAA,CACxB,EAgBE,aAdmB,SAEhB,MAAMA,EAAa,SAAS,gBAAmB,CAC9C,QAAS,GACT,MAAO,IAAA,CAUX,EAGF,OACEG,EAAAA,kBAAAA,IAACL,EAAiB,SAAjB,CAA0B,MAAAD,EACxB,SAAAf,CAAA,CACH,CAEJ,EAGasB,EAAe,IAAM,CAChC,MAAMd,EAAUC,EAAAA,WAAWO,CAAgB,EAC3C,GAAI,CAACR,EACH,MAAM,IAAI,MAAM,sDAAsD,EAExE,OAAOA,CACT"}
@@ -1,6 +1,6 @@
1
1
  import { j as u } from "./jsx-runtime-Dpn_P65e.js";
2
2
  import { useEffect as m, createContext as i, useContext as S, useRef as x } from "react";
3
- import { ak as f } from "./apiUtils-DxzLqPhU.js";
3
+ import { ak as f } from "./apiUtils-DSwE62oG.js";
4
4
  const n = {
5
5
  // 권한 관련
6
6
  AUTH_BTNS: "SCMSIGN00202",
@@ -52,9 +52,7 @@ const n = {
52
52
  const t = o(e);
53
53
  console.log(` ${e}: ${t}`);
54
54
  }
55
- }, d = i(null), w = ({
56
- children: o
57
- }) => {
55
+ }, d = i(null), w = ({ children: o }) => {
58
56
  const e = x(null), v = {
59
57
  searchBoxRef: e,
60
58
  getFormData: () => e.current?.getFormData() || {},
@@ -85,4 +83,4 @@ export {
85
83
  D as e,
86
84
  M as u
87
85
  };
88
- //# sourceMappingURL=SearchBoxContext-BCvEYyFk.js.map
86
+ //# sourceMappingURL=SearchBoxContext-gWM7FHIw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchBoxContext-gWM7FHIw.js","sources":["../../src/provider/contexts/ServiceCodeContext.tsx","../../src/provider/contexts/SearchBoxContext.tsx"],"sourcesContent":["import { createContext, FC, ReactNode, useContext, useEffect } from 'react';\r\nimport {\r\n ServiceCodeKey,\r\n setServiceCodeOverrides,\r\n} from '../../utils/serviceConfig';\r\n\r\n// 서비스코드 설정을 위한 Context 타입\r\ninterface ServiceCodeContextType {\r\n serviceCodes: Partial<Record<ServiceCodeKey, string>>;\r\n getServiceCode: (key: ServiceCodeKey) => string;\r\n}\r\n\r\n// 기본 서비스코드 정의\r\nconst DEFAULT_SERVICE_CODES = {\r\n // 권한 관련\r\n AUTH_BTNS: 'SCMSIGN00202', // 버튼 권한 조회\r\n AUTH_MENU: 'SCMSIGN00201', // 메뉴 권한 조회\r\n SRCH_CODE: 'SCMSIGN00301', // 코드 조회\r\n\r\n // 팝업 관련\r\n SRCH_POPU: 'SCMPOPU00101', // 팝업 조회\r\n\r\n // 즐겨찾기 관련\r\n AUTH_BMRK: 'SCMBMRK00101', // 즐겨찾기 관리\r\n} as const;\r\n\r\n// Context 생성\r\nconst ServiceCodeContext = createContext<ServiceCodeContextType | null>(null);\r\n\r\n// Provider Props 타입\r\ninterface ServiceCodeProviderProps {\r\n children: ReactNode;\r\n /**\r\n * 서비스코드 오버라이드 설정\r\n * 외부 프로젝트에서 기본 서비스코드를 재정의할 수 있습니다.\r\n *\r\n * @example\r\n * ```tsx\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * SRCH_CODE: 'CUSTOM_SRCH_CODE',\r\n * SRCH_POPU: 'CUSTOM_SRCH_POPU_CODE',\r\n * AUTH_BMRK: 'CUSTOM_AUTH_BMRK_CODE',\r\n * }}\r\n * >\r\n * {children}\r\n * </ServiceCodeProvider>\r\n * ```\r\n *\r\n * @description\r\n * - AUTH_BTNS: 버튼 권한 조회 서비스코드\r\n * - AUTH_MENU: 메뉴 권한 조회 서비스코드\r\n * - SRCH_CODE: 코드 조회 서비스코드\r\n * - SRCH_POPU: 팝업 조회 서비스코드\r\n * - AUTH_BMRK: 즐겨찾기 관리 서비스코드\r\n *\r\n * 설정하지 않은 서비스코드는 기본값을 사용합니다.\r\n */\r\n serviceCodes?: Partial<Record<ServiceCodeKey, string>>;\r\n}\r\n\r\n/**\r\n * 서비스코드 Provider 컴포넌트\r\n * 외부 프로젝트에서 서비스코드를 설정할 수 있도록 함\r\n *\r\n * @example\r\n * ```tsx\r\n * import { ServiceCodeProvider } from '@bwg/core/provider';\r\n *\r\n * function App() {\r\n * return (\r\n * <ServiceCodeProvider\r\n * serviceCodes={{\r\n * AUTH_BTNS: 'CUSTOM_AUTH_BTNS_CODE',\r\n * AUTH_MENU: 'CUSTOM_AUTH_MENU_CODE',\r\n * }}\r\n * >\r\n * <YourApp />\r\n * </ServiceCodeProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const ServiceCodeProvider: FC<ServiceCodeProviderProps> = ({\r\n children,\r\n serviceCodes = {},\r\n}) => {\r\n // serviceCodes가 변경될 때마다 serviceConfig.ts의 오버라이드를 업데이트\r\n useEffect(() => {\r\n setServiceCodeOverrides(serviceCodes);\r\n }, [serviceCodes]);\r\n\r\n // 서비스코드 가져오기 함수\r\n const getServiceCode = (key: ServiceCodeKey): string => {\r\n // 1. Provider에서 설정된 값 우선 확인\r\n if (serviceCodes[key] && serviceCodes[key]!.trim() !== '') {\r\n console.log(`🔧 Provider 설정 사용: ${key} = ${serviceCodes[key]}`);\r\n return serviceCodes[key]!;\r\n }\r\n\r\n // 2. 기본값 사용\r\n const defaultValue = DEFAULT_SERVICE_CODES[key];\r\n console.log(`🔧 기본값 사용: ${key} = ${defaultValue}`);\r\n return defaultValue;\r\n };\r\n\r\n const contextValue: ServiceCodeContextType = {\r\n serviceCodes,\r\n getServiceCode,\r\n };\r\n\r\n return (\r\n <ServiceCodeContext.Provider value={contextValue}>\r\n {children}\r\n </ServiceCodeContext.Provider>\r\n );\r\n};\r\n\r\n/**\r\n * 서비스코드 Context를 사용하는 Hook\r\n *\r\n * @example\r\n * ```tsx\r\n * const { getServiceCode, serviceCodes } = useServiceCode();\r\n * const authBtnsCode = getServiceCode('AUTH_BTNS');\r\n * ```\r\n */\r\nexport const useServiceCode = (): ServiceCodeContextType => {\r\n const context = useContext(ServiceCodeContext);\r\n if (!context) {\r\n throw new Error('useServiceCode must be used within a ServiceCodeProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * 특정 서비스코드를 가져오는 Hook\r\n *\r\n * @param key - 서비스코드 키\r\n * @returns 실제 서비스코드 값\r\n *\r\n * @example\r\n * ```tsx\r\n * const authBtnsCode = useServiceCodeValue('AUTH_BTNS');\r\n * const authMenuCode = useServiceCodeValue('AUTH_MENU');\r\n * ```\r\n */\r\nexport const useServiceCodeValue = (key: ServiceCodeKey): string => {\r\n const { getServiceCode } = useServiceCode();\r\n return getServiceCode(key);\r\n};\r\n\r\n/**\r\n * 모든 서비스코드를 가져오는 Hook\r\n *\r\n * @returns 모든 서비스코드 객체\r\n *\r\n * @example\r\n * ```tsx\r\n * const allServiceCodes = useAllServiceCodes();\r\n * console.log(allServiceCodes.AUTH_BTNS); // 'SCMSIGN00202' 또는 커스텀 값\r\n * ```\r\n */\r\nexport const useAllServiceCodes = (): Record<ServiceCodeKey, string> => {\r\n const { getServiceCode } = useServiceCode();\r\n const result = {} as Record<ServiceCodeKey, string>;\r\n\r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n result[key] = getServiceCode(key);\r\n }\r\n\r\n return result;\r\n};\r\n\r\n/**\r\n * 서비스코드 설정을 로그로 출력하는 Hook\r\n * 개발 시 현재 설정된 서비스코드를 확인할 수 있습니다.\r\n *\r\n * @example\r\n * ```tsx\r\n * useLogServiceCodeConfig();\r\n * // 콘솔에 현재 설정된 모든 서비스코드가 출력됩니다.\r\n * ```\r\n */\r\nexport const useLogServiceCodeConfig = (): void => {\r\n const { getServiceCode } = useServiceCode();\r\n\r\n console.log('🔧 bwg-core 서비스코드 설정:');\r\n console.log('📋 Provider 설정 > 기본값 순서로 확인');\r\n\r\n for (const key of Object.keys(DEFAULT_SERVICE_CODES) as ServiceCodeKey[]) {\r\n const value = getServiceCode(key);\r\n console.log(` ${key}: ${value}`);\r\n }\r\n};\r\n\r\n// 타입 내보내기\r\nexport type { ServiceCodeKey };\r\n","import {\r\n createContext,\r\n FC,\r\n ReactNode,\r\n RefObject,\r\n useContext,\r\n useRef,\r\n} from 'react';\r\nimport { SearchBoxRef } from '../../components/common/SearchBox';\r\n\r\n// SearchBox Context 타입\r\ninterface SearchBoxContextType {\r\n searchBoxRef: RefObject<SearchBoxRef> | null;\r\n getFormData: () => any;\r\n setFormData: (data: any) => void;\r\n resetForm: () => void;\r\n validateForm: () => Promise<any>;\r\n}\r\n\r\n// Context 생성\r\nconst SearchBoxContext = createContext<SearchBoxContextType | null>(null);\r\n\r\n// Provider Props\r\ninterface SearchBoxProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n// Provider 컴포넌트\r\nexport const SearchBoxProvider: FC<SearchBoxProviderProps> = ({ children }) => {\r\n const searchBoxRef = useRef<SearchBoxRef>(null);\r\n\r\n const getFormData = () => {\r\n return searchBoxRef.current?.getFormData() || {};\r\n };\r\n\r\n const setFormData = (data: any) => {\r\n searchBoxRef.current?.setFormData(data);\r\n };\r\n\r\n const resetForm = () => {\r\n searchBoxRef.current?.resetForm();\r\n };\r\n\r\n const validateForm = async () => {\r\n return (\r\n (await searchBoxRef.current?.validateForm()) || {\r\n success: false,\r\n error: null,\r\n }\r\n );\r\n };\r\n\r\n const value: SearchBoxContextType = {\r\n searchBoxRef,\r\n getFormData,\r\n setFormData,\r\n resetForm,\r\n validateForm,\r\n };\r\n\r\n return (\r\n <SearchBoxContext.Provider value={value}>\r\n {children}\r\n </SearchBoxContext.Provider>\r\n );\r\n};\r\n\r\n// Hook\r\nexport const useSearchBox = () => {\r\n const context = useContext(SearchBoxContext);\r\n if (!context) {\r\n throw new Error('useSearchBox must be used within a SearchBoxProvider');\r\n }\r\n return context;\r\n};\r\n"],"names":["DEFAULT_SERVICE_CODES","ServiceCodeContext","createContext","ServiceCodeProvider","children","serviceCodes","useEffect","setServiceCodeOverrides","contextValue","key","defaultValue","useServiceCode","context","useContext","useServiceCodeValue","getServiceCode","useAllServiceCodes","result","useLogServiceCodeConfig","value","SearchBoxContext","SearchBoxProvider","searchBoxRef","useRef","data","jsx","useSearchBox"],"mappings":";;;AAaA,MAAMA,IAAwB;AAAA;AAAA,EAE5B,WAAW;AAAA;AAAA,EACX,WAAW;AAAA;AAAA,EACX,WAAW;AAAA;AAAA;AAAA,EAGX,WAAW;AAAA;AAAA;AAAA,EAGX,WAAW;AAAA;AACb,GAGMC,IAAqBC,EAA6C,IAAI,GA0D/DC,IAAoD,CAAC;AAAA,EAChE,UAAAC;AAAA,EACA,cAAAC,IAAe,CAAA;AACjB,MAAM;AAEJ,EAAAC,EAAU,MAAM;AACd,IAAAC,EAAwBF,CAAY;AAAA,EACtC,GAAG,CAACA,CAAY,CAAC;AAgBjB,QAAMG,IAAuC;AAAA,IAC3C,cAAAH;AAAA,IACA,gBAfqB,CAACI,MAAgC;AAEtD,UAAIJ,EAAaI,CAAG,KAAKJ,EAAaI,CAAG,EAAG,KAAA,MAAW;AACrD,uBAAQ,IAAI,sBAAsBA,CAAG,MAAMJ,EAAaI,CAAG,CAAC,EAAE,GACvDJ,EAAaI,CAAG;AAIzB,YAAMC,IAAeV,EAAsBS,CAAG;AAC9C,qBAAQ,IAAI,cAAcA,CAAG,MAAMC,CAAY,EAAE,GAC1CA;AAAA,IACT;AAAA,EAIE;AAGF,+BACGT,EAAmB,UAAnB,EAA4B,OAAOO,GACjC,UAAAJ,GACH;AAEJ,GAWaO,IAAiB,MAA8B;AAC1D,QAAMC,IAAUC,EAAWZ,CAAkB;AAC7C,MAAI,CAACW;AACH,UAAM,IAAI,MAAM,0DAA0D;AAE5E,SAAOA;AACT,GAcaE,IAAsB,CAACL,MAAgC;AAClE,QAAM,EAAE,gBAAAM,EAAA,IAAmBJ,EAAA;AAC3B,SAAOI,EAAeN,CAAG;AAC3B,GAaaO,IAAqB,MAAsC;AACtE,QAAM,EAAE,gBAAAD,EAAA,IAAmBJ,EAAA,GACrBM,IAAS,CAAA;AAEf,aAAWR,KAAO,OAAO,KAAKT,CAAqB;AACjD,IAAAiB,EAAOR,CAAG,IAAIM,EAAeN,CAAG;AAGlC,SAAOQ;AACT,GAYaC,IAA0B,MAAY;AACjD,QAAM,EAAE,gBAAAH,EAAA,IAAmBJ,EAAA;AAE3B,UAAQ,IAAI,uBAAuB,GACnC,QAAQ,IAAI,6BAA6B;AAEzC,aAAWF,KAAO,OAAO,KAAKT,CAAqB,GAAuB;AACxE,UAAMmB,IAAQJ,EAAeN,CAAG;AAChC,YAAQ,IAAI,KAAKA,CAAG,KAAKU,CAAK,EAAE;AAAA,EAClC;AACF,GChLMC,IAAmBlB,EAA2C,IAAI,GAQ3DmB,IAAgD,CAAC,EAAE,UAAAjB,QAAe;AAC7E,QAAMkB,IAAeC,EAAqB,IAAI,GAuBxCJ,IAA8B;AAAA,IAClC,cAAAG;AAAA,IACA,aAvBkB,MACXA,EAAa,SAAS,YAAA,KAAiB,CAAA;AAAA,IAuB9C,aApBkB,CAACE,MAAc;AACjC,MAAAF,EAAa,SAAS,YAAYE,CAAI;AAAA,IACxC;AAAA,IAmBE,WAjBgB,MAAM;AACtB,MAAAF,EAAa,SAAS,UAAA;AAAA,IACxB;AAAA,IAgBE,cAdmB,YAEhB,MAAMA,EAAa,SAAS,kBAAmB;AAAA,MAC9C,SAAS;AAAA,MACT,OAAO;AAAA,IAAA;AAAA,EAUX;AAGF,SACEG,gBAAAA,EAAAA,IAACL,EAAiB,UAAjB,EAA0B,OAAAD,GACxB,UAAAf,EAAA,CACH;AAEJ,GAGasB,IAAe,MAAM;AAChC,QAAMd,IAAUC,EAAWO,CAAgB;AAC3C,MAAI,CAACR;AACH,UAAM,IAAI,MAAM,sDAAsD;AAExE,SAAOA;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ViewContainer-Bhq22_B3.cjs","sources":["../../src/components/layout/ErrorBound.tsx","../../src/components/layout/PrivateProtectedOverlay.tsx","../../src/components/layout/ProgressOverlay.tsx","../../src/components/layout/ProtectLayout.tsx","../../src/components/layout/PublicLayout.tsx","../../src/components/layout/ViewContainer.tsx"],"sourcesContent":["import React, { Component, ErrorInfo, ReactNode } from 'react';\r\nimport { Result, Button } from 'antd';\r\nimport { ReloadOutlined, HomeOutlined } from '@ant-design/icons';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ninterface Props {\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error?: Error;\r\n errorInfo?: ErrorInfo;\r\n}\r\n\r\n// 에러 페이지 컴포넌트\r\nexport const ErrorPage: React.FC<{\r\n error?: Error;\r\n resetError?: () => void;\r\n onGoHome?: () => void;\r\n}> = ({ error, resetError, onGoHome }) => {\r\n const navigate = useNavigate();\r\n\r\n const handleGoHome = () => {\r\n if (onGoHome) {\r\n onGoHome();\r\n } else {\r\n // 기본 홈 이동 로직\r\n navigate('/');\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n padding: '40px 20px',\r\n textAlign: 'center',\r\n backgroundColor: '#fafafa',\r\n minHeight: '400px',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <Result\r\n status=\"error\"\r\n title=\"컴포넌트 로딩 중 오류가 발생했습니다\"\r\n subTitle={\r\n error\r\n ? `오류 내용: ${error.message}`\r\n : '알 수 없는 오류가 발생했습니다'\r\n }\r\n extra={[\r\n <Button\r\n key=\"retry\"\r\n type=\"primary\"\r\n icon={<ReloadOutlined />}\r\n onClick={resetError}\r\n style={{ marginRight: 8 }}\r\n >\r\n 다시 시도\r\n </Button>,\r\n <Button key=\"home\" icon={<HomeOutlined />} onClick={handleGoHome}>\r\n 홈으로\r\n </Button>,\r\n ]}\r\n />\r\n {error && (\r\n <details\r\n style={{\r\n marginTop: '20px',\r\n textAlign: 'left',\r\n maxWidth: '600px',\r\n backgroundColor: '#fff',\r\n padding: '16px',\r\n borderRadius: '6px',\r\n border: '1px solid #d9d9d9',\r\n }}\r\n >\r\n <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>\r\n 오류 상세 정보\r\n </summary>\r\n <pre\r\n style={{\r\n marginTop: '8px',\r\n fontSize: '12px',\r\n color: '#666',\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n }}\r\n >\r\n {error.stack}\r\n </pre>\r\n </details>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// 에러 경계 클래스 컴포넌트\r\nexport class ErrorBound extends Component<Props, State> {\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = { hasError: false };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): State {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n console.error('ErrorBound caught an error:', error, errorInfo);\r\n this.setState({\r\n error,\r\n errorInfo,\r\n });\r\n }\r\n\r\n resetError = () => {\r\n this.setState({ hasError: false, error: undefined, errorInfo: undefined });\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n if (this.props.fallback) {\r\n return this.props.fallback;\r\n }\r\n\r\n return (\r\n <div\r\n style={{\r\n padding: '40px 20px',\r\n textAlign: 'center',\r\n backgroundColor: '#fafafa',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <Result\r\n status=\"error\"\r\n title=\"컴포넌트 로딩 중 오류가 발생했습니다\"\r\n subTitle={\r\n this.state.error\r\n ? `오류 내용: ${this.state.error.message}`\r\n : '알 수 없는 오류가 발생했습니다'\r\n }\r\n extra={[\r\n <Button\r\n key=\"retry\"\r\n type=\"primary\"\r\n icon={<ReloadOutlined />}\r\n onClick={this.resetError}\r\n style={{ marginRight: 8 }}\r\n >\r\n 다시 시도\r\n </Button>,\r\n ]}\r\n />\r\n {this.state.error && (\r\n <details\r\n style={{\r\n marginTop: '20px',\r\n textAlign: 'left',\r\n maxWidth: '600px',\r\n backgroundColor: '#fff',\r\n padding: '16px',\r\n borderRadius: '6px',\r\n border: '1px solid #d9d9d9',\r\n }}\r\n >\r\n <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>\r\n 오류 상세 정보\r\n </summary>\r\n <pre\r\n style={{\r\n marginTop: '8px',\r\n fontSize: '12px',\r\n color: '#666',\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n }}\r\n >\r\n {this.state.error.stack}\r\n </pre>\r\n </details>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\n// 함수형 컴포넌트용 에러 경계 훅\r\nexport const useErrorHandler = () => {\r\n const [error, setError] = React.useState<Error | null>(null);\r\n\r\n const handleError = React.useCallback((error: Error) => {\r\n console.error('useErrorHandler caught an error:', error);\r\n setError(error);\r\n }, []);\r\n\r\n const resetError = React.useCallback(() => {\r\n setError(null);\r\n }, []);\r\n\r\n return { error, handleError, resetError };\r\n};\r\n","import { ScreenProtectProvider, useLock } from \"@/provider/contexts/ScreenProtectContext\";\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\n\r\n// ──────────────────────────────────────────────\r\n// 공통 스타일 유틸\r\n// ──────────────────────────────────────────────\r\nconst createTabStyle = (isActive: boolean) => ({\r\n position: 'absolute' as const,\r\n inset: 0,\r\n visibility: isActive ? ('visible' as const) : ('hidden' as const),\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? ('auto' as const) : ('none' as const),\r\n });\r\n\r\n// ──────────────────────────────────────────────\r\n// AutoLock (활성 탭일 때 잠금 트리거)\r\n// ──────────────────────────────────────────────\r\nconst AutoLock: React.FC<{ once?: boolean }> = ({ once = true }) => {\r\n const { lock } = useLock();\r\n const called = useRef(false);\r\n useEffect(() => {\r\n if (once && called.current) return;\r\n called.current = true;\r\n lock();\r\n }, [once, lock]);\r\n return null;\r\n };\r\n\r\n// ──────────────────────────────────────────────\r\n// PrivateProtectedOverlay (개인정보 포함 화면 보호레이어)\r\n// ──────────────────────────────────────────────\r\nconst PrivateProtectedOverlay: React.FC<{\r\n isActive: boolean;\r\n flagged: boolean;\r\n tabKey: string;\r\n onUnlock: () => void;\r\n children: React.ReactNode;\r\n }> = ({ isActive, flagged, tabKey, onUnlock, children }) => {\r\n const shellRef = useRef<HTMLDivElement>(null);\r\n const [ready, setReady] = useState(false);\r\n \r\n const setShellRef = useCallback((el: HTMLDivElement | null) => {\r\n (shellRef as React.MutableRefObject<HTMLDivElement | null>).current = el;\r\n setReady(!!el);\r\n }, []);\r\n \r\n const shellStyle = createTabStyle(isActive);\r\n \r\n return (\r\n <div ref={setShellRef} style={shellStyle}>\r\n {ready ? (\r\n <ScreenProtectProvider\r\n idleMs={Number.POSITIVE_INFINITY}\r\n persistLocked={false}\r\n overlayScope=\"scoped\"\r\n overlayPosition=\"absolute\"\r\n eventTarget={shellRef.current!}\r\n overlayId={`tab-overlay-${tabKey}`}\r\n onUnlock={async () => {\r\n onUnlock();\r\n return true;\r\n }}\r\n >\r\n {isActive && flagged ? <AutoLock once /> : null}\r\n {children}\r\n </ScreenProtectProvider>\r\n ) : (\r\n children\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n export default PrivateProtectedOverlay;","import { useAuth } from \"@/provider/contexts/AuthContext\";\r\nimport { Spin } from \"antd\";\r\nimport React, { useEffect } from 'react';\r\n\r\nconst DOTLINE_STYLE_ID = 'bwg-dot-line-wave-v4';\r\nfunction ensureDotLineWaveStylesV4() {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(DOTLINE_STYLE_ID)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = DOTLINE_STYLE_ID;\r\n style.textContent = `\r\n .bwg-dotline {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--bwg-gap, 12px);\r\n height: calc(var(--bwg-size, 12px) + 2 * var(--bwg-amp, 12px));\r\n line-height: 0;\r\n }\r\n .bwg-dotline .dot {\r\n width: var(--bwg-size, 12px);\r\n height: var(--bwg-size, 12px);\r\n border-radius: 50%;\r\n background: currentColor;\r\n will-change: transform, opacity;\r\n filter: drop-shadow(0 1px 2px rgba(0,0,0,.12));\r\n animation: bwg-dotline-sine var(--bwg-speed, 780ms) linear infinite;\r\n }\r\n\r\n /* sin(θ) 근사: 0, 45, 90, 135, 180, 225, 270, 315, 360deg */\r\n @keyframes bwg-dotline-sine {\r\n 0% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n 12.5%{ transform: translate3d(0, calc(-0.7071 * var(--bwg-amp, 12px)), 0) scale(1.03); opacity: .92; }\r\n 25% { transform: translate3d(0, calc(-1 * var(--bwg-amp, 12px)), 0) scale(1.06); opacity: 1; }\r\n 37.5%{ transform: translate3d(0, calc(-0.7071 * var(--bwg-amp, 12px)), 0) scale(1.03); opacity: .92; }\r\n 50% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n 62.5%{ transform: translate3d(0, calc( 0.7071 * var(--bwg-amp, 12px)), 0) scale(.97); opacity: .78; }\r\n 75% { transform: translate3d(0, calc( 1 * var(--bwg-amp, 12px)), 0) scale(.96); opacity: .76; }\r\n 87.5%{ transform: translate3d(0, calc( 0.7071 * var(--bwg-amp, 12px)), 0) scale(.97); opacity: .78; }\r\n 100% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .bwg-dotline .dot { animation: none; }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n}\r\n\r\n/* 직선 도트 파동 인디케이터 */\r\nconst DotLineSmoothIndicator: React.FC<{\r\n colors?: string[]; // 각 점 색\r\n count?: number; // 점 개수 (기본: colors 길이)\r\n size?: number; // 점 지름\r\n gap?: number; // 점 간격\r\n amp?: number; // 진폭(px)\r\n speedMs?: number; // 한 주기(ms)\r\n direction?: 'ltr' | 'rtl'; // 파동 진행 방향\r\n phase?: number; // 점 간 지연 비율(0~1) — 낮출수록 부드러움\r\n}> = ({\r\n colors = ['#DAD3FF', '#B3A6FF', '#9380FF', '#816BFA'],\r\n count,\r\n size = 12,\r\n gap = 10,\r\n amp = 16,\r\n speedMs = 900,\r\n direction = 'ltr',\r\n phase = 0.7,\r\n}) => {\r\n useEffect(() => { ensureDotLineWaveStylesV4(); }, []);\r\n\r\n const n = count ?? colors.length;\r\n const dots = Array.from({ length: n });\r\n const baseStyle = {\r\n ['--bwg-size' as any]: `${size}px`,\r\n ['--bwg-gap' as any]: `${gap}px`,\r\n ['--bwg-amp' as any]: `${amp}px`,\r\n ['--bwg-speed' as any]: `${speedMs}ms`,\r\n } as React.CSSProperties;\r\n\r\n const perDotDelay = (speedMs / n) * phase;\r\n\r\n return (\r\n <span className=\"bwg-dotline\" role=\"img\" aria-label=\"loading\" style={baseStyle}>\r\n {dots.map((_, i) => (\r\n <span\r\n key={i}\r\n className=\"dot\"\r\n style={{\r\n backgroundColor: colors[i % colors.length],\r\n animationDelay:\r\n direction === 'ltr'\r\n ? `${(i * perDotDelay)}ms`\r\n : `${((n - 1 - i) * perDotDelay)}ms`,\r\n }}\r\n />\r\n ))}\r\n </span>\r\n );\r\n};\r\n\r\n\r\n/**\r\n * 진행 중 표시\r\n * @returns ProgressOverlay\r\n */\r\nconst ProgressOverlay: React.FC<{spin?: boolean | null; text?: string }> = ({spin = null, text = '인증중...',}) => {\r\n const { busy } = useAuth();\r\n const show = (spin ?? busy);\r\n if (!show) return null;\r\n return (\r\n <div\r\n style={{\r\n position: \"fixed\",\r\n height: \"100vh\",\r\n left: 0,\r\n right: 0,\r\n top: 0,\r\n display: \"flex\",\r\n flexDirection:'column',\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n gap: 8,\r\n padding: \"8px 12px\",\r\n background: \"rgba(0,0,0,0.6)\",\r\n color: \"#fff\",\r\n zIndex: 10000,\r\n }}\r\n aria-live=\"polite\"\r\n aria-busy=\"true\"\r\n role=\"status\"\r\n >\r\n <Spin\r\n indicator={\r\n <DotLineSmoothIndicator\r\n colors={['#DAD3FF', '#B3A6FF', '#9380FF', '#816BFA']}\r\n size={12}\r\n gap={10}\r\n amp={16}\r\n speedMs={900}\r\n phase={0.75} \r\n direction=\"ltr\"\r\n />\r\n }\r\n />\r\n <span className=\"bwg-spin-txt\" style={{marginTop:\"15px\"}}>{text}</span>\r\n </div>\r\n );\r\n };\r\n\r\nexport default ProgressOverlay;","import { useAuth } from \"@/provider/contexts/AuthContext\";\r\nimport { ScreenProtectProvider } from \"@/provider/contexts/ScreenProtectContext\";\r\nimport { isLocal } from \"@/utils/envUtils\";\r\nimport { ConfigProvider } from \"antd\";\r\nimport { Outlet } from \"react-router-dom\";\r\nimport ProgressOverlay from \"./ProgressOverlay\";\r\n\r\n/**\r\n * 보호 레이아웃\r\n * @returns ProtectedLayout\r\n */\r\nconst ProtectedLayout = () => {\r\n const { reauthWithPin } = useAuth();\r\n // NOTE: 인증 여부 체크는 각 페이지(/main)의 스토어 가드에 위임합니다.\r\n // 필요하다면 여기서도 RequireAuth로 감싸세요.\r\n return (\r\n <ScreenProtectProvider idleMs={30 * 60_000} onUnlock={async (pin) => {\r\n if(isLocal) {\r\n // 로컬에서는 항상 true\r\n return true;\r\n }\r\n return !!pin && (await reauthWithPin(pin));\r\n }}>\r\n {/* Ensure AntD portals mount inside protected shell if you need it */}\r\n <ConfigProvider getPopupContainer={() => document.getElementById(\"app-shell\") || document.body}>\r\n <div id=\"app-shell\">\r\n <ProgressOverlay />\r\n <Outlet />\r\n </div>\r\n </ConfigProvider>\r\n </ScreenProtectProvider>\r\n );\r\n }\r\n\r\n export default ProtectedLayout;","import { Outlet } from \"react-router-dom\";\r\nimport ProgressOverlay from \"./ProgressOverlay\";\r\n\r\n/**\r\n * 공개 레이아웃\r\n * @returns PublicLayout\r\n */\r\nconst PublicLayout = () => {\r\n return (\r\n <div>\r\n <ProgressOverlay />\r\n <Outlet />\r\n </div>\r\n );\r\n}\r\n\r\nexport default PublicLayout;","import { CloseOutlined, ExclamationCircleTwoTone } from \"@ant-design/icons\";\r\nimport { Button, Result, Space, Typography } from \"antd\";\r\nimport React, { memo, Suspense } from \"react\";\r\nimport { useMenuViewStore } from \"../../stores/menuViewStore\";\r\nimport { ErrorBound } from \"./ErrorBound\";\r\n\r\nconst ViewContainer = ({\r\n isActive,\r\n instance,\r\n params,\r\n }: {\r\n isActive: boolean;\r\n instance?: React.ComponentType;\r\n params?: Record<string, any>;\r\n }) => {\r\n const { activeMenuId, closeTab } = useMenuViewStore();\r\n\r\n // 현재 활성 탭 닫기 핸들러\r\n const onClose = () => {\r\n if (activeMenuId) {\r\n closeTab(activeMenuId);\r\n }\r\n };\r\n\r\n if(instance) {\r\n return (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n visibility: isActive ? 'visible' : 'hidden',\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? 'auto' : 'none',\r\n }}\r\n >\r\n <ErrorBound>\r\n <Suspense fallback={null}>\r\n {instance && React.createElement(instance, { params } as any)}\r\n </Suspense>\r\n </ErrorBound>\r\n </div>\r\n );\r\n } else {\r\n return (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n visibility: isActive ? 'visible' : 'hidden',\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? 'auto' : 'none',\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: 500,\r\n maxWidth: '90%',\r\n background: '#fff',\r\n borderRadius: 16,\r\n boxShadow: '0 8px 30px rgba(0,0,0,0.05)',\r\n padding: 24,\r\n }}\r\n >\r\n <Result\r\n icon={<ExclamationCircleTwoTone twoToneColor=\"#69b1ff\" />}\r\n status=\"warning\"\r\n title=\"등록된 메뉴 정보가 없거나 유효한 메뉴가 아닙니다.\"\r\n subTitle={\r\n <Typography.Text type=\"secondary\">\r\n 자세한 내용은 관리자에게 문의바랍니다.\r\n </Typography.Text>\r\n }\r\n extra={\r\n <Space>\r\n <Button icon={<CloseOutlined />} onClick={onClose}>\r\n 탭 닫기\r\n </Button>\r\n </Space>\r\n }\r\n />\r\n </div>\r\n </div>\r\n );\r\n }\r\n};\r\n\r\nexport default memo(ViewContainer);"],"names":["ErrorBound","Component","props","error","errorInfo","jsxs","jsx","Result","Button","ReloadOutlined","createTabStyle","isActive","AutoLock","once","lock","useLock","called","useRef","useEffect","PrivateProtectedOverlay","flagged","tabKey","onUnlock","children","shellRef","ready","setReady","useState","setShellRef","useCallback","el","shellStyle","ScreenProtectProvider","DOTLINE_STYLE_ID","ensureDotLineWaveStylesV4","style","DotLineSmoothIndicator","colors","count","size","gap","amp","speedMs","direction","phase","n","dots","baseStyle","perDotDelay","_","i","ProgressOverlay","spin","text","busy","useAuth","Spin","ProtectedLayout","reauthWithPin","pin","isLocal","ConfigProvider","Outlet","PublicLayout","ViewContainer","instance","params","activeMenuId","closeTab","useMenuViewStore","onClose","Suspense","React","ExclamationCircleTwoTone","Typography","Space","CloseOutlined","ViewContainer$1","memo"],"mappings":"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"}
1
+ {"version":3,"file":"ViewContainer-Bhq22_B3.cjs","sources":["../../src/components/layout/ErrorBound.tsx","../../src/components/layout/PrivateProtectedOverlay.tsx","../../src/components/layout/ProgressOverlay.tsx","../../src/components/layout/ProtectLayout.tsx","../../src/components/layout/PublicLayout.tsx","../../src/components/layout/ViewContainer.tsx"],"sourcesContent":["import { HomeOutlined, ReloadOutlined } from '@ant-design/icons';\r\nimport { Button, Result } from 'antd';\r\nimport {\r\n Component,\r\n ErrorInfo,\r\n FC,\r\n ReactNode,\r\n useCallback,\r\n useState,\r\n} from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ninterface Props {\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error?: Error;\r\n errorInfo?: ErrorInfo;\r\n}\r\n\r\n// 에러 페이지 컴포넌트\r\nexport const ErrorPage: FC<{\r\n error?: Error;\r\n resetError?: () => void;\r\n onGoHome?: () => void;\r\n}> = ({ error, resetError, onGoHome }) => {\r\n const navigate = useNavigate();\r\n\r\n const handleGoHome = () => {\r\n if (onGoHome) {\r\n onGoHome();\r\n } else {\r\n // 기본 홈 이동 로직\r\n navigate('/');\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n padding: '40px 20px',\r\n textAlign: 'center',\r\n backgroundColor: '#fafafa',\r\n minHeight: '400px',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <Result\r\n status='error'\r\n title='컴포넌트 로딩 중 오류가 발생했습니다'\r\n subTitle={\r\n error\r\n ? `오류 내용: ${error.message}`\r\n : '알 수 없는 오류가 발생했습니다'\r\n }\r\n extra={[\r\n <Button\r\n key='retry'\r\n type='primary'\r\n icon={<ReloadOutlined />}\r\n onClick={resetError}\r\n style={{ marginRight: 8 }}\r\n >\r\n 다시 시도\r\n </Button>,\r\n <Button key='home' icon={<HomeOutlined />} onClick={handleGoHome}>\r\n 홈으로\r\n </Button>,\r\n ]}\r\n />\r\n {error && (\r\n <details\r\n style={{\r\n marginTop: '20px',\r\n textAlign: 'left',\r\n maxWidth: '600px',\r\n backgroundColor: '#fff',\r\n padding: '16px',\r\n borderRadius: '6px',\r\n border: '1px solid #d9d9d9',\r\n }}\r\n >\r\n <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>\r\n 오류 상세 정보\r\n </summary>\r\n <pre\r\n style={{\r\n marginTop: '8px',\r\n fontSize: '12px',\r\n color: '#666',\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n }}\r\n >\r\n {error.stack}\r\n </pre>\r\n </details>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// 에러 경계 클래스 컴포넌트\r\nexport class ErrorBound extends Component<Props, State> {\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = { hasError: false };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): State {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n console.error('ErrorBound caught an error:', error, errorInfo);\r\n this.setState({\r\n error,\r\n errorInfo,\r\n });\r\n }\r\n\r\n resetError = () => {\r\n this.setState({ hasError: false, error: undefined, errorInfo: undefined });\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n if (this.props.fallback) {\r\n return this.props.fallback;\r\n }\r\n\r\n return (\r\n <div\r\n style={{\r\n padding: '40px 20px',\r\n textAlign: 'center',\r\n backgroundColor: '#fafafa',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <Result\r\n status='error'\r\n title='컴포넌트 로딩 중 오류가 발생했습니다'\r\n subTitle={\r\n this.state.error\r\n ? `오류 내용: ${this.state.error.message}`\r\n : '알 수 없는 오류가 발생했습니다'\r\n }\r\n extra={[\r\n <Button\r\n key='retry'\r\n type='primary'\r\n icon={<ReloadOutlined />}\r\n onClick={this.resetError}\r\n style={{ marginRight: 8 }}\r\n >\r\n 다시 시도\r\n </Button>,\r\n ]}\r\n />\r\n {this.state.error && (\r\n <details\r\n style={{\r\n marginTop: '20px',\r\n textAlign: 'left',\r\n maxWidth: '600px',\r\n backgroundColor: '#fff',\r\n padding: '16px',\r\n borderRadius: '6px',\r\n border: '1px solid #d9d9d9',\r\n }}\r\n >\r\n <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>\r\n 오류 상세 정보\r\n </summary>\r\n <pre\r\n style={{\r\n marginTop: '8px',\r\n fontSize: '12px',\r\n color: '#666',\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n }}\r\n >\r\n {this.state.error.stack}\r\n </pre>\r\n </details>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\n// 함수형 컴포넌트용 에러 경계 훅\r\nexport const useErrorHandler = () => {\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const handleError = useCallback((error: Error) => {\r\n console.error('useErrorHandler caught an error:', error);\r\n setError(error);\r\n }, []);\r\n\r\n const resetError = useCallback(() => {\r\n setError(null);\r\n }, []);\r\n\r\n return { error, handleError, resetError };\r\n};\r\n","import {\r\n ScreenProtectProvider,\r\n useLock,\r\n} from '@/provider/contexts/ScreenProtectContext';\r\nimport {\r\n FC,\r\n MutableRefObject,\r\n ReactNode,\r\n useCallback,\r\n useEffect,\r\n useRef,\r\n useState,\r\n} from 'react';\r\n\r\n// ──────────────────────────────────────────────\r\n// 공통 스타일 유틸\r\n// ──────────────────────────────────────────────\r\nconst createTabStyle = (isActive: boolean) => ({\r\n position: 'absolute' as const,\r\n inset: 0,\r\n visibility: isActive ? ('visible' as const) : ('hidden' as const),\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? ('auto' as const) : ('none' as const),\r\n});\r\n\r\n// ──────────────────────────────────────────────\r\n// AutoLock (활성 탭일 때 잠금 트리거)\r\n// ──────────────────────────────────────────────\r\nconst AutoLock: FC<{ once?: boolean }> = ({ once = true }) => {\r\n const { lock } = useLock();\r\n const called = useRef(false);\r\n useEffect(() => {\r\n if (once && called.current) return;\r\n called.current = true;\r\n lock();\r\n }, [once, lock]);\r\n return null;\r\n};\r\n\r\n// ──────────────────────────────────────────────\r\n// PrivateProtectedOverlay (개인정보 포함 화면 보호레이어)\r\n// ──────────────────────────────────────────────\r\nconst PrivateProtectedOverlay: FC<{\r\n isActive: boolean;\r\n flagged: boolean;\r\n tabKey: string;\r\n onUnlock: () => void;\r\n children: ReactNode;\r\n}> = ({ isActive, flagged, tabKey, onUnlock, children }) => {\r\n const shellRef = useRef<HTMLDivElement>(null);\r\n const [ready, setReady] = useState(false);\r\n\r\n const setShellRef = useCallback((el: HTMLDivElement | null) => {\r\n (shellRef as MutableRefObject<HTMLDivElement | null>).current = el;\r\n setReady(!!el);\r\n }, []);\r\n\r\n const shellStyle = createTabStyle(isActive);\r\n\r\n return (\r\n <div ref={setShellRef} style={shellStyle}>\r\n {ready ? (\r\n <ScreenProtectProvider\r\n idleMs={Number.POSITIVE_INFINITY}\r\n persistLocked={false}\r\n overlayScope='scoped'\r\n overlayPosition='absolute'\r\n eventTarget={shellRef.current!}\r\n overlayId={`tab-overlay-${tabKey}`}\r\n onUnlock={async () => {\r\n onUnlock();\r\n return true;\r\n }}\r\n >\r\n {isActive && flagged ? <AutoLock once /> : null}\r\n {children}\r\n </ScreenProtectProvider>\r\n ) : (\r\n children\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default PrivateProtectedOverlay;\r\n","import { useAuth } from \"@/provider/contexts/AuthContext\";\r\nimport { Spin } from \"antd\";\r\nimport { CSSProperties, FC, useEffect } from 'react';\r\n\r\nconst DOTLINE_STYLE_ID = 'bwg-dot-line-wave-v4';\r\nfunction ensureDotLineWaveStylesV4() {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(DOTLINE_STYLE_ID)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = DOTLINE_STYLE_ID;\r\n style.textContent = `\r\n .bwg-dotline {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--bwg-gap, 12px);\r\n height: calc(var(--bwg-size, 12px) + 2 * var(--bwg-amp, 12px));\r\n line-height: 0;\r\n }\r\n .bwg-dotline .dot {\r\n width: var(--bwg-size, 12px);\r\n height: var(--bwg-size, 12px);\r\n border-radius: 50%;\r\n background: currentColor;\r\n will-change: transform, opacity;\r\n filter: drop-shadow(0 1px 2px rgba(0,0,0,.12));\r\n animation: bwg-dotline-sine var(--bwg-speed, 780ms) linear infinite;\r\n }\r\n\r\n /* sin(θ) 근사: 0, 45, 90, 135, 180, 225, 270, 315, 360deg */\r\n @keyframes bwg-dotline-sine {\r\n 0% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n 12.5%{ transform: translate3d(0, calc(-0.7071 * var(--bwg-amp, 12px)), 0) scale(1.03); opacity: .92; }\r\n 25% { transform: translate3d(0, calc(-1 * var(--bwg-amp, 12px)), 0) scale(1.06); opacity: 1; }\r\n 37.5%{ transform: translate3d(0, calc(-0.7071 * var(--bwg-amp, 12px)), 0) scale(1.03); opacity: .92; }\r\n 50% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n 62.5%{ transform: translate3d(0, calc( 0.7071 * var(--bwg-amp, 12px)), 0) scale(.97); opacity: .78; }\r\n 75% { transform: translate3d(0, calc( 1 * var(--bwg-amp, 12px)), 0) scale(.96); opacity: .76; }\r\n 87.5%{ transform: translate3d(0, calc( 0.7071 * var(--bwg-amp, 12px)), 0) scale(.97); opacity: .78; }\r\n 100% { transform: translate3d(0, 0, 0) scale(.98); opacity: .80; }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .bwg-dotline .dot { animation: none; }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n}\r\n\r\n/* 직선 도트 파동 인디케이터 */\r\nconst DotLineSmoothIndicator: FC<{\r\n colors?: string[]; // 각 점 색\r\n count?: number; // 점 개수 (기본: colors 길이)\r\n size?: number; // 점 지름\r\n gap?: number; // 점 간격\r\n amp?: number; // 진폭(px)\r\n speedMs?: number; // 한 주기(ms)\r\n direction?: 'ltr' | 'rtl'; // 파동 진행 방향\r\n phase?: number; // 점 간 지연 비율(0~1) — 낮출수록 부드러움\r\n}> = ({\r\n colors = ['#DAD3FF', '#B3A6FF', '#9380FF', '#816BFA'],\r\n count,\r\n size = 12,\r\n gap = 10,\r\n amp = 16,\r\n speedMs = 900,\r\n direction = 'ltr',\r\n phase = 0.7,\r\n}) => {\r\n useEffect(() => {\r\n ensureDotLineWaveStylesV4();\r\n }, []);\r\n\r\n const n = count ?? colors.length;\r\n const dots = Array.from({ length: n });\r\n const baseStyle = {\r\n ['--bwg-size' as any]: `${size}px`,\r\n ['--bwg-gap' as any]: `${gap}px`,\r\n ['--bwg-amp' as any]: `${amp}px`,\r\n ['--bwg-speed' as any]: `${speedMs}ms`,\r\n } as CSSProperties;\r\n\r\n const perDotDelay = (speedMs / n) * phase;\r\n\r\n return (\r\n <span\r\n className='bwg-dotline'\r\n role='img'\r\n aria-label='loading'\r\n style={baseStyle}\r\n >\r\n {dots.map((_, i) => (\r\n <span\r\n key={i}\r\n className='dot'\r\n style={{\r\n backgroundColor: colors[i % colors.length],\r\n animationDelay:\r\n direction === 'ltr'\r\n ? `${i * perDotDelay}ms`\r\n : `${(n - 1 - i) * perDotDelay}ms`,\r\n }}\r\n />\r\n ))}\r\n </span>\r\n );\r\n};\r\n\r\n/**\r\n * 진행 중 표시\r\n * @returns ProgressOverlay\r\n */\r\nconst ProgressOverlay: FC<{ spin?: boolean | null; text?: string }> = ({\r\n spin = null,\r\n text = '인증중...',\r\n}) => {\r\n const { busy } = useAuth();\r\n const show = spin ?? busy;\r\n if (!show) return null;\r\n return (\r\n <div\r\n style={{\r\n position: 'fixed',\r\n height: '100vh',\r\n left: 0,\r\n right: 0,\r\n top: 0,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n gap: 8,\r\n padding: '8px 12px',\r\n background: 'rgba(0,0,0,0.6)',\r\n color: '#fff',\r\n zIndex: 10000,\r\n }}\r\n aria-live='polite'\r\n aria-busy='true'\r\n role='status'\r\n >\r\n <Spin\r\n indicator={\r\n <DotLineSmoothIndicator\r\n colors={['#DAD3FF', '#B3A6FF', '#9380FF', '#816BFA']}\r\n size={12}\r\n gap={10}\r\n amp={16}\r\n speedMs={900}\r\n phase={0.75}\r\n direction='ltr'\r\n />\r\n }\r\n />\r\n <span className='bwg-spin-txt' style={{ marginTop: '15px' }}>\r\n {text}\r\n </span>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ProgressOverlay;","import { useAuth } from \"@/provider/contexts/AuthContext\";\r\nimport { ScreenProtectProvider } from \"@/provider/contexts/ScreenProtectContext\";\r\nimport { isLocal } from \"@/utils/envUtils\";\r\nimport { ConfigProvider } from \"antd\";\r\nimport { Outlet } from \"react-router-dom\";\r\nimport ProgressOverlay from \"./ProgressOverlay\";\r\n\r\n/**\r\n * 보호 레이아웃\r\n * @returns ProtectedLayout\r\n */\r\nconst ProtectedLayout = () => {\r\n const { reauthWithPin } = useAuth();\r\n // NOTE: 인증 여부 체크는 각 페이지(/main)의 스토어 가드에 위임합니다.\r\n // 필요하다면 여기서도 RequireAuth로 감싸세요.\r\n return (\r\n <ScreenProtectProvider idleMs={30 * 60_000} onUnlock={async (pin) => {\r\n if(isLocal) {\r\n // 로컬에서는 항상 true\r\n return true;\r\n }\r\n return !!pin && (await reauthWithPin(pin));\r\n }}>\r\n {/* Ensure AntD portals mount inside protected shell if you need it */}\r\n <ConfigProvider getPopupContainer={() => document.getElementById(\"app-shell\") || document.body}>\r\n <div id=\"app-shell\">\r\n <ProgressOverlay />\r\n <Outlet />\r\n </div>\r\n </ConfigProvider>\r\n </ScreenProtectProvider>\r\n );\r\n }\r\n\r\n export default ProtectedLayout;","import { Outlet } from \"react-router-dom\";\r\nimport ProgressOverlay from \"./ProgressOverlay\";\r\n\r\n/**\r\n * 공개 레이아웃\r\n * @returns PublicLayout\r\n */\r\nconst PublicLayout = () => {\r\n return (\r\n <div>\r\n <ProgressOverlay />\r\n <Outlet />\r\n </div>\r\n );\r\n}\r\n\r\nexport default PublicLayout;","import { CloseOutlined, ExclamationCircleTwoTone } from \"@ant-design/icons\";\r\nimport { Button, Result, Space, Typography } from \"antd\";\r\nimport { ComponentType, createElement, memo, Suspense } from 'react';\r\nimport { useMenuViewStore } from '../../stores/menuViewStore';\r\nimport { ErrorBound } from './ErrorBound';\r\n\r\nconst ViewContainer = ({\r\n isActive,\r\n instance,\r\n params,\r\n}: {\r\n isActive: boolean;\r\n instance?: ComponentType;\r\n params?: Record<string, any>;\r\n}) => {\r\n const { activeMenuId, closeTab } = useMenuViewStore();\r\n\r\n // 현재 활성 탭 닫기 핸들러\r\n const onClose = () => {\r\n if (activeMenuId) {\r\n closeTab(activeMenuId);\r\n }\r\n };\r\n\r\n if (instance) {\r\n return (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n visibility: isActive ? 'visible' : 'hidden',\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? 'auto' : 'none',\r\n }}\r\n >\r\n <ErrorBound>\r\n <Suspense fallback={null}>\r\n {instance && createElement(instance, { params } as any)}\r\n </Suspense>\r\n </ErrorBound>\r\n </div>\r\n );\r\n } else {\r\n return (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n visibility: isActive ? 'visible' : 'hidden',\r\n opacity: isActive ? 1 : 0,\r\n transition: 'opacity 0.2s ease-in-out',\r\n pointerEvents: isActive ? 'auto' : 'none',\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: 500,\r\n maxWidth: '90%',\r\n background: '#fff',\r\n borderRadius: 16,\r\n boxShadow: '0 8px 30px rgba(0,0,0,0.05)',\r\n padding: 24,\r\n }}\r\n >\r\n <Result\r\n icon={<ExclamationCircleTwoTone twoToneColor='#69b1ff' />}\r\n status='warning'\r\n title='등록된 메뉴 정보가 없거나 유효한 메뉴가 아닙니다.'\r\n subTitle={\r\n <Typography.Text type='secondary'>\r\n 자세한 내용은 관리자에게 문의바랍니다.\r\n </Typography.Text>\r\n }\r\n extra={\r\n <Space>\r\n <Button icon={<CloseOutlined />} onClick={onClose}>\r\n 탭 닫기\r\n </Button>\r\n </Space>\r\n }\r\n />\r\n </div>\r\n </div>\r\n );\r\n }\r\n};\r\n\r\nexport default memo(ViewContainer);"],"names":["ErrorBound","Component","props","error","errorInfo","jsxs","jsx","Result","Button","ReloadOutlined","createTabStyle","isActive","AutoLock","once","lock","useLock","called","useRef","useEffect","PrivateProtectedOverlay","flagged","tabKey","onUnlock","children","shellRef","ready","setReady","useState","setShellRef","useCallback","el","shellStyle","ScreenProtectProvider","DOTLINE_STYLE_ID","ensureDotLineWaveStylesV4","style","DotLineSmoothIndicator","colors","count","size","gap","amp","speedMs","direction","phase","n","dots","baseStyle","perDotDelay","_","i","ProgressOverlay","spin","text","busy","useAuth","Spin","ProtectedLayout","reauthWithPin","pin","isLocal","ConfigProvider","Outlet","PublicLayout","ViewContainer","instance","params","activeMenuId","closeTab","useMenuViewStore","onClose","Suspense","createElement","ExclamationCircleTwoTone","Typography","Space","CloseOutlined","ViewContainer$1","memo"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { j as e } from "./jsx-runtime-Dpn_P65e.js";
2
2
  import { S as m, u as E } from "./ScreenProtectContext-3my4PHFa.js";
3
- import k, { Component as C, useRef as f, useState as S, useCallback as T, useEffect as g, memo as F, Suspense as I } from "react";
4
- import { u as y } from "./AuthContext-Ei2P-z4d.js";
5
- import { a7 as D, aH as P } from "./apiUtils-DxzLqPhU.js";
6
- import { Result as b, Button as w, Spin as R, ConfigProvider as B, Space as L, Typography as $ } from "antd";
3
+ import { Component as k, useRef as f, useState as C, useCallback as S, useEffect as g, memo as T, Suspense as F, createElement as I } from "react";
4
+ import { u as y } from "./AuthContext-DrEpBrpB.js";
5
+ import { a7 as D, aH as P } from "./apiUtils-DSwE62oG.js";
6
+ import { Result as b, Button as w, Spin as B, ConfigProvider as L, Space as R, Typography as $ } from "antd";
7
7
  import { Outlet as j } from "react-router-dom";
8
8
  import { ReloadOutlined as z, CloseOutlined as N, ExclamationCircleTwoTone as O } from "@ant-design/icons";
9
- class V extends C {
9
+ class V extends k {
10
10
  constructor(r) {
11
11
  super(r), this.resetError = () => {
12
12
  this.setState({ hasError: !1, error: void 0, errorInfo: void 0 });
@@ -91,22 +91,22 @@ class V extends C {
91
91
  ) : this.props.children;
92
92
  }
93
93
  }
94
- const _ = (t) => ({
94
+ const W = (t) => ({
95
95
  position: "absolute",
96
96
  inset: 0,
97
97
  visibility: t ? "visible" : "hidden",
98
98
  opacity: t ? 1 : 0,
99
99
  transition: "opacity 0.2s ease-in-out",
100
100
  pointerEvents: t ? "auto" : "none"
101
- }), W = ({ once: t = !0 }) => {
101
+ }), M = ({ once: t = !0 }) => {
102
102
  const { lock: r } = E(), s = f(!1);
103
103
  return g(() => {
104
104
  t && s.current || (s.current = !0, r());
105
105
  }, [t, r]), null;
106
106
  }, ee = ({ isActive: t, flagged: r, tabKey: s, onUnlock: a, children: o }) => {
107
- const n = f(null), [d, p] = S(!1), i = T((l) => {
107
+ const n = f(null), [d, p] = C(!1), i = S((l) => {
108
108
  n.current = l, p(!!l);
109
- }, []), u = _(t);
109
+ }, []), u = W(t);
110
110
  return /* @__PURE__ */ e.jsx("div", { ref: i, style: u, children: d ? /* @__PURE__ */ e.jsxs(
111
111
  m,
112
112
  {
@@ -118,13 +118,13 @@ const _ = (t) => ({
118
118
  overlayId: `tab-overlay-${s}`,
119
119
  onUnlock: async () => (a(), !0),
120
120
  children: [
121
- t && r ? /* @__PURE__ */ e.jsx(W, { once: !0 }) : null,
121
+ t && r ? /* @__PURE__ */ e.jsx(M, { once: !0 }) : null,
122
122
  o
123
123
  ]
124
124
  }
125
125
  ) : o });
126
126
  }, x = "bwg-dot-line-wave-v4";
127
- function M() {
127
+ function _() {
128
128
  if (typeof document > "u" || document.getElementById(x)) return;
129
129
  const t = document.createElement("style");
130
130
  t.id = x, t.textContent = `
@@ -174,7 +174,7 @@ const A = ({
174
174
  phase: p = 0.7
175
175
  }) => {
176
176
  g(() => {
177
- M();
177
+ _();
178
178
  }, []);
179
179
  const i = r ?? t.length, u = Array.from({ length: i }), l = {
180
180
  "--bwg-size": `${s}px`,
@@ -182,18 +182,30 @@ const A = ({
182
182
  "--bwg-amp": `${o}px`,
183
183
  "--bwg-speed": `${n}ms`
184
184
  }, h = n / i * p;
185
- return /* @__PURE__ */ e.jsx("span", { className: "bwg-dotline", role: "img", "aria-label": "loading", style: l, children: u.map((Y, c) => /* @__PURE__ */ e.jsx(
185
+ return /* @__PURE__ */ e.jsx(
186
186
  "span",
187
187
  {
188
- className: "dot",
189
- style: {
190
- backgroundColor: t[c % t.length],
191
- animationDelay: d === "ltr" ? `${c * h}ms` : `${(i - 1 - c) * h}ms`
192
- }
193
- },
194
- c
195
- )) });
196
- }, v = ({ spin: t = null, text: r = "인증중..." }) => {
188
+ className: "bwg-dotline",
189
+ role: "img",
190
+ "aria-label": "loading",
191
+ style: l,
192
+ children: u.map((Y, c) => /* @__PURE__ */ e.jsx(
193
+ "span",
194
+ {
195
+ className: "dot",
196
+ style: {
197
+ backgroundColor: t[c % t.length],
198
+ animationDelay: d === "ltr" ? `${c * h}ms` : `${(i - 1 - c) * h}ms`
199
+ }
200
+ },
201
+ c
202
+ ))
203
+ }
204
+ );
205
+ }, v = ({
206
+ spin: t = null,
207
+ text: r = "인증중..."
208
+ }) => {
197
209
  const { busy: s } = y();
198
210
  return t ?? s ? /* @__PURE__ */ e.jsxs(
199
211
  "div",
@@ -219,7 +231,7 @@ const A = ({
219
231
  role: "status",
220
232
  children: [
221
233
  /* @__PURE__ */ e.jsx(
222
- R,
234
+ B,
223
235
  {
224
236
  indicator: /* @__PURE__ */ e.jsx(
225
237
  A,
@@ -241,7 +253,7 @@ const A = ({
241
253
  ) : null;
242
254
  }, te = () => {
243
255
  const { reauthWithPin: t } = y();
244
- return /* @__PURE__ */ e.jsx(m, { idleMs: 30 * 6e4, onUnlock: async (r) => D ? !0 : !!r && await t(r), children: /* @__PURE__ */ e.jsx(B, { getPopupContainer: () => document.getElementById("app-shell") || document.body, children: /* @__PURE__ */ e.jsxs("div", { id: "app-shell", children: [
256
+ return /* @__PURE__ */ e.jsx(m, { idleMs: 30 * 6e4, onUnlock: async (r) => D ? !0 : !!r && await t(r), children: /* @__PURE__ */ e.jsx(L, { getPopupContainer: () => document.getElementById("app-shell") || document.body, children: /* @__PURE__ */ e.jsxs("div", { id: "app-shell", children: [
245
257
  /* @__PURE__ */ e.jsx(v, {}),
246
258
  /* @__PURE__ */ e.jsx(j, {})
247
259
  ] }) }) });
@@ -270,7 +282,7 @@ const A = ({
270
282
  transition: "opacity 0.2s ease-in-out",
271
283
  pointerEvents: t ? "auto" : "none"
272
284
  },
273
- children: /* @__PURE__ */ e.jsx(V, { children: /* @__PURE__ */ e.jsx(I, { fallback: null, children: r && k.createElement(r, { params: s }) }) })
285
+ children: /* @__PURE__ */ e.jsx(V, { children: /* @__PURE__ */ e.jsx(F, { fallback: null, children: r && I(r, { params: s }) }) })
274
286
  }
275
287
  ) : /* @__PURE__ */ e.jsx(
276
288
  "div",
@@ -307,14 +319,14 @@ const A = ({
307
319
  status: "warning",
308
320
  title: "등록된 메뉴 정보가 없거나 유효한 메뉴가 아닙니다.",
309
321
  subTitle: /* @__PURE__ */ e.jsx($.Text, { type: "secondary", children: "자세한 내용은 관리자에게 문의바랍니다." }),
310
- extra: /* @__PURE__ */ e.jsx(L, { children: /* @__PURE__ */ e.jsx(w, { icon: /* @__PURE__ */ e.jsx(N, {}), onClick: n, children: "탭 닫기" }) })
322
+ extra: /* @__PURE__ */ e.jsx(R, { children: /* @__PURE__ */ e.jsx(w, { icon: /* @__PURE__ */ e.jsx(N, {}), onClick: n, children: "탭 닫기" }) })
311
323
  }
312
324
  )
313
325
  }
314
326
  )
315
327
  }
316
328
  );
317
- }, se = F(U);
329
+ }, se = T(U);
318
330
  export {
319
331
  V as E,
320
332
  ee as P,
@@ -323,4 +335,4 @@ export {
323
335
  te as b,
324
336
  re as c
325
337
  };
326
- //# sourceMappingURL=ViewContainer-CjpJqoGG.js.map
338
+ //# sourceMappingURL=ViewContainer-D9SKBnrn.js.map