@sonhoseong/mfa-lib 1.3.7 → 1.3.10

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 (162) hide show
  1. package/dist/components/button/ScrollTopButton.js +5 -3
  2. package/dist/components/error/ErrorBoundary.js +14 -4
  3. package/dist/components/error/NotFound.d.ts +20 -0
  4. package/dist/components/error/NotFound.d.ts.map +1 -0
  5. package/dist/components/error/NotFound.js +84 -0
  6. package/dist/components/error/index.d.ts +2 -0
  7. package/dist/components/error/index.d.ts.map +1 -1
  8. package/dist/components/error/index.js +1 -0
  9. package/dist/components/icons/Icons.d.ts +51 -0
  10. package/dist/components/icons/Icons.d.ts.map +1 -0
  11. package/dist/components/icons/Icons.js +100 -0
  12. package/dist/components/icons/index.d.ts +5 -0
  13. package/dist/components/icons/index.d.ts.map +1 -0
  14. package/dist/components/icons/index.js +4 -0
  15. package/dist/components/index.d.ts +3 -0
  16. package/dist/components/index.d.ts.map +1 -1
  17. package/dist/components/index.js +6 -0
  18. package/dist/components/layout/Container.js +7 -2
  19. package/dist/components/loading/DeferredComponent.d.ts +19 -0
  20. package/dist/components/loading/DeferredComponent.d.ts.map +1 -0
  21. package/dist/components/loading/DeferredComponent.js +32 -0
  22. package/dist/components/loading/GlobalLoading.js +14 -3
  23. package/dist/components/loading/index.d.ts +1 -0
  24. package/dist/components/loading/index.d.ts.map +1 -1
  25. package/dist/components/loading/index.js +1 -0
  26. package/dist/components/logo/Logo.d.ts +2 -0
  27. package/dist/components/logo/Logo.d.ts.map +1 -1
  28. package/dist/components/logo/Logo.js +13 -4
  29. package/dist/components/modal/ModalContainer.js +17 -8
  30. package/dist/components/modal/ModalContext.js +2 -3
  31. package/dist/components/navigation/AppNavbar.js +21 -9
  32. package/dist/components/navigation/AppSidebar.css +58 -3
  33. package/dist/components/navigation/AppSidebar.d.ts +1 -1
  34. package/dist/components/navigation/AppSidebar.d.ts.map +1 -1
  35. package/dist/components/navigation/AppSidebar.js +58 -15
  36. package/dist/components/navigation/Footer.d.ts +15 -0
  37. package/dist/components/navigation/Footer.d.ts.map +1 -0
  38. package/dist/components/navigation/Footer.js +12 -0
  39. package/dist/components/navigation/Header.d.ts.map +1 -1
  40. package/dist/components/navigation/Header.js +17 -4
  41. package/dist/components/navigation/Lnb.d.ts +2 -7
  42. package/dist/components/navigation/Lnb.d.ts.map +1 -1
  43. package/dist/components/navigation/Lnb.js +34 -6
  44. package/dist/components/navigation/StickyNav.js +19 -11
  45. package/dist/components/navigation/index.d.ts +1 -0
  46. package/dist/components/navigation/index.d.ts.map +1 -1
  47. package/dist/components/navigation/index.js +1 -0
  48. package/dist/components/page/LoginPage.d.ts +4 -1
  49. package/dist/components/page/LoginPage.d.ts.map +1 -1
  50. package/dist/components/page/LoginPage.js +146 -21
  51. package/dist/components/remote/RemoteErrorBoundary.d.ts +28 -0
  52. package/dist/components/remote/RemoteErrorBoundary.d.ts.map +1 -0
  53. package/dist/components/remote/RemoteErrorBoundary.js +44 -0
  54. package/dist/components/remote/RemoteErrorFallback.d.ts +16 -0
  55. package/dist/components/remote/RemoteErrorFallback.d.ts.map +1 -0
  56. package/dist/components/remote/RemoteErrorFallback.js +76 -0
  57. package/dist/components/remote/index.d.ts +8 -0
  58. package/dist/components/remote/index.d.ts.map +1 -0
  59. package/dist/components/remote/index.js +5 -0
  60. package/dist/components/router/BrowserRouter.d.ts +13 -0
  61. package/dist/components/router/BrowserRouter.d.ts.map +1 -0
  62. package/dist/components/router/BrowserRouter.js +17 -0
  63. package/dist/components/router/RouteGuard.d.ts +79 -0
  64. package/dist/components/router/RouteGuard.d.ts.map +1 -0
  65. package/dist/components/router/RouteGuard.js +86 -0
  66. package/dist/components/router/index.d.ts +4 -0
  67. package/dist/components/router/index.d.ts.map +1 -0
  68. package/dist/components/router/index.js +2 -0
  69. package/dist/components/toast/ToastContainer.js +17 -6
  70. package/dist/components/toast/ToastContext.js +2 -3
  71. package/dist/hooks/index.d.ts +9 -1
  72. package/dist/hooks/index.d.ts.map +1 -1
  73. package/dist/hooks/index.js +15 -1
  74. package/dist/hooks/use-auth.d.ts +2 -1
  75. package/dist/hooks/use-auth.d.ts.map +1 -1
  76. package/dist/hooks/use-auth.js +19 -18
  77. package/dist/hooks/use-debounce.d.ts +56 -0
  78. package/dist/hooks/use-debounce.d.ts.map +1 -0
  79. package/dist/hooks/use-debounce.js +140 -0
  80. package/dist/hooks/use-effect-once.d.ts +77 -0
  81. package/dist/hooks/use-effect-once.d.ts.map +1 -0
  82. package/dist/hooks/use-effect-once.js +124 -0
  83. package/dist/hooks/use-error-notification.d.ts +1 -1
  84. package/dist/hooks/use-error-notification.js +1 -1
  85. package/dist/hooks/use-global-loading.d.ts +1 -1
  86. package/dist/hooks/use-global-loading.js +1 -1
  87. package/dist/hooks/use-initialize.d.ts +8 -1
  88. package/dist/hooks/use-initialize.d.ts.map +1 -1
  89. package/dist/hooks/use-initialize.js +126 -23
  90. package/dist/hooks/use-modal.d.ts +21 -5
  91. package/dist/hooks/use-modal.d.ts.map +1 -1
  92. package/dist/hooks/use-modal.js +57 -17
  93. package/dist/hooks/use-navigate.d.ts +1 -1
  94. package/dist/hooks/use-navigate.js +1 -1
  95. package/dist/hooks/use-network-status.d.ts +15 -0
  96. package/dist/hooks/use-network-status.d.ts.map +1 -0
  97. package/dist/hooks/use-network-status.js +49 -0
  98. package/dist/hooks/use-permission.d.ts +22 -0
  99. package/dist/hooks/use-permission.d.ts.map +1 -0
  100. package/dist/hooks/use-permission.js +73 -0
  101. package/dist/hooks/use-recent-menu.d.ts +46 -0
  102. package/dist/hooks/use-recent-menu.d.ts.map +1 -0
  103. package/dist/hooks/use-recent-menu.js +169 -0
  104. package/dist/hooks/use-scroll-restoration.d.ts +51 -0
  105. package/dist/hooks/use-scroll-restoration.d.ts.map +1 -0
  106. package/dist/hooks/use-scroll-restoration.js +143 -0
  107. package/dist/hooks/use-supabase-auth.d.ts +49 -0
  108. package/dist/hooks/use-supabase-auth.d.ts.map +1 -0
  109. package/dist/hooks/use-supabase-auth.js +229 -0
  110. package/dist/hooks/use-track-history.d.ts +2 -1
  111. package/dist/hooks/use-track-history.d.ts.map +1 -1
  112. package/dist/hooks/use-track-history.js +14 -2
  113. package/dist/index.d.ts +1 -1
  114. package/dist/index.js +1 -1
  115. package/dist/network/axios-factory.d.ts +30 -1
  116. package/dist/network/axios-factory.d.ts.map +1 -1
  117. package/dist/network/axios-factory.js +192 -24
  118. package/dist/network/index.d.ts +3 -1
  119. package/dist/network/index.d.ts.map +1 -1
  120. package/dist/network/index.js +5 -1
  121. package/dist/network/supabase-client.d.ts +28 -0
  122. package/dist/network/supabase-client.d.ts.map +1 -0
  123. package/dist/network/supabase-client.js +46 -0
  124. package/dist/store/app-store.d.ts +222 -12
  125. package/dist/store/app-store.d.ts.map +1 -1
  126. package/dist/store/app-store.js +46 -29
  127. package/dist/store/index.d.ts +2 -0
  128. package/dist/store/index.d.ts.map +1 -1
  129. package/dist/store/index.js +3 -0
  130. package/dist/store/menu-slice.d.ts +96 -0
  131. package/dist/store/menu-slice.d.ts.map +1 -0
  132. package/dist/store/menu-slice.js +98 -0
  133. package/dist/store/recent-menu-slice.d.ts +209 -0
  134. package/dist/store/recent-menu-slice.d.ts.map +1 -0
  135. package/dist/store/recent-menu-slice.js +110 -0
  136. package/dist/store/store-access.d.ts +1 -1
  137. package/dist/store/store-access.js +1 -1
  138. package/dist/types/index.d.ts +74 -17
  139. package/dist/types/index.d.ts.map +1 -1
  140. package/dist/types/service.d.ts +1 -1
  141. package/dist/types/service.js +1 -1
  142. package/dist/utils/classnames.d.ts +65 -0
  143. package/dist/utils/classnames.d.ts.map +1 -0
  144. package/dist/utils/classnames.js +98 -0
  145. package/dist/utils/formatter.d.ts +78 -0
  146. package/dist/utils/formatter.d.ts.map +1 -0
  147. package/dist/utils/formatter.js +216 -0
  148. package/dist/utils/index.d.ts +5 -0
  149. package/dist/utils/index.d.ts.map +1 -1
  150. package/dist/utils/index.js +5 -0
  151. package/dist/utils/permission.d.ts +33 -0
  152. package/dist/utils/permission.d.ts.map +1 -0
  153. package/dist/utils/permission.js +132 -0
  154. package/dist/utils/query-string.d.ts +67 -0
  155. package/dist/utils/query-string.d.ts.map +1 -0
  156. package/dist/utils/query-string.js +136 -0
  157. package/dist/utils/storage.d.ts +1 -1
  158. package/dist/utils/storage.js +1 -1
  159. package/dist/utils/validation.d.ts +98 -0
  160. package/dist/utils/validation.d.ts.map +1 -0
  161. package/dist/utils/validation.js +260 -0
  162. package/package.json +5 -3
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Menu Slice
3
+ * 메뉴 상태 관리 (GNB, LNB, 선택 상태)
4
+ */
5
+ import { createSlice, createSelector } from '@reduxjs/toolkit';
6
+ const initialState = {
7
+ gnbItems: [],
8
+ lnbItems: [],
9
+ selectedGnbId: '',
10
+ selectedLnbId: '',
11
+ expandedIds: [],
12
+ isLoading: false,
13
+ };
14
+ // ============================================
15
+ // Slice
16
+ // ============================================
17
+ const menuSlice = createSlice({
18
+ name: 'menu',
19
+ initialState,
20
+ reducers: {
21
+ setGnbItems: (state, action) => {
22
+ state.gnbItems = action.payload;
23
+ },
24
+ setLnbItems: (state, action) => {
25
+ state.lnbItems = action.payload;
26
+ },
27
+ setSelectedGnbId: (state, action) => {
28
+ state.selectedGnbId = action.payload;
29
+ },
30
+ setSelectedLnbId: (state, action) => {
31
+ state.selectedLnbId = action.payload;
32
+ },
33
+ setExpandedIds: (state, action) => {
34
+ state.expandedIds = action.payload;
35
+ },
36
+ toggleExpanded: (state, action) => {
37
+ const id = action.payload;
38
+ const index = state.expandedIds.indexOf(id);
39
+ if (index >= 0) {
40
+ state.expandedIds.splice(index, 1);
41
+ }
42
+ else {
43
+ state.expandedIds.push(id);
44
+ }
45
+ },
46
+ setMenuLoading: (state, action) => {
47
+ state.isLoading = action.payload;
48
+ },
49
+ resetMenu: () => initialState,
50
+ },
51
+ });
52
+ export const { setGnbItems, setLnbItems, setSelectedGnbId, setSelectedLnbId, setExpandedIds, toggleExpanded, setMenuLoading, resetMenu, } = menuSlice.actions;
53
+ // 기본 Selectors
54
+ export const selectMenuState = (state) => state.menu;
55
+ export const selectGnbItems = (state) => state.menu.gnbItems;
56
+ export const selectLnbItems = (state) => state.menu.lnbItems;
57
+ export const selectSelectedGnbId = (state) => state.menu.selectedGnbId;
58
+ export const selectSelectedLnbId = (state) => state.menu.selectedLnbId;
59
+ export const selectExpandedIds = (state) => state.menu.expandedIds;
60
+ export const selectMenuLoading = (state) => state.menu.isLoading;
61
+ // 파생 Selectors (Memoized)
62
+ export const selectSelectedGnb = createSelector([selectGnbItems, selectSelectedGnbId], (gnbItems, selectedId) => gnbItems.find((item) => item.id === selectedId) || null);
63
+ export const selectSelectedLnb = createSelector([selectLnbItems, selectSelectedLnbId], (lnbItems, selectedId) => {
64
+ // 중첩 메뉴에서 찾기
65
+ const findItem = (items) => {
66
+ for (const item of items) {
67
+ if (item.id === selectedId)
68
+ return item;
69
+ if (item.children) {
70
+ const found = findItem(item.children);
71
+ if (found)
72
+ return found;
73
+ }
74
+ }
75
+ return null;
76
+ };
77
+ return findItem(lnbItems);
78
+ });
79
+ // 현재 경로의 breadcrumb 계산
80
+ export const selectBreadcrumb = createSelector([selectLnbItems, selectSelectedLnbId], (lnbItems, selectedId) => {
81
+ const breadcrumb = [];
82
+ const findPath = (items, path = []) => {
83
+ for (const item of items) {
84
+ const currentPath = [...path, item];
85
+ if (item.id === selectedId) {
86
+ breadcrumb.push(...currentPath);
87
+ return true;
88
+ }
89
+ if (item.children && findPath(item.children, currentPath)) {
90
+ return true;
91
+ }
92
+ }
93
+ return false;
94
+ };
95
+ findPath(lnbItems);
96
+ return breadcrumb;
97
+ });
98
+ export default menuSlice.reducer;
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Recent Menu Slice
3
+ * 최근 방문 메뉴 상태 관리 (탭)
4
+ */
5
+ import { PayloadAction } from '@reduxjs/toolkit';
6
+ import { RecentMenu } from '../types';
7
+ export interface RecentMenuState {
8
+ /** 최근 메뉴 목록 */
9
+ list: RecentMenu[];
10
+ /** 현재 활성 메뉴 ID */
11
+ currentId: string;
12
+ /** 최대 탭 개수 */
13
+ maxTabs: number;
14
+ }
15
+ export declare const recentMenuSlice: import("@reduxjs/toolkit").Slice<RecentMenuState, {
16
+ /** 최근 메뉴 목록 설정 (복구용) */
17
+ setRecentMenuList: (state: {
18
+ list: {
19
+ id: string;
20
+ pathname: string;
21
+ search: string;
22
+ title: string;
23
+ service?: string | undefined;
24
+ state?: any;
25
+ data?: any;
26
+ }[];
27
+ currentId: string;
28
+ maxTabs: number;
29
+ }, action: PayloadAction<RecentMenu[]>) => void;
30
+ /** 최근 메뉴 추가/업데이트 */
31
+ addRecentMenu: (state: {
32
+ list: {
33
+ id: string;
34
+ pathname: string;
35
+ search: string;
36
+ title: string;
37
+ service?: string | undefined;
38
+ state?: any;
39
+ data?: any;
40
+ }[];
41
+ currentId: string;
42
+ maxTabs: number;
43
+ }, action: PayloadAction<RecentMenu>) => void;
44
+ /** 최근 메뉴 제거 */
45
+ removeRecentMenu: (state: {
46
+ list: {
47
+ id: string;
48
+ pathname: string;
49
+ search: string;
50
+ title: string;
51
+ service?: string | undefined;
52
+ state?: any;
53
+ data?: any;
54
+ }[];
55
+ currentId: string;
56
+ maxTabs: number;
57
+ }, action: PayloadAction<string>) => void;
58
+ /** 현재 메뉴 변경 */
59
+ setCurrentRecentMenu: (state: {
60
+ list: {
61
+ id: string;
62
+ pathname: string;
63
+ search: string;
64
+ title: string;
65
+ service?: string | undefined;
66
+ state?: any;
67
+ data?: any;
68
+ }[];
69
+ currentId: string;
70
+ maxTabs: number;
71
+ }, action: PayloadAction<string>) => void;
72
+ /** 메뉴 상태 업데이트 (스크롤 위치, 검색 조건 등) */
73
+ updateRecentMenuState: (state: {
74
+ list: {
75
+ id: string;
76
+ pathname: string;
77
+ search: string;
78
+ title: string;
79
+ service?: string | undefined;
80
+ state?: any;
81
+ data?: any;
82
+ }[];
83
+ currentId: string;
84
+ maxTabs: number;
85
+ }, action: PayloadAction<{
86
+ id: string;
87
+ state?: any;
88
+ data?: any;
89
+ }>) => void;
90
+ /** 모든 최근 메뉴 제거 */
91
+ clearRecentMenu: (state: {
92
+ list: {
93
+ id: string;
94
+ pathname: string;
95
+ search: string;
96
+ title: string;
97
+ service?: string | undefined;
98
+ state?: any;
99
+ data?: any;
100
+ }[];
101
+ currentId: string;
102
+ maxTabs: number;
103
+ }) => void;
104
+ /** 현재 메뉴 외 모든 메뉴 제거 */
105
+ closeOtherMenus: (state: {
106
+ list: {
107
+ id: string;
108
+ pathname: string;
109
+ search: string;
110
+ title: string;
111
+ service?: string | undefined;
112
+ state?: any;
113
+ data?: any;
114
+ }[];
115
+ currentId: string;
116
+ maxTabs: number;
117
+ }) => void;
118
+ /** 최대 탭 개수 설정 */
119
+ setMaxTabs: (state: {
120
+ list: {
121
+ id: string;
122
+ pathname: string;
123
+ search: string;
124
+ title: string;
125
+ service?: string | undefined;
126
+ state?: any;
127
+ data?: any;
128
+ }[];
129
+ currentId: string;
130
+ maxTabs: number;
131
+ }, action: PayloadAction<number>) => void;
132
+ }, "recentMenu", "recentMenu", import("@reduxjs/toolkit").SliceSelectors<RecentMenuState>>;
133
+ export declare const setRecentMenuList: import("@reduxjs/toolkit").ActionCreatorWithPayload<RecentMenu[], "recentMenu/setRecentMenuList">, addRecentMenu: import("@reduxjs/toolkit").ActionCreatorWithPayload<RecentMenu, "recentMenu/addRecentMenu">, removeRecentMenu: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "recentMenu/removeRecentMenu">, setCurrentRecentMenu: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "recentMenu/setCurrentRecentMenu">, updateRecentMenuState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
134
+ id: string;
135
+ state?: any;
136
+ data?: any;
137
+ }, "recentMenu/updateRecentMenuState">, clearRecentMenu: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"recentMenu/clearRecentMenu">, closeOtherMenus: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"recentMenu/closeOtherMenus">, setMaxTabs: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "recentMenu/setMaxTabs">;
138
+ interface RootStateWithRecentMenu {
139
+ recentMenu: RecentMenuState;
140
+ }
141
+ export declare const selectRecentMenuState: (state: RootStateWithRecentMenu) => RecentMenuState;
142
+ export declare const selectRecentMenuList: (state: RootStateWithRecentMenu) => RecentMenu[];
143
+ export declare const selectCurrentRecentMenuId: (state: RootStateWithRecentMenu) => string;
144
+ export declare const selectCurrentRecentMenu: ((state: RootStateWithRecentMenu) => RecentMenu | null) & {
145
+ clearCache: () => void;
146
+ resultsCount: () => number;
147
+ resetResultsCount: () => void;
148
+ } & {
149
+ resultFunc: (resultFuncArgs_0: RecentMenu[], resultFuncArgs_1: string) => RecentMenu | null;
150
+ memoizedResultFunc: ((resultFuncArgs_0: RecentMenu[], resultFuncArgs_1: string) => RecentMenu | null) & {
151
+ clearCache: () => void;
152
+ resultsCount: () => number;
153
+ resetResultsCount: () => void;
154
+ };
155
+ lastResult: () => RecentMenu | null;
156
+ dependencies: [(state: RootStateWithRecentMenu) => RecentMenu[], (state: RootStateWithRecentMenu) => string];
157
+ recomputations: () => number;
158
+ resetRecomputations: () => void;
159
+ dependencyRecomputations: () => number;
160
+ resetDependencyRecomputations: () => void;
161
+ } & {
162
+ memoize: typeof import("reselect").weakMapMemoize;
163
+ argsMemoize: typeof import("reselect").weakMapMemoize;
164
+ };
165
+ export declare const selectRecentMenuCount: ((state: RootStateWithRecentMenu) => number) & {
166
+ clearCache: () => void;
167
+ resultsCount: () => number;
168
+ resetResultsCount: () => void;
169
+ } & {
170
+ resultFunc: (resultFuncArgs_0: RecentMenu[]) => number;
171
+ memoizedResultFunc: ((resultFuncArgs_0: RecentMenu[]) => number) & {
172
+ clearCache: () => void;
173
+ resultsCount: () => number;
174
+ resetResultsCount: () => void;
175
+ };
176
+ lastResult: () => number;
177
+ dependencies: [(state: RootStateWithRecentMenu) => RecentMenu[]];
178
+ recomputations: () => number;
179
+ resetRecomputations: () => void;
180
+ dependencyRecomputations: () => number;
181
+ resetDependencyRecomputations: () => void;
182
+ } & {
183
+ memoize: typeof import("reselect").weakMapMemoize;
184
+ argsMemoize: typeof import("reselect").weakMapMemoize;
185
+ };
186
+ export declare const selectHasRecentMenu: ((state: RootStateWithRecentMenu) => boolean) & {
187
+ clearCache: () => void;
188
+ resultsCount: () => number;
189
+ resetResultsCount: () => void;
190
+ } & {
191
+ resultFunc: (resultFuncArgs_0: RecentMenu[]) => boolean;
192
+ memoizedResultFunc: ((resultFuncArgs_0: RecentMenu[]) => boolean) & {
193
+ clearCache: () => void;
194
+ resultsCount: () => number;
195
+ resetResultsCount: () => void;
196
+ };
197
+ lastResult: () => boolean;
198
+ dependencies: [(state: RootStateWithRecentMenu) => RecentMenu[]];
199
+ recomputations: () => number;
200
+ resetRecomputations: () => void;
201
+ dependencyRecomputations: () => number;
202
+ resetDependencyRecomputations: () => void;
203
+ } & {
204
+ memoize: typeof import("reselect").weakMapMemoize;
205
+ argsMemoize: typeof import("reselect").weakMapMemoize;
206
+ };
207
+ declare const _default: import("redux").Reducer<RecentMenuState>;
208
+ export default _default;
209
+ //# sourceMappingURL=recent-menu-slice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recent-menu-slice.d.ts","sourceRoot":"","sources":["../../src/store/recent-menu-slice.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAe,aAAa,EAAkB,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAOtC,MAAM,WAAW,eAAe;IAC9B,eAAe;IACf,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD,eAAO,MAAM,eAAe;IAIxB,wBAAwB;;;;;;;;;;;mBAnBf,MAAM;iBAER,MAAM;eAkBsB,aAAa,CAAC,UAAU,EAAE,CAAC;IAI9D,oBAAoB;;;;;;;;;;;mBAxBX,MAAM;iBAER,MAAM;eAuBkB,aAAa,CAAC,UAAU,CAAC;IA6BxD,eAAe;;;;;;;;;;;mBAtDN,MAAM;iBAER,MAAM;eAqDqB,aAAa,CAAC,MAAM,CAAC;IAmBvD,eAAe;;;;;;;;;;;mBA1EN,MAAM;iBAER,MAAM;eAyEyB,aAAa,CAAC,MAAM,CAAC;IAI3D,mCAAmC;;;;;;;;;;;mBA/E1B,MAAM;iBAER,MAAM;eAgFH,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAchE,kBAAkB;;;;;;;;;;;mBAhGT,MAAM;iBAER,MAAM;;IAqGb,uBAAuB;;;;;;;;;;;mBAvGd,MAAM;iBAER,MAAM;;IA4Gb,iBAAiB;;;;;;;;;;;mBA9GR,MAAM;iBAER,MAAM;eA6Ge,aAAa,CAAC,MAAM,CAAC;0FAInD,CAAC;AAEH,eAAO,MACL,iBAAiB,qGACjB,aAAa,+FACb,gBAAgB,8FAChB,oBAAoB,kGACpB,qBAAqB;QAxCW,MAAM;YAAU,GAAG;WAAS,GAAG;wCAyC/D,eAAe,wFACf,eAAe,wFACf,UAAU,sFACe,CAAC;AAM5B,UAAU,uBAAuB;IAC/B,UAAU,EAAE,eAAe,CAAC;CAC7B;AAGD,eAAO,MAAM,qBAAqB,GAAI,OAAO,uBAAuB,oBAAqB,CAAC;AAC1F,eAAO,MAAM,oBAAoB,GAAI,OAAO,uBAAuB,iBAA0B,CAAC;AAC9F,eAAO,MAAM,yBAAyB,GAAI,OAAO,uBAAuB,WAA+B,CAAC;AAGxG,eAAO,MAAM,uBAAuB;;;;;;;;;;;;2BAJQ,uBAAuB,2BAClB,uBAAuB;;;;;;;;CAMvE,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;2BATU,uBAAuB;;;;;;;;CAYlE,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;2BAdY,uBAAuB;;;;;;;;CAiBlE,CAAC;;AAEF,wBAAuC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Recent Menu Slice
3
+ * 최근 방문 메뉴 상태 관리 (탭)
4
+ */
5
+ import { createSlice, createSelector } from '@reduxjs/toolkit';
6
+ import { storage } from '../utils/storage';
7
+ const initialState = {
8
+ list: [],
9
+ currentId: '',
10
+ maxTabs: 10,
11
+ };
12
+ // ============================================
13
+ // Slice
14
+ // ============================================
15
+ export const recentMenuSlice = createSlice({
16
+ name: 'recentMenu',
17
+ initialState,
18
+ reducers: {
19
+ /** 최근 메뉴 목록 설정 (복구용) */
20
+ setRecentMenuList: (state, action) => {
21
+ state.list = action.payload;
22
+ },
23
+ /** 최근 메뉴 추가/업데이트 */
24
+ addRecentMenu: (state, action) => {
25
+ const newMenu = action.payload;
26
+ const existingIndex = state.list.findIndex((m) => m.id === newMenu.id);
27
+ if (existingIndex >= 0) {
28
+ // 이미 존재하면 업데이트
29
+ state.list[existingIndex] = {
30
+ ...state.list[existingIndex],
31
+ ...newMenu,
32
+ };
33
+ }
34
+ else {
35
+ // 새로 추가
36
+ if (state.list.length >= state.maxTabs) {
37
+ // 최대 개수 초과 시 가장 오래된 것 제거 (현재 활성 제외)
38
+ const oldestIndex = state.list.findIndex((m) => m.id !== state.currentId);
39
+ if (oldestIndex >= 0) {
40
+ state.list.splice(oldestIndex, 1);
41
+ }
42
+ }
43
+ state.list.push(newMenu);
44
+ }
45
+ // 현재 메뉴로 설정
46
+ state.currentId = newMenu.id;
47
+ // localStorage에 저장
48
+ storage.setRecentMenu(state.list);
49
+ },
50
+ /** 최근 메뉴 제거 */
51
+ removeRecentMenu: (state, action) => {
52
+ const id = action.payload;
53
+ const index = state.list.findIndex((m) => m.id === id);
54
+ if (index >= 0) {
55
+ state.list.splice(index, 1);
56
+ // 현재 메뉴가 제거되면 다른 메뉴로 전환
57
+ if (state.currentId === id) {
58
+ // 이전 또는 다음 메뉴로 전환
59
+ const newCurrent = state.list[Math.max(0, index - 1)];
60
+ state.currentId = newCurrent?.id || '';
61
+ }
62
+ // localStorage에 저장
63
+ storage.setRecentMenu(state.list);
64
+ }
65
+ },
66
+ /** 현재 메뉴 변경 */
67
+ setCurrentRecentMenu: (state, action) => {
68
+ state.currentId = action.payload;
69
+ },
70
+ /** 메뉴 상태 업데이트 (스크롤 위치, 검색 조건 등) */
71
+ updateRecentMenuState: (state, action) => {
72
+ const { id, state: menuState, data } = action.payload;
73
+ const menu = state.list.find((m) => m.id === id);
74
+ if (menu) {
75
+ if (menuState !== undefined)
76
+ menu.state = menuState;
77
+ if (data !== undefined)
78
+ menu.data = data;
79
+ // localStorage에 저장
80
+ storage.setRecentMenu(state.list);
81
+ }
82
+ },
83
+ /** 모든 최근 메뉴 제거 */
84
+ clearRecentMenu: (state) => {
85
+ state.list = [];
86
+ state.currentId = '';
87
+ storage.setRecentMenu([]);
88
+ },
89
+ /** 현재 메뉴 외 모든 메뉴 제거 */
90
+ closeOtherMenus: (state) => {
91
+ const currentMenu = state.list.find((m) => m.id === state.currentId);
92
+ state.list = currentMenu ? [currentMenu] : [];
93
+ storage.setRecentMenu(state.list);
94
+ },
95
+ /** 최대 탭 개수 설정 */
96
+ setMaxTabs: (state, action) => {
97
+ state.maxTabs = action.payload;
98
+ },
99
+ },
100
+ });
101
+ export const { setRecentMenuList, addRecentMenu, removeRecentMenu, setCurrentRecentMenu, updateRecentMenuState, clearRecentMenu, closeOtherMenus, setMaxTabs, } = recentMenuSlice.actions;
102
+ // 기본 Selectors
103
+ export const selectRecentMenuState = (state) => state.recentMenu;
104
+ export const selectRecentMenuList = (state) => state.recentMenu.list;
105
+ export const selectCurrentRecentMenuId = (state) => state.recentMenu.currentId;
106
+ // 파생 Selectors (Memoized)
107
+ export const selectCurrentRecentMenu = createSelector([selectRecentMenuList, selectCurrentRecentMenuId], (list, currentId) => list.find((m) => m.id === currentId) || null);
108
+ export const selectRecentMenuCount = createSelector([selectRecentMenuList], (list) => list.length);
109
+ export const selectHasRecentMenu = createSelector([selectRecentMenuList], (list) => list.length > 0);
110
+ export default recentMenuSlice.reducer;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Host Store 접근 유틸리티 - KOMCA 패턴
2
+ * Host Store 접근 유틸리티
3
3
  * Remote 앱에서 Host의 Redux Store에 접근
