@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,228 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import { useRouter, useSearchParams } from 'next/navigation';
5
+ import { Plus, Search, Trash2, X, MoreVertical, Edit, CheckCircle, Lock, Unlock, RotateCcw, Shield } from 'lucide-react';
6
+ import toast from 'react-hot-toast';
7
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
8
+ import { getApiClient } from '../auth/api-client';
9
+ import { CORE_API_ROUTES } from '../constants/api-routes';
10
+ import { useAdminConfig } from '../config/AdminConfigContext';
11
+ import { UserStats } from './users/UserStats';
12
+ import { UserDetailModal } from './users/UserDetailModal';
13
+ import Badge from '../ui/Badge';
14
+ import Button from '../ui/Button';
15
+ import Input from '../ui/Input';
16
+ import DataTable, { TableRenderers } from '../ui/DataTable';
17
+ import Dropdown from '../ui/Dropdown';
18
+ export default function UsersPage() {
19
+ const apiClient = getApiClient();
20
+ const router = useRouter();
21
+ const searchParams = useSearchParams();
22
+ const queryClient = useQueryClient();
23
+ const { resolvedRoutes } = useAdminConfig();
24
+ // State
25
+ const [searchTerm, setSearchTerm] = useState(searchParams.get('search') || '');
26
+ const [currentPage, setCurrentPage] = useState(Number(searchParams.get('page')) || 1);
27
+ const [itemsPerPage, setItemsPerPage] = useState(10);
28
+ const [roleFilter, setRoleFilter] = useState(searchParams.get('role') || '');
29
+ const [statusFilter, setStatusFilter] = useState(searchParams.get('status') || '');
30
+ const [showDeleted, setShowDeleted] = useState(searchParams.get('includeDeleted') === 'true');
31
+ const [selectedUser, setSelectedUser] = useState(null);
32
+ // Stats State (separate from React Query for now as it aggregates manually in the original code)
33
+ // Ideally this should be a separate query
34
+ const [stats, setStats] = useState({
35
+ total: 0,
36
+ active: 0,
37
+ verified: 0,
38
+ new: 0
39
+ });
40
+ // Update URL when filters change
41
+ useEffect(() => {
42
+ const params = new URLSearchParams();
43
+ if (searchTerm)
44
+ params.set('search', searchTerm);
45
+ if (currentPage > 1)
46
+ params.set('page', currentPage.toString());
47
+ if (roleFilter)
48
+ params.set('role', roleFilter);
49
+ if (statusFilter)
50
+ params.set('status', statusFilter);
51
+ if (showDeleted)
52
+ params.set('includeDeleted', 'true');
53
+ const queryString = params.toString();
54
+ const newUrl = queryString ? `${resolvedRoutes.USERS_LIST}?${queryString}` : resolvedRoutes.USERS_LIST;
55
+ router.replace(newUrl, { scroll: false });
56
+ }, [searchTerm, currentPage, roleFilter, statusFilter, showDeleted, router]);
57
+ // Data Fetching
58
+ const { data, isLoading } = useQuery({
59
+ queryKey: ['users', currentPage, itemsPerPage, searchTerm, roleFilter, statusFilter, showDeleted],
60
+ queryFn: async () => {
61
+ const params = new URLSearchParams({
62
+ page: currentPage.toString(),
63
+ limit: itemsPerPage.toString(),
64
+ sortBy: 'createdAt',
65
+ sortOrder: 'DESC',
66
+ });
67
+ if (searchTerm)
68
+ params.append('search', searchTerm);
69
+ if (roleFilter)
70
+ params.append('role', roleFilter);
71
+ if (statusFilter)
72
+ params.append('status', statusFilter);
73
+ if (showDeleted)
74
+ params.append('includeDeleted', 'true');
75
+ const response = await apiClient.get(`${CORE_API_ROUTES.ADMIN_USERS.BASE}?${params}`);
76
+ // Update stats based on loaded data (simplified for now, mimicking original behavior)
77
+ const usersData = response.data.data;
78
+ const activeCount = usersData.filter(u => u.isActive && !u.deletedAt).length;
79
+ const verifiedCount = usersData.filter(u => u.emailVerified).length;
80
+ setStats(prev => ({
81
+ ...prev,
82
+ total: response.data.total,
83
+ active: activeCount, // Note: This is only for current page in this implementation
84
+ verified: verifiedCount // Note: This is only for current page in this implementation
85
+ }));
86
+ return response.data;
87
+ },
88
+ });
89
+ // Mutations
90
+ const deleteMutation = useMutation({
91
+ mutationFn: async (id) => {
92
+ return apiClient.delete(CORE_API_ROUTES.ADMIN_USERS.BY_ID(id));
93
+ },
94
+ onSuccess: () => {
95
+ toast.success('Xóa người dùng thành công');
96
+ queryClient.invalidateQueries({ queryKey: ['users'] });
97
+ },
98
+ onError: () => {
99
+ toast.error('Không thể xóa người dùng');
100
+ }
101
+ });
102
+ const restoreMutation = useMutation({
103
+ mutationFn: async (id) => {
104
+ return apiClient.post(CORE_API_ROUTES.ADMIN_USERS.RESTORE(id));
105
+ },
106
+ onSuccess: () => {
107
+ toast.success('Khôi phục người dùng thành công');
108
+ queryClient.invalidateQueries({ queryKey: ['users'] });
109
+ },
110
+ onError: () => {
111
+ toast.error('Không thể khôi phục người dùng');
112
+ }
113
+ });
114
+ const updateStatusMutation = useMutation({
115
+ mutationFn: async ({ id, status }) => {
116
+ return apiClient.patch(CORE_API_ROUTES.ADMIN_USERS.UPDATE_STATUS(id), { status });
117
+ },
118
+ onSuccess: (_, variables) => {
119
+ toast.success(`Đã chuyển trạng thái sang ${variables.status}`);
120
+ queryClient.invalidateQueries({ queryKey: ['users'] });
121
+ },
122
+ onError: () => {
123
+ toast.error('Không thể cập nhật trạng thái');
124
+ }
125
+ });
126
+ const verifyEmailMutation = useMutation({
127
+ mutationFn: async (id) => {
128
+ return apiClient.post(CORE_API_ROUTES.ADMIN_USERS.VERIFY_EMAIL(id));
129
+ },
130
+ onSuccess: () => {
131
+ toast.success('Xác thực email thành công');
132
+ queryClient.invalidateQueries({ queryKey: ['users'] });
133
+ },
134
+ onError: () => {
135
+ toast.error('Không thể xác thực email');
136
+ }
137
+ });
138
+ // Handlers
139
+ const handleDelete = (id) => {
140
+ if (confirm('Bạn có chắc chắn muốn xóa người dùng này?')) {
141
+ deleteMutation.mutate(id);
142
+ }
143
+ };
144
+ const handleBulkDelete = (items) => {
145
+ if (confirm(`Bạn có chắc chắn muốn xóa ${items.length} người dùng?`)) {
146
+ // Assuming generic bulk delete endpoint exists or mapping single deletions
147
+ // For now just logging as implemented in generic way
148
+ items.forEach(item => deleteMutation.mutate(item.id));
149
+ }
150
+ };
151
+ const handleClearFilters = () => {
152
+ setSearchTerm('');
153
+ setRoleFilter('');
154
+ setStatusFilter('');
155
+ setShowDeleted(false);
156
+ setCurrentPage(1);
157
+ };
158
+ // Helper for role badge style
159
+ const getRoleBadgeVariant = (role) => {
160
+ const styles = {
161
+ viewer: 'neutral',
162
+ editor: 'info',
163
+ admin: 'warning',
164
+ super_admin: 'error',
165
+ };
166
+ return (styles[role] || 'neutral');
167
+ };
168
+ // Columns Configuration
169
+ const columns = [
170
+ {
171
+ key: 'id',
172
+ label: 'ID',
173
+ render: (_, user) => TableRenderers.id(user.id)
174
+ },
175
+ {
176
+ key: 'user',
177
+ label: 'NGƯỜI DÙNG',
178
+ render: (_, user) => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "w-10 h-10 rounded-full bg-base-300 flex items-center justify-center overflow-hidden border border-base-200", children: user.avatar ? (_jsx("img", { src: user.avatar, alt: user.name, className: "w-full h-full object-cover" })) : (_jsx("span", { className: "text-lg font-semibold text-base-content/50", children: user.name.charAt(0).toUpperCase() })) }), _jsxs("div", { children: [_jsx("div", { className: "font-semibold text-base-content", children: user.name }), _jsx("div", { className: "text-sm text-base-content/60", children: user.email })] })] }))
179
+ },
180
+ {
181
+ key: 'role',
182
+ label: 'VAI TRÒ',
183
+ width: '120px',
184
+ render: (value) => (_jsx(Badge, { variant: getRoleBadgeVariant(value), size: "sm", className: "capitalize", children: value.replace('_', ' ') }))
185
+ },
186
+ {
187
+ key: 'status',
188
+ label: 'TRẠNG THÁI & BẢO MẬT',
189
+ width: '200px',
190
+ render: (_, user) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: `flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium border ${user.deletedAt ? 'bg-gray-50 text-gray-500 border-gray-200' :
191
+ user.isActive ? 'bg-green-50 text-green-700 border-green-100' :
192
+ 'bg-red-50 text-red-700 border-red-100'}`, children: [_jsx("div", { className: `w-1.5 h-1.5 rounded-full ${user.deletedAt ? 'bg-gray-400' : user.isActive ? 'bg-green-500' : 'bg-red-500'}` }), user.deletedAt ? 'Deleted' : user.isActive ? 'Active' : 'Locked'] }), _jsx("div", { className: `p-1 rounded ${user.emailVerified ? 'text-green-600 bg-green-50' : 'text-gray-300 bg-gray-50'}`, title: user.emailVerified ? "Email Verified" : "Email Unverified", children: _jsx(CheckCircle, { className: "w-3.5 h-3.5" }) }), user.twoFactorEnabled && (_jsx("div", { className: "p-1 rounded text-purple-600 bg-purple-50", title: "2FA Enabled", children: _jsx(Shield, { className: "w-3.5 h-3.5" }) }))] }))
193
+ },
194
+ {
195
+ key: 'createdAt',
196
+ label: 'NGÀY THAM GIA',
197
+ width: '150px',
198
+ render: (value) => TableRenderers.datetime(value)
199
+ },
200
+ {
201
+ key: 'actions',
202
+ label: 'ACTION',
203
+ align: 'right',
204
+ width: '60px',
205
+ render: (_, user) => (_jsx(Dropdown, { align: "right", trigger: _jsx("button", { className: "p-2 text-base-content/40 hover:text-base-content hover:bg-base-200 rounded-lg transition-all", children: _jsx(MoreVertical, { className: "w-4 h-4" }) }), children: _jsxs("div", { className: "py-1", children: [_jsxs("button", { onClick: () => router.push(resolvedRoutes.USERS_VIEW(user.id)), className: "w-full px-4 py-2.5 text-left text-sm text-base-content hover:bg-base-200 flex items-center gap-2", children: [_jsx(Edit, { className: "w-4 h-4 text-base-content/50" }), "Ch\u1EC9nh s\u1EEDa"] }), !user.emailVerified && !user.deletedAt && (_jsxs("button", { onClick: () => verifyEmailMutation.mutate(user.id), className: "w-full px-4 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2", children: [_jsx(CheckCircle, { className: "w-4 h-4 text-green-500" }), "X\u00E1c th\u1EF1c Email"] })), _jsx("div", { className: "h-px bg-base-200 my-1" }), !user.deletedAt ? (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: () => updateStatusMutation.mutate({ id: user.id, status: user.isActive ? 'LOCKED' : 'ACTIVE' }), className: `w-full px-4 py-2.5 text-left text-sm hover:bg-gray-50 flex items-center gap-2 ${user.isActive ? 'text-amber-600' : 'text-green-600'}`, children: [user.isActive ? _jsx(Lock, { className: "w-4 h-4" }) : _jsx(Unlock, { className: "w-4 h-4" }), user.isActive ? 'Khóa tài khoản' : 'Kích hoạt'] }), _jsxs("button", { onClick: () => handleDelete(user.id), className: "w-full px-4 py-2.5 text-left text-sm text-red-600 hover:bg-red-50 flex items-center gap-2", children: [_jsx(Trash2, { className: "w-4 h-4" }), "X\u00F3a ng\u01B0\u1EDDi d\u00F9ng"] })] })) : (_jsxs("button", { onClick: () => restoreMutation.mutate(user.id), className: "w-full px-4 py-2.5 text-left text-sm text-green-600 hover:bg-green-50 flex items-center gap-2", children: [_jsx(RotateCcw, { className: "w-4 h-4" }), "Kh\u00F4i ph\u1EE5c l\u1EA1i"] }))] }) }))
206
+ }
207
+ ];
208
+ const bulkActions = [
209
+ {
210
+ key: 'delete',
211
+ label: 'Delete Selected',
212
+ icon: _jsx(Trash2, { className: "h-4 w-4" }),
213
+ variant: 'error',
214
+ onClick: handleBulkDelete,
215
+ },
216
+ ];
217
+ // Pagination Props
218
+ const pagination = data ? {
219
+ currentPage,
220
+ totalPages: data.totalPages || 1,
221
+ totalItems: data.total || 0,
222
+ itemsPerPage,
223
+ startItem: (currentPage - 1) * itemsPerPage + 1,
224
+ endItem: Math.min(currentPage * itemsPerPage, data.total || 0),
225
+ } : undefined;
226
+ return (_jsxs("div", { className: "container mx-auto bg-base-200 min-h-screen p-6", children: [_jsxs("div", { className: 'space-y-6', children: [_jsxs("div", { className: 'flex gap-2 justify-between items-center', children: [_jsx("h1", { className: "text-2xl font-semibold text-base-content", children: "Users" }), _jsxs(Button, { variant: "primary", onClick: () => router.push(resolvedRoutes.USERS_NEW), children: [_jsx(Plus, { className: "w-5 h-5 mr-2" }), "Th\u00EAm ng\u01B0\u1EDDi d\u00F9ng m\u1EDBi"] })] }), _jsx(UserStats, { total: stats.total, activeCount: stats.active, verifiedCount: stats.verified, newUsersCount: stats.new }), _jsx("div", { className: "bg-base-100 rounded-lg p-6 border border-base-200", children: _jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-4 flex-1", children: [_jsx("div", { className: "w-full sm:w-auto sm:min-w-[300px]", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-base-content/50" }), _jsx(Input, { type: "text", placeholder: "T\u00ECm ki\u1EBFm ng\u01B0\u1EDDi d\u00F9ng...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "pl-10 w-full" })] }) }), _jsxs("select", { value: roleFilter, onChange: (e) => setRoleFilter(e.target.value), className: "select select-bordered w-full sm:w-auto", children: [_jsx("option", { value: "", children: "T\u1EA5t c\u1EA3 vai tr\u00F2" }), _jsx("option", { value: "viewer", children: "Viewer" }), _jsx("option", { value: "editor", children: "Editor" }), _jsx("option", { value: "admin", children: "Admin" }), _jsx("option", { value: "super_admin", children: "Super Admin" })] }), _jsxs("select", { value: statusFilter, onChange: (e) => setStatusFilter(e.target.value), className: "select select-bordered w-full sm:w-auto", children: [_jsx("option", { value: "", children: "T\u1EA5t c\u1EA3 tr\u1EA1ng th\u00E1i" }), _jsx("option", { value: "ACTIVE", children: "Ho\u1EA1t \u0111\u1ED9ng" }), _jsx("option", { value: "INACTIVE", children: "\u0110\u00E3 kh\u00F3a" })] }), _jsxs("label", { className: "label cursor-pointer gap-2 border border-base-200 rounded-lg px-3 py-2 hover:bg-base-200 transition-colors", children: [_jsx("input", { type: "checkbox", className: "checkbox checkbox-sm checkbox-primary", checked: showDeleted, onChange: (e) => setShowDeleted(e.target.checked) }), _jsx("span", { className: "label-text", children: "\u0110\u00E3 x\u00F3a" })] }), (searchTerm || roleFilter || statusFilter || showDeleted) && (_jsxs(Button, { variant: "secondary", onClick: handleClearFilters, children: [_jsx(X, { className: "h-4 w-4 mr-1" }), "X\u00F3a l\u1ECDc"] }))] }) }), _jsx("div", { className: "bg-base-100 rounded-lg overflow-hidden border border-base-200", children: _jsx(DataTable, { data: data?.data || [], columns: columns, bulkActions: bulkActions, loading: isLoading, selectable: true, pagination: pagination, onPageChange: setCurrentPage, onItemsPerPageChange: setItemsPerPage, emptyMessage: "Kh\u00F4ng t\u00ECm th\u1EA5y ng\u01B0\u1EDDi d\u00F9ng n\u00E0o", onRowClick: setSelectedUser }) })] }), _jsx(UserDetailModal, { user: selectedUser, onClose: () => setSelectedUser(null) })] }));
227
+ }
228
+ //# sourceMappingURL=UsersPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsersPage.js","sourceRoot":"","sources":["../../../src/client/pages/UsersPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function VerifyEmailPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=VerifyEmailPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyEmailPage.d.ts","sourceRoot":"","sources":["../../../src/client/pages/VerifyEmailPage.tsx"],"names":[],"mappings":"AA4FA,MAAM,CAAC,OAAO,UAAU,eAAe,4CAUtC"}
@@ -0,0 +1,43 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Suspense, useEffect, useState } from 'react';
4
+ import { useRouter, useSearchParams } from 'next/navigation';
5
+ import { useAdminConfig } from '../config/AdminConfigContext';
6
+ import { authService } from '../auth/auth.service';
7
+ import { VerificationStatus } from '../types/status';
8
+ function VerifyEmailContent() {
9
+ const { resolvedRoutes } = useAdminConfig();
10
+ const router = useRouter();
11
+ const searchParams = useSearchParams();
12
+ const [status, setStatus] = useState(VerificationStatus.VERIFYING);
13
+ const [message, setMessage] = useState('');
14
+ useEffect(() => {
15
+ const verifyEmail = async () => {
16
+ const token = searchParams.get('token');
17
+ if (!token) {
18
+ setStatus(VerificationStatus.ERROR);
19
+ setMessage('Token xác thực không hợp lệ');
20
+ return;
21
+ }
22
+ try {
23
+ await authService.verifyEmail(token);
24
+ setStatus(VerificationStatus.SUCCESS);
25
+ setMessage('Xác thực email thành công!');
26
+ // Redirect to login after 2 seconds
27
+ setTimeout(() => {
28
+ router.push(resolvedRoutes.LOGIN);
29
+ }, 2000);
30
+ }
31
+ catch (error) {
32
+ setStatus(VerificationStatus.ERROR);
33
+ setMessage(error.response?.data?.message || 'Xác thực email thất bại. Token có thể đã hết hạn hoặc không hợp lệ.');
34
+ }
35
+ };
36
+ verifyEmail();
37
+ }, [searchParams, router, resolvedRoutes]);
38
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center bg-base-200 px-4", children: _jsx("div", { className: "card w-full max-w-md bg-base-100 shadow-xl", children: _jsxs("div", { className: "card-body text-center", children: [status === VerificationStatus.VERIFYING && (_jsxs(_Fragment, { children: [_jsx("span", { className: "loading loading-spinner loading-lg text-primary mx-auto" }), _jsx("h2", { className: "card-title text-2xl justify-center mt-4", children: "\u0110ang x\u00E1c th\u1EF1c email..." })] })), status === VerificationStatus.SUCCESS && (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-success/20", children: _jsx("svg", { className: "h-6 w-6 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" }) }) }), _jsx("h2", { className: "card-title text-2xl justify-center mt-4", children: "X\u00E1c th\u1EF1c th\u00E0nh c\u00F4ng!" }), _jsx("p", { className: "text-base-content/70", children: message }), _jsx("p", { className: "text-sm text-base-content/50", children: "\u0110ang chuy\u1EC3n h\u01B0\u1EDBng \u0111\u1EBFn trang \u0111\u0103ng nh\u1EADp..." })] })), status === VerificationStatus.ERROR && (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-error/20", children: _jsx("svg", { className: "h-6 w-6 text-error", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) }) }), _jsx("h2", { className: "card-title text-2xl justify-center mt-4", children: "X\u00E1c th\u1EF1c th\u1EA5t b\u1EA1i" }), _jsx("p", { className: "text-base-content/70", children: message }), _jsx("div", { className: "card-actions justify-center mt-4", children: _jsx("button", { onClick: () => router.push(resolvedRoutes.LOGIN), className: "btn btn-primary", children: "V\u1EC1 trang \u0111\u0103ng nh\u1EADp" }) })] }))] }) }) }));
39
+ }
40
+ export default function VerifyEmailPage() {
41
+ return (_jsx(Suspense, { fallback: _jsx("div", { className: "min-h-screen flex items-center justify-center bg-base-200", children: _jsx("div", { className: "loading loading-spinner loading-lg" }) }), children: _jsx(VerifyEmailContent, {}) }));
42
+ }
43
+ //# sourceMappingURL=VerifyEmailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyEmailPage.js","sourceRoot":"","sources":["../../../src/client/pages/VerifyEmailPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { default as LoginPage } from './LoginPage';
2
+ export { default as ChangePasswordPage } from './ChangePasswordPage';
3
+ export { default as ForgotPasswordPage } from './ForgotPasswordPage';
4
+ export { default as ResetPasswordPage } from './ResetPasswordPage';
5
+ export { default as VerifyEmailPage } from './VerifyEmailPage';
6
+ export { default as UnauthorizedPage } from './UnauthorizedPage';
7
+ export { default as UsersPage } from './UsersPage';
8
+ export { default as UserDetailPage } from './UserDetailPage';
9
+ export { default as RolesPage } from './RolesPage';
10
+ export { default as PermissionsPage } from './PermissionsPage';
11
+ export { default as ProfilePage } from './ProfilePage';
12
+ export { default as UserPreferencesPage } from './UserPreferencesPage';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/pages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,13 @@
1
+ export { default as LoginPage } from './LoginPage';
2
+ export { default as ChangePasswordPage } from './ChangePasswordPage';
3
+ export { default as ForgotPasswordPage } from './ForgotPasswordPage';
4
+ export { default as ResetPasswordPage } from './ResetPasswordPage';
5
+ export { default as VerifyEmailPage } from './VerifyEmailPage';
6
+ export { default as UnauthorizedPage } from './UnauthorizedPage';
7
+ export { default as UsersPage } from './UsersPage';
8
+ export { default as UserDetailPage } from './UserDetailPage';
9
+ export { default as RolesPage } from './RolesPage';
10
+ export { default as PermissionsPage } from './PermissionsPage';
11
+ export { default as ProfilePage } from './ProfilePage';
12
+ export { default as UserPreferencesPage } from './UserPreferencesPage';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/pages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { Role } from '../../types/rbac';
2
+ interface RoleModalProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ onSuccess: () => void;
6
+ role: Role | null;
7
+ }
8
+ export default function RoleModal({ isOpen, onClose, onSuccess, role }: RoleModalProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=RoleModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleModal.d.ts","sourceRoot":"","sources":["../../../../src/client/pages/roles/RoleModal.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAc,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAExD,UAAU,cAAc;IACtB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;CAClB;AAMD,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,2CA2TrF"}
@@ -0,0 +1,123 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { useQuery, useMutation } from '@tanstack/react-query';
5
+ import { Search, ChevronDown, ChevronUp } from 'lucide-react';
6
+ import { getApiClient } from '../../auth/api-client';
7
+ import { CORE_ADMIN_API_ROUTES } from '../../constants/api-routes';
8
+ import Modal from '../../ui/Modal';
9
+ import { useToast } from '../../hooks/useToast';
10
+ export default function RoleModal({ isOpen, onClose, onSuccess, role }) {
11
+ const apiClient = getApiClient();
12
+ const [name, setName] = useState('');
13
+ const [description, setDescription] = useState('');
14
+ const [selectedPermissionIds, setSelectedPermissionIds] = useState([]);
15
+ const [searchTerm, setSearchTerm] = useState('');
16
+ const [expandedGroups, setExpandedGroups] = useState([]);
17
+ const { showToast } = useToast();
18
+ // Fetch permissions
19
+ const { data: permissionsData } = useQuery({
20
+ queryKey: ['permissions'],
21
+ queryFn: async () => {
22
+ const response = await apiClient.get(CORE_ADMIN_API_ROUTES.PERMISSIONS.BASE);
23
+ return response.data;
24
+ },
25
+ enabled: isOpen,
26
+ });
27
+ // Set form data when role changes
28
+ useEffect(() => {
29
+ if (role) {
30
+ setName(role.name);
31
+ setDescription(role.description || '');
32
+ setSelectedPermissionIds(role.permissionIds || []);
33
+ }
34
+ else {
35
+ setName('');
36
+ setDescription('');
37
+ setSelectedPermissionIds([]);
38
+ }
39
+ }, [role]);
40
+ // Expand all groups by default
41
+ useEffect(() => {
42
+ if (permissionsData?.grouped && expandedGroups.length === 0) {
43
+ setExpandedGroups(Object.keys(permissionsData.grouped));
44
+ }
45
+ }, [permissionsData]);
46
+ // Create/Update mutation
47
+ const saveMutation = useMutation({
48
+ mutationFn: async (data) => {
49
+ if (role) {
50
+ return apiClient.put(CORE_ADMIN_API_ROUTES.ROLES.BY_ID(role.id), data);
51
+ }
52
+ else {
53
+ return apiClient.post(CORE_ADMIN_API_ROUTES.ROLES.BASE, data);
54
+ }
55
+ },
56
+ onSuccess: () => {
57
+ showToast(role ? 'Cập nhật vai trò thành công' : 'Tạo vai trò thành công', 'success');
58
+ onSuccess();
59
+ },
60
+ onError: (error) => {
61
+ showToast(error.response?.data?.message || 'Thao tác thất bại', 'error');
62
+ },
63
+ });
64
+ const handleSubmit = (e) => {
65
+ e.preventDefault();
66
+ if (!name.trim()) {
67
+ showToast('Vui lòng nhập tên vai trò', 'error');
68
+ return;
69
+ }
70
+ saveMutation.mutate({
71
+ name: name.trim(),
72
+ description: description.trim(),
73
+ permissionIds: selectedPermissionIds,
74
+ });
75
+ };
76
+ const togglePermission = (permissionId) => {
77
+ setSelectedPermissionIds((prev) => prev.includes(permissionId)
78
+ ? prev.filter((id) => id !== permissionId)
79
+ : [...prev, permissionId]);
80
+ };
81
+ const toggleGroup = (resource) => {
82
+ setExpandedGroups((prev) => prev.includes(resource) ? prev.filter((r) => r !== resource) : [...prev, resource]);
83
+ };
84
+ const selectAllInGroup = (permissions) => {
85
+ const permissionIds = permissions.map((p) => p.id);
86
+ const allSelected = permissionIds.every((id) => selectedPermissionIds.includes(id));
87
+ if (allSelected) {
88
+ // Deselect all in group
89
+ setSelectedPermissionIds((prev) => prev.filter((id) => !permissionIds.includes(id)));
90
+ }
91
+ else {
92
+ // Select all in group
93
+ const newIds = [...selectedPermissionIds];
94
+ permissionIds.forEach((id) => {
95
+ if (!newIds.includes(id)) {
96
+ newIds.push(id);
97
+ }
98
+ });
99
+ setSelectedPermissionIds(newIds);
100
+ }
101
+ };
102
+ const filteredGrouped = permissionsData?.grouped
103
+ ? Object.entries(permissionsData.grouped).reduce((acc, [resource, permissions]) => {
104
+ const filtered = permissions.filter((p) => p.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
105
+ p.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
106
+ resource.toLowerCase().includes(searchTerm.toLowerCase()));
107
+ if (filtered.length > 0) {
108
+ acc[resource] = filtered;
109
+ }
110
+ return acc;
111
+ }, {})
112
+ : {};
113
+ const isReadOnly = role?.isSystem || false;
114
+ return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: role ? (isReadOnly ? 'Chi tiết vai trò' : 'Chỉnh sửa vai trò') : 'Tạo vai trò mới', size: "xl", children: _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "name", className: "label", children: _jsxs("span", { className: "label-text", children: ["T\u00EAn vai tr\u00F2 ", _jsx("span", { className: "text-error", children: "*" })] }) }), _jsx("input", { id: "name", type: "text", value: name, onChange: (e) => setName(e.target.value), disabled: isReadOnly, placeholder: "V\u00ED d\u1EE5: Content Manager", className: "input input-bordered w-full", required: true })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "description", className: "label", children: _jsx("span", { className: "label-text", children: "M\u00F4 t\u1EA3" }) }), _jsx("textarea", { id: "description", value: description, onChange: (e) => setDescription(e.target.value), disabled: isReadOnly, placeholder: "M\u00F4 t\u1EA3 vai tr\u00F2 v\u00E0 tr\u00E1ch nhi\u1EC7m", rows: 3, className: "textarea textarea-bordered w-full" })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex justify-between items-center mb-2", children: [_jsx("label", { className: "label", children: _jsxs("span", { className: "label-text", children: ["Quy\u1EC1n \u00E1p d\u1EE5ng (", selectedPermissionIds.length, " \u0111\u00E3 ch\u1ECDn)"] }) }), !isReadOnly && (_jsx("button", { type: "button", onClick: () => setSelectedPermissionIds([]), className: "link link-primary text-sm", children: "B\u1ECF ch\u1ECDn t\u1EA5t c\u1EA3" }))] }), _jsxs("div", { className: "relative mb-4", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-base-content/60 w-4 h-4 z-1" }), _jsx("input", { type: "text", placeholder: "T\u00ECm ki\u1EBFm quy\u1EC1n...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "input input-bordered w-full pl-10" })] }), _jsxs("div", { className: "border border-base-300 rounded-lg max-h-96 overflow-y-auto", children: [Object.entries(filteredGrouped).map(([resource, permissions]) => {
115
+ const isExpanded = expandedGroups.includes(resource);
116
+ const allSelected = permissions.every((p) => selectedPermissionIds.includes(p.id));
117
+ const someSelected = permissions.some((p) => selectedPermissionIds.includes(p.id));
118
+ return (_jsxs("div", { className: "border-b border-base-300 last:border-b-0", children: [_jsx("div", { className: "bg-base-200 px-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("button", { type: "button", onClick: () => toggleGroup(resource), className: "flex items-center gap-2 flex-1 text-left", children: [isExpanded ? (_jsx(ChevronUp, { className: "w-4 h-4 text-base-content/60" })) : (_jsx(ChevronDown, { className: "w-4 h-4 text-base-content/60" })), _jsx("span", { className: "font-semibold uppercase text-sm", children: resource }), _jsxs("span", { className: "text-xs text-base-content/60", children: ["(", permissions.filter((p) => selectedPermissionIds.includes(p.id)).length, "/", permissions.length, ")"] })] }), !isReadOnly && (_jsx("button", { type: "button", onClick: () => selectAllInGroup(permissions), className: "link link-primary text-sm", children: allSelected ? 'Bỏ chọn tất cả' : 'Chọn tất cả' }))] }) }), isExpanded && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-2 p-4", children: permissions.map((permission) => (_jsxs("label", { className: `flex items-start gap-3 p-3 rounded-lg border ${selectedPermissionIds.includes(permission.id)
119
+ ? 'border-primary bg-primary/10'
120
+ : 'border-base-300 hover:bg-base-200'} ${isReadOnly ? 'cursor-default' : 'cursor-pointer'} transition-colors`, children: [_jsx("input", { type: "checkbox", checked: selectedPermissionIds.includes(permission.id), onChange: () => togglePermission(permission.id), disabled: isReadOnly, className: "checkbox checkbox-primary mt-1" }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "font-medium text-sm", children: permission.name }), permission.description && (_jsx("div", { className: "text-xs text-base-content/60 mt-1", children: permission.description }))] })] }, permission.id))) }))] }, resource));
121
+ }), Object.keys(filteredGrouped).length === 0 && (_jsx("div", { className: "text-center py-8 text-base-content/60", children: "Kh\u00F4ng t\u00ECm th\u1EA5y quy\u1EC1n n\u00E0o" }))] })] }), !isReadOnly && (_jsxs("div", { className: "flex justify-end gap-3 pt-4 border-t border-base-300", children: [_jsx("button", { type: "button", onClick: onClose, className: "btn btn-outline", disabled: saveMutation.isPending, children: "H\u1EE7y" }), _jsx("button", { type: "submit", disabled: saveMutation.isPending, className: "btn btn-primary", children: saveMutation.isPending ? 'Đang lưu...' : role ? 'Cập nhật' : 'Tạo mới' })] })), isReadOnly && (_jsx("div", { className: "flex justify-end pt-4 border-t border-base-300", children: _jsx("button", { type: "button", onClick: onClose, className: "btn", children: "\u0110\u00F3ng" }) }))] }) }));
122
+ }
123
+ //# sourceMappingURL=RoleModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleModal.js","sourceRoot":"","sources":["../../../../src/client/pages/roles/RoleModal.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAK,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAc/C,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAkB;IACpF,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAClD,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAA;IAChF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAChD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAA;IAElE,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,CAAA;IAEhC,oBAAoB;IACpB,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,QAAQ,CAAuD;QAC/F,QAAQ,EAAE,CAAC,aAAa,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAC5E,OAAO,QAAQ,CAAC,IAAI,CAAA;QACtB,CAAC;QACD,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;IAEF,kCAAkC;IAClC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,cAAc,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;YACtC,wBAAwB,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAA;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,EAAE,CAAC,CAAA;YACX,cAAc,CAAC,EAAE,CAAC,CAAA;YAClB,wBAAwB,CAAC,EAAE,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,+BAA+B;IAC/B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,eAAe,EAAE,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAA;QACzD,CAAC;IACH,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAA;IAErB,yBAAyB;IACzB,MAAM,YAAY,GAAG,WAAW,CAAC;QAC/B,UAAU,EAAE,KAAK,EAAE,IAAoE,EAAE,EAAE;YACzF,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;YACxE,CAAC;iBAAM,CAAC;gBACN,OAAO,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/D,CAAC;QACH,CAAC;QACD,SAAS,EAAE,GAAG,EAAE;YACd,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;YACrF,SAAS,EAAE,CAAA;QACb,CAAC;QACD,OAAO,EAAE,CAAC,KAAU,EAAE,EAAE;YACtB,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,mBAAmB,EAAE,OAAO,CAAC,CAAA;QAC1E,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,CAAC,CAAkB,EAAE,EAAE;QAC1C,CAAC,CAAC,cAAc,EAAE,CAAA;QAElB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAA;YAC/C,OAAM;QACR,CAAC;QAED,YAAY,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YACjB,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;YAC/B,aAAa,EAAE,qBAAqB;SACrC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,YAAoB,EAAE,EAAE;QAChD,wBAAwB,CAAC,CAAC,IAAI,EAAE,EAAE,CAChC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YACzB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,YAAY,CAAC;YAC1C,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAC5B,CAAA;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,EAAE;QACvC,iBAAiB,CAAC,CAAC,IAAI,EAAE,EAAE,CACzB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,CACnF,CAAA;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,WAAyB,EAAE,EAAE;QACrD,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;QAEnF,IAAI,WAAW,EAAE,CAAC;YAChB,wBAAwB;YACxB,wBAAwB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtF,CAAC;aAAM,CAAC;YACN,sBAAsB;YACtB,MAAM,MAAM,GAAG,CAAC,GAAG,qBAAqB,CAAC,CAAA;YACzC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;gBAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;gBACjB,CAAC;YACH,CAAC,CAAC,CAAA;YACF,wBAAwB,CAAC,MAAM,CAAC,CAAA;QAClC,CAAC;IACH,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,eAAe,EAAE,OAAO;QAC9C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE;YAC9E,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;gBACvD,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;gBAC/D,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAC5D,CAAA;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;YAC1B,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC,EAAE,EAAwB,CAAC;QAC9B,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,UAAU,GAAG,IAAI,EAAE,QAAQ,IAAI,KAAK,CAAA;IAE1C,OAAO,CACL,KAAC,KAAK,IACJ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,iBAAiB,EACzF,IAAI,EAAC,IAAI,YAET,gBAAM,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAC,WAAW,aAEjD,0BACE,gBAAO,OAAO,EAAC,MAAM,EAAC,SAAS,EAAC,OAAO,YACrC,gBAAM,SAAS,EAAC,YAAY,uCAAa,eAAM,SAAS,EAAC,YAAY,kBAAS,IAAO,GAC/E,EACR,gBACE,EAAE,EAAC,MAAM,EACT,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACxC,QAAQ,EAAE,UAAU,EACpB,WAAW,EAAC,kCAAwB,EACpC,SAAS,EAAC,6BAA6B,EACvC,QAAQ,SACR,IACE,EAGN,0BACE,gBAAO,OAAO,EAAC,aAAa,EAAC,SAAS,EAAC,OAAO,YAC5C,eAAM,SAAS,EAAC,YAAY,gCAAa,GACnC,EACR,mBACE,EAAE,EAAC,aAAa,EAChB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/C,QAAQ,EAAE,UAAU,EACpB,WAAW,EAAC,4DAA8B,EAC1C,IAAI,EAAE,CAAC,EACP,SAAS,EAAC,mCAAmC,GAC7C,IACE,EAGN,0BACE,eAAK,SAAS,EAAC,wCAAwC,aACrD,gBAAO,SAAS,EAAC,OAAO,YACtB,gBAAM,SAAS,EAAC,YAAY,+CAAiB,qBAAqB,CAAC,MAAM,gCAAiB,GACpF,EACP,CAAC,UAAU,IAAI,CACd,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,wBAAwB,CAAC,EAAE,CAAC,EAC3C,SAAS,EAAC,2BAA2B,mDAG9B,CACV,IACG,EAGN,eAAK,SAAS,EAAC,eAAe,aAC5B,KAAC,MAAM,IAAC,SAAS,EAAC,qFAAqF,GAAG,EAC1G,gBACE,IAAI,EAAC,MAAM,EACX,WAAW,EAAC,kCAAmB,EAC/B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC9C,SAAS,EAAC,mCAAmC,GAC7C,IACE,EAGN,eAAK,SAAS,EAAC,4DAA4D,aACxE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE;oCAC/D,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;oCACpD,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;oCAClF,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;oCAElF,OAAO,CACL,eAAoB,SAAS,EAAC,0CAA0C,aAEtE,cAAK,SAAS,EAAC,uBAAuB,YACpC,eAAK,SAAS,EAAC,mCAAmC,aAChD,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EACpC,SAAS,EAAC,0CAA0C,aAEnD,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,SAAS,IAAC,SAAS,EAAC,8BAA8B,GAAG,CACvD,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,IAAC,SAAS,EAAC,8BAA8B,GAAG,CACzD,EACD,eAAM,SAAS,EAAC,iCAAiC,YAC9C,QAAQ,GACJ,EACP,gBAAM,SAAS,EAAC,8BAA8B,kBAC1C,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,OAAG,WAAW,CAAC,MAAM,SACxF,IACA,EAER,CAAC,UAAU,IAAI,CACd,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAC5C,SAAS,EAAC,2BAA2B,YAEpC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,GACxC,CACV,IACG,GACF,EAGL,UAAU,IAAI,CACb,cAAK,SAAS,EAAC,2CAA2C,YACvD,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAC/B,iBAEE,SAAS,EAAE,gDACT,qBAAqB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;wDAC3C,CAAC,CAAC,8BAA8B;wDAChC,CAAC,CAAC,mCACN,IAAI,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,oBAAoB,aAExE,gBACE,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,qBAAqB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,EACtD,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC,EAC/C,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,QAAQ,aACrB,cAAK,SAAS,EAAC,qBAAqB,YACjC,UAAU,CAAC,IAAI,GACZ,EACL,UAAU,CAAC,WAAW,IAAI,CACzB,cAAK,SAAS,EAAC,mCAAmC,YAC/C,UAAU,CAAC,WAAW,GACnB,CACP,IACG,KAvBD,UAAU,CAAC,EAAE,CAwBZ,CACT,CAAC,GACE,CACP,KAlEO,QAAQ,CAmEZ,CACP,CAAA;gCACH,CAAC,CAAC,EAED,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAC5C,cAAK,SAAS,EAAC,uCAAuC,kEAEhD,CACP,IACG,IACF,EAGL,CAAC,UAAU,IAAI,CACd,eAAK,SAAS,EAAC,sDAAsD,aACnE,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,iBAAiB,EAC3B,QAAQ,EAAE,YAAY,CAAC,SAAS,yBAGzB,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,YAAY,CAAC,SAAS,EAChC,SAAS,EAAC,iBAAiB,YAE1B,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GAChE,IACL,CACP,EAEA,UAAU,IAAI,CACb,cAAK,SAAS,EAAC,gDAAgD,YAC7D,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,KAAK,+BAGR,GACL,CACP,IACI,GACD,CACT,CAAA;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ interface DangerZoneProps {
2
+ isActive: boolean;
3
+ isDeleted: boolean;
4
+ onUpdateStatus: (status: string) => void;
5
+ onDelete: () => void;
6
+ onRestore: () => void;
7
+ }
8
+ export declare const DangerZone: ({ isActive, onUpdateStatus, }: DangerZoneProps) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=DangerZone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DangerZone.d.ts","sourceRoot":"","sources":["../../../../src/client/pages/users/DangerZone.tsx"],"names":[],"mappings":"AAEA,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,eAAO,MAAM,UAAU,GAAI,+BAIxB,eAAe,4CAmDjB,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { AlertTriangle } from 'lucide-react';
3
+ export const DangerZone = ({ isActive,
4
+ // isDeleted, // Not currently used in basic danger zone but good for future extension
5
+ onUpdateStatus, }) => {
6
+ return (_jsxs("div", { className: "bg-white rounded-2xl border border-red-100 overflow-hidden", children: [_jsx("div", { className: "p-6 border-b border-red-50 bg-red-50/30", children: _jsxs("h3", { className: "font-semibold text-red-900 flex items-center gap-2", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-500" }), "V\u00F9ng nguy hi\u1EC3m"] }) }), _jsx("div", { className: "p-6 space-y-4", children: _jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 p-4 rounded-xl border border-gray-100 bg-gray-50/50", children: [_jsxs("div", { children: [_jsx("h4", { className: "font-medium text-gray-900", children: "Tr\u1EA1ng th\u00E1i t\u00E0i kho\u1EA3n" }), _jsxs("p", { className: "text-sm text-gray-500 mt-0.5", children: ["T\u00E0i kho\u1EA3n hi\u1EC7n \u0111ang ", isActive ? _jsx("span", { className: "text-green-600 font-medium", children: "Ho\u1EA1t \u0111\u1ED9ng" }) : _jsx("span", { className: "text-red-600 font-medium", children: "B\u1ECB kh\u00F3a/T\u1EA1m ng\u01B0ng" }), ".", isActive ? ' Ngưng hoạt động sẽ chặn người dùng đăng nhập.' : ' Kích hoạt lại để cho phép truy cập.'] })] }), _jsx("div", { className: "flex gap-2 w-full sm:w-auto", children: isActive ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => onUpdateStatus('SUSPENDED'), className: "flex-1 sm:flex-none px-4 py-2 border border-gray-300 bg-white text-gray-700 rounded-lg hover:bg-gray-50 text-sm font-medium", children: "T\u1EA1m ng\u01B0ng" }), _jsx("button", { type: "button", onClick: () => onUpdateStatus('LOCKED'), className: "flex-1 sm:flex-none px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 text-sm font-medium transition-colors", children: "Kh\u00F3a t\u00E0i kho\u1EA3n" })] })) : (_jsx("button", { type: "button", onClick: () => onUpdateStatus('ACTIVE'), className: "w-full sm:w-auto px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 text-sm font-medium transition-colors", children: "K\u00EDch ho\u1EA1t l\u1EA1i" })) })] }) })] }));
7
+ };
8
+ //# sourceMappingURL=DangerZone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DangerZone.js","sourceRoot":"","sources":["../../../../src/client/pages/users/DangerZone.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAU5C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,QAAQ;AACR,sFAAsF;AACtF,cAAc,GACE,EAAE,EAAE;IACpB,OAAO,CACL,eAAK,SAAS,EAAC,4DAA4D,aACzE,cAAK,SAAS,EAAC,yCAAyC,YACtD,cAAI,SAAS,EAAC,oDAAoD,aAChE,KAAC,aAAa,IAAC,SAAS,EAAC,sBAAsB,GAAG,gCAE/C,GACD,EAEN,cAAK,SAAS,EAAC,eAAe,YAC5B,eAAK,SAAS,EAAC,kHAAkH,aAC/H,0BACE,aAAI,SAAS,EAAC,2BAA2B,yDAA0B,EACnE,aAAG,SAAS,EAAC,8BAA8B,yDACpB,QAAQ,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,4BAA4B,yCAAiB,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,0BAA0B,sDAAyB,OAClK,QAAQ,CAAC,CAAC,CAAC,gDAAgD,CAAC,CAAC,CAAC,sCAAsC,IACnG,IACA,EACN,cAAK,SAAS,EAAC,6BAA6B,YACxC,QAAQ,CAAC,CAAC,CAAC,CACT,8BACE,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,WAAW,CAAC,EAC1C,SAAS,EAAC,6HAA6H,oCAGhI,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EACvC,SAAS,EAAC,uHAAuH,8CAG1H,IACR,CACL,CAAC,CAAC,CAAC,CACD,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EACvC,SAAS,EAAC,wHAAwH,6CAG3H,CACX,GACE,IACF,GACF,IACF,CACP,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ interface ProfileCardProps {
2
+ avatar: string;
3
+ name: string;
4
+ email: string;
5
+ role: string;
6
+ isEditing: boolean;
7
+ onAvatarChange: () => void;
8
+ onNameChange: (value: string) => void;
9
+ onEmailChange: (value: string) => void;
10
+ onRoleChange: (value: string) => void;
11
+ }
12
+ export declare const ProfileCard: ({ avatar, name, email, role, onAvatarChange, onNameChange, onEmailChange, onRoleChange, }: ProfileCardProps) => import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=ProfileCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileCard.d.ts","sourceRoot":"","sources":["../../../../src/client/pages/users/ProfileCard.tsx"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,eAAO,MAAM,WAAW,GAAI,2FAUzB,gBAAgB,4CAwElB,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Camera, Mail, Shield } from 'lucide-react';
3
+ export const ProfileCard = ({ avatar, name, email, role,
4
+ // isEditing,
5
+ onAvatarChange, onNameChange, onEmailChange, onRoleChange, }) => {
6
+ return (_jsx("div", { className: "bg-white rounded-2xl border border-gray-200 p-6 h-fit", children: _jsxs("div", { className: "flex flex-col items-center text-center", children: [_jsxs("div", { className: "relative group cursor-pointer mb-6", onClick: onAvatarChange, children: [_jsx("div", { className: "w-32 h-32 rounded-full bg-gray-50 border border-gray-200 overflow-hidden flex items-center justify-center", children: avatar ? (_jsx("img", { src: avatar, alt: "Avatar", className: "w-full h-full object-cover" })) : (_jsx("span", { className: "text-4xl font-bold text-gray-300 select-none", children: name ? name.charAt(0).toUpperCase() : 'U' })) }), _jsx("div", { className: "absolute inset-0 rounded-full bg-black/40 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all duration-200", children: _jsx(Camera, { className: "w-8 h-8 text-white" }) }), _jsx("div", { className: "absolute bottom-0 right-2 w-8 h-8 bg-white rounded-full flex items-center justify-center border border-gray-200 text-primary hover:bg-gray-50", children: _jsx(Camera, { className: "w-4 h-4" }) })] }), _jsxs("div", { className: "w-full space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-500 mb-1.5 uppercase text-left", children: "T\u00EAn hi\u1EC3n th\u1ECB" }), _jsx("input", { type: "text", required: true, value: name, onChange: (e) => onNameChange(e.target.value), className: "w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all font-medium text-gray-900 placeholder:text-gray-400", placeholder: "Nh\u1EADp t\u00EAn hi\u1EC3n th\u1ECB" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-500 mb-1.5 uppercase text-left", children: "Email" }), _jsxs("div", { className: "relative", children: [_jsx(Mail, { className: "absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "email", required: true, value: email, onChange: (e) => onEmailChange(e.target.value), className: "w-full pl-10 pr-4 py-2.5 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all text-gray-900 placeholder:text-gray-400", placeholder: "email@example.com" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-500 mb-1.5 uppercase text-left", children: "Vai tr\u00F2" }), _jsxs("div", { className: "relative", children: [_jsx(Shield, { className: "absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsxs("select", { value: role, onChange: (e) => onRoleChange(e.target.value), className: "w-full pl-10 pr-4 py-2.5 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all appearance-none bg-white font-medium", children: [_jsx("option", { value: "viewer", children: "Viewer" }), _jsx("option", { value: "editor", children: "Editor" }), _jsx("option", { value: "admin", children: "Admin" }), _jsx("option", { value: "super_admin", children: "Super Admin" })] })] })] })] })] }) }));
7
+ };
8
+ //# sourceMappingURL=ProfileCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileCard.js","sourceRoot":"","sources":["../../../../src/client/pages/users/ProfileCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAcnD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,MAAM,EACN,IAAI,EACJ,KAAK,EACL,IAAI;AACJ,aAAa;AACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,GACK,EAAE,EAAE;IACrB,OAAO,CACL,cAAK,SAAS,EAAC,uDAAuD,YACpE,eAAK,SAAS,EAAC,wCAAwC,aAErD,eAAK,SAAS,EAAC,oCAAoC,EAAC,OAAO,EAAE,cAAc,aACzE,cAAK,SAAS,EAAC,2GAA2G,YACvH,MAAM,CAAC,CAAC,CAAC,CACR,cAAK,GAAG,EAAE,MAAM,EAAE,GAAG,EAAC,QAAQ,EAAC,SAAS,EAAC,4BAA4B,GAAG,CACzE,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,8CAA8C,YAC3D,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,GACrC,CACR,GACG,EACN,cAAK,SAAS,EAAC,0IAA0I,YACvJ,KAAC,MAAM,IAAC,SAAS,EAAC,oBAAoB,GAAG,GACrC,EACN,cAAK,SAAS,EAAC,+IAA+I,YAC5J,KAAC,MAAM,IAAC,SAAS,EAAC,SAAS,GAAG,GAC1B,IACF,EAGN,eAAK,SAAS,EAAC,kBAAkB,aAC/B,0BACE,gBAAO,SAAS,EAAC,oEAAoE,4CAAqB,EAC1G,gBACE,IAAI,EAAC,MAAM,EACX,QAAQ,QACR,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7C,SAAS,EAAC,oMAAoM,EAC9M,WAAW,EAAC,uCAAmB,GAC/B,IACE,EAEN,0BACE,gBAAO,SAAS,EAAC,oEAAoE,sBAAc,EACnG,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,IAAI,IAAC,SAAS,EAAC,kEAAkE,GAAG,EACrF,gBACE,IAAI,EAAC,OAAO,EACZ,QAAQ,QACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC9C,SAAS,EAAC,8LAA8L,EACxM,WAAW,EAAC,mBAAmB,GAC/B,IACE,IACF,EAEN,0BACE,gBAAO,SAAS,EAAC,oEAAoE,6BAAgB,EACrG,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,MAAM,IAAC,SAAS,EAAC,kEAAkE,GAAG,EACvF,kBACE,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7C,SAAS,EAAC,2LAA2L,aAErM,iBAAQ,KAAK,EAAC,QAAQ,uBAAgB,EACtC,iBAAQ,KAAK,EAAC,QAAQ,uBAAgB,EACtC,iBAAQ,KAAK,EAAC,OAAO,sBAAe,EACpC,iBAAQ,KAAK,EAAC,aAAa,4BAAqB,IACzC,IACL,IACF,IACF,IACF,GACF,CACP,CAAA;AACH,CAAC,CAAA"}