nucleus-core-ts 0.8.6 → 0.8.8

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 (209) hide show
  1. package/dist/client.js +1 -1
  2. package/dist/dist/index.d.ts +475 -12
  3. package/dist/fe/components/AbstractAnimatedBackground/index.js +437 -0
  4. package/dist/fe/components/AuthorizationPage/components/AuthorizationPage.js +841 -0
  5. package/dist/fe/components/AuthorizationPage/components/ClaimList.js +100 -0
  6. package/dist/fe/components/AuthorizationPage/components/RoleClaimEditor.js +232 -0
  7. package/dist/fe/components/AuthorizationPage/components/RoleList.js +115 -0
  8. package/dist/fe/components/AuthorizationPage/index.js +6 -0
  9. package/dist/fe/components/AuthorizationPage/store/index.js +117 -0
  10. package/dist/fe/components/AuthorizationPage/theme/index.js +137 -0
  11. package/dist/fe/components/AuthorizationPage/types/index.js +1 -0
  12. package/dist/fe/components/Button/components/Button.js +158 -0
  13. package/dist/fe/components/Button/components/ButtonSpinner.js +52 -0
  14. package/dist/fe/components/Button/index.js +3 -0
  15. package/dist/fe/components/Button/theme/index.js +186 -0
  16. package/dist/fe/components/Button/types/index.js +1 -0
  17. package/dist/fe/components/Button/utils/cn.js +5 -0
  18. package/dist/fe/components/Captcha/components/Captcha.js +311 -0
  19. package/dist/fe/components/Captcha/index.js +2 -0
  20. package/dist/fe/components/Captcha/theme.js +52 -0
  21. package/dist/fe/components/Captcha/types.js +1 -0
  22. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordForm.js +242 -0
  23. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordHeader.js +39 -0
  24. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordPage.js +60 -0
  25. package/dist/fe/components/ChangePasswordPage/index.js +5 -0
  26. package/dist/fe/components/ChangePasswordPage/store/index.js +44 -0
  27. package/dist/fe/components/ChangePasswordPage/theme/index.js +87 -0
  28. package/dist/fe/components/ChangePasswordPage/types/index.js +1 -0
  29. package/dist/fe/components/Checkbox/components/Checkbox.js +115 -0
  30. package/dist/fe/components/Checkbox/components/CheckboxIcon.js +119 -0
  31. package/dist/fe/components/Checkbox/components/SwitchTrack.js +178 -0
  32. package/dist/fe/components/Checkbox/index.js +4 -0
  33. package/dist/fe/components/Checkbox/theme/index.js +221 -0
  34. package/dist/fe/components/Checkbox/types/index.js +1 -0
  35. package/dist/fe/components/Checkbox/utils/cn.js +5 -0
  36. package/dist/fe/components/DataTable/DataTable.js +225 -0
  37. package/dist/fe/components/DataTable/components/ActionCell.js +26 -0
  38. package/dist/fe/components/DataTable/components/DataCell.js +76 -0
  39. package/dist/fe/components/DataTable/components/EditableCell.js +221 -0
  40. package/dist/fe/components/DataTable/components/EmptyState.js +29 -0
  41. package/dist/fe/components/DataTable/components/HeaderCell.js +64 -0
  42. package/dist/fe/components/DataTable/components/InfiniteScrollTrigger.js +66 -0
  43. package/dist/fe/components/DataTable/components/LoadingSpinner.js +19 -0
  44. package/dist/fe/components/DataTable/components/ResizeHandle.js +41 -0
  45. package/dist/fe/components/DataTable/components/SelectionCell.js +105 -0
  46. package/dist/fe/components/DataTable/components/SkeletonRow.js +56 -0
  47. package/dist/fe/components/DataTable/components/SkeletonTable.js +83 -0
  48. package/dist/fe/components/DataTable/components/SortIcon.js +39 -0
  49. package/dist/fe/components/DataTable/components/TableHeader.js +49 -0
  50. package/dist/fe/components/DataTable/components/TableRow.js +118 -0
  51. package/dist/fe/components/DataTable/components/index.js +14 -0
  52. package/dist/fe/components/DataTable/hooks/index.js +2 -0
  53. package/dist/fe/components/DataTable/hooks/useAutoFitColumn.js +23 -0
  54. package/dist/fe/components/DataTable/hooks/useResizeColumn.js +122 -0
  55. package/dist/fe/components/DataTable/index.js +3 -0
  56. package/dist/fe/components/DataTable/store/index.js +97 -0
  57. package/dist/fe/components/DataTable/theme/index.js +144 -0
  58. package/dist/fe/components/DataTable/types/index.js +1 -0
  59. package/dist/fe/components/DataTable/utils/cn.js +5 -0
  60. package/dist/fe/components/DatePicker/components/CalendarGrid.js +95 -0
  61. package/dist/fe/components/DatePicker/components/CalendarHeader.js +152 -0
  62. package/dist/fe/components/DatePicker/components/DatePicker.js +381 -0
  63. package/dist/fe/components/DatePicker/components/MonthYearSelector.js +93 -0
  64. package/dist/fe/components/DatePicker/index.js +7 -0
  65. package/dist/fe/components/DatePicker/locales/index.js +1113 -0
  66. package/dist/fe/components/DatePicker/theme/index.js +315 -0
  67. package/dist/fe/components/DatePicker/types/index.js +1 -0
  68. package/dist/fe/components/DatePicker/utils/cn.js +5 -0
  69. package/dist/fe/components/DatePicker/utils/date.js +132 -0
  70. package/dist/fe/components/DevicesPage/components/DeviceCard.js +251 -0
  71. package/dist/fe/components/DevicesPage/components/DevicesHeader.js +42 -0
  72. package/dist/fe/components/DevicesPage/components/DevicesPage.js +450 -0
  73. package/dist/fe/components/DevicesPage/index.js +5 -0
  74. package/dist/fe/components/DevicesPage/store/index.js +55 -0
  75. package/dist/fe/components/DevicesPage/theme/index.js +131 -0
  76. package/dist/fe/components/DevicesPage/types/index.js +1 -0
  77. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordForm.js +214 -0
  78. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordHeader.js +42 -0
  79. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordPage.js +59 -0
  80. package/dist/fe/components/ForgotPasswordPage/index.js +5 -0
  81. package/dist/fe/components/ForgotPasswordPage/store/index.js +28 -0
  82. package/dist/fe/components/ForgotPasswordPage/theme/index.js +87 -0
  83. package/dist/fe/components/ForgotPasswordPage/types/index.js +1 -0
  84. package/dist/fe/components/FormBuilder/components/FormBuilder.js +156 -0
  85. package/dist/fe/components/FormBuilder/components/FormField.js +218 -0
  86. package/dist/fe/components/FormBuilder/hooks/useFormBuilder.js +152 -0
  87. package/dist/fe/components/FormBuilder/index.js +4 -0
  88. package/dist/fe/components/FormBuilder/theme/index.js +134 -0
  89. package/dist/fe/components/FormBuilder/types/index.js +1 -0
  90. package/dist/fe/components/FormBuilder/utils/cn.js +5 -0
  91. package/dist/fe/components/FormBuilder/utils/fieldMapping.js +216 -0
  92. package/dist/fe/components/FormBuilder/utils/validation.js +78 -0
  93. package/dist/fe/components/LoginPage/components/LoginForm.js +214 -0
  94. package/dist/fe/components/LoginPage/components/LoginHeader.js +24 -0
  95. package/dist/fe/components/LoginPage/components/LoginPage.js +138 -0
  96. package/dist/fe/components/LoginPage/index.js +5 -0
  97. package/dist/fe/components/LoginPage/store/index.js +59 -0
  98. package/dist/fe/components/LoginPage/theme/index.js +98 -0
  99. package/dist/fe/components/LoginPage/types/index.js +1 -0
  100. package/dist/fe/components/MagicLinkVerifyPage/components/MagicLinkVerifyPage.js +200 -0
  101. package/dist/fe/components/MagicLinkVerifyPage/index.js +3 -0
  102. package/dist/fe/components/MagicLinkVerifyPage/store.js +20 -0
  103. package/dist/fe/components/MagicLinkVerifyPage/theme.js +36 -0
  104. package/dist/fe/components/MagicLinkVerifyPage/types.js +1 -0
  105. package/dist/fe/components/NucleusEntityShowcase.js +1409 -0
  106. package/dist/fe/components/NucleusTextInput/components/FloatingLabel.js +56 -0
  107. package/dist/fe/components/NucleusTextInput/components/InputIcons.js +258 -0
  108. package/dist/fe/components/NucleusTextInput/components/NucleusTextInput.js +321 -0
  109. package/dist/fe/components/NucleusTextInput/components/PasswordStrengthIndicator.js +104 -0
  110. package/dist/fe/components/NucleusTextInput/components/TypewriterText.js +56 -0
  111. package/dist/fe/components/NucleusTextInput/index.js +7 -0
  112. package/dist/fe/components/NucleusTextInput/theme/index.js +121 -0
  113. package/dist/fe/components/NucleusTextInput/types/index.js +1 -0
  114. package/dist/fe/components/NucleusTextInput/utils/cn.js +5 -0
  115. package/dist/fe/components/NucleusTextInput/utils/format.js +62 -0
  116. package/dist/fe/components/NucleusTextInput/utils/validation.js +191 -0
  117. package/dist/fe/components/ProfilePage/components/AddressCard.js +196 -0
  118. package/dist/fe/components/ProfilePage/components/PhoneCard.js +206 -0
  119. package/dist/fe/components/ProfilePage/components/ProfileHeader.js +150 -0
  120. package/dist/fe/components/ProfilePage/components/ProfilePage.js +1336 -0
  121. package/dist/fe/components/ProfilePage/index.js +6 -0
  122. package/dist/fe/components/ProfilePage/store/index.js +115 -0
  123. package/dist/fe/components/ProfilePage/theme/index.js +168 -0
  124. package/dist/fe/components/ProfilePage/types/index.js +1 -0
  125. package/dist/fe/components/RangePicker/components/RangePicker.js +338 -0
  126. package/dist/fe/components/RangePicker/components/RangeThumb.js +68 -0
  127. package/dist/fe/components/RangePicker/components/RangeTooltip.js +45 -0
  128. package/dist/fe/components/RangePicker/components/RangeTrack.js +32 -0
  129. package/dist/fe/components/RangePicker/index.js +5 -0
  130. package/dist/fe/components/RangePicker/theme/index.js +88 -0
  131. package/dist/fe/components/RangePicker/types/index.js +1 -0
  132. package/dist/fe/components/RangePicker/utils/cn.js +3 -0
  133. package/dist/fe/components/RegisterPage/components/PasswordStrengthIndicator.js +107 -0
  134. package/dist/fe/components/RegisterPage/components/RegisterForm.js +322 -0
  135. package/dist/fe/components/RegisterPage/components/RegisterHeader.js +23 -0
  136. package/dist/fe/components/RegisterPage/components/RegisterPage.js +85 -0
  137. package/dist/fe/components/RegisterPage/index.js +6 -0
  138. package/dist/fe/components/RegisterPage/store/index.js +106 -0
  139. package/dist/fe/components/RegisterPage/theme/index.js +128 -0
  140. package/dist/fe/components/RegisterPage/types/index.js +1 -0
  141. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordForm.js +347 -0
  142. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordHeader.js +42 -0
  143. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordPage.js +61 -0
  144. package/dist/fe/components/ResetPasswordPage/index.js +5 -0
  145. package/dist/fe/components/ResetPasswordPage/store/index.js +36 -0
  146. package/dist/fe/components/ResetPasswordPage/theme/index.js +99 -0
  147. package/dist/fe/components/ResetPasswordPage/types/index.js +1 -0
  148. package/dist/fe/components/SearchBox/components/SearchBox.js +271 -0
  149. package/dist/fe/components/SearchBox/components/SearchBoxDropdown.js +87 -0
  150. package/dist/fe/components/SearchBox/index.js +5 -0
  151. package/dist/fe/components/SearchBox/theme/index.js +184 -0
  152. package/dist/fe/components/SearchBox/types/index.js +1 -0
  153. package/dist/fe/components/SearchBox/utils/cn.js +5 -0
  154. package/dist/fe/components/SearchBox/utils/debounce.js +22 -0
  155. package/dist/fe/components/SearchBox/utils/sanitize.js +48 -0
  156. package/dist/fe/components/SelectBox/components/SelectBox.js +364 -0
  157. package/dist/fe/components/SelectBox/components/SelectDropdown.js +92 -0
  158. package/dist/fe/components/SelectBox/components/SelectOptionItem.js +43 -0
  159. package/dist/fe/components/SelectBox/components/SelectTrigger.js +22 -0
  160. package/dist/fe/components/SelectBox/index.js +5 -0
  161. package/dist/fe/components/SelectBox/theme/index.js +98 -0
  162. package/dist/fe/components/SelectBox/types/index.js +1 -0
  163. package/dist/fe/components/SelectBox/utils/cn.js +3 -0
  164. package/dist/fe/components/SetPasswordPage/components/PasswordStrengthIndicator.js +107 -0
  165. package/dist/fe/components/SetPasswordPage/components/SetPasswordForm.js +142 -0
  166. package/dist/fe/components/SetPasswordPage/components/SetPasswordHeader.js +23 -0
  167. package/dist/fe/components/SetPasswordPage/components/SetPasswordPage.js +263 -0
  168. package/dist/fe/components/SetPasswordPage/index.js +7 -0
  169. package/dist/fe/components/SetPasswordPage/store/index.js +79 -0
  170. package/dist/fe/components/SetPasswordPage/theme/index.js +98 -0
  171. package/dist/fe/components/SetPasswordPage/types/index.js +12 -0
  172. package/dist/fe/components/UsersPage/components/InviteUserModal.js +262 -0
  173. package/dist/fe/components/UsersPage/components/Pagination.js +147 -0
  174. package/dist/fe/components/UsersPage/components/RoleAssignmentModal.js +186 -0
  175. package/dist/fe/components/UsersPage/components/StatsCards.js +124 -0
  176. package/dist/fe/components/UsersPage/components/UserDetailDrawer.js +444 -0
  177. package/dist/fe/components/UsersPage/components/UserFilters.js +142 -0
  178. package/dist/fe/components/UsersPage/components/UserListItem.js +125 -0
  179. package/dist/fe/components/UsersPage/components/UserListSkeleton.js +40 -0
  180. package/dist/fe/components/UsersPage/components/UsersPage.js +556 -0
  181. package/dist/fe/components/UsersPage/index.js +10 -0
  182. package/dist/fe/components/UsersPage/store/index.js +151 -0
  183. package/dist/fe/components/UsersPage/theme/index.js +231 -0
  184. package/dist/fe/components/UsersPage/types/index.js +1 -0
  185. package/dist/fe/components/VerifyEmailPage/components/VerifyEmailPage.js +290 -0
  186. package/dist/fe/components/VerifyEmailPage/index.js +3 -0
  187. package/dist/fe/components/VerifyEmailPage/store/index.js +45 -0
  188. package/dist/fe/components/VerifyEmailPage/theme/index.js +52 -0
  189. package/dist/fe/components/VerifyEmailPage/types/index.js +1 -0
  190. package/dist/fe/hooks/useNucleusEntity.js +247 -0
  191. package/dist/fe/index.js +28 -110
  192. package/dist/fe/types/index.js +1 -0
  193. package/dist/fe/utils/cn.js +5 -0
  194. package/dist/fe/utils/columnUtils.js +189 -0
  195. package/dist/fe/utils/endpointKeys.js +44 -0
  196. package/dist/index.js +1 -1
  197. package/dist/nucleus.config.d.ts +3 -0
  198. package/dist/src/Client/Proxy/httpProxy.js +1 -0
  199. package/dist/src/Client/Proxy/index.js +1 -1
  200. package/dist/src/Client/Proxy/server.js +1 -0
  201. package/dist/src/Client/Proxy/types.js +1 -0
  202. package/dist/src/Client/Proxy/utils.js +1 -0
  203. package/dist/src/Client/Proxy/wsProxy.js +1 -0
  204. package/package.json +1 -1
  205. package/scripts/build.ts +78 -8
  206. package/dist/dist/index-0yyw12k6.d.ts +0 -8
  207. package/dist/dist/index-tv67j5qd.d.ts +0 -488
  208. package/dist/index-0yyw12k6.js +0 -1
  209. package/dist/index-tv67j5qd.js +0 -1
