@goplusvn/core 0.1.0 → 0.1.2

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 (591) hide show
  1. package/package.json +31 -175
  2. package/src/assets/erp_wallpaper.png +0 -0
  3. package/src/assets/goeat_logo.png +0 -0
  4. package/src/audit/audit-manager.ts +139 -0
  5. package/src/audit/index.ts +11 -0
  6. package/src/audit/memory-audit-logger.ts +86 -0
  7. package/src/audit/types.ts +50 -0
  8. package/src/auth/auth-service.ts +97 -0
  9. package/src/auth/index.ts +266 -0
  10. package/src/code-generation/index.ts +69 -0
  11. package/src/configs/auth-routes.ts +17 -0
  12. package/src/configs/crud.ts +136 -0
  13. package/src/configs/data/navigations.ts +781 -0
  14. package/src/configs/data/oauth-links.ts +10 -0
  15. package/src/configs/entities/material-categories.config.ts +125 -0
  16. package/src/configs/i18n.ts +12 -0
  17. package/src/configs/index.ts +26 -0
  18. package/src/configs/status.ts +25 -0
  19. package/src/configs/themes.ts +100 -0
  20. package/src/crud/components/crud-bulk-actions.tsx +91 -0
  21. package/src/crud/components/crud-card-view.tsx +241 -0
  22. package/src/crud/components/crud-context.tsx +122 -0
  23. package/src/crud/components/crud-delete-dialog.tsx +145 -0
  24. package/src/crud/components/crud-dialog.tsx +406 -0
  25. package/src/crud/components/crud-empty-state.tsx +104 -0
  26. package/src/crud/components/crud-export-button.tsx +170 -0
  27. package/src/crud/components/crud-field-renderer.tsx +653 -0
  28. package/src/crud/components/crud-filter-chips.tsx +102 -0
  29. package/src/crud/components/crud-filters/checkbox-filter.tsx +97 -0
  30. package/src/crud/components/crud-filters/datetime-filter.tsx +83 -0
  31. package/src/crud/components/crud-filters/filter-builder.tsx +66 -0
  32. package/src/crud/components/crud-filters/index.tsx +76 -0
  33. package/src/crud/components/crud-filters/radio-filter.tsx +86 -0
  34. package/src/crud/components/crud-filters/select-filter.tsx +141 -0
  35. package/src/crud/components/crud-filters/text-filter.tsx +86 -0
  36. package/src/crud/components/crud-form.tsx +642 -0
  37. package/src/crud/components/crud-import-dialog.tsx +440 -0
  38. package/src/crud/components/crud-infinite-scroll.tsx +116 -0
  39. package/src/crud/components/crud-page.tsx +1017 -0
  40. package/src/crud/components/crud-provider.tsx +277 -0
  41. package/src/crud/components/crud-row-actions.tsx +189 -0
  42. package/src/crud/components/crud-search.tsx +82 -0
  43. package/src/crud/components/crud-sheet.tsx +336 -0
  44. package/src/crud/components/crud-table-skeleton.tsx +26 -0
  45. package/src/crud/components/crud-table-toolbar.tsx +91 -0
  46. package/src/crud/components/crud-table.tsx +352 -0
  47. package/src/crud/components/crud-virtual-table.tsx +55 -0
  48. package/src/crud/components/index.tsx +20 -0
  49. package/src/crud/crud-filters/checkbox-filter.tsx +87 -0
  50. package/src/crud/crud-filters/datetime-filter.tsx +82 -0
  51. package/src/crud/crud-filters/filter-builder.tsx +64 -0
  52. package/src/crud/crud-filters/index.tsx +78 -0
  53. package/src/crud/crud-filters/radio-filter.tsx +79 -0
  54. package/src/crud/crud-filters/select-filter.tsx +148 -0
  55. package/src/crud/crud-filters/text-filter.tsx +81 -0
  56. package/src/crud/index.ts +43 -0
  57. package/src/crud/lib/crud-service.test.ts +334 -0
  58. package/src/crud/lib/crud-service.ts +358 -0
  59. package/src/crud/lib/crud-utils.test.ts +354 -0
  60. package/src/crud/lib/crud-utils.ts +299 -0
  61. package/src/crud/lib/crud-validator.ts +247 -0
  62. package/src/crud/lib/data-loader.ts +234 -0
  63. package/src/crud/lib/field-calculator.ts +241 -0
  64. package/src/crud/lib/field-formatter.ts +240 -0
  65. package/src/crud/lib/import-export-service.test.ts +290 -0
  66. package/src/crud/lib/import-export-service.ts +352 -0
  67. package/src/crud/lib/import-server-utils.ts +109 -0
  68. package/src/crud/lib/lazy-loader.ts +241 -0
  69. package/src/crud/lib/parse-filters.ts +85 -0
  70. package/src/crud/lib/permissions.ts +52 -0
  71. package/src/crud/lib/serialize-config.ts +60 -0
  72. package/src/crud/lib/stream-loader.ts +145 -0
  73. package/src/crud/lib/translate-config.ts +335 -0
  74. package/src/crud/lib/types.ts +11 -0
  75. package/src/crud/pages/entity-crud-page.tsx +144 -0
  76. package/src/crud/server.ts +8 -0
  77. package/src/home/constants.tsx +142 -0
  78. package/src/home/feature-showcase.tsx +171 -0
  79. package/src/home/home-page.tsx +191 -0
  80. package/src/home/hooks/index.ts +1 -0
  81. package/src/home/hooks/useWidgetPreferences.ts +167 -0
  82. package/src/home/index.ts +33 -0
  83. package/src/home/quick-access-dialog.tsx +271 -0
  84. package/src/home/quick-access-menu.tsx +267 -0
  85. package/src/home/types.ts +140 -0
  86. package/src/home/welcome-card.tsx +92 -0
  87. package/src/home/widget-container.tsx +258 -0
  88. package/src/home/widgets/base-widget.tsx +200 -0
  89. package/src/home/widgets/customers-widget.tsx +74 -0
  90. package/src/home/widgets/index.ts +6 -0
  91. package/src/home/widgets/orders-widget.tsx +87 -0
  92. package/src/home/widgets/revenue-widget.tsx +71 -0
  93. package/src/home/widgets/stock-widget.tsx +109 -0
  94. package/src/hooks/index.tsx +598 -0
  95. package/src/hooks/use-tenant.test.tsx +30 -0
  96. package/src/hooks/use-tenant.ts +5 -0
  97. package/src/index.ts +17 -0
  98. package/src/infrastructure/__tests__/architecture-verification.spec.ts +103 -0
  99. package/src/infrastructure/api-service.ts +317 -0
  100. package/src/infrastructure/cache/cache-manager.ts +107 -0
  101. package/src/infrastructure/cache/cache.ts +120 -0
  102. package/src/infrastructure/cache/index.ts +8 -0
  103. package/src/infrastructure/cache/types.ts +48 -0
  104. package/src/infrastructure/cron/cron-manager.ts +239 -0
  105. package/src/infrastructure/cron/index.ts +6 -0
  106. package/src/infrastructure/cron/types.ts +41 -0
  107. package/src/infrastructure/event-bus/event-bus.ts +145 -0
  108. package/src/infrastructure/event-bus/index.ts +2 -0
  109. package/src/infrastructure/event-bus/types.ts +22 -0
  110. package/src/infrastructure/index.ts +32 -0
  111. package/src/infrastructure/lock/decorators.ts +67 -0
  112. package/src/infrastructure/lock/index.ts +2 -0
  113. package/src/infrastructure/lock/lock-manager.ts +33 -0
  114. package/src/infrastructure/logger/index.ts +2 -0
  115. package/src/infrastructure/logger/logger.ts +96 -0
  116. package/src/infrastructure/logger/types.ts +25 -0
  117. package/src/layout/index.tsx +185 -0
  118. package/src/navigation/index.ts +91 -0
  119. package/src/notification/index.ts +14 -0
  120. package/src/notification/notification-service.ts +120 -0
  121. package/src/notification/storage/in-memory.ts +56 -0
  122. package/src/notification/storage/index.ts +1 -0
  123. package/src/notification/types.ts +51 -0
  124. package/src/organization/branch-service.ts +299 -0
  125. package/src/organization/branches.config.ts +154 -0
  126. package/src/organization/index.ts +5 -0
  127. package/src/plugin/apps-registry.ts +97 -0
  128. package/src/plugin/index.ts +5 -0
  129. package/src/plugin/types.ts +41 -0
  130. package/src/providers/index.tsx +109 -0
  131. package/src/providers/tenant-provider.tsx +45 -0
  132. package/src/rbac/components/roles/role-card.tsx +158 -0
  133. package/src/rbac/components/roles/role-stats-cards.tsx +29 -0
  134. package/src/rbac/components/roles/role-toolbar.tsx +123 -0
  135. package/src/rbac/hooks/use-role-operations.ts +159 -0
  136. package/src/rbac/hooks/use-roles-data.ts +59 -0
  137. package/src/rbac/index.ts +297 -0
  138. package/src/rbac/lib/permission-helpers.ts +63 -0
  139. package/src/rbac/pages/action-list-page.tsx +25 -0
  140. package/src/rbac/pages/resource-list-page.tsx +25 -0
  141. package/src/rbac/pages/role-list-page.tsx +378 -0
  142. package/src/rbac/permission-service.ts +140 -0
  143. package/src/rbac/permissions.ts +135 -0
  144. package/src/rbac/resource-service.ts +115 -0
  145. package/src/rbac/resource-validator.ts +119 -0
  146. package/src/rbac/role-service.ts +165 -0
  147. package/src/rbac/server.ts +16 -0
  148. package/src/rbac/types.ts +38 -0
  149. package/src/schemas/action.schema.ts +66 -0
  150. package/src/schemas/branch.schema.ts +52 -0
  151. package/src/schemas/coming-soon-schema.ts +9 -0
  152. package/src/schemas/company.schema.ts +44 -0
  153. package/src/schemas/forgot-passward-schema.ts +9 -0
  154. package/src/schemas/index.ts +30 -0
  155. package/src/schemas/material-category.schema.ts +43 -0
  156. package/src/schemas/material-pricing.schema.ts +74 -0
  157. package/src/schemas/material.schema.ts +76 -0
  158. package/src/schemas/materials.ts +52 -0
  159. package/src/schemas/new-passward-schema.ts +15 -0
  160. package/src/schemas/partner-company.schema.ts +149 -0
  161. package/src/schemas/register-schema.ts +36 -0
  162. package/src/schemas/resource.schema.ts +133 -0
  163. package/src/schemas/role.schema.ts +11 -0
  164. package/src/schemas/sign-in-schema.ts +24 -0
  165. package/src/schemas/supplier-pricing.schema.ts +15 -0
  166. package/src/schemas/supplier.schema.ts +120 -0
  167. package/src/schemas/system-category-group.schema.ts +67 -0
  168. package/src/schemas/system-category.schema.ts +77 -0
  169. package/src/schemas/system-config.schema.ts +118 -0
  170. package/src/schemas/uom.schema.ts +75 -0
  171. package/src/schemas/user-supplier.schema.ts +179 -0
  172. package/src/schemas/user.schema.ts +18 -0
  173. package/src/schemas/verify-email-schema.ts +9 -0
  174. package/src/schemas/warehouse.schema.ts +49 -0
  175. package/src/system/components/categories/category-list.tsx +529 -0
  176. package/src/system/components/categories/category-manager.tsx +89 -0
  177. package/src/system/components/categories/group-sidebar.tsx +308 -0
  178. package/src/system/components/settings/setting-dialogs.tsx +197 -0
  179. package/src/system/components/settings/setting-field.tsx +291 -0
  180. package/src/system/components/settings/setting-form-dialog.tsx +308 -0
  181. package/src/system/components/settings/settings-groups.ts +80 -0
  182. package/src/system/components/settings/settings-search.tsx +71 -0
  183. package/src/system/components/settings/settings-section.tsx +74 -0
  184. package/src/system/components/settings/settings-sidebar.tsx +81 -0
  185. package/src/system/constants.ts +3 -0
  186. package/src/system/index.ts +150 -0
  187. package/src/system/job-manager.ts +176 -0
  188. package/src/system/pages/components/categories/category-list.tsx +537 -0
  189. package/src/system/pages/components/categories/category-manager.tsx +90 -0
  190. package/src/system/pages/components/categories/group-sidebar.tsx +311 -0
  191. package/src/system/pages/components/settings/sales-rules-settings.tsx +222 -0
  192. package/src/system/pages/components/settings/setting-dialogs.tsx +197 -0
  193. package/src/system/pages/components/settings/setting-field.tsx +292 -0
  194. package/src/system/pages/components/settings/setting-form-dialog.tsx +308 -0
  195. package/src/system/pages/components/settings/settings-groups.ts +87 -0
  196. package/src/system/pages/components/settings/settings-page.tsx +372 -0
  197. package/src/system/pages/components/settings/settings-search.tsx +71 -0
  198. package/src/system/pages/components/settings/settings-section.tsx +74 -0
  199. package/src/system/pages/components/settings/settings-sidebar.tsx +81 -0
  200. package/src/system/pages/components/settings/system-settings.tsx +244 -0
  201. package/src/system/pages/system-category-page.tsx +15 -0
  202. package/src/system/pages/system-settings-page.tsx +380 -0
  203. package/src/system/schemas/system-category-group.schema.ts +46 -0
  204. package/src/system/schemas/system-category.schema.ts +56 -0
  205. package/src/system/services/settings-service.ts +127 -0
  206. package/src/system/services/system-category-service.ts +63 -0
  207. package/src/system/types.ts +45 -0
  208. package/src/types/index.ts +703 -0
  209. package/src/ui/auth/auth-layout.tsx +135 -0
  210. package/src/ui/auth/forgot-password-form.tsx +98 -0
  211. package/src/ui/auth/index.tsx +7 -0
  212. package/src/ui/auth/new-password-form.tsx +107 -0
  213. package/src/ui/auth/oauth-links.tsx +30 -0
  214. package/src/ui/auth/register-form.tsx +202 -0
  215. package/src/ui/auth/sign-in-form.tsx +238 -0
  216. package/src/ui/auth/verify-email-form.tsx +104 -0
  217. package/src/ui/crud/index.tsx +10 -0
  218. package/src/ui/data-display/accordion.tsx +65 -0
  219. package/src/ui/data-display/aspect-ratio.tsx +11 -0
  220. package/src/ui/data-display/avatar.tsx +163 -0
  221. package/src/ui/data-display/bento-grid.tsx +77 -0
  222. package/src/ui/data-display/carousel.tsx +249 -0
  223. package/src/ui/data-display/chart.tsx +363 -0
  224. package/src/ui/data-display/code-block-highlight.tsx +54 -0
  225. package/src/ui/data-display/collapsible.tsx +42 -0
  226. package/src/ui/data-display/compact-stat-bar.tsx +149 -0
  227. package/src/ui/data-display/data-table/data-table-context.tsx +255 -0
  228. package/src/ui/data-display/data-table/data-table-empty-state.tsx +133 -0
  229. package/src/ui/data-display/data-table/data-table-skeleton.tsx +145 -0
  230. package/src/ui/data-display/data-table/data-table-toolbar.tsx +353 -0
  231. package/src/ui/data-display/data-table/data-table.tsx +597 -0
  232. package/src/ui/data-display/data-table/index.ts +44 -0
  233. package/src/ui/data-display/data-table-column-header.tsx +75 -0
  234. package/src/ui/data-display/data-table-pagination.tsx +130 -0
  235. package/src/ui/data-display/data-table-view-options.tsx +59 -0
  236. package/src/ui/data-display/formatted-number-input.tsx +210 -0
  237. package/src/ui/data-display/highlight.tsx +20 -0
  238. package/src/ui/data-display/hover-card.tsx +48 -0
  239. package/src/ui/data-display/index.tsx +50 -0
  240. package/src/ui/data-display/iphone-15-pro.tsx +114 -0
  241. package/src/ui/data-display/kanban/index.ts +4 -0
  242. package/src/ui/data-display/kanban/kanban-board.tsx +192 -0
  243. package/src/ui/data-display/kanban/kanban-column.tsx +74 -0
  244. package/src/ui/data-display/kanban/kanban-item.tsx +50 -0
  245. package/src/ui/data-display/kanban/kanban-types.ts +21 -0
  246. package/src/ui/data-display/kpi-card.tsx +68 -0
  247. package/src/ui/data-display/media-grid.tsx +110 -0
  248. package/src/ui/data-display/safari.tsx +175 -0
  249. package/src/ui/data-display/show-more-text.tsx +55 -0
  250. package/src/ui/data-display/tabs.tsx +68 -0
  251. package/src/ui/data-display/timeline.tsx +256 -0
  252. package/src/ui/feedback/alert.tsx +60 -0
  253. package/src/ui/feedback/context-menu.tsx +245 -0
  254. package/src/ui/feedback/drawer.tsx +132 -0
  255. package/src/ui/feedback/error-dialog.tsx +273 -0
  256. package/src/ui/feedback/index.tsx +183 -0
  257. package/src/ui/feedback/progress.tsx +32 -0
  258. package/src/ui/feedback/sheet.tsx +148 -0
  259. package/src/ui/feedback/sonner.tsx +36 -0
  260. package/src/ui/forms/command.tsx +157 -0
  261. package/src/ui/forms/date-picker.tsx +73 -0
  262. package/src/ui/forms/date-range-picker.tsx +76 -0
  263. package/src/ui/forms/date-time-picker.tsx +109 -0
  264. package/src/ui/forms/editor/editor-menu-bar.tsx +394 -0
  265. package/src/ui/forms/editor/index.tsx +130 -0
  266. package/src/ui/forms/editor/multi-select-example.tsx +1234 -0
  267. package/src/ui/forms/emoji-picker.tsx +109 -0
  268. package/src/ui/forms/file-dropzone.tsx +169 -0
  269. package/src/ui/forms/file-thumbnail.tsx +29 -0
  270. package/src/ui/forms/index.tsx +201 -0
  271. package/src/ui/forms/input-file.tsx +99 -0
  272. package/src/ui/forms/input-group.tsx +46 -0
  273. package/src/ui/forms/input-otp.tsx +81 -0
  274. package/src/ui/forms/input-phone.tsx +172 -0
  275. package/src/ui/forms/input-spin.tsx +116 -0
  276. package/src/ui/forms/input-tags.tsx +219 -0
  277. package/src/ui/forms/input-time.tsx +42 -0
  278. package/src/ui/forms/multi-select.tsx +629 -0
  279. package/src/ui/forms/multiple-date-picker.tsx +74 -0
  280. package/src/ui/forms/radio-group.tsx +42 -0
  281. package/src/ui/forms/rating.tsx +158 -0
  282. package/src/ui/forms/time-picker.tsx +57 -0
  283. package/src/ui/index.tsx +17 -0
  284. package/src/ui/layout/animated-list.tsx +77 -0
  285. package/src/ui/layout/animated-sidebar.tsx +294 -0
  286. package/src/ui/layout/command-menu.tsx +355 -0
  287. package/src/ui/layout/customizer.tsx +324 -0
  288. package/src/ui/layout/footer.tsx +43 -0
  289. package/src/ui/layout/full-screen-toggle.tsx +52 -0
  290. package/src/ui/layout/header-breadcrumb.tsx +77 -0
  291. package/src/ui/layout/horizontal-layout-header.tsx +83 -0
  292. package/src/ui/layout/horizontal-layout.tsx +50 -0
  293. package/src/ui/layout/index.tsx +25 -0
  294. package/src/ui/layout/language-dropdown.tsx +103 -0
  295. package/src/ui/layout/logo.tsx +63 -0
  296. package/src/ui/layout/main-layout.tsx +57 -0
  297. package/src/ui/layout/mode-dropdown.tsx +58 -0
  298. package/src/ui/layout/notification-dropdown.tsx +127 -0
  299. package/src/ui/layout/page-tabs.tsx +306 -0
  300. package/src/ui/layout/route-cache.tsx +214 -0
  301. package/src/ui/layout/sidebar-group-icon-menu.tsx +195 -0
  302. package/src/ui/layout/sidebar.tsx +279 -0
  303. package/src/ui/layout/tab-content-cache.tsx +201 -0
  304. package/src/ui/layout/tab-navigation-provider.tsx +536 -0
  305. package/src/ui/layout/toggle-mobile-sidebar.tsx +33 -0
  306. package/src/ui/layout/top-bar-header-menubar.tsx +412 -0
  307. package/src/ui/layout/user-dropdown.tsx +188 -0
  308. package/src/ui/layout/vertical-layout-header.tsx +65 -0
  309. package/src/ui/layout/vertical-layout.tsx +47 -0
  310. package/src/ui/management/audit-log-page.tsx +209 -0
  311. package/src/ui/management/cache-management.tsx +349 -0
  312. package/src/ui/management/index.ts +3 -0
  313. package/src/ui/management/job-management.tsx +308 -0
  314. package/src/ui/pages/not-found.tsx +30 -0
  315. package/src/ui/primitives/badge.tsx +66 -0
  316. package/src/ui/primitives/breadcrumb.tsx +103 -0
  317. package/src/ui/primitives/button.tsx +129 -0
  318. package/src/ui/primitives/calendar.tsx +74 -0
  319. package/src/ui/primitives/card.tsx +86 -0
  320. package/src/ui/primitives/checkbox.tsx +31 -0
  321. package/src/ui/primitives/client.ts +30 -0
  322. package/src/ui/primitives/combobox.tsx +290 -0
  323. package/src/ui/primitives/dialog.tsx +121 -0
  324. package/src/ui/primitives/dropdown-menu.tsx +239 -0
  325. package/src/ui/primitives/dynamic-icon.tsx +24 -0
  326. package/src/ui/primitives/index.tsx +134 -0
  327. package/src/ui/primitives/input-number.tsx +131 -0
  328. package/src/ui/primitives/input.tsx +22 -0
  329. package/src/ui/primitives/keyboard.tsx +23 -0
  330. package/src/ui/primitives/label.tsx +24 -0
  331. package/src/ui/primitives/menubar.tsx +262 -0
  332. package/src/ui/primitives/navigation-menu.tsx +157 -0
  333. package/src/ui/primitives/pagination.tsx +118 -0
  334. package/src/ui/primitives/popover.tsx +56 -0
  335. package/src/ui/primitives/prefetch-link.tsx +60 -0
  336. package/src/ui/primitives/resizable.tsx +59 -0
  337. package/src/ui/primitives/scroll-area.tsx +63 -0
  338. package/src/ui/primitives/select.tsx +172 -0
  339. package/src/ui/primitives/separator.tsx +51 -0
  340. package/src/ui/primitives/sidebar.tsx +844 -0
  341. package/src/ui/primitives/slider.tsx +27 -0
  342. package/src/ui/primitives/status-badge.tsx +47 -0
  343. package/src/ui/primitives/sticky-layout.tsx +50 -0
  344. package/src/ui/primitives/switch.tsx +29 -0
  345. package/src/ui/primitives/table.tsx +116 -0
  346. package/src/ui/primitives/tabs.tsx +55 -0
  347. package/src/ui/primitives/toggle-group.tsx +70 -0
  348. package/src/ui/primitives/toggle.tsx +47 -0
  349. package/src/ui/primitives/tooltip.tsx +59 -0
  350. package/src/user/components/dangerous-zone.tsx +34 -0
  351. package/src/user/components/delete-account-form.tsx +40 -0
  352. package/src/user/components/index.ts +4 -0
  353. package/src/user/components/profile-info-form.tsx +390 -0
  354. package/src/user/components/profile-info.tsx +32 -0
  355. package/src/user/components/unified-profile-dialog.tsx +1019 -0
  356. package/src/user/components/user-stats.tsx +27 -0
  357. package/src/user/components/user-toolbar.tsx +137 -0
  358. package/src/user/components/users-card-view.tsx +253 -0
  359. package/src/user/index.ts +11 -0
  360. package/src/user/pages/user-list-page.tsx +234 -0
  361. package/src/user/pages/users-client-page.tsx +385 -0
  362. package/src/user/profile-page.tsx +19 -0
  363. package/src/user/schemas.ts +68 -0
  364. package/src/user/types.ts +34 -0
  365. package/src/user/user-service.ts +538 -0
  366. package/src/utils/index.ts +906 -0
  367. package/src/workflow/activity-timeline.tsx +412 -0
  368. package/src/workflow/approval-workflow.tsx +31 -0
  369. package/src/workflow/index.ts +2 -0
  370. package/dist/audit/index.d.mts +0 -115
  371. package/dist/audit/index.d.ts +0 -115
  372. package/dist/audit/index.js +0 -204
  373. package/dist/audit/index.js.map +0 -1
  374. package/dist/audit/index.mjs +0 -200
  375. package/dist/audit/index.mjs.map +0 -1
  376. package/dist/auth/index.d.mts +0 -86
  377. package/dist/auth/index.d.ts +0 -86
  378. package/dist/auth/index.js +0 -210
  379. package/dist/auth/index.js.map +0 -1
  380. package/dist/auth/index.mjs +0 -198
  381. package/dist/auth/index.mjs.map +0 -1
  382. package/dist/button-1dWvP9Ib.d.mts +0 -30
  383. package/dist/button-1dWvP9Ib.d.ts +0 -30
  384. package/dist/calendar-2QzdEo1z.d.mts +0 -20
  385. package/dist/calendar-2QzdEo1z.d.ts +0 -20
  386. package/dist/code-generation/index.d.mts +0 -30
  387. package/dist/code-generation/index.d.ts +0 -30
  388. package/dist/code-generation/index.js +0 -31
  389. package/dist/code-generation/index.js.map +0 -1
  390. package/dist/code-generation/index.mjs +0 -28
  391. package/dist/code-generation/index.mjs.map +0 -1
  392. package/dist/configs/index.d.mts +0 -175
  393. package/dist/configs/index.d.ts +0 -175
  394. package/dist/configs/index.js +0 -254
  395. package/dist/configs/index.js.map +0 -1
  396. package/dist/configs/index.mjs +0 -233
  397. package/dist/configs/index.mjs.map +0 -1
  398. package/dist/crud/index.d.mts +0 -646
  399. package/dist/crud/index.d.ts +0 -646
  400. package/dist/crud/index.js +0 -11772
  401. package/dist/crud/index.js.map +0 -1
  402. package/dist/crud/index.mjs +0 -11665
  403. package/dist/crud/index.mjs.map +0 -1
  404. package/dist/crud/server.d.mts +0 -20
  405. package/dist/crud/server.d.ts +0 -20
  406. package/dist/crud/server.js +0 -123
  407. package/dist/crud/server.js.map +0 -1
  408. package/dist/crud/server.mjs +0 -120
  409. package/dist/crud/server.mjs.map +0 -1
  410. package/dist/data-table-skeleton-12NA8Mjx.d.mts +0 -39
  411. package/dist/data-table-skeleton-12NA8Mjx.d.ts +0 -39
  412. package/dist/dialog-bKfjZMTd.d.mts +0 -22
  413. package/dist/dialog-bKfjZMTd.d.ts +0 -22
  414. package/dist/dynamic-icon-DrGIiu2N.d.mts +0 -10
  415. package/dist/dynamic-icon-DrGIiu2N.d.ts +0 -10
  416. package/dist/home/index.d.mts +0 -269
  417. package/dist/home/index.d.ts +0 -269
  418. package/dist/home/index.js +0 -1678
  419. package/dist/home/index.js.map +0 -1
  420. package/dist/home/index.mjs +0 -1635
  421. package/dist/home/index.mjs.map +0 -1
  422. package/dist/hooks/index.d.mts +0 -7
  423. package/dist/hooks/index.d.ts +0 -7
  424. package/dist/hooks/index.js +0 -8316
  425. package/dist/hooks/index.js.map +0 -1
  426. package/dist/hooks/index.mjs +0 -8255
  427. package/dist/hooks/index.mjs.map +0 -1
  428. package/dist/index-50hpiPrV.d.ts +0 -116
  429. package/dist/index-B9zQVEVi.d.mts +0 -116
  430. package/dist/index.d.mts +0 -5
  431. package/dist/index.d.ts +0 -5
  432. package/dist/index.js +0 -123
  433. package/dist/index.js.map +0 -1
  434. package/dist/index.mjs +0 -118
  435. package/dist/index.mjs.map +0 -1
  436. package/dist/infrastructure/index.d.mts +0 -423
  437. package/dist/infrastructure/index.d.ts +0 -423
  438. package/dist/infrastructure/index.js +0 -633
  439. package/dist/infrastructure/index.js.map +0 -1
  440. package/dist/infrastructure/index.mjs +0 -619
  441. package/dist/infrastructure/index.mjs.map +0 -1
  442. package/dist/label-DWTEkNPo.d.ts +0 -226
  443. package/dist/label-LPpdcoBx.d.mts +0 -226
  444. package/dist/layout/index.d.mts +0 -48
  445. package/dist/layout/index.d.ts +0 -48
  446. package/dist/layout/index.js +0 -117
  447. package/dist/layout/index.js.map +0 -1
  448. package/dist/layout/index.mjs +0 -90
  449. package/dist/layout/index.mjs.map +0 -1
  450. package/dist/navigation/index.d.mts +0 -16
  451. package/dist/navigation/index.d.ts +0 -16
  452. package/dist/navigation/index.js +0 -53
  453. package/dist/navigation/index.js.map +0 -1
  454. package/dist/navigation/index.mjs +0 -50
  455. package/dist/navigation/index.mjs.map +0 -1
  456. package/dist/notification/index.d.mts +0 -105
  457. package/dist/notification/index.d.ts +0 -105
  458. package/dist/notification/index.js +0 -278
  459. package/dist/notification/index.js.map +0 -1
  460. package/dist/notification/index.mjs +0 -274
  461. package/dist/notification/index.mjs.map +0 -1
  462. package/dist/organization/index.d.mts +0 -99
  463. package/dist/organization/index.d.ts +0 -99
  464. package/dist/organization/index.js +0 -360
  465. package/dist/organization/index.js.map +0 -1
  466. package/dist/organization/index.mjs +0 -352
  467. package/dist/organization/index.mjs.map +0 -1
  468. package/dist/plugin/index.d.mts +0 -83
  469. package/dist/plugin/index.d.ts +0 -83
  470. package/dist/plugin/index.js +0 -86
  471. package/dist/plugin/index.js.map +0 -1
  472. package/dist/plugin/index.mjs +0 -84
  473. package/dist/plugin/index.mjs.map +0 -1
  474. package/dist/providers/index.d.mts +0 -25
  475. package/dist/providers/index.d.ts +0 -25
  476. package/dist/providers/index.js +0 -84
  477. package/dist/providers/index.js.map +0 -1
  478. package/dist/providers/index.mjs +0 -77
  479. package/dist/providers/index.mjs.map +0 -1
  480. package/dist/rbac/index.d.mts +0 -226
  481. package/dist/rbac/index.d.ts +0 -226
  482. package/dist/rbac/index.js +0 -4784
  483. package/dist/rbac/index.js.map +0 -1
  484. package/dist/rbac/index.mjs +0 -4722
  485. package/dist/rbac/index.mjs.map +0 -1
  486. package/dist/rbac/permissions.d.mts +0 -26
  487. package/dist/rbac/permissions.d.ts +0 -26
  488. package/dist/rbac/permissions.js +0 -94
  489. package/dist/rbac/permissions.js.map +0 -1
  490. package/dist/rbac/permissions.mjs +0 -90
  491. package/dist/rbac/permissions.mjs.map +0 -1
  492. package/dist/rbac/server.d.mts +0 -1
  493. package/dist/rbac/server.d.ts +0 -1
  494. package/dist/rbac/server.js +0 -128
  495. package/dist/rbac/server.js.map +0 -1
  496. package/dist/rbac/server.mjs +0 -124
  497. package/dist/rbac/server.mjs.map +0 -1
  498. package/dist/schemas/index.d.mts +0 -1257
  499. package/dist/schemas/index.d.ts +0 -1257
  500. package/dist/schemas/index.js +0 -572
  501. package/dist/schemas/index.js.map +0 -1
  502. package/dist/schemas/index.mjs +0 -523
  503. package/dist/schemas/index.mjs.map +0 -1
  504. package/dist/server-QuYCTa89.d.mts +0 -83
  505. package/dist/server-QuYCTa89.d.ts +0 -83
  506. package/dist/sonner-C74GlRDQ.d.mts +0 -71
  507. package/dist/sonner-C74GlRDQ.d.ts +0 -71
  508. package/dist/status-BOXZgIqX.d.mts +0 -12
  509. package/dist/status-BOXZgIqX.d.ts +0 -12
  510. package/dist/system/index.d.mts +0 -77
  511. package/dist/system/index.d.ts +0 -77
  512. package/dist/system/index.js +0 -102
  513. package/dist/system/index.js.map +0 -1
  514. package/dist/system/index.mjs +0 -100
  515. package/dist/system/index.mjs.map +0 -1
  516. package/dist/tabs-C6FfBwPY.d.mts +0 -18
  517. package/dist/tabs-C6FfBwPY.d.ts +0 -18
  518. package/dist/tenant-provider-B8eC_Wpb.d.mts +0 -27
  519. package/dist/tenant-provider-B8eC_Wpb.d.ts +0 -27
  520. package/dist/types/index.d.mts +0 -469
  521. package/dist/types/index.d.ts +0 -469
  522. package/dist/types/index.js +0 -25
  523. package/dist/types/index.js.map +0 -1
  524. package/dist/types/index.mjs +0 -21
  525. package/dist/types/index.mjs.map +0 -1
  526. package/dist/ui/auth.d.mts +0 -39
  527. package/dist/ui/auth.d.ts +0 -39
  528. package/dist/ui/auth.js +0 -4941
  529. package/dist/ui/auth.js.map +0 -1
  530. package/dist/ui/auth.mjs +0 -4896
  531. package/dist/ui/auth.mjs.map +0 -1
  532. package/dist/ui/crud.d.mts +0 -2
  533. package/dist/ui/crud.d.ts +0 -2
  534. package/dist/ui/crud.js +0 -4
  535. package/dist/ui/crud.js.map +0 -1
  536. package/dist/ui/crud.mjs +0 -3
  537. package/dist/ui/crud.mjs.map +0 -1
  538. package/dist/ui/data-display.d.mts +0 -596
  539. package/dist/ui/data-display.d.ts +0 -596
  540. package/dist/ui/data-display.js +0 -5307
  541. package/dist/ui/data-display.js.map +0 -1
  542. package/dist/ui/data-display.mjs +0 -5212
  543. package/dist/ui/data-display.mjs.map +0 -1
  544. package/dist/ui/feedback.d.mts +0 -55
  545. package/dist/ui/feedback.d.ts +0 -55
  546. package/dist/ui/feedback.js +0 -2608
  547. package/dist/ui/feedback.js.map +0 -1
  548. package/dist/ui/feedback.mjs +0 -2526
  549. package/dist/ui/feedback.mjs.map +0 -1
  550. package/dist/ui/forms.d.mts +0 -309
  551. package/dist/ui/forms.d.ts +0 -309
  552. package/dist/ui/forms.js +0 -4656
  553. package/dist/ui/forms.js.map +0 -1
  554. package/dist/ui/forms.mjs +0 -4571
  555. package/dist/ui/forms.mjs.map +0 -1
  556. package/dist/ui/index.d.mts +0 -331
  557. package/dist/ui/index.d.ts +0 -331
  558. package/dist/ui/index.js +0 -16953
  559. package/dist/ui/index.js.map +0 -1
  560. package/dist/ui/index.mjs +0 -16598
  561. package/dist/ui/index.mjs.map +0 -1
  562. package/dist/ui/primitives/client.d.mts +0 -61
  563. package/dist/ui/primitives/client.d.ts +0 -61
  564. package/dist/ui/primitives/client.js +0 -3408
  565. package/dist/ui/primitives/client.js.map +0 -1
  566. package/dist/ui/primitives/client.mjs +0 -3256
  567. package/dist/ui/primitives/client.mjs.map +0 -1
  568. package/dist/ui/primitives.d.mts +0 -113
  569. package/dist/ui/primitives.d.ts +0 -113
  570. package/dist/ui/primitives.js +0 -3356
  571. package/dist/ui/primitives.js.map +0 -1
  572. package/dist/ui/primitives.mjs +0 -3227
  573. package/dist/ui/primitives.mjs.map +0 -1
  574. package/dist/user/index.d.mts +0 -228
  575. package/dist/user/index.d.ts +0 -228
  576. package/dist/user/index.js +0 -4306
  577. package/dist/user/index.js.map +0 -1
  578. package/dist/user/index.mjs +0 -4260
  579. package/dist/user/index.mjs.map +0 -1
  580. package/dist/utils/index.d.mts +0 -205
  581. package/dist/utils/index.d.ts +0 -205
  582. package/dist/utils/index.js +0 -574
  583. package/dist/utils/index.js.map +0 -1
  584. package/dist/utils/index.mjs +0 -514
  585. package/dist/utils/index.mjs.map +0 -1
  586. package/dist/workflow/index.d.mts +0 -40
  587. package/dist/workflow/index.d.ts +0 -40
  588. package/dist/workflow/index.js +0 -3710
  589. package/dist/workflow/index.js.map +0 -1
  590. package/dist/workflow/index.mjs +0 -3677
  591. package/dist/workflow/index.mjs.map +0 -1
