@udhuong/admin-core 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/dist/client/auth/AuthContext.d.ts +19 -0
  2. package/dist/client/auth/AuthContext.d.ts.map +1 -0
  3. package/dist/client/auth/AuthContext.js +115 -0
  4. package/dist/client/auth/AuthContext.js.map +1 -0
  5. package/dist/client/auth/PermissionGuard.d.ts +12 -0
  6. package/dist/client/auth/PermissionGuard.d.ts.map +1 -0
  7. package/dist/client/auth/PermissionGuard.js +23 -0
  8. package/dist/client/auth/PermissionGuard.js.map +1 -0
  9. package/dist/client/auth/ProtectedPage.d.ts +9 -0
  10. package/dist/client/auth/ProtectedPage.d.ts.map +1 -0
  11. package/dist/client/auth/ProtectedPage.js +57 -0
  12. package/dist/client/auth/ProtectedPage.js.map +1 -0
  13. package/dist/client/auth/ProtectedRoute.d.ts +4 -0
  14. package/dist/client/auth/ProtectedRoute.d.ts.map +1 -0
  15. package/dist/client/auth/ProtectedRoute.js +25 -0
  16. package/dist/client/auth/ProtectedRoute.js.map +1 -0
  17. package/dist/client/auth/api-client.d.ts +4 -0
  18. package/dist/client/auth/api-client.d.ts.map +1 -0
  19. package/dist/client/auth/api-client.js +83 -0
  20. package/dist/client/auth/api-client.js.map +1 -0
  21. package/dist/client/auth/auth.service.d.ts +7 -0
  22. package/dist/client/auth/auth.service.d.ts.map +1 -0
  23. package/dist/client/auth/auth.service.js +19 -0
  24. package/dist/client/auth/auth.service.js.map +1 -0
  25. package/dist/client/auth/index.d.ts +7 -0
  26. package/dist/client/auth/index.d.ts.map +1 -0
  27. package/dist/client/auth/index.js +7 -0
  28. package/dist/client/auth/index.js.map +1 -0
  29. package/dist/client/components/PageHeader.d.ts +19 -0
  30. package/dist/client/components/PageHeader.d.ts.map +1 -0
  31. package/dist/client/components/PageHeader.js +7 -0
  32. package/dist/client/components/PageHeader.js.map +1 -0
  33. package/dist/client/components/Providers.d.ts +9 -0
  34. package/dist/client/components/Providers.d.ts.map +1 -0
  35. package/dist/client/components/Providers.js +52 -0
  36. package/dist/client/components/Providers.js.map +1 -0
  37. package/dist/client/components/ThemeToggle.d.ts +6 -0
  38. package/dist/client/components/ThemeToggle.d.ts.map +1 -0
  39. package/dist/client/components/ThemeToggle.js +22 -0
  40. package/dist/client/components/ThemeToggle.js.map +1 -0
  41. package/dist/client/components/index.d.ts +4 -0
  42. package/dist/client/components/index.d.ts.map +1 -0
  43. package/dist/client/components/index.js +4 -0
  44. package/dist/client/components/index.js.map +1 -0
  45. package/dist/client/config/AdminConfigContext.d.ts +12 -0
  46. package/dist/client/config/AdminConfigContext.d.ts.map +1 -0
  47. package/dist/client/config/AdminConfigContext.js +29 -0
  48. package/dist/client/config/AdminConfigContext.js.map +1 -0
  49. package/dist/client/config/defaults.d.ts +4 -0
  50. package/dist/client/config/defaults.d.ts.map +1 -0
  51. package/dist/client/config/defaults.js +86 -0
  52. package/dist/client/config/defaults.js.map +1 -0
  53. package/dist/client/config/types.d.ts +61 -0
  54. package/dist/client/config/types.d.ts.map +1 -0
  55. package/dist/client/config/types.js +2 -0
  56. package/dist/client/config/types.js.map +1 -0
  57. package/dist/client/constants/api-routes.d.ts +104 -0
  58. package/dist/client/constants/api-routes.d.ts.map +1 -0
  59. package/dist/client/constants/api-routes.js +91 -0
  60. package/dist/client/constants/api-routes.js.map +1 -0
  61. package/dist/client/constants/permissions.d.ts +38 -0
  62. package/dist/client/constants/permissions.d.ts.map +1 -0
  63. package/dist/client/constants/permissions.js +37 -0
  64. package/dist/client/constants/permissions.js.map +1 -0
  65. package/dist/client/contexts/ThemeContext.d.ts +3 -0
  66. package/dist/client/contexts/ThemeContext.d.ts.map +1 -0
  67. package/dist/client/contexts/ThemeContext.js +8 -0
  68. package/dist/client/contexts/ThemeContext.js.map +1 -0
  69. package/dist/client/hooks/useToast.d.ts +14 -0
  70. package/dist/client/hooks/useToast.d.ts.map +1 -0
  71. package/dist/client/hooks/useToast.js +90 -0
  72. package/dist/client/hooks/useToast.js.map +1 -0
  73. package/dist/client/index.d.ts +25 -0
  74. package/dist/client/index.d.ts.map +1 -0
  75. package/dist/client/index.js +33 -0
  76. package/dist/client/index.js.map +1 -0
  77. package/dist/client/layouts/AdminLayout.d.ts +4 -0
  78. package/dist/client/layouts/AdminLayout.d.ts.map +1 -0
  79. package/dist/client/layouts/AdminLayout.js +72 -0
  80. package/dist/client/layouts/AdminLayout.js.map +1 -0
  81. package/dist/client/layouts/Sidebar.d.ts +6 -0
  82. package/dist/client/layouts/Sidebar.d.ts.map +1 -0
  83. package/dist/client/layouts/Sidebar.js +86 -0
  84. package/dist/client/layouts/Sidebar.js.map +1 -0
  85. package/dist/client/layouts/index.d.ts +3 -0
  86. package/dist/client/layouts/index.d.ts.map +1 -0
  87. package/dist/client/layouts/index.js +3 -0
  88. package/dist/client/layouts/index.js.map +1 -0
  89. package/dist/client/lib/utils.d.ts +5 -0
  90. package/dist/client/lib/utils.d.ts.map +1 -0
  91. package/dist/client/lib/utils.js +22 -0
  92. package/dist/client/lib/utils.js.map +1 -0
  93. package/dist/client/pages/ChangePasswordPage.d.ts +2 -0
  94. package/dist/client/pages/ChangePasswordPage.d.ts.map +1 -0
  95. package/dist/client/pages/ChangePasswordPage.js +58 -0
  96. package/dist/client/pages/ChangePasswordPage.js.map +1 -0
  97. package/dist/client/pages/ForgotPasswordPage.d.ts +2 -0
  98. package/dist/client/pages/ForgotPasswordPage.d.ts.map +1 -0
  99. package/dist/client/pages/ForgotPasswordPage.js +30 -0
  100. package/dist/client/pages/ForgotPasswordPage.js.map +1 -0
  101. package/dist/client/pages/LoginPage.d.ts +2 -0
  102. package/dist/client/pages/LoginPage.d.ts.map +1 -0
  103. package/dist/client/pages/LoginPage.js +52 -0
  104. package/dist/client/pages/LoginPage.js.map +1 -0
  105. package/dist/client/pages/PermissionsPage.d.ts +2 -0
  106. package/dist/client/pages/PermissionsPage.d.ts.map +1 -0
  107. package/dist/client/pages/PermissionsPage.js +42 -0
  108. package/dist/client/pages/PermissionsPage.js.map +1 -0
  109. package/dist/client/pages/ProfilePage.d.ts +2 -0
  110. package/dist/client/pages/ProfilePage.d.ts.map +1 -0
  111. package/dist/client/pages/ProfilePage.js +107 -0
  112. package/dist/client/pages/ProfilePage.js.map +1 -0
  113. package/dist/client/pages/ResetPasswordPage.d.ts +2 -0
  114. package/dist/client/pages/ResetPasswordPage.d.ts.map +1 -0
  115. package/dist/client/pages/ResetPasswordPage.js +68 -0
  116. package/dist/client/pages/ResetPasswordPage.js.map +1 -0
  117. package/dist/client/pages/RolesPage.d.ts +2 -0
  118. package/dist/client/pages/RolesPage.d.ts.map +1 -0
  119. package/dist/client/pages/RolesPage.js +82 -0
  120. package/dist/client/pages/RolesPage.js.map +1 -0
  121. package/dist/client/pages/UnauthorizedPage.d.ts +2 -0
  122. package/dist/client/pages/UnauthorizedPage.d.ts.map +1 -0
  123. package/dist/client/pages/UnauthorizedPage.js +9 -0
  124. package/dist/client/pages/UnauthorizedPage.js.map +1 -0
  125. package/dist/client/pages/UserDetailPage.d.ts +6 -0
  126. package/dist/client/pages/UserDetailPage.d.ts.map +1 -0
  127. package/dist/client/pages/UserDetailPage.js +220 -0
  128. package/dist/client/pages/UserDetailPage.js.map +1 -0
  129. package/dist/client/pages/UserPreferencesPage.d.ts +2 -0
  130. package/dist/client/pages/UserPreferencesPage.d.ts.map +1 -0
  131. package/dist/client/pages/UserPreferencesPage.js +152 -0
  132. package/dist/client/pages/UserPreferencesPage.js.map +1 -0
  133. package/dist/client/pages/UsersPage.d.ts +2 -0
  134. package/dist/client/pages/UsersPage.d.ts.map +1 -0
  135. package/dist/client/pages/UsersPage.js +228 -0
  136. package/dist/client/pages/UsersPage.js.map +1 -0
  137. package/dist/client/pages/VerifyEmailPage.d.ts +2 -0
  138. package/dist/client/pages/VerifyEmailPage.d.ts.map +1 -0
  139. package/dist/client/pages/VerifyEmailPage.js +43 -0
  140. package/dist/client/pages/VerifyEmailPage.js.map +1 -0
  141. package/dist/client/pages/index.d.ts +13 -0
  142. package/dist/client/pages/index.d.ts.map +1 -0
  143. package/dist/client/pages/index.js +13 -0
  144. package/dist/client/pages/index.js.map +1 -0
  145. package/dist/client/pages/roles/RoleModal.d.ts +10 -0
  146. package/dist/client/pages/roles/RoleModal.d.ts.map +1 -0
  147. package/dist/client/pages/roles/RoleModal.js +123 -0
  148. package/dist/client/pages/roles/RoleModal.js.map +1 -0
  149. package/dist/client/pages/users/DangerZone.d.ts +10 -0
  150. package/dist/client/pages/users/DangerZone.d.ts.map +1 -0
  151. package/dist/client/pages/users/DangerZone.js +8 -0
  152. package/dist/client/pages/users/DangerZone.js.map +1 -0
  153. package/dist/client/pages/users/ProfileCard.d.ts +14 -0
  154. package/dist/client/pages/users/ProfileCard.d.ts.map +1 -0
  155. package/dist/client/pages/users/ProfileCard.js +8 -0
  156. package/dist/client/pages/users/ProfileCard.js.map +1 -0
  157. package/dist/client/pages/users/SecuritySection.d.ts +14 -0
  158. package/dist/client/pages/users/SecuritySection.d.ts.map +1 -0
  159. package/dist/client/pages/users/SecuritySection.js +16 -0
  160. package/dist/client/pages/users/SecuritySection.js.map +1 -0
  161. package/dist/client/pages/users/SessionsSection.d.ts +25 -0
  162. package/dist/client/pages/users/SessionsSection.d.ts.map +1 -0
  163. package/dist/client/pages/users/SessionsSection.js +93 -0
  164. package/dist/client/pages/users/SessionsSection.js.map +1 -0
  165. package/dist/client/pages/users/SocialAccountsSection.d.ts +29 -0
  166. package/dist/client/pages/users/SocialAccountsSection.d.ts.map +1 -0
  167. package/dist/client/pages/users/SocialAccountsSection.js +72 -0
  168. package/dist/client/pages/users/SocialAccountsSection.js.map +1 -0
  169. package/dist/client/pages/users/UserDetailModal.d.ts +24 -0
  170. package/dist/client/pages/users/UserDetailModal.d.ts.map +1 -0
  171. package/dist/client/pages/users/UserDetailModal.js +42 -0
  172. package/dist/client/pages/users/UserDetailModal.js.map +1 -0
  173. package/dist/client/pages/users/UserFilters.d.ts +14 -0
  174. package/dist/client/pages/users/UserFilters.d.ts.map +1 -0
  175. package/dist/client/pages/users/UserFilters.js +22 -0
  176. package/dist/client/pages/users/UserFilters.js.map +1 -0
  177. package/dist/client/pages/users/UserStats.d.ts +9 -0
  178. package/dist/client/pages/users/UserStats.d.ts.map +1 -0
  179. package/dist/client/pages/users/UserStats.js +37 -0
  180. package/dist/client/pages/users/UserStats.js.map +1 -0
  181. package/dist/client/pages/users/UserTable.d.ts +24 -0
  182. package/dist/client/pages/users/UserTable.d.ts.map +1 -0
  183. package/dist/client/pages/users/UserTable.js +39 -0
  184. package/dist/client/pages/users/UserTable.js.map +1 -0
  185. package/dist/client/pages/users/VerificationSection.d.ts +9 -0
  186. package/dist/client/pages/users/VerificationSection.d.ts.map +1 -0
  187. package/dist/client/pages/users/VerificationSection.js +8 -0
  188. package/dist/client/pages/users/VerificationSection.js.map +1 -0
  189. package/dist/client/types/auth.d.ts +29 -0
  190. package/dist/client/types/auth.d.ts.map +1 -0
  191. package/dist/client/types/auth.js +2 -0
  192. package/dist/client/types/auth.js.map +1 -0
  193. package/dist/client/types/rbac.d.ts +39 -0
  194. package/dist/client/types/rbac.d.ts.map +1 -0
  195. package/dist/client/types/rbac.js +5 -0
  196. package/dist/client/types/rbac.js.map +1 -0
  197. package/dist/client/types/status.d.ts +12 -0
  198. package/dist/client/types/status.d.ts.map +1 -0
  199. package/dist/client/types/status.js +14 -0
  200. package/dist/client/types/status.js.map +1 -0
  201. package/dist/client/ui/Badge.d.ts +14 -0
  202. package/dist/client/ui/Badge.d.ts.map +1 -0
  203. package/dist/client/ui/Badge.js +32 -0
  204. package/dist/client/ui/Badge.js.map +1 -0
  205. package/dist/client/ui/Button.d.ts +18 -0
  206. package/dist/client/ui/Button.d.ts.map +1 -0
  207. package/dist/client/ui/Button.js +33 -0
  208. package/dist/client/ui/Button.js.map +1 -0
  209. package/dist/client/ui/Checkbox.d.ts +14 -0
  210. package/dist/client/ui/Checkbox.d.ts.map +1 -0
  211. package/dist/client/ui/Checkbox.js +35 -0
  212. package/dist/client/ui/Checkbox.js.map +1 -0
  213. package/dist/client/ui/ConfirmModal.d.ts +14 -0
  214. package/dist/client/ui/ConfirmModal.d.ts.map +1 -0
  215. package/dist/client/ui/ConfirmModal.js +43 -0
  216. package/dist/client/ui/ConfirmModal.js.map +1 -0
  217. package/dist/client/ui/DataTable.d.ts +69 -0
  218. package/dist/client/ui/DataTable.d.ts.map +1 -0
  219. package/dist/client/ui/DataTable.js +133 -0
  220. package/dist/client/ui/DataTable.js.map +1 -0
  221. package/dist/client/ui/Dropdown.d.ts +11 -0
  222. package/dist/client/ui/Dropdown.d.ts.map +1 -0
  223. package/dist/client/ui/Dropdown.js +65 -0
  224. package/dist/client/ui/Dropdown.js.map +1 -0
  225. package/dist/client/ui/FileInput.d.ts +16 -0
  226. package/dist/client/ui/FileInput.d.ts.map +1 -0
  227. package/dist/client/ui/FileInput.js +45 -0
  228. package/dist/client/ui/FileInput.js.map +1 -0
  229. package/dist/client/ui/Input.d.ts +16 -0
  230. package/dist/client/ui/Input.d.ts.map +1 -0
  231. package/dist/client/ui/Input.js +33 -0
  232. package/dist/client/ui/Input.js.map +1 -0
  233. package/dist/client/ui/LoadingSpinner.d.ts +7 -0
  234. package/dist/client/ui/LoadingSpinner.d.ts.map +1 -0
  235. package/dist/client/ui/LoadingSpinner.js +12 -0
  236. package/dist/client/ui/LoadingSpinner.js.map +1 -0
  237. package/dist/client/ui/Modal.d.ts +14 -0
  238. package/dist/client/ui/Modal.d.ts.map +1 -0
  239. package/dist/client/ui/Modal.js +46 -0
  240. package/dist/client/ui/Modal.js.map +1 -0
  241. package/dist/client/ui/Pagination.d.ts +14 -0
  242. package/dist/client/ui/Pagination.d.ts.map +1 -0
  243. package/dist/client/ui/Pagination.js +50 -0
  244. package/dist/client/ui/Pagination.js.map +1 -0
  245. package/dist/client/ui/Radio.d.ts +34 -0
  246. package/dist/client/ui/Radio.d.ts.map +1 -0
  247. package/dist/client/ui/Radio.js +44 -0
  248. package/dist/client/ui/Radio.js.map +1 -0
  249. package/dist/client/ui/Range.d.ts +17 -0
  250. package/dist/client/ui/Range.d.ts.map +1 -0
  251. package/dist/client/ui/Range.js +28 -0
  252. package/dist/client/ui/Range.js.map +1 -0
  253. package/dist/client/ui/Rating.d.ts +18 -0
  254. package/dist/client/ui/Rating.d.ts.map +1 -0
  255. package/dist/client/ui/Rating.js +64 -0
  256. package/dist/client/ui/Rating.js.map +1 -0
  257. package/dist/client/ui/Select.d.ts +20 -0
  258. package/dist/client/ui/Select.d.ts.map +1 -0
  259. package/dist/client/ui/Select.js +30 -0
  260. package/dist/client/ui/Select.js.map +1 -0
  261. package/dist/client/ui/Textarea.d.ts +14 -0
  262. package/dist/client/ui/Textarea.d.ts.map +1 -0
  263. package/dist/client/ui/Textarea.js +20 -0
  264. package/dist/client/ui/Textarea.js.map +1 -0
  265. package/dist/client/ui/Toggle.d.ts +13 -0
  266. package/dist/client/ui/Toggle.d.ts.map +1 -0
  267. package/dist/client/ui/Toggle.js +29 -0
  268. package/dist/client/ui/Toggle.js.map +1 -0
  269. package/dist/client/ui/index.d.ts +31 -0
  270. package/dist/client/ui/index.d.ts.map +1 -0
  271. package/dist/client/ui/index.js +35 -0
  272. package/dist/client/ui/index.js.map +1 -0
  273. package/dist/tailwind.preset.d.ts +10 -0
  274. package/dist/tailwind.preset.js +12 -0
  275. package/package.json +46 -17