@@ -0,0 +1,151 @@
1
+ "use client";
2
+ import { batch, createStore } from "h-state";
3
+ const initialState = {
4
+ users: [],
5
+ profiles: [],
6
+ addresses: [],
7
+ phones: [],
8
+ files: [],
9
+ roles: [],
10
+ userRoles: [],
11
+ selectedUser: null,
12
+ searchQuery: "",
13
+ statusFilter: "all",
14
+ roleFilter: "all",
15
+ isDetailPanelOpen: false,
16
+ assigningRoleId: null,
17
+ currentPage: 1,
18
+ pageSize: 25,
19
+ totalItems: 0,
20
+ totalPages: 0,
21
+ isLoading: false
22
+ };
23
+ export const { useStore: useUsersStore } = createStore(initialState, {
24
+ setUsers: (store)=>(users)=>{
25
+ store.users = users;
26
+ },
27
+ setProfiles: (store)=>(profiles)=>{
28
+ store.profiles = profiles;
29
+ },
30
+ setAddresses: (store)=>(addresses)=>{
31
+ store.addresses = addresses;
32
+ },
33
+ setPhones: (store)=>(phones)=>{
34
+ store.phones = phones;
35
+ },
36
+ setFiles: (store)=>(files)=>{
37
+ store.files = files;
38
+ },
39
+ setRoles: (store)=>(roles)=>{
40
+ store.roles = roles;
41
+ },
42
+ setUserRoles: (store)=>(userRoles)=>{
43
+ store.userRoles = userRoles;
44
+ },
45
+ setSelectedUser: (store)=>(user)=>{
46
+ store.selectedUser = user;
47
+ store.isDetailPanelOpen = user !== null;
48
+ },
49
+ setSearchQuery: (store)=>(query)=>{
50
+ store.searchQuery = query;
51
+ },
52
+ setStatusFilter: (store)=>(filter)=>{
53
+ store.statusFilter = filter;
54
+ },
55
+ setRoleFilter: (store)=>(roleId)=>{
56
+ store.roleFilter = roleId;
57
+ },
58
+ setDetailPanelOpen: (store)=>(open)=>{
59
+ store.isDetailPanelOpen = open;
60
+ if (!open) {
61
+ store.selectedUser = null;
62
+ }
63
+ },
64
+ setAssigningRoleId: (store)=>(roleId)=>{
65
+ store.assigningRoleId = roleId;
66
+ },
67
+ setCurrentPage: (store)=>(page)=>{
68
+ store.currentPage = page;
69
+ },
70
+ setPageSize: (store)=>(size)=>{
71
+ store.pageSize = size;
72
+ store.currentPage = 1;
73
+ },
74
+ setPagination: (store)=>(total, totalPages)=>{
75
+ store.totalItems = total;
76
+ store.totalPages = totalPages;
77
+ },
78
+ setIsLoading: (store)=>(loading)=>{
79
+ store.isLoading = loading;
80
+ },
81
+ updateUser: (store)=>(userId, updates)=>{
82
+ store.users = store.users.map((u)=>u.id === userId ? {
83
+ ...u,
84
+ ...updates
85
+ } : u);
86
+ if (store.selectedUser?.id === userId) {
87
+ store.selectedUser = {
88
+ ...store.selectedUser,
89
+ ...updates
90
+ };
91
+ }
92
+ },
93
+ addUser: (store)=>(user)=>{
94
+ store.users = [
95
+ user,
96
+ ...store.users
97
+ ];
98
+ store.totalItems = store.totalItems + 1;
99
+ },
100
+ addUserRole: (store)=>(userRole)=>{
101
+ store.userRoles = [
102
+ ...store.userRoles,
103
+ userRole
104
+ ];
105
+ },
106
+ removeUserRole: (store)=>(userRoleId)=>{
107
+ store.userRoles = store.userRoles.filter((ur)=>ur.id !== userRoleId);
108
+ },
109
+ getUserWithDetails: (store)=>(userId)=>{
110
+ const user = store.users.find((u)=>u.id === userId);
111
+ if (!user) return null;
112
+ const profile = store.profiles.find((p)=>p.userId === userId);
113
+ const userAddresses = store.addresses.filter((a)=>a.ownerType === "user" && a.ownerId === userId);
114
+ const userPhones = store.phones.filter((p)=>p.ownerType === "user" && p.ownerId === userId);
115
+ const userFiles = store.files.filter((f)=>f.uploadedBy === userId);
116
+ const userUserRoles = store.userRoles.filter((ur)=>ur.userId === userId).map((ur)=>({
117
+ ...ur,
118
+ role: store.roles.find((r)=>r.id === ur.roleId)
119
+ }));
120
+ return {
121
+ ...user,
122
+ profile: profile || null,
123
+ addresses: userAddresses,
124
+ phones: userPhones,
125
+ files: userFiles,
126
+ userRoles: userUserRoles
127
+ };
128
+ },
129
+ reset: (store)=>()=>{
130
+ batch(()=>{
131
+ store.users = [];
132
+ store.profiles = [];
133
+ store.addresses = [];
134
+ store.phones = [];
135
+ store.files = [];
136
+ store.roles = [];
137
+ store.userRoles = [];
138
+ store.selectedUser = null;
139
+ store.searchQuery = "";
140
+ store.statusFilter = "all";
141
+ store.roleFilter = "all";
142
+ store.isDetailPanelOpen = false;
143
+ store.assigningRoleId = null;
144
+ store.currentPage = 1;
145
+ store.pageSize = 25;
146
+ store.totalItems = 0;
147
+ store.totalPages = 0;
148
+ store.isLoading = false;
149
+ });
150
+ }
151
+ });
@@ -0,0 +1,231 @@
1
+ export const usersPageTheme = {
2
+ container: {
3
+ base: "min-h-screen bg-zinc-50 dark:bg-zinc-950 transition-colors",
4
+ padding: {
5
+ sm: "p-3",
6
+ md: "p-4",
7
+ lg: "p-6",
8
+ xl: "p-8",
9
+ "2xl": "p-10"
10
+ }
11
+ },
12
+ header: {
13
+ wrapper: "flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between mb-4 sm:mb-6",
14
+ title: "text-xl sm:text-2xl lg:text-3xl font-bold text-zinc-900 dark:text-zinc-100",
15
+ subtitle: "text-xs sm:text-sm text-zinc-500 dark:text-zinc-400",
16
+ actions: "flex items-center gap-2 mt-2 sm:mt-0"
17
+ },
18
+ layout: {
19
+ wrapper: "flex flex-col lg:flex-row gap-4 lg:gap-6",
20
+ sidebar: {
21
+ base: "transition-all duration-300 ease-in-out",
22
+ collapsed: "w-full",
23
+ expanded: "w-full lg:w-3/5 xl:w-2/3"
24
+ },
25
+ main: "w-full lg:w-2/5 xl:w-1/3 lg:sticky lg:top-4 lg:self-start"
26
+ },
27
+ filters: {
28
+ wrapper: "flex flex-col gap-3 p-3 sm:p-4 bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 mb-4",
29
+ searchInput: "w-full px-3 py-2 text-sm border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 placeholder:text-zinc-400 focus:outline-none focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-500",
30
+ select: "px-3 py-2 text-sm border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-500",
31
+ button: {
32
+ base: "px-3 py-2 text-sm font-medium rounded-lg transition-colors",
33
+ active: "bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300",
34
+ inactive: "bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700"
35
+ },
36
+ badge: "px-2 py-0.5 text-xs font-medium bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 rounded-full"
37
+ },
38
+ table: {
39
+ wrapper: "bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden",
40
+ header: {
41
+ row: "border-b border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50",
42
+ cell: "px-3 sm:px-4 py-3 text-left text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wider"
43
+ },
44
+ body: {
45
+ row: {
46
+ base: "border-b border-zinc-100 dark:border-zinc-800/50 transition-colors cursor-pointer",
47
+ hover: "hover:bg-zinc-50 dark:hover:bg-zinc-800/30",
48
+ selected: "bg-emerald-50 dark:bg-emerald-900/20"
49
+ },
50
+ cell: "px-3 sm:px-4 py-3 text-sm"
51
+ }
52
+ },
53
+ userCard: {
54
+ wrapper: {
55
+ base: "p-3 sm:p-4 border-b border-zinc-100 dark:border-zinc-800/50 transition-colors cursor-pointer",
56
+ hover: "hover:bg-zinc-50 dark:hover:bg-zinc-800/30",
57
+ selected: "bg-emerald-50 dark:bg-emerald-900/20 border-l-2 border-l-emerald-500"
58
+ },
59
+ avatar: {
60
+ wrapper: "relative flex-shrink-0",
61
+ image: "w-10 h-10 sm:w-12 sm:h-12 rounded-full object-cover",
62
+ placeholder: "w-10 h-10 sm:w-12 sm:h-12 rounded-full bg-gradient-to-br from-emerald-400 to-emerald-600 flex items-center justify-center text-white font-semibold text-sm sm:text-base",
63
+ statusDot: {
64
+ base: "absolute -bottom-0.5 -right-0.5 w-3 h-3 sm:w-3.5 sm:h-3.5 rounded-full border-2 border-white dark:border-zinc-900",
65
+ active: "bg-emerald-500",
66
+ locked: "bg-red-500",
67
+ unverified: "bg-amber-500"
68
+ }
69
+ },
70
+ content: {
71
+ wrapper: "flex-1 min-w-0 ml-3",
72
+ name: "font-medium text-sm sm:text-base text-zinc-900 dark:text-zinc-100 truncate",
73
+ email: "text-xs sm:text-sm text-zinc-500 dark:text-zinc-400 truncate",
74
+ meta: "text-xs text-zinc-400 dark:text-zinc-500 mt-0.5"
75
+ },
76
+ badges: {
77
+ wrapper: "flex flex-wrap gap-1 mt-1.5",
78
+ role: "px-1.5 py-0.5 text-xs bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 rounded",
79
+ status: {
80
+ active: "px-1.5 py-0.5 text-xs font-medium bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 rounded",
81
+ locked: "px-1.5 py-0.5 text-xs font-medium bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 rounded",
82
+ unverified: "px-1.5 py-0.5 text-xs font-medium bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300 rounded",
83
+ god: "px-1.5 py-0.5 text-xs font-medium bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 rounded"
84
+ }
85
+ }
86
+ },
87
+ detailPanel: {
88
+ overlay: "fixed inset-0 bg-black/50 z-40 lg:hidden",
89
+ wrapper: {
90
+ base: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 overflow-hidden z-50 transition-all duration-300",
91
+ mobile: "fixed inset-x-0 bottom-0 rounded-t-2xl max-h-[85vh]",
92
+ tablet: "fixed inset-y-0 right-0 w-96 rounded-l-2xl",
93
+ desktop: "rounded-xl sticky top-4"
94
+ },
95
+ header: {
96
+ wrapper: "flex items-center justify-between p-4 border-b border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50",
97
+ title: "text-base sm:text-lg font-semibold text-zinc-900 dark:text-zinc-100",
98
+ closeButton: "p-1.5 rounded-lg text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors"
99
+ },
100
+ content: {
101
+ wrapper: "p-4 space-y-4 overflow-y-auto max-h-[calc(100vh-200px)]",
102
+ section: {
103
+ wrapper: "space-y-2",
104
+ title: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wider",
105
+ content: "bg-zinc-50 dark:bg-zinc-800/50 rounded-lg p-3 space-y-2"
106
+ },
107
+ row: {
108
+ wrapper: "flex items-center justify-between gap-2",
109
+ label: "text-sm text-zinc-500 dark:text-zinc-400",
110
+ value: "text-sm font-medium text-zinc-900 dark:text-zinc-100 text-right truncate"
111
+ }
112
+ },
113
+ actions: {
114
+ wrapper: "p-4 border-t border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50",
115
+ button: {
116
+ base: "w-full px-3 py-2 text-sm font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
117
+ primary: "bg-emerald-600 hover:bg-emerald-700 text-white",
118
+ danger: "bg-red-100 hover:bg-red-200 dark:bg-red-900/30 dark:hover:bg-red-900/50 text-red-700 dark:text-red-300",
119
+ warning: "bg-amber-100 hover:bg-amber-200 dark:bg-amber-900/30 dark:hover:bg-amber-900/50 text-amber-700 dark:text-amber-300",
120
+ info: "bg-blue-100 hover:bg-blue-200 dark:bg-blue-900/30 dark:hover:bg-blue-900/50 text-blue-700 dark:text-blue-300"
121
+ }
122
+ }
123
+ },
124
+ pagination: {
125
+ wrapper: "flex flex-col sm:flex-row items-center justify-between gap-3 p-3 sm:p-4 bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 mt-4",
126
+ info: "text-sm text-zinc-500 dark:text-zinc-400",
127
+ controls: {
128
+ wrapper: "flex items-center gap-1 sm:gap-2",
129
+ button: {
130
+ base: "px-2 sm:px-3 py-1.5 text-sm rounded-lg transition-colors",
131
+ active: "bg-emerald-600 text-white",
132
+ disabled: "text-zinc-300 dark:text-zinc-600 cursor-not-allowed"
133
+ },
134
+ pageSize: "px-2 py-1.5 text-sm border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100"
135
+ }
136
+ },
137
+ skeleton: {
138
+ base: "animate-pulse bg-zinc-200 dark:bg-zinc-800 rounded",
139
+ avatar: "w-10 h-10 sm:w-12 sm:h-12 rounded-full",
140
+ text: "h-4 rounded",
141
+ button: "h-9 rounded-lg"
142
+ },
143
+ emptyState: {
144
+ wrapper: "flex flex-col items-center justify-center py-12 px-4 text-center",
145
+ icon: "w-12 h-12 text-zinc-300 dark:text-zinc-600 mb-4",
146
+ title: "text-lg font-medium text-zinc-900 dark:text-zinc-100 mb-1",
147
+ description: "text-sm text-zinc-500 dark:text-zinc-400"
148
+ },
149
+ modal: {
150
+ overlay: "fixed inset-0 bg-black/60 backdrop-blur-sm z-40",
151
+ wrapper: "w-full max-w-md bg-white dark:bg-zinc-900 rounded-2xl shadow-2xl border border-zinc-200 dark:border-zinc-800 overflow-hidden",
152
+ header: {
153
+ wrapper: "flex items-start justify-between gap-4 p-5 border-b border-zinc-200 dark:border-zinc-800",
154
+ icon: "flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-xl bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400",
155
+ title: "text-lg font-semibold text-zinc-900 dark:text-zinc-100",
156
+ subtitle: "text-sm text-zinc-500 dark:text-zinc-400 mt-0.5"
157
+ },
158
+ content: "p-5",
159
+ infoBox: "flex items-start gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-100 dark:border-blue-800/30",
160
+ footer: "flex items-center justify-end gap-3 p-5 border-t border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50"
161
+ },
162
+ stats: {
163
+ wrapper: "grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4 mb-4 sm:mb-6",
164
+ card: {
165
+ base: "p-3 sm:p-4 bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 transition-all hover:shadow-md hover:border-zinc-300 dark:hover:border-zinc-700",
166
+ icon: {
167
+ wrapper: "w-8 h-8 sm:w-10 sm:h-10 flex items-center justify-center rounded-lg mb-2 sm:mb-3",
168
+ primary: "bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400",
169
+ success: "bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400",
170
+ warning: "bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400",
171
+ danger: "bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400"
172
+ },
173
+ value: "text-xl sm:text-2xl font-bold text-zinc-900 dark:text-zinc-100",
174
+ label: "text-xs sm:text-sm text-zinc-500 dark:text-zinc-400 mt-0.5"
175
+ }
176
+ }
177
+ };
178
+ export function extendUsersPageTheme(overrides) {
179
+ return {
180
+ ...usersPageTheme,
181
+ ...overrides,
182
+ container: {
183
+ ...usersPageTheme.container,
184
+ ...overrides.container
185
+ },
186
+ header: {
187
+ ...usersPageTheme.header,
188
+ ...overrides.header
189
+ },
190
+ layout: {
191
+ ...usersPageTheme.layout,
192
+ ...overrides.layout
193
+ },
194
+ filters: {
195
+ ...usersPageTheme.filters,
196
+ ...overrides.filters
197
+ },
198
+ table: {
199
+ ...usersPageTheme.table,
200
+ ...overrides.table
201
+ },
202
+ userCard: {
203
+ ...usersPageTheme.userCard,
204
+ ...overrides.userCard
205
+ },
206
+ detailPanel: {
207
+ ...usersPageTheme.detailPanel,
208
+ ...overrides.detailPanel
209
+ },
210
+ pagination: {
211
+ ...usersPageTheme.pagination,
212
+ ...overrides.pagination
213
+ },
214
+ skeleton: {
215
+ ...usersPageTheme.skeleton,
216
+ ...overrides.skeleton
217
+ },
218
+ emptyState: {
219
+ ...usersPageTheme.emptyState,
220
+ ...overrides.emptyState
221
+ },
222
+ modal: {
223
+ ...usersPageTheme.modal,
224
+ ...overrides.modal
225
+ },
226
+ stats: {
227
+ ...usersPageTheme.stats,
228
+ ...overrides.stats
229
+ }
230
+ };
231
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,290 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useGSAP } from "@gsap/react";
4
+ import gsap from "gsap";
5
+ import { useEffect, useEffectEvent, useRef } from "react";
6
+ import { cn } from "../../../utils/cn";
7
+ import { useVerifyEmailStore } from "../store";
8
+ import { verifyEmailPageTheme } from "../theme";
9
+ gsap.registerPlugin(useGSAP);
10
+ function parseErrorMessage(error, defaultMsg) {
11
+ if (!error?.message) return defaultMsg;
12
+ try {
13
+ const parsed = JSON.parse(error.message);
14
+ const msg = parsed.message || "";
15
+ if (msg.includes("Failed query") || msg.includes("select") || msg.includes("params:")) {
16
+ return "An error occurred. Please try again later.";
17
+ }
18
+ return msg || defaultMsg;
19
+ } catch {
20
+ if (error.message.includes("Failed query") || error.message.includes("select")) {
21
+ return "An error occurred. Please try again later.";
22
+ }
23
+ return error.message;
24
+ }
25
+ }
26
+ export function VerifyEmailPage({ token, email: initialEmail = "", verifyEmailAction, resendVerificationAction, onSuccess, onBackToLogin, backToLoginHref, showResendForm = true, redirectDelay = 3000, className }) {
27
+ const theme = verifyEmailPageTheme;
28
+ const containerRef = useRef(null);
29
+ const cardRef = useRef(null);
30
+ const hasVerified = useRef(false);
31
+ const store = useVerifyEmailStore();
32
+ const setInitialEmail = useEffectEvent((email)=>{
33
+ if (email) {
34
+ store.setEmail(email);
35
+ }
36
+ });
37
+ const verifyToken = useEffectEvent((tokenValue)=>{
38
+ if (!tokenValue) {
39
+ store.setStep("error");
40
+ store.setMessage("Invalid verification link. No token provided.");
41
+ return;
42
+ }
43
+ if (hasVerified.current) return;
44
+ hasVerified.current = true;
45
+ verifyEmailAction.start({
46
+ payload: {
47
+ token: tokenValue
48
+ },
49
+ onAfterHandle: (response)=>{
50
+ if (!response) {
51
+ store.setStep("error");
52
+ store.setMessage("Verification failed. Please try again.");
53
+ return;
54
+ }
55
+ if (response.success) {
56
+ store.setStep("success");
57
+ store.setMessage(response.message || "Email verified successfully!");
58
+ setTimeout(()=>{
59
+ if (onSuccess) {
60
+ onSuccess();
61
+ } else if (onBackToLogin) {
62
+ onBackToLogin();
63
+ }
64
+ }, redirectDelay);
65
+ } else {
66
+ store.setStep("error");
67
+ store.setMessage(response.message || "Verification failed. Please try again.");
68
+ }
69
+ },
70
+ onErrorHandle: (error)=>{
71
+ store.setStep("error");
72
+ store.setMessage(parseErrorMessage(error, "Verification failed. Please try again."));
73
+ }
74
+ });
75
+ });
76
+ const decrementCooldownTick = useEffectEvent(()=>{
77
+ store.decrementCooldown();
78
+ });
79
+ useEffect(()=>{
80
+ setInitialEmail(initialEmail);
81
+ }, [
82
+ initialEmail
83
+ ]);
84
+ useEffect(()=>{
85
+ if (token) {
86
+ verifyToken(token);
87
+ } else {
88
+ store.setStep("error");
89
+ store.setMessage("Invalid verification link. No token provided.");
90
+ }
91
+ return ()=>{
92
+ store.reset();
93
+ };
94
+ }, [
95
+ token
96
+ ]);
97
+ useEffect(()=>{
98
+ if (store.cooldown <= 0) return;
99
+ const timer = setInterval(decrementCooldownTick, 1000);
100
+ return ()=>clearInterval(timer);
101
+ }, [
102
+ store.cooldown
103
+ ]);
104
+ useGSAP(()=>{
105
+ if (!cardRef.current) return;
106
+ gsap.fromTo(cardRef.current, {
107
+ opacity: 0,
108
+ y: 30,
109
+ scale: 0.95
110
+ }, {
111
+ opacity: 1,
112
+ y: 0,
113
+ scale: 1,
114
+ duration: 0.6,
115
+ ease: "power3.out"
116
+ });
117
+ }, {
118
+ scope: containerRef
119
+ });
120
+ const handleResend = useEffectEvent(()=>{
121
+ if (!store.email || store.cooldown > 0 || store.resendStatus === "loading" || !resendVerificationAction) return;
122
+ store.setResendStatus("loading");
123
+ store.setResendMessage("");
124
+ resendVerificationAction.start({
125
+ payload: {
126
+ email: store.email
127
+ },
128
+ onAfterHandle: (response)=>{
129
+ if (!response) {
130
+ store.setResendStatus("error");
131
+ store.setResendMessage("Failed to resend verification email.");
132
+ return;
133
+ }
134
+ if (response.success) {
135
+ store.setResendStatus("success");
136
+ store.setResendMessage(response.message || "Verification email sent!");
137
+ if (response.data?.cooldownSeconds) {
138
+ store.setCooldown(response.data.cooldownSeconds);
139
+ }
140
+ } else {
141
+ store.setResendStatus("error");
142
+ store.setResendMessage(response.message || "Failed to resend.");
143
+ if (response.data?.cooldownRemaining) {
144
+ store.setCooldown(response.data.cooldownRemaining);
145
+ }
146
+ }
147
+ },
148
+ onErrorHandle: (error)=>{
149
+ store.setResendStatus("error");
150
+ store.setResendMessage(parseErrorMessage(error, "Failed to resend verification email."));
151
+ }
152
+ });
153
+ });
154
+ const handleBackToLogin = ()=>{
155
+ if (onBackToLogin) {
156
+ onBackToLogin();
157
+ } else if (backToLoginHref) {
158
+ window.location.href = backToLoginHref;
159
+ }
160
+ };
161
+ return /*#__PURE__*/ _jsx("main", {
162
+ ref: containerRef,
163
+ className: cn(theme.container.base, className),
164
+ children: /*#__PURE__*/ _jsx("article", {
165
+ ref: cardRef,
166
+ className: cn(theme.card.base, theme.card.background, theme.card.border, theme.card.shadow, theme.card.rounded),
167
+ children: /*#__PURE__*/ _jsxs("div", {
168
+ className: theme.content.wrapper,
169
+ children: [
170
+ store.step === "verifying" && /*#__PURE__*/ _jsxs(_Fragment, {
171
+ children: [
172
+ /*#__PURE__*/ _jsx("div", {
173
+ className: theme.states.verifying.spinner
174
+ }),
175
+ /*#__PURE__*/ _jsx("h1", {
176
+ className: theme.states.verifying.title,
177
+ children: "Verifying Email"
178
+ }),
179
+ /*#__PURE__*/ _jsx("p", {
180
+ className: theme.states.verifying.subtitle,
181
+ children: store.message
182
+ })
183
+ ]
184
+ }),
185
+ store.step === "success" && /*#__PURE__*/ _jsxs(_Fragment, {
186
+ children: [
187
+ /*#__PURE__*/ _jsx("div", {
188
+ className: theme.states.success.iconWrapper,
189
+ children: /*#__PURE__*/ _jsx("svg", {
190
+ className: theme.states.success.icon,
191
+ fill: "none",
192
+ stroke: "currentColor",
193
+ viewBox: "0 0 24 24",
194
+ "aria-hidden": "true",
195
+ children: /*#__PURE__*/ _jsx("path", {
196
+ strokeLinecap: "round",
197
+ strokeLinejoin: "round",
198
+ strokeWidth: 2,
199
+ d: "M5 13l4 4L19 7"
200
+ })
201
+ })
202
+ }),
203
+ /*#__PURE__*/ _jsx("h1", {
204
+ className: theme.states.success.title,
205
+ children: "Email Verified!"
206
+ }),
207
+ /*#__PURE__*/ _jsx("p", {
208
+ className: theme.states.success.subtitle,
209
+ children: store.message
210
+ }),
211
+ /*#__PURE__*/ _jsx("p", {
212
+ className: theme.states.success.redirectText,
213
+ children: "Redirecting to login..."
214
+ })
215
+ ]
216
+ }),
217
+ store.step === "error" && /*#__PURE__*/ _jsxs(_Fragment, {
218
+ children: [
219
+ /*#__PURE__*/ _jsx("div", {
220
+ className: theme.states.error.iconWrapper,
221
+ children: /*#__PURE__*/ _jsx("svg", {
222
+ className: theme.states.error.icon,
223
+ fill: "none",
224
+ stroke: "currentColor",
225
+ viewBox: "0 0 24 24",
226
+ "aria-hidden": "true",
227
+ children: /*#__PURE__*/ _jsx("path", {
228
+ strokeLinecap: "round",
229
+ strokeLinejoin: "round",
230
+ strokeWidth: 2,
231
+ d: "M6 18L18 6M6 6l12 12"
232
+ })
233
+ })
234
+ }),
235
+ /*#__PURE__*/ _jsx("h1", {
236
+ className: theme.states.error.title,
237
+ children: "Verification Failed"
238
+ }),
239
+ /*#__PURE__*/ _jsx("p", {
240
+ className: theme.states.error.subtitle,
241
+ children: store.message
242
+ }),
243
+ showResendForm && resendVerificationAction && /*#__PURE__*/ _jsxs("div", {
244
+ className: theme.resendForm.wrapper,
245
+ children: [
246
+ /*#__PURE__*/ _jsx("p", {
247
+ className: theme.resendForm.label,
248
+ children: "Request a new verification email:"
249
+ }),
250
+ /*#__PURE__*/ _jsx("input", {
251
+ type: "email",
252
+ value: store.email,
253
+ onChange: (e)=>store.setEmail(e.target.value),
254
+ placeholder: "Enter your email",
255
+ className: theme.resendForm.input
256
+ }),
257
+ /*#__PURE__*/ _jsx("button", {
258
+ type: "button",
259
+ onClick: handleResend,
260
+ disabled: !store.email || store.cooldown > 0 || store.resendStatus === "loading",
261
+ className: theme.resendForm.button,
262
+ children: store.resendStatus === "loading" ? /*#__PURE__*/ _jsxs("span", {
263
+ className: theme.resendForm.buttonContent,
264
+ children: [
265
+ /*#__PURE__*/ _jsx("span", {
266
+ className: theme.resendForm.buttonSpinner
267
+ }),
268
+ "Sending..."
269
+ ]
270
+ }) : store.cooldown > 0 ? `Resend in ${store.cooldown}s` : "Resend Verification Email"
271
+ }),
272
+ store.resendMessage && /*#__PURE__*/ _jsx("p", {
273
+ className: store.resendStatus === "success" ? theme.resendForm.messageSuccess : theme.resendForm.messageError,
274
+ children: store.resendMessage
275
+ })
276
+ ]
277
+ }),
278
+ (onBackToLogin || backToLoginHref) && /*#__PURE__*/ _jsx("button", {
279
+ type: "button",
280
+ onClick: handleBackToLogin,
281
+ className: theme.backButton,
282
+ children: "Go to Login"
283
+ })
284
+ ]
285
+ })
286
+ ]
287
+ })
288
+ })
289
+ });
290
+ }
@@ -0,0 +1,3 @@
1
+ export { VerifyEmailPage } from "./components/VerifyEmailPage";
2
+ export { useVerifyEmailStore } from "./store";
3
+ export { extendVerifyEmailPageTheme, verifyEmailPageTheme } from "./theme";