@@ -0,0 +1,10 @@
1
+ import { Facebook, Github, Chrome, Twitter } from "lucide-react";
2
+
3
+ import type { OAuthLinkType } from "../../types";
4
+
5
+ export const oauthLinksData: OAuthLinkType[] = [
6
+ { href: "/", label: "Facebook", icon: Facebook },
7
+ { href: "/", label: "GitHub", icon: Github },
8
+ { href: "/", label: "Google", icon: Chrome },
9
+ { href: "/", label: "X", icon: Twitter },
10
+ ];
@@ -0,0 +1,125 @@
1
+ import { FolderTree } from "lucide-react";
2
+
3
+ import type { EntityConfig } from "../../types";
4
+
5
+ import { STATUS_OPTIONS } from "../status";
6
+
7
+ export const materialCategoriesConfig: EntityConfig = {
8
+ name: "material-category",
9
+ label: "Danh mục nguyên vật liệu",
10
+ pluralLabel: "Danh mục nguyên vật liệu",
11
+ icon: FolderTree,
12
+ description: "Quản lý danh mục nguyên vật liệu",
13
+ apiEndpoint: "/api/material-categories",
14
+ idField: "id",
15
+ displayField: "name",
16
+
17
+ // Custom row actions
18
+ rowActions: [
19
+ {
20
+ label: "Copy",
21
+ action: "copy",
22
+ icon: "Copy",
23
+ excludeFields: ["id", "createdAt", "createdBy", "updatedAt", "updatedBy"],
24
+ transformData: (rowData) => ({
25
+ ...rowData,
26
+ code: `${rowData.code}-COPY`,
27
+ name: `${rowData.name} (Copy)`,
28
+ }),
29
+ },
30
+ ],
31
+
32
+ fields: [
33
+ {
34
+ name: "id",
35
+ label: "ID",
36
+ type: "text",
37
+ hideInForm: true,
38
+ hideInTable: true,
39
+ },
40
+ {
41
+ name: "code",
42
+ label: "Mã danh mục",
43
+ type: "text",
44
+ required: true,
45
+ placeholder: "Nhập mã danh mục",
46
+
47
+ filterable: true,
48
+ disableOnEdit: true,
49
+ },
50
+ {
51
+ name: "name",
52
+ label: "Tên danh mục",
53
+ type: "text",
54
+ required: true,
55
+ placeholder: "Nhập tên danh mục",
56
+
57
+ filterable: true,
58
+ },
59
+ {
60
+ name: "description",
61
+ label: "Mô tả",
62
+ type: "textarea",
63
+ placeholder: "Nhập mô tả",
64
+ rows: 3,
65
+ hideInTable: true,
66
+ },
67
+ {
68
+ name: "status",
69
+ label: "Trạng thái",
70
+ type: "switch",
71
+ required: true,
72
+ defaultValue: "active",
73
+
74
+ filterable: true,
75
+ options: STATUS_OPTIONS,
76
+ },
77
+ {
78
+ name: "createdAt",
79
+ label: "Ngày tạo",
80
+ type: "datetime",
81
+ hideInForm: true,
82
+
83
+ renderCell: (value) => {
84
+ return new Date(value as string).toLocaleDateString("vi-VN");
85
+ },
86
+ },
87
+ ],
88
+
89
+ filters: [
90
+ {
91
+ name: "search",
92
+ label: "Tìm kiếm",
93
+ type: "text",
94
+ field: "name",
95
+ operator: "contains",
96
+ },
97
+ {
98
+ name: "status",
99
+ label: "Trạng thái",
100
+ type: "checkbox",
101
+ field: "status",
102
+ operator: "in",
103
+ options: [
104
+ { label: "Hoạt động", value: "active" },
105
+ { label: "Không hoạt động", value: "inactive" },
106
+ ],
107
+ },
108
+ ],
109
+
110
+ permissions: {
111
+ create: true,
112
+ read: true,
113
+ update: true,
114
+ delete: true,
115
+ export: true,
116
+ import: true,
117
+ },
118
+
119
+ features: {
120
+ search: true,
121
+ bulkActions: true,
122
+ export: true,
123
+ import: true,
124
+ },
125
+ };
@@ -0,0 +1,12 @@
1
+ export const i18n = {
2
+ defaultLocale: "vi",
3
+ locales: ["vi", "en"],
4
+ localeDirection: {
5
+ vi: "ltr",
6
+ en: "ltr",
7
+ },
8
+ localeNames: {
9
+ vi: "vietnamese",
10
+ en: "english",
11
+ },
12
+ } as const;
@@ -0,0 +1,26 @@
1
+ // @goerp/core/configs
2
+ // Core configuration for GoERP platform
3
+ // Consolidated from packages/shared/configs
4
+
5
+ // Local data configs
6
+ export * from "./data/oauth-links";
7
+
8
+ // Inline configs
9
+ export * from "./i18n";
10
+ export * from "./themes";
11
+ export * from "./auth-routes";
12
+ export * from "./status";
13
+ export * from "./crud";
14
+
15
+ // Create locales export for backward compatibility
16
+ import { i18n as _i18n } from "./i18n";
17
+ export const locales = _i18n.locales;
18
+
19
+ // Re-exports with aliases for backward compatibility
20
+ export {
21
+ STATUS_COLORS as CONFIG_STATUS_COLORS,
22
+ STATUS_ACTIVE as CONFIG_STATUS_ACTIVE,
23
+ STATUS_INACTIVE as CONFIG_STATUS_INACTIVE,
24
+ STATUS_OPTIONS as CONFIG_STATUS_OPTIONS,
25
+ STATUS_VALUES as CONFIG_STATUS_VALUES,
26
+ } from "./status";
@@ -0,0 +1,25 @@
1
+ export const STATUS_ACTIVE = "active";
2
+ export const STATUS_INACTIVE = "inactive";
3
+
4
+ export const STATUS_VALUES = [STATUS_ACTIVE, STATUS_INACTIVE] as const;
5
+
6
+ export const STATUS_OPTIONS = [
7
+ { label: "crud.common.options.active", value: STATUS_ACTIVE },
8
+ { label: "crud.common.options.inactive", value: STATUS_INACTIVE },
9
+ ];
10
+
11
+ export const STATUS_COLORS: Record<
12
+ string,
13
+ "success" | "warning" | "default" | "destructive" | "secondary" | "outline"
14
+ > = {
15
+ [STATUS_ACTIVE]: "success",
16
+ [STATUS_INACTIVE]: "warning",
17
+ };
18
+
19
+ export function booleanToStatus(value: boolean): string {
20
+ return value ? STATUS_ACTIVE : STATUS_INACTIVE;
21
+ }
22
+
23
+ export function statusToBoolean(value: string): boolean {
24
+ return value === STATUS_ACTIVE;
25
+ }
@@ -0,0 +1,100 @@
1
+ export const radii = [0, 0.3, 0.5, 0.75, 1];
2
+
3
+ export const themes = {
4
+ zinc: {
5
+ label: "Zinc",
6
+ activeColor: {
7
+ light: "240 5.9% 10%",
8
+ dark: "240 5.2% 33.9%",
9
+ foreground: "0 0% 98%",
10
+ },
11
+ },
12
+ slate: {
13
+ label: "Slate",
14
+ activeColor: {
15
+ light: "215.4 16.3% 46.9%",
16
+ dark: "215.3 19.3% 34.5%",
17
+ foreground: "210 40% 98%",
18
+ },
19
+ },
20
+ stone: {
21
+ label: "Stone",
22
+ activeColor: {
23
+ light: "25 5.3% 44.7%",
24
+ dark: "33.3 5.5% 32.4%",
25
+ foreground: "60 9.1% 97.8%",
26
+ },
27
+ },
28
+ gray: {
29
+ label: "Gray",
30
+ activeColor: {
31
+ light: "220 8.9% 46.1%",
32
+ dark: "215 13.8% 34.1%",
33
+ foreground: "210 20% 98%",
34
+ },
35
+ },
36
+ neutral: {
37
+ label: "Neutral",
38
+ activeColor: {
39
+ light: "0 0% 45.1%",
40
+ dark: "0 0% 32.2%",
41
+ foreground: "0 0% 98%",
42
+ },
43
+ },
44
+ red: {
45
+ label: "Red",
46
+ activeColor: {
47
+ light: "0 72.2% 50.6%",
48
+ dark: "0 72.2% 50.6%",
49
+ foreground: "0 85.7% 97.3%",
50
+ },
51
+ },
52
+ rose: {
53
+ label: "Rose",
54
+ activeColor: {
55
+ light: "346.8 77.2% 49.8%",
56
+ dark: "346.8 77.2% 49.8%",
57
+ foreground: "355.7 100% 97.3%",
58
+ },
59
+ },
60
+ orange: {
61
+ label: "Orange",
62
+ activeColor: {
63
+ light: "24.6 95% 53.1%",
64
+ dark: "20.5 90.2% 48.2%",
65
+ foreground: "60 9.1% 97.8%",
66
+ },
67
+ },
68
+ green: {
69
+ label: "Green",
70
+ activeColor: {
71
+ light: "142.1 76.2% 36.3%",
72
+ dark: "142.1 70.6% 45.3%",
73
+ foreground: "355.7 100% 97.3%",
74
+ },
75
+ },
76
+ blue: {
77
+ label: "Blue",
78
+ activeColor: {
79
+ light: "221.2 83.2% 53.3%",
80
+ dark: "217.2 91.2% 59.8%",
81
+ foreground: "210 40% 98%",
82
+ },
83
+ },
84
+ yellow: {
85
+ label: "Yellow",
86
+ activeColor: {
87
+ light: "47.9 95.8% 53.1%",
88
+ dark: "47.9 95.8% 53.1%",
89
+ foreground: "26 83.3% 14.1%",
90
+ },
91
+ },
92
+ violet: {
93
+ label: "Violet",
94
+ activeColor: {
95
+ light: "262.1 83.3% 57.8%",
96
+ dark: "263.4 70% 50.4%",
97
+ foreground: "210 20% 98%",
98
+ },
99
+ },
100
+ };
@@ -0,0 +1,91 @@
1
+ "use client";
2
+
3
+ import { MoreHorizontal, Trash2 } from "lucide-react";
4
+
5
+ import type { CrudPermissions, EntityConfig } from "../../types";
6
+
7
+ import { Button } from "../../ui";
8
+ import {
9
+ DropdownMenu,
10
+ DropdownMenuContent,
11
+ DropdownMenuItem,
12
+ DropdownMenuSeparator,
13
+ DropdownMenuTrigger,
14
+ } from "../../ui/primitives/client";
15
+ import { useCrudContext } from "./crud-provider";
16
+
17
+ interface CrudBulkActionsProps {
18
+ config: EntityConfig;
19
+ permissions: CrudPermissions;
20
+ onDelete?: (rowIds: string[]) => void;
21
+ onExport?: (rowIds: string[]) => void;
22
+ }
23
+
24
+ export function CrudBulkActions({
25
+ config,
26
+ permissions,
27
+ onDelete,
28
+ onExport,
29
+ }: CrudBulkActionsProps) {
30
+ const { selectedRows, clearSelection, translations } = useCrudContext();
31
+
32
+ // Chỉ hiển thị bulk actions nếu selection column được bật
33
+ const showRowSelection = config.features?.showRowSelection !== false; // Default: true
34
+ if (!showRowSelection) {
35
+ return null;
36
+ }
37
+
38
+ const selectedCount = selectedRows.size;
39
+
40
+ if (selectedCount === 0) {
41
+ return null;
42
+ }
43
+
44
+ const selectedIds = Array.from(selectedRows);
45
+
46
+ // Translation fallbacks
47
+ const t = {
48
+ selected: "selected",
49
+ actions: translations.actions || "Actions",
50
+ exportSelected: "Export selected",
51
+ deleteSelected: translations.deleteSelected || "Delete selected",
52
+ };
53
+
54
+ return (
55
+ <div className="flex items-center gap-2">
56
+ <span className="text-sm text-muted-foreground">
57
+ {selectedCount} {t.selected}
58
+ </span>
59
+ <DropdownMenu>
60
+ <DropdownMenuTrigger asChild>
61
+ <Button variant="outline" size="sm">
62
+ <MoreHorizontal className="mr-2 h-4 w-4" />
63
+ {t.actions}
64
+ </Button>
65
+ </DropdownMenuTrigger>
66
+ <DropdownMenuContent>
67
+ {permissions.export && onExport && (
68
+ <DropdownMenuItem onClick={() => onExport(selectedIds)}>
69
+ {t.exportSelected}
70
+ </DropdownMenuItem>
71
+ )}
72
+ {permissions.delete && onDelete && (
73
+ <>
74
+ {permissions.export && <DropdownMenuSeparator />}
75
+ <DropdownMenuItem
76
+ onClick={() => {
77
+ onDelete(selectedIds);
78
+ clearSelection();
79
+ }}
80
+ className="text-destructive"
81
+ >
82
+ <Trash2 className="mr-2 h-4 w-4" />
83
+ {t.deleteSelected}
84
+ </DropdownMenuItem>
85
+ </>
86
+ )}
87
+ </DropdownMenuContent>
88
+ </DropdownMenu>
89
+ </div>
90
+ );
91
+ }
@@ -0,0 +1,241 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import {
5
+ getCoreRowModel,
6
+ getPaginationRowModel,
7
+ useReactTable,
8
+ } from "@tanstack/react-table";
9
+
10
+ import type { CrudPermissions, CrudResponse, EntityConfig } from "../../types";
11
+
12
+ import { isFieldVisibleInTable, sortFieldsByOrder } from "../lib/crud-utils";
13
+ import { formatFieldValue } from "../lib/field-formatter";
14
+
15
+ import { Badge } from "../../ui";
16
+ import { Card, CardContent, CardHeader } from "../../ui";
17
+ import { Checkbox } from "../../ui/primitives/client";
18
+ import { DataTablePagination } from "../../ui";
19
+ import { CrudEmptyState } from "./crud-empty-state";
20
+ import { useCrudConfig, useCrudSelection, useCrudState } from "./crud-context";
21
+ import { CrudRowActions } from "./crud-row-actions";
22
+ import { CrudTableSkeleton } from "./crud-table-skeleton";
23
+
24
+ interface CrudCardViewProps<TData = Record<string, unknown>> {
25
+ // ... existing props ...
26
+ config: EntityConfig; // Config is passed as prop here, but we should use context if possible or keep it consistent
27
+ data: CrudResponse<TData>;
28
+ permissions: CrudPermissions; // Permissions passed as prop
29
+ loading?: boolean;
30
+ onEdit?: (rowId: string, rowData?: Record<string, unknown>) => void;
31
+ onDelete?: (rowId: string) => void;
32
+ onCustomAction?: (
33
+ action: string,
34
+ rowId: string,
35
+ rowData: Record<string, unknown>,
36
+ ) => void | Promise<void>;
37
+ onEmptyStateAction?: {
38
+ onCreate?: () => void;
39
+ onClearSearch?: () => void;
40
+ onClearFilters?: () => void;
41
+ };
42
+ }
43
+
44
+ export function CrudCardView<TData extends Record<string, unknown>>({
45
+ config: propConfig, // Rename to avoid conflict if we use context, but here we might just use props as it was designed
46
+ data,
47
+ permissions: propPermissions,
48
+ loading = false,
49
+ onEdit,
50
+ onDelete,
51
+ onCustomAction,
52
+ onEmptyStateAction,
53
+ }: CrudCardViewProps<TData>) {
54
+ // ✅ All hooks must be called before any early returns
55
+ // Note: CrudCardView receives config and permissions as props, so we might not need useCrudConfig
56
+ // But to be consistent with Context Splitting, we should use what we need.
57
+ // However, the original code used props for config/permissions.
58
+ // Let's stick to using the hooks for state and selection.
59
+
60
+ const { selectedRows, toggleRowSelection } = useCrudSelection();
61
+ const { search, filters, clearFilters, setSearch, pagination } =
62
+ useCrudState();
63
+
64
+ // Use props for config/permissions as they are passed down
65
+ const config = propConfig;
66
+ const permissions = propPermissions;
67
+
68
+ // Create a minimal table instance for pagination
69
+ // Always call this hook, even when loading or empty data
70
+ const table = useReactTable({
71
+ data: data.data || [],
72
+ columns: [],
73
+ getCoreRowModel: getCoreRowModel(),
74
+ getPaginationRowModel: getPaginationRowModel(),
75
+ pageCount: Math.ceil((data.total || 0) / (data.pageSize || 10)),
76
+ state: {
77
+ pagination: {
78
+ pageIndex: (data.page || 1) - 1,
79
+ pageSize: data.pageSize || 10,
80
+ },
81
+ },
82
+ manualPagination: true,
83
+ });
84
+
85
+ // Get visible fields (not hidden in table) - sort by order first
86
+ const visibleFields = sortFieldsByOrder(config.fields).filter(
87
+ (field) => !field.hideInTable && field.name !== config.idField,
88
+ );
89
+
90
+ // Get primary field (displayField) and secondary fields
91
+ const primaryField = config.fields.find(
92
+ (f) => f.name === config.displayField,
93
+ );
94
+ const secondaryFields = visibleFields
95
+ .filter((f) => f.name !== config.displayField)
96
+ .slice(0, 3); // Show max 3 secondary fields
97
+
98
+ if (loading) {
99
+ return (
100
+ <div className="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
101
+ {Array.from({ length: 6 }).map((_, index) => (
102
+ <Card key={`skeleton-card-${index}`} className="animate-pulse">
103
+ <CardHeader className="pb-3">
104
+ <div className="flex items-start gap-2">
105
+ {config.features?.showRowSelection !== false && (
106
+ <div className="h-4 w-4 bg-muted rounded shrink-0 mt-0.5" />
107
+ )}
108
+ <div className="flex-1 space-y-2">
109
+ <div className="h-4 w-3/4 bg-muted rounded" />
110
+ <div className="h-3 w-1/2 bg-muted rounded" />
111
+ </div>
112
+ </div>
113
+ </CardHeader>
114
+ <CardContent className="pt-0">
115
+ <div className="space-y-2">
116
+ <div className="h-4 w-full bg-muted rounded" />
117
+ <div className="h-4 w-2/3 bg-muted rounded" />
118
+ </div>
119
+ </CardContent>
120
+ </Card>
121
+ ))}
122
+ </div>
123
+ );
124
+ }
125
+
126
+ if (!data.data || data.data.length === 0) {
127
+ return (
128
+ <div className="min-h-[400px]">
129
+ <CrudEmptyState
130
+ config={config}
131
+ hasSearch={!!search && search.trim().length > 0}
132
+ hasFilters={filters.length > 0}
133
+ onClearSearch={() => setSearch("")}
134
+ onClearFilters={clearFilters}
135
+ onCreate={onEmptyStateAction?.onCreate}
136
+ canCreate={permissions.create}
137
+ />
138
+ </div>
139
+ );
140
+ }
141
+
142
+ return (
143
+ <div className="space-y-4">
144
+ <div className="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
145
+ {data.data.map((row) => {
146
+ const rowId = String(row[config.idField]);
147
+ const isSelected = selectedRows.has(rowId);
148
+ const primaryValue = row[config.displayField];
149
+ const primaryLabel = primaryField?.label || config.displayField;
150
+
151
+ return (
152
+ <Card
153
+ key={rowId}
154
+ className={`transition-all duration-150 hover:shadow-md ${
155
+ isSelected ? "ring-2 ring-primary" : ""
156
+ }`}
157
+ >
158
+ <CardHeader className="pb-3">
159
+ <div className="flex items-start justify-between gap-2">
160
+ <div className="flex items-start gap-2 flex-1 min-w-0">
161
+ {config.features?.showRowSelection !== false && (
162
+ <Checkbox
163
+ checked={isSelected}
164
+ onCheckedChange={() => toggleRowSelection(rowId)}
165
+ className="mt-0.5 shrink-0"
166
+ aria-label={`Select ${primaryValue}`}
167
+ />
168
+ )}
169
+ <div className="flex-1 min-w-0">
170
+ <h3 className="font-semibold text-sm truncate">
171
+ {primaryField?.renderCell
172
+ ? (primaryField.renderCell(primaryValue, row) as any)
173
+ : primaryField
174
+ ? formatFieldValue(primaryValue, primaryField)
175
+ : String(primaryValue ?? "")}
176
+ </h3>
177
+ {primaryField?.description && (
178
+ <p className="text-xs text-muted-foreground mt-0.5">
179
+ {primaryField.description}
180
+ </p>
181
+ )}
182
+ </div>
183
+ </div>
184
+ {(permissions.update ||
185
+ permissions.delete ||
186
+ (config.rowActions && config.rowActions.length > 0)) && (
187
+ <CrudRowActions
188
+ rowId={rowId}
189
+ rowData={row as Record<string, unknown>}
190
+ config={config}
191
+ permissions={permissions}
192
+ onEdit={onEdit}
193
+ onDelete={onDelete}
194
+ onCustomAction={onCustomAction}
195
+ />
196
+ )}
197
+ </div>
198
+ </CardHeader>
199
+ <CardContent className="pt-0">
200
+ <div className="space-y-2">
201
+ {secondaryFields.map((field) => {
202
+ const value = row[field.name];
203
+ if (value === null || value === undefined || value === "") {
204
+ return null;
205
+ }
206
+
207
+ return (
208
+ <div
209
+ key={field.name}
210
+ className="flex items-start gap-2 text-sm"
211
+ >
212
+ <span className="text-muted-foreground font-medium shrink-0 min-w-[80px]">
213
+ {field.label}:
214
+ </span>
215
+ <span className="text-foreground flex-1 break-words">
216
+ {field.renderCell
217
+ ? (field.renderCell(value, row) as any)
218
+ : formatFieldValue(value, field)}
219
+ </span>
220
+ </div>
221
+ );
222
+ })}
223
+ </div>
224
+ </CardContent>
225
+ </Card>
226
+ );
227
+ })}
228
+ </div>
229
+
230
+ {/* Pagination Section */}
231
+ <div className="border-t bg-muted/30 px-4 sm:px-6 py-3">
232
+ <DataTablePagination
233
+ table={table}
234
+ totalItems={data.total}
235
+ currentPage={pagination.page}
236
+ pageSize={pagination.pageSize}
237
+ />
238
+ </div>
239
+ </div>
240
+ );
241
+ }