@@ -0,0 +1,19 @@
1
+ import { LoginCredentials, User } from '../types/auth';
2
+ import React from 'react';
3
+ interface AuthContextType {
4
+ user: User | null;
5
+ loading: boolean;
6
+ login: (credentials: LoginCredentials) => Promise<void>;
7
+ logout: () => void;
8
+ refreshProfile: () => Promise<void>;
9
+ isAuthenticated: boolean;
10
+ can: (permission: string) => boolean;
11
+ hasAnyPermission: (permissions: string[]) => boolean;
12
+ hasAllPermissions: (permissions: string[]) => boolean;
13
+ }
14
+ export declare function AuthProvider({ children }: {
15
+ children: React.ReactNode;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ export declare function useAuth(): AuthContextType;
18
+ export {};
19
+ //# sourceMappingURL=AuthContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../../src/client/auth/AuthContext.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAgB,gBAAgB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpE,OAAO,KAAyD,MAAM,OAAO,CAAA;AAE7E,UAAU,eAAe;IACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,CAAC,WAAW,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,eAAe,EAAE,OAAO,CAAA;IACxB,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAA;IACpC,gBAAgB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAA;IACpD,iBAAiB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAA;CACtD;AAID,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CA4GvE;AAED,wBAAgB,OAAO,oBAMtB"}
@@ -0,0 +1,115 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useAdminConfig } from '../config/AdminConfigContext';
4
+ import { getApiClient } from './api-client';
5
+ import { CORE_API_ROUTES } from '../constants/api-routes';
6
+ import { useRouter } from 'next/navigation';
7
+ import { createContext, useContext, useEffect, useState } from 'react';
8
+ const AuthContext = createContext(undefined);
9
+ export function AuthProvider({ children }) {
10
+ const [user, setUser] = useState(null);
11
+ const [loading, setLoading] = useState(true);
12
+ const router = useRouter();
13
+ const config = useAdminConfig();
14
+ const tokenKey = config.tokenStorageKey || 'admin_token';
15
+ const routes = config.resolvedRoutes;
16
+ useEffect(() => {
17
+ checkAuth();
18
+ }, []);
19
+ const checkAuth = async () => {
20
+ try {
21
+ const token = localStorage.getItem(tokenKey);
22
+ if (token) {
23
+ const apiClient = getApiClient();
24
+ const response = await apiClient.get(CORE_API_ROUTES.AUTH.PROFILE);
25
+ const userData = response.data?.data || response.data;
26
+ setUser(userData);
27
+ }
28
+ }
29
+ catch (error) {
30
+ console.error('Auth check failed:', error?.message);
31
+ localStorage.removeItem(tokenKey);
32
+ setUser(null);
33
+ }
34
+ finally {
35
+ setLoading(false);
36
+ }
37
+ };
38
+ const login = async (credentials) => {
39
+ try {
40
+ const apiClient = getApiClient();
41
+ const response = await apiClient.post(CORE_API_ROUTES.AUTH.LOGIN, credentials);
42
+ const data = response.data;
43
+ const accessToken = data?.accessToken;
44
+ const loginUser = data?.user;
45
+ if (!accessToken || !loginUser) {
46
+ throw new Error('Invalid login response: missing token or user');
47
+ }
48
+ localStorage.setItem(tokenKey, accessToken);
49
+ setUser(loginUser);
50
+ if (loginUser.isFirstLogin) {
51
+ router.push(routes.CHANGE_PASSWORD);
52
+ }
53
+ else {
54
+ router.push(routes.DASHBOARD);
55
+ }
56
+ }
57
+ catch (error) {
58
+ console.error('Login failed:', error);
59
+ throw error;
60
+ }
61
+ };
62
+ const logout = () => {
63
+ localStorage.removeItem(tokenKey);
64
+ setUser(null);
65
+ router.push(routes.LOGIN);
66
+ };
67
+ const refreshProfile = async () => {
68
+ try {
69
+ const token = localStorage.getItem(tokenKey);
70
+ if (token) {
71
+ const apiClient = getApiClient();
72
+ const response = await apiClient.get(CORE_API_ROUTES.AUTH.PROFILE);
73
+ const userData = response.data?.data || response.data;
74
+ setUser(userData);
75
+ }
76
+ }
77
+ catch (error) {
78
+ console.error('Failed to refresh profile:', error);
79
+ }
80
+ };
81
+ const can = (permission) => {
82
+ if (!user?.permissions)
83
+ return false;
84
+ return user.permissions.includes(permission);
85
+ };
86
+ const hasAnyPermission = (permissions) => {
87
+ if (!user?.permissions)
88
+ return false;
89
+ return permissions.some(permission => user.permissions.includes(permission));
90
+ };
91
+ const hasAllPermissions = (permissions) => {
92
+ if (!user?.permissions)
93
+ return false;
94
+ return permissions.every(permission => user.permissions.includes(permission));
95
+ };
96
+ return (_jsx(AuthContext.Provider, { value: {
97
+ user,
98
+ loading,
99
+ login,
100
+ logout,
101
+ refreshProfile,
102
+ isAuthenticated: !!user,
103
+ can,
104
+ hasAnyPermission,
105
+ hasAllPermissions,
106
+ }, children: children }));
107
+ }
108
+ export function useAuth() {
109
+ const context = useContext(AuthContext);
110
+ if (context === undefined) {
111
+ throw new Error('useAuth must be used within an AuthProvider');
112
+ }
113
+ return context;
114
+ }
115
+ //# sourceMappingURL=AuthContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthContext.js","sourceRoot":"","sources":["../../../src/client/auth/AuthContext.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ interface PermissionGuardProps {
3
+ permission?: string;
4
+ permissions?: string[];
5
+ requireAll?: boolean;
6
+ fallback?: ReactNode;
7
+ showFallback?: boolean;
8
+ children: ReactNode;
9
+ }
10
+ export default function PermissionGuard({ permission, permissions, requireAll, fallback, showFallback, children, }: PermissionGuardProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
12
+ //# sourceMappingURL=PermissionGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGuard.d.ts","sourceRoot":"","sources":["../../../src/client/auth/PermissionGuard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjC,UAAU,oBAAoB;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,UAAU,EACV,WAAW,EACX,UAAkB,EAClB,QAAiG,EACjG,YAAoB,EACpB,QAAQ,GACT,EAAE,oBAAoB,kDAoBtB"}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useAuth } from './AuthContext';
4
+ export default function PermissionGuard({ permission, permissions, requireAll = false, fallback = _jsx("div", { className: "text-gray-500 text-sm", children: "B\u1EA1n kh\u00F4ng c\u00F3 quy\u1EC1n truy c\u1EADp ch\u1EE9c n\u0103ng n\u00E0y" }), showFallback = false, children, }) {
5
+ const { can, hasAnyPermission, hasAllPermissions } = useAuth();
6
+ let hasAccess = true;
7
+ if (permission) {
8
+ hasAccess = can(permission);
9
+ }
10
+ else if (permissions && permissions.length > 0) {
11
+ if (requireAll) {
12
+ hasAccess = hasAllPermissions(permissions);
13
+ }
14
+ else {
15
+ hasAccess = hasAnyPermission(permissions);
16
+ }
17
+ }
18
+ if (!hasAccess) {
19
+ return showFallback ? _jsx(_Fragment, { children: fallback }) : null;
20
+ }
21
+ return _jsx(_Fragment, { children: children });
22
+ }
23
+ //# sourceMappingURL=PermissionGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGuard.js","sourceRoot":"","sources":["../../../src/client/auth/PermissionGuard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAGZ,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAWvC,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,UAAU,EACV,WAAW,EACX,UAAU,GAAG,KAAK,EAClB,QAAQ,GAAG,cAAK,SAAS,EAAC,uBAAuB,kGAAgD,EACjG,YAAY,GAAG,KAAK,EACpB,QAAQ,GACa;IACrB,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,OAAO,EAAE,CAAA;IAE9D,IAAI,SAAS,GAAG,IAAI,CAAA;IAEpB,IAAI,UAAU,EAAE,CAAC;QACf,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;SAAM,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,YAAY,CAAC,CAAC,CAAC,4BAAG,QAAQ,GAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9C,CAAC;IAED,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC"}
@@ -0,0 +1,9 @@
1
+ interface ProtectedPageProps {
2
+ permission?: string;
3
+ permissions?: string[];
4
+ requireAll?: boolean;
5
+ children: React.ReactNode;
6
+ }
7
+ export default function ProtectedPage({ permission, permissions, requireAll, children, }: ProtectedPageProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export {};
9
+ //# sourceMappingURL=ProtectedPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedPage.d.ts","sourceRoot":"","sources":["../../../src/client/auth/ProtectedPage.tsx"],"names":[],"mappings":"AAOA,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,UAAU,EACV,WAAW,EACX,UAAkB,EAClB,QAAQ,GACT,EAAE,kBAAkB,kDA2DpB"}
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { useAuth } from './AuthContext';
6
+ import { useAdminConfig } from '../config/AdminConfigContext';
7
+ export default function ProtectedPage({ permission, permissions, requireAll = false, children, }) {
8
+ const { user, loading, can, hasAnyPermission, hasAllPermissions } = useAuth();
9
+ const router = useRouter();
10
+ const { resolvedRoutes } = useAdminConfig();
11
+ useEffect(() => {
12
+ if (loading)
13
+ return;
14
+ if (!user) {
15
+ router.push(resolvedRoutes.LOGIN);
16
+ return;
17
+ }
18
+ let hasAccess = true;
19
+ if (permission) {
20
+ hasAccess = can(permission);
21
+ }
22
+ else if (permissions && permissions.length > 0) {
23
+ if (requireAll) {
24
+ hasAccess = hasAllPermissions(permissions);
25
+ }
26
+ else {
27
+ hasAccess = hasAnyPermission(permissions);
28
+ }
29
+ }
30
+ if (!hasAccess) {
31
+ router.push(resolvedRoutes.UNAUTHORIZED);
32
+ }
33
+ }, [user, loading, permission, permissions, requireAll, can, hasAnyPermission, hasAllPermissions, router, resolvedRoutes]);
34
+ if (loading) {
35
+ return (_jsx("div", { className: "flex items-center justify-center min-h-screen", children: _jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900" }) }));
36
+ }
37
+ if (!user) {
38
+ return null;
39
+ }
40
+ let hasAccess = true;
41
+ if (permission) {
42
+ hasAccess = can(permission);
43
+ }
44
+ else if (permissions && permissions.length > 0) {
45
+ if (requireAll) {
46
+ hasAccess = hasAllPermissions(permissions);
47
+ }
48
+ else {
49
+ hasAccess = hasAnyPermission(permissions);
50
+ }
51
+ }
52
+ if (!hasAccess) {
53
+ return null;
54
+ }
55
+ return _jsx(_Fragment, { children: children });
56
+ }
57
+ //# sourceMappingURL=ProtectedPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedPage.js","sourceRoot":"","sources":["../../../src/client/auth/ProtectedPage.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAS7D,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,UAAU,EACV,WAAW,EACX,UAAU,GAAG,KAAK,EAClB,QAAQ,GACW;IACnB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,OAAO,EAAE,CAAA;IAC7E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAAA;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO;YAAE,OAAM;QAEnB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;YACjC,OAAM;QACR,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAA;QAEpB,IAAI,UAAU,EAAE,CAAC;YACf,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;QAC7B,CAAC;aAAM,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,UAAU,EAAE,CAAC;gBACf,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;YAC5C,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;YAC3C,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;IAE1H,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,+CAA+C,YAC5D,cAAK,SAAS,EAAC,8DAA8D,GAAO,GAChF,CACP,CAAA;IACH,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,SAAS,GAAG,IAAI,CAAA;IAEpB,IAAI,UAAU,EAAE,CAAC;QACf,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;SAAM,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export default function ProtectedRoute({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react/jsx-runtime").JSX.Element | null;
4
+ //# sourceMappingURL=ProtectedRoute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedRoute.d.ts","sourceRoot":"","sources":["../../../src/client/auth/ProtectedRoute.tsx"],"names":[],"mappings":"AAQA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,kDAwBjF"}
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { useAuth } from './AuthContext';
6
+ import { useAdminConfig } from '../config/AdminConfigContext';
7
+ import LoadingSpinner from '../ui/LoadingSpinner';
8
+ export default function ProtectedRoute({ children }) {
9
+ const { isAuthenticated, loading } = useAuth();
10
+ const router = useRouter();
11
+ const { resolvedRoutes } = useAdminConfig();
12
+ useEffect(() => {
13
+ if (!loading && !isAuthenticated) {
14
+ router.push(resolvedRoutes.LOGIN);
15
+ }
16
+ }, [isAuthenticated, loading, router, resolvedRoutes.LOGIN]);
17
+ if (loading) {
18
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center", children: _jsx(LoadingSpinner, { size: "lg" }) }));
19
+ }
20
+ if (!isAuthenticated) {
21
+ return null;
22
+ }
23
+ return _jsx(_Fragment, { children: children });
24
+ }
25
+ //# sourceMappingURL=ProtectedRoute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedRoute.js","sourceRoot":"","sources":["../../../src/client/auth/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,cAAc,MAAM,sBAAsB,CAAA;AAEjD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAiC;IAChF,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAAA;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAE5D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,+CAA+C,YAC5D,KAAC,cAAc,IAAC,IAAI,EAAC,IAAI,GAAG,GACxB,CACP,CAAA;IACH,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export declare function initApiClient(baseURL: string, tokenKey: string, loginRoute: string, authProfileRoute?: string): AxiosInstance;
3
+ export declare function getApiClient(): AxiosInstance;
4
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/client/auth/api-client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAQ5C,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,gBAAgB,GAAE,MAAwB,iBAgF3C;AAED,wBAAgB,YAAY,IAAI,aAAa,CAK5C"}
@@ -0,0 +1,83 @@
1
+ import axios from 'axios';
2
+ import toast from 'react-hot-toast';
3
+ let _apiClient = null;
4
+ let _tokenStorageKey = 'admin_token';
5
+ let _loginRoute = '/login';
6
+ let _authProfileRoute = '/auth/profile';
7
+ export function initApiClient(baseURL, tokenKey, loginRoute, authProfileRoute = '/auth/profile') {
8
+ _tokenStorageKey = tokenKey;
9
+ _loginRoute = loginRoute;
10
+ _authProfileRoute = authProfileRoute;
11
+ _apiClient = axios.create({
12
+ baseURL,
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ },
16
+ });
17
+ _apiClient.interceptors.request.use((config) => {
18
+ const token = localStorage.getItem(_tokenStorageKey);
19
+ if (token) {
20
+ config.headers.Authorization = `Bearer ${token}`;
21
+ }
22
+ if (config.data instanceof FormData) {
23
+ delete config.headers['Content-Type'];
24
+ }
25
+ return config;
26
+ }, (error) => Promise.reject(error));
27
+ _apiClient.interceptors.response.use((response) => {
28
+ if (response.data && response.data.success !== undefined && response.data.data !== undefined) {
29
+ return {
30
+ ...response,
31
+ data: response.data.data,
32
+ originalResponse: response.data,
33
+ };
34
+ }
35
+ return response;
36
+ }, (error) => {
37
+ if (error.response?.status === 401) {
38
+ const isLoginPage = window.location.pathname.endsWith(_loginRoute);
39
+ const isAuthCheck = error.config?.url === _authProfileRoute;
40
+ if (!isLoginPage) {
41
+ localStorage.removeItem(_tokenStorageKey);
42
+ if (!isAuthCheck) {
43
+ window.location.href = _loginRoute;
44
+ }
45
+ }
46
+ }
47
+ else if (error.response?.status === 403) {
48
+ const message = error.response?.data?.message ||
49
+ error.response?.data?.data?.message ||
50
+ 'Bạn không có quyền thực hiện thao tác này';
51
+ toast.error(message, {
52
+ duration: 4000,
53
+ position: 'top-right',
54
+ style: {
55
+ background: '#fee2e2',
56
+ color: '#dc2626',
57
+ border: '1px solid #fecaca',
58
+ },
59
+ icon: '🚫',
60
+ });
61
+ }
62
+ else {
63
+ const message = error.response?.data?.message ||
64
+ error.response?.data?.data?.message ||
65
+ 'Đã xảy ra lỗi';
66
+ if (error.response?.status >= 400) {
67
+ toast.error(message, {
68
+ duration: 4000,
69
+ position: 'top-right',
70
+ });
71
+ }
72
+ }
73
+ return Promise.reject(error);
74
+ });
75
+ return _apiClient;
76
+ }
77
+ export function getApiClient() {
78
+ if (!_apiClient) {
79
+ throw new Error('apiClient not initialized. Wrap your app in CoreProviders.');
80
+ }
81
+ return _apiClient;
82
+ }
83
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/client/auth/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const authService: {
2
+ verifyEmail: (token: string) => Promise<import("axios").AxiosResponse<any, any, {}>>;
3
+ forgotPassword: (email: string) => Promise<import("axios").AxiosResponse<any, any, {}>>;
4
+ resetPassword: (token: string, password: string) => Promise<import("axios").AxiosResponse<any, any, {}>>;
5
+ resendVerification: () => Promise<import("axios").AxiosResponse<any, any, {}>>;
6
+ };
7
+ //# sourceMappingURL=auth.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../../src/client/auth/auth.service.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;yBACK,MAAM;4BAIH,MAAM;2BAIP,MAAM,YAAY,MAAM;;CAUtD,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { getApiClient } from './api-client';
2
+ export const authService = {
3
+ verifyEmail: async (token) => {
4
+ return await getApiClient().get(`/email/verify?token=${token}`);
5
+ },
6
+ forgotPassword: async (email) => {
7
+ return await getApiClient().post('/password/forgot', { email });
8
+ },
9
+ resetPassword: async (token, password) => {
10
+ return await getApiClient().post('/password/reset', {
11
+ token,
12
+ password,
13
+ });
14
+ },
15
+ resendVerification: async () => {
16
+ return await getApiClient().post('/email/resend-verification');
17
+ },
18
+ };
19
+ //# sourceMappingURL=auth.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../src/client/auth/auth.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;QACnC,OAAO,MAAM,YAAY,EAAE,CAAC,GAAG,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAA;IACjE,CAAC;IAED,cAAc,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;QACtC,OAAO,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACjE,CAAC;IAED,aAAa,EAAE,KAAK,EAAE,KAAa,EAAE,QAAgB,EAAE,EAAE;QACvD,OAAO,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAClD,KAAK;YACL,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC;IAED,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAC7B,OAAO,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;IAChE,CAAC;CACF,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { AuthProvider, useAuth } from './AuthContext';
2
+ export { default as ProtectedRoute } from './ProtectedRoute';
3
+ export { default as ProtectedPage } from './ProtectedPage';
4
+ export { default as PermissionGuard } from './PermissionGuard';
5
+ export { initApiClient, getApiClient } from './api-client';
6
+ export { authService } from './auth.service';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { AuthProvider, useAuth } from './AuthContext';
2
+ export { default as ProtectedRoute } from './ProtectedRoute';
3
+ export { default as ProtectedPage } from './ProtectedPage';
4
+ export { default as PermissionGuard } from './PermissionGuard';
5
+ export { initApiClient, getApiClient } from './api-client';
6
+ export { authService } from './auth.service';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,19 @@
1
+ interface BreadcrumbItem {
2
+ label: string;
3
+ href?: string;
4
+ isActive?: boolean;
5
+ }
6
+ interface BackButton {
7
+ href: string;
8
+ label?: string;
9
+ }
10
+ interface PageHeaderProps {
11
+ title: string;
12
+ breadcrumbs?: BreadcrumbItem[];
13
+ actions?: React.ReactNode;
14
+ description?: string;
15
+ back?: BackButton;
16
+ }
17
+ export default function PageHeader({ title, breadcrumbs, }: PageHeaderProps): import("react/jsx-runtime").JSX.Element;
18
+ export {};
19
+ //# sourceMappingURL=PageHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../../src/client/components/PageHeader.tsx"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,cAAc,EAAE,CAAA;IAC9B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAK,EACL,WAAgB,GACjB,EAAE,eAAe,2CAmCjB"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronRight } from 'lucide-react';
3
+ import Link from 'next/link';
4
+ export default function PageHeader({ title, breadcrumbs = [], }) {
5
+ return (_jsx("div", { className: "pb-4", children: _jsxs("div", { className: "flex flex-col md:flex-row gap-2 items-center justify-between", children: [_jsx("h1", { className: "text-2xl font-semibold text-base-content", children: title }), breadcrumbs.length > 0 && (_jsx("nav", { className: "flex items-center text-sm text-base-content/60 overflow-x-autonsi", children: breadcrumbs.map((item, index) => (_jsxs("div", { className: "flex items-center", children: [item.href && !item.isActive ? (_jsx(Link, { href: item.href, className: "hover:text-base-content/80 transition-colors", children: item.label })) : (_jsx("span", { className: item.isActive ? 'text-base-content font-medium' : '', children: item.label })), index < breadcrumbs.length - 1 && (_jsx(ChevronRight, { className: "w-4 h-4 mx-2 text-base-content/40" }))] }, index))) }))] }) }));
6
+ }
7
+ //# sourceMappingURL=PageHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../../src/client/components/PageHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAa,MAAM,cAAc,CAAA;AACtD,OAAO,IAAI,MAAM,WAAW,CAAA;AAqB5B,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAK,EACL,WAAW,GAAG,EAAE,GACA;IAChB,OAAO,CACL,cAAK,SAAS,EAAC,MAAM,YACnB,eAAK,SAAS,EAAC,8DAA8D,aAE3E,aAAI,SAAS,EAAC,0CAA0C,YAAE,KAAK,GAAM,EAGpE,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CACzB,cAAK,SAAS,EAAC,mEAAmE,YAC/E,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,eAAiB,SAAS,EAAC,mBAAmB,aAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC7B,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,SAAS,EAAC,8CAA8C,YAEvD,IAAI,CAAC,KAAK,GACN,CACR,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,EAAE,YAClE,IAAI,CAAC,KAAK,GACN,CACR,EAEA,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CACjC,KAAC,YAAY,IAAC,SAAS,EAAC,mCAAmC,GAAG,CAC/D,KAhBO,KAAK,CAiBT,CACP,CAAC,GACE,CACP,IACG,GACF,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ import type { AdminConfig } from '../config/types';
3
+ interface CoreProvidersProps {
4
+ config: AdminConfig;
5
+ children: ReactNode;
6
+ }
7
+ export declare function CoreProviders({ config, children }: CoreProvidersProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=Providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Providers.d.ts","sourceRoot":"","sources":["../../../src/client/components/Providers.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,SAAS,EAAU,MAAM,OAAO,CAAA;AAOnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGlD,UAAU,kBAAkB;IAC1B,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,kBAAkB,2CA0DrE"}
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
+ import { useState, useRef } from 'react';
5
+ import { ThemeProvider } from '../contexts/ThemeContext';
6
+ import { AuthProvider } from '../auth/AuthContext';
7
+ import { AdminConfigProvider } from '../config/AdminConfigContext';
8
+ import { initApiClient } from '../auth/api-client';
9
+ import { DEFAULT_CORE_ROUTES } from '../config/defaults';
10
+ import { CORE_API_ROUTES } from '../constants/api-routes';
11
+ import { Toaster } from 'react-hot-toast';
12
+ export function CoreProviders({ config, children }) {
13
+ const [queryClient] = useState(() => new QueryClient({
14
+ defaultOptions: {
15
+ queries: {
16
+ staleTime: 60 * 1000,
17
+ refetchOnWindowFocus: false,
18
+ },
19
+ },
20
+ }));
21
+ const initialized = useRef(false);
22
+ if (!initialized.current) {
23
+ const tokenKey = config.tokenStorageKey || 'admin_token';
24
+ const loginRoute = config.routes?.LOGIN || DEFAULT_CORE_ROUTES.LOGIN;
25
+ initApiClient(config.apiUrl, tokenKey, loginRoute, CORE_API_ROUTES.AUTH.PROFILE);
26
+ initialized.current = true;
27
+ }
28
+ return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(AdminConfigProvider, { config: config, children: _jsx(ThemeProvider, { children: _jsxs(AuthProvider, { children: [children, _jsx(Toaster, { position: "top-right", toastOptions: {
29
+ duration: 4000,
30
+ style: {
31
+ borderRadius: '8px',
32
+ fontSize: '14px',
33
+ },
34
+ success: {
35
+ style: {
36
+ background: '#f0fdf4',
37
+ color: '#166534',
38
+ border: '1px solid #bbf7d0',
39
+ },
40
+ icon: '✅',
41
+ },
42
+ error: {
43
+ style: {
44
+ background: '#fee2e2',
45
+ color: '#dc2626',
46
+ border: '1px solid #fecaca',
47
+ },
48
+ icon: '🚫',
49
+ },
50
+ } })] }) }) }) }));
51
+ }
52
+ //# sourceMappingURL=Providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Providers.js","sourceRoot":"","sources":["../../../src/client/components/Providers.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAa,MAAM,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAOzC,MAAM,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAsB;IACpE,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAC5B,GAAG,EAAE,CACH,IAAI,WAAW,CAAC;QACd,cAAc,EAAE;YACd,OAAO,EAAE;gBACP,SAAS,EAAE,EAAE,GAAG,IAAI;gBACpB,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF,CAAC,CACL,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACjC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI,aAAa,CAAA;QACxD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,mBAAmB,CAAC,KAAK,CAAA;QACpE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAChF,WAAW,CAAC,OAAO,GAAG,IAAI,CAAA;IAC5B,CAAC;IAED,OAAO,CACL,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACtC,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,YACjC,KAAC,aAAa,cACZ,MAAC,YAAY,eACV,QAAQ,EACT,KAAC,OAAO,IACN,QAAQ,EAAC,WAAW,EACpB,YAAY,EAAE;gCACZ,QAAQ,EAAE,IAAI;gCACd,KAAK,EAAE;oCACL,YAAY,EAAE,KAAK;oCACnB,QAAQ,EAAE,MAAM;iCACjB;gCACD,OAAO,EAAE;oCACP,KAAK,EAAE;wCACL,UAAU,EAAE,SAAS;wCACrB,KAAK,EAAE,SAAS;wCAChB,MAAM,EAAE,mBAAmB;qCAC5B;oCACD,IAAI,EAAE,GAAG;iCACV;gCACD,KAAK,EAAE;oCACL,KAAK,EAAE;wCACL,UAAU,EAAE,SAAS;wCACrB,KAAK,EAAE,SAAS;wCAChB,MAAM,EAAE,mBAAmB;qCAC5B;oCACD,IAAI,EAAE,IAAI;iCACX;6BACF,GACD,IACW,GACD,GACI,GACF,CACvB,CAAA;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface ThemeToggleProps {
2
+ className?: string;
3
+ }
4
+ export default function ThemeToggle({ className }: ThemeToggleProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=ThemeToggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../../src/client/components/ThemeToggle.tsx"],"names":[],"mappings":"AAOA,UAAU,gBAAgB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CA8BlE"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { Moon, Sun } from 'lucide-react';
5
+ import { useTheme } from '../contexts/ThemeContext';
6
+ import { cn } from '../lib/utils';
7
+ const THEME_STORAGE_KEY = 'dark';
8
+ export default function ThemeToggle({ className }) {
9
+ const [mounted, setMounted] = useState(false);
10
+ const { theme, setTheme } = useTheme();
11
+ useEffect(() => {
12
+ setMounted(true);
13
+ }, []);
14
+ if (!mounted) {
15
+ return (_jsx("div", { className: cn('w-10 h-10', className) }));
16
+ }
17
+ const toggleTheme = () => {
18
+ setTheme(theme === THEME_STORAGE_KEY ? 'light' : THEME_STORAGE_KEY);
19
+ };
20
+ return (_jsxs("label", { className: "swap swap-rotate btn btn-ghost btn-circle", children: [_jsx("input", { type: "checkbox", checked: theme === THEME_STORAGE_KEY, onChange: toggleTheme, "aria-label": "Toggle theme" }), _jsx(Sun, { className: "swap-off h-5 w-5" }), _jsx(Moon, { className: "swap-on h-5 w-5" })] }));
21
+ }
22
+ //# sourceMappingURL=ThemeToggle.js.map