4
4
  */
5
5
  import { User, HostStore, HostRootState } from '../types';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Host Store 접근 유틸리티 - KOMCA 패턴
2
+ * Host Store 접근 유틸리티
3
3
  * Remote 앱에서 Host의 Redux Store에 접근
4
4
  */
5
5
  /**
@@ -1,12 +1,69 @@
1
1
  /**
2
2
  * MFA 공통 타입 정의
3
3
  */
4
+ import { ReactNode } from 'react';
4
5
  export * from './service';
6
+ /** 사용자 역할 */
7
+ export type UserRole = 'admin' | 'user' | 'editor' | 'viewer' | 'guest';
8
+ /** 권한 액션 타입 */
9
+ export type PermissionAction = 'read' | 'write' | 'delete' | 'admin';
10
+ /** 개별 권한 */
11
+ export interface Permission {
12
+ /** 메뉴/리소스 코드 */
13
+ code: string;
14
+ /** 허용된 액션 목록 */
15
+ actions: PermissionAction[];
16
+ }
17
+ /** 사용자 타입 */
5
18
  export interface User {
6
19
  id: string;
7
20
  name: string;
8
21
  email: string;
9
- role?: 'admin' | 'user';
22
+ role?: UserRole | string;
23
+ avatar?: string;
24
+ /** 사용자 권한 목록 */
25
+ permissions?: Permission[];
26
+ }
27
+ /** 메뉴 권한 요구사항 */
28
+ export interface MenuPermission {
29
+ /** 필요한 메뉴 코드 (OR 조건) */
30
+ requiredCodes?: string[];
31
+ /** 필요한 역할 (OR 조건) */
32
+ requiredRoles?: UserRole[];
33
+ /** 필요한 액션 */
34
+ requiredAction?: PermissionAction;
35
+ }
36
+ /** LNB 메뉴 아이템 (기본) */
37
+ export interface LnbMenuItem {
38
+ id: string;
39
+ title: string;
40
+ path?: string;
41
+ /** 아이콘 (ReactNode 또는 문자열) */
42
+ icon?: ReactNode | string;
43
+ /** 하위 메뉴 */
44
+ children?: LnbMenuItem[];
45
+ /** 권한 요구사항 (없으면 모두 접근 가능) */
46
+ permission?: MenuPermission;
47
+ /** 메뉴 숨김 여부 */
48
+ hidden?: boolean;
49
+ /** 비활성화 여부 */
50
+ disabled?: boolean;
51
+ /** 뱃지 */
52
+ badge?: {
53
+ text: string;
54
+ variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'error';
55
+ };
56
+ }
57
+ /** MenuItem은 LnbMenuItem의 별칭 (하위 호환) */
58
+ export type MenuItem = LnbMenuItem;
59
+ /** Remote에서 export하는 LnbItems 구조 (KOMCA 패턴) */
60
+ export interface RemoteLnbItems {
61
+ /** 경로 prefix */
62
+ pathPrefix?: string;
63
+ /** Guest용 메뉴 (비로그인) */
64
+ hasPrefixList?: LnbMenuItem[];
65
+ /** Auth용 메뉴 (로그인) */
66
+ hasPrefixAuthList?: LnbMenuItem[];
10
67
  }
11
68
  export interface AppState {
12
69
  accessToken: string;
@@ -25,24 +82,22 @@ export interface RecentMenu {
25
82
  state?: any;
26
83
  data?: any;
27
84
  }
28
- export interface MenuItem {
29
- id: string;
30
- title: string;
31
- path: string;
32
- icon?: string;
33
- children?: MenuItem[];
34
- }
35
- export interface MenuState {
36
- menuList: MenuItem[];
37
- }
38
- export interface RecentMenuState {
39
- list: RecentMenu[];
40
- currentId: string;
41
- }
42
85
  export interface HostRootState {
43
86
  app: AppState;
44
- recentMenu: RecentMenuState;
45
- [key: string]: any;
87
+ recentMenu: {
88
+ list: RecentMenu[];
89
+ currentId: string;
90
+ maxTabs?: number;
91
+ };
92
+ menu?: {
93
+ gnbItems: LnbMenuItem[];
94
+ lnbItems: LnbMenuItem[];
95
+ selectedGnbId: string;
96
+ selectedLnbId: string;
97
+ expandedIds: string[];
98
+ isLoading: boolean;
99
+ };
100
+ [key: string]: unknown;
46
101
  }
47
102
  export interface HostStore {
48
103
  getState: () => HostRootState;
@@ -50,9 +105,11 @@ export interface HostStore {
50
105
  subscribe: (listener: () => void) => () => void;
51
106
  replaceReducer: (reducer: any) => void;
52
107
  }
108
+ export type InjectReducerFn = (key: string, reducer: import('@reduxjs/toolkit').Reducer) => void;
53
109
  declare global {
54
110
  interface Window {
55
111
  __REDUX_STORE__: HostStore;
112
+ __INJECT_REDUCER__?: InjectReducerFn;
56
113
  }
57
114
  }
58
115
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,cAAc,WAAW,CAAC;AAG1B,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAGD,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAGD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAGD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAGD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,QAAQ,CAAC;IACd,UAAU,EAAE,eAAe,CAAC;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,aAAa,CAAC;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAC/B,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAChD,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;CACxC;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,eAAe,EAAE,SAAS,CAAC;KAC5B;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Service Type 정의 - KOMCA 패턴
2
+ * Service Type 정의
3
3
  * 각 Remote 앱을 구분하는 타입
4
4
  */
5
5
  export type ServiceType = 'resume' | 'blog' | 'portfolio';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Service Type 정의 - KOMCA 패턴
2
+ * Service Type 정의
3
3
  * 각 Remote 앱을 구분하는 타입
4
4
  */
5
5
  // Service Type → Prefix 매핑
@@ -0,0 +1,65 @@
1
+ /**
2
+ * ClassName 유틸리티
3
+ * 조건부 클래스 이름 결합 (clsx/classnames 대체)
4
+ * 외부 의존성 없이 구현
5
+ */
6
+ export type ClassValue = string | number | boolean | null | undefined | ClassValue[] | Record<string, boolean | null | undefined>;
7
+ /**
8
+ * 여러 클래스 이름을 조건부로 결합
9
+ *
10
+ * @example
11
+ * // 기본 사용
12
+ * cn('foo', 'bar') // 'foo bar'
13
+ *
14
+ * @example
15
+ * // 조건부 클래스
16
+ * cn('btn', { 'btn-primary': isPrimary, 'btn-disabled': isDisabled })
17
+ * // isPrimary=true, isDisabled=false -> 'btn btn-primary'
18
+ *
19
+ * @example
20
+ * // 배열 사용
21
+ * cn(['foo', 'bar'], 'baz') // 'foo bar baz'
22
+ *
23
+ * @example
24
+ * // falsy 값 무시
25
+ * cn('foo', null, undefined, false, 'bar') // 'foo bar'
26
+ */
27
+ export declare function cn(...inputs: ClassValue[]): string;
28
+ /**
29
+ * cn의 별칭 (classNames)
30
+ */
31
+ export declare const classNames: typeof cn;
32
+ /**
33
+ * cn의 별칭 (clsx 호환)
34
+ */
35
+ export declare const clsx: typeof cn;
36
+ /**
37
+ * 조건부 클래스 생성 헬퍼
38
+ *
39
+ * @example
40
+ * const buttonClass = createClassVariants({
41
+ * base: 'btn',
42
+ * variants: {
43
+ * variant: {
44
+ * primary: 'btn-primary',
45
+ * secondary: 'btn-secondary',
46
+ * },
47
+ * size: {
48
+ * sm: 'btn-sm',
49
+ * md: 'btn-md',
50
+ * lg: 'btn-lg',
51
+ * },
52
+ * },
53
+ * });
54
+ *
55
+ * buttonClass({ variant: 'primary', size: 'lg' })
56
+ * // 'btn btn-primary btn-lg'
57
+ */
58
+ export declare function createClassVariants<T extends Record<string, Record<string, string>>>(config: {
59
+ base?: string;
60
+ variants: T;
61
+ }): (options: Partial<{
62
+ [K in keyof T]: keyof T[K];
63
+ }>) => string;
64
+ export default cn;
65
+ //# sourceMappingURL=classnames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classnames.d.ts","sourceRoot":"","sources":["../../src/utils/classnames.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,UAAU,EAAE,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAqBlD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,WAAK,CAAC;AAE7B;;GAEG;AACH,eAAO,MAAM,IAAI,WAAK,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAChD,MAAM,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC;CACb,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,KAAK,MAAM,CAkB/D;AAED,eAAe,EAAE,CAAC"}