@pattern-stack/frontend-patterns 0.0.5 → 0.0.6

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 (282) hide show
  1. package/dist/atoms/composed/Accordion/Accordion.d.ts +20 -0
  2. package/dist/atoms/composed/Accordion/Accordion.d.ts.map +1 -0
  3. package/dist/atoms/composed/Accordion/index.d.ts +2 -0
  4. package/dist/atoms/composed/Accordion/index.d.ts.map +1 -0
  5. package/dist/atoms/composed/Alert/Alert.d.ts +25 -0
  6. package/dist/atoms/composed/Alert/Alert.d.ts.map +1 -0
  7. package/dist/atoms/composed/Alert/index.d.ts +2 -0
  8. package/dist/atoms/composed/Alert/index.d.ts.map +1 -0
  9. package/dist/atoms/composed/Breadcrumb/Breadcrumb.d.ts +17 -0
  10. package/dist/atoms/composed/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  11. package/dist/atoms/composed/Breadcrumb/index.d.ts +2 -0
  12. package/dist/atoms/composed/Breadcrumb/index.d.ts.map +1 -0
  13. package/dist/atoms/composed/Chart/Chart.d.ts +37 -0
  14. package/dist/atoms/composed/Chart/Chart.d.ts.map +1 -0
  15. package/dist/atoms/composed/Chart/index.d.ts +3 -0
  16. package/dist/atoms/composed/Chart/index.d.ts.map +1 -0
  17. package/dist/atoms/composed/ColorSwatch/ColorSwatch.d.ts +19 -0
  18. package/dist/atoms/composed/ColorSwatch/ColorSwatch.d.ts.map +1 -0
  19. package/dist/atoms/composed/ColorSwatch/index.d.ts +2 -0
  20. package/dist/atoms/composed/ColorSwatch/index.d.ts.map +1 -0
  21. package/dist/atoms/composed/DarkModeToggle.d.ts +4 -0
  22. package/dist/atoms/composed/DarkModeToggle.d.ts.map +1 -0
  23. package/dist/atoms/composed/DataBadge/DataBadge.d.ts +13 -0
  24. package/dist/atoms/composed/DataBadge/DataBadge.d.ts.map +1 -0
  25. package/dist/atoms/composed/DataBadge/index.d.ts +2 -0
  26. package/dist/atoms/composed/DataBadge/index.d.ts.map +1 -0
  27. package/dist/atoms/composed/DataTable/DataTable.d.ts +28 -0
  28. package/dist/atoms/composed/DataTable/DataTable.d.ts.map +1 -0
  29. package/dist/atoms/composed/DataTable/TableCellWithTooltip.d.ts +10 -0
  30. package/dist/atoms/composed/DataTable/TableCellWithTooltip.d.ts.map +1 -0
  31. package/dist/atoms/composed/DataTable/index.d.ts +3 -0
  32. package/dist/atoms/composed/DataTable/index.d.ts.map +1 -0
  33. package/dist/atoms/composed/DateTimePicker/DateTimePicker.d.ts +45 -0
  34. package/dist/atoms/composed/DateTimePicker/DateTimePicker.d.ts.map +1 -0
  35. package/dist/atoms/composed/DateTimePicker/index.d.ts +3 -0
  36. package/dist/atoms/composed/DateTimePicker/index.d.ts.map +1 -0
  37. package/dist/atoms/composed/DetailedCard/DetailedCard.d.ts +30 -0
  38. package/dist/atoms/composed/DetailedCard/DetailedCard.d.ts.map +1 -0
  39. package/dist/atoms/composed/DetailedCard/index.d.ts +3 -0
  40. package/dist/atoms/composed/DetailedCard/index.d.ts.map +1 -0
  41. package/dist/atoms/composed/EmptyState/EmptyState.d.ts +18 -0
  42. package/dist/atoms/composed/EmptyState/EmptyState.d.ts.map +1 -0
  43. package/dist/atoms/composed/EmptyState/index.d.ts +2 -0
  44. package/dist/atoms/composed/EmptyState/index.d.ts.map +1 -0
  45. package/dist/atoms/composed/FileUpload/FileUpload.d.ts +46 -0
  46. package/dist/atoms/composed/FileUpload/FileUpload.d.ts.map +1 -0
  47. package/dist/atoms/composed/FileUpload/index.d.ts +3 -0
  48. package/dist/atoms/composed/FileUpload/index.d.ts.map +1 -0
  49. package/dist/atoms/composed/FormField/FormField.d.ts +23 -0
  50. package/dist/atoms/composed/FormField/FormField.d.ts.map +1 -0
  51. package/dist/atoms/composed/FormField/index.d.ts +2 -0
  52. package/dist/atoms/composed/FormField/index.d.ts.map +1 -0
  53. package/dist/atoms/composed/GlobalSearch/GlobalSearch.d.ts +8 -0
  54. package/dist/atoms/composed/GlobalSearch/GlobalSearch.d.ts.map +1 -0
  55. package/dist/atoms/composed/GlobalSearch/index.d.ts +2 -0
  56. package/dist/atoms/composed/GlobalSearch/index.d.ts.map +1 -0
  57. package/dist/atoms/composed/IconBadge/IconBadge.d.ts +16 -0
  58. package/dist/atoms/composed/IconBadge/IconBadge.d.ts.map +1 -0
  59. package/dist/atoms/composed/IconBadge/index.d.ts +3 -0
  60. package/dist/atoms/composed/IconBadge/index.d.ts.map +1 -0
  61. package/dist/atoms/composed/Modal/Modal.d.ts +18 -0
  62. package/dist/atoms/composed/Modal/Modal.d.ts.map +1 -0
  63. package/dist/atoms/composed/Modal/index.d.ts +3 -0
  64. package/dist/atoms/composed/Modal/index.d.ts.map +1 -0
  65. package/dist/atoms/composed/PaletteSwitcher.d.ts +7 -0
  66. package/dist/atoms/composed/PaletteSwitcher.d.ts.map +1 -0
  67. package/dist/atoms/composed/ProgressBar/ProgressBar.d.ts +25 -0
  68. package/dist/atoms/composed/ProgressBar/ProgressBar.d.ts.map +1 -0
  69. package/dist/atoms/composed/ProgressBar/index.d.ts +2 -0
  70. package/dist/atoms/composed/ProgressBar/index.d.ts.map +1 -0
  71. package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts +19 -0
  72. package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts.map +1 -0
  73. package/dist/atoms/composed/SalesPanel/index.d.ts +2 -0
  74. package/dist/atoms/composed/SalesPanel/index.d.ts.map +1 -0
  75. package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts +63 -0
  76. package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts.map +1 -0
  77. package/dist/atoms/composed/StatCard/StatCard.d.ts +21 -0
  78. package/dist/atoms/composed/StatCard/StatCard.d.ts.map +1 -0
  79. package/dist/atoms/composed/StatCard/index.d.ts +2 -0
  80. package/dist/atoms/composed/StatCard/index.d.ts.map +1 -0
  81. package/dist/atoms/composed/StyleGuide.d.ts +3 -0
  82. package/dist/atoms/composed/StyleGuide.d.ts.map +1 -0
  83. package/dist/atoms/composed/Toast/Toast.d.ts +40 -0
  84. package/dist/atoms/composed/Toast/Toast.d.ts.map +1 -0
  85. package/dist/atoms/composed/Toast/index.d.ts +2 -0
  86. package/dist/atoms/composed/Toast/index.d.ts.map +1 -0
  87. package/dist/atoms/composed/Tooltip/Tooltip.d.ts +16 -0
  88. package/dist/atoms/composed/Tooltip/Tooltip.d.ts.map +1 -0
  89. package/dist/atoms/composed/Tooltip/index.d.ts +2 -0
  90. package/dist/atoms/composed/Tooltip/index.d.ts.map +1 -0
  91. package/dist/atoms/composed/UserAvatar/UserAvatar.d.ts +8 -0
  92. package/dist/atoms/composed/UserAvatar/UserAvatar.d.ts.map +1 -0
  93. package/dist/atoms/composed/UserAvatar/index.d.ts +2 -0
  94. package/dist/atoms/composed/UserAvatar/index.d.ts.map +1 -0
  95. package/dist/atoms/composed/UserMenu/UserMenu.d.ts +8 -0
  96. package/dist/atoms/composed/UserMenu/UserMenu.d.ts.map +1 -0
  97. package/dist/atoms/composed/UserMenu/index.d.ts +2 -0
  98. package/dist/atoms/composed/UserMenu/index.d.ts.map +1 -0
  99. package/dist/atoms/composed/index.d.ts +26 -0
  100. package/dist/atoms/composed/index.d.ts.map +1 -0
  101. package/dist/atoms/hooks/useApi.d.ts +25 -0
  102. package/dist/atoms/hooks/useApi.d.ts.map +1 -0
  103. package/dist/atoms/hooks/useHealth.d.ts +19 -0
  104. package/dist/atoms/hooks/useHealth.d.ts.map +1 -0
  105. package/dist/atoms/index.d.ts +9 -0
  106. package/dist/atoms/index.d.ts.map +1 -0
  107. package/dist/atoms/services/api/client.d.ts +20 -0
  108. package/dist/atoms/services/api/client.d.ts.map +1 -0
  109. package/dist/atoms/services/auth-service.d.ts +24 -0
  110. package/dist/atoms/services/auth-service.d.ts.map +1 -0
  111. package/dist/atoms/services/health.d.ts +7 -0
  112. package/dist/atoms/services/health.d.ts.map +1 -0
  113. package/dist/atoms/services/index.d.ts +4 -0
  114. package/dist/atoms/services/index.d.ts.map +1 -0
  115. package/dist/atoms/shared/config/constants.d.ts +15 -0
  116. package/dist/atoms/shared/config/constants.d.ts.map +1 -0
  117. package/dist/atoms/shared/config/dashboard-sizes.d.ts +83 -0
  118. package/dist/atoms/shared/config/dashboard-sizes.d.ts.map +1 -0
  119. package/dist/atoms/shared/config/environment.d.ts +10 -0
  120. package/dist/atoms/shared/config/environment.d.ts.map +1 -0
  121. package/dist/atoms/shared/index.d.ts +4 -0
  122. package/dist/atoms/shared/index.d.ts.map +1 -0
  123. package/dist/atoms/types/auth.d.ts +56 -0
  124. package/dist/atoms/types/auth.d.ts.map +1 -0
  125. package/dist/atoms/types/entity-config.d.ts +117 -0
  126. package/dist/atoms/types/entity-config.d.ts.map +1 -0
  127. package/dist/atoms/types/generated.d.ts +1469 -0
  128. package/dist/atoms/types/generated.d.ts.map +1 -0
  129. package/dist/atoms/types/index.d.ts +6 -0
  130. package/dist/atoms/types/index.d.ts.map +1 -0
  131. package/dist/atoms/types/loading.d.ts +26 -0
  132. package/dist/atoms/types/loading.d.ts.map +1 -0
  133. package/dist/atoms/types/navigation.d.ts +30 -0
  134. package/dist/atoms/types/navigation.d.ts.map +1 -0
  135. package/dist/atoms/ui/Badge.d.ts +10 -0
  136. package/dist/atoms/ui/Badge.d.ts.map +1 -0
  137. package/dist/atoms/ui/ErrorBoundary.d.ts +18 -0
  138. package/dist/atoms/ui/ErrorBoundary.d.ts.map +1 -0
  139. package/dist/atoms/ui/Select.d.ts +28 -0
  140. package/dist/atoms/ui/Select.d.ts.map +1 -0
  141. package/dist/atoms/ui/Switch.d.ts +9 -0
  142. package/dist/atoms/ui/Switch.d.ts.map +1 -0
  143. package/dist/atoms/ui/Tabs.d.ts +30 -0
  144. package/dist/atoms/ui/Tabs.d.ts.map +1 -0
  145. package/dist/atoms/ui/avatar.d.ts +7 -0
  146. package/dist/atoms/ui/avatar.d.ts.map +1 -0
  147. package/dist/atoms/ui/button.d.ts +14 -0
  148. package/dist/atoms/ui/button.d.ts.map +1 -0
  149. package/dist/atoms/ui/card.d.ts +12 -0
  150. package/dist/atoms/ui/card.d.ts.map +1 -0
  151. package/dist/atoms/ui/dropdown-menu.d.ts +28 -0
  152. package/dist/atoms/ui/dropdown-menu.d.ts.map +1 -0
  153. package/dist/atoms/ui/index.d.ts +15 -0
  154. package/dist/atoms/ui/index.d.ts.map +1 -0
  155. package/dist/atoms/ui/input.d.ts +5 -0
  156. package/dist/atoms/ui/input.d.ts.map +1 -0
  157. package/dist/atoms/ui/label.d.ts +6 -0
  158. package/dist/atoms/ui/label.d.ts.map +1 -0
  159. package/dist/atoms/ui/skeleton.d.ts +3 -0
  160. package/dist/atoms/ui/skeleton.d.ts.map +1 -0
  161. package/dist/atoms/ui/spinner.d.ts +14 -0
  162. package/dist/atoms/ui/spinner.d.ts.map +1 -0
  163. package/dist/atoms/ui/table.d.ts +11 -0
  164. package/dist/atoms/ui/table.d.ts.map +1 -0
  165. package/dist/atoms/utils/animations.d.ts +65 -0
  166. package/dist/atoms/utils/animations.d.ts.map +1 -0
  167. package/dist/atoms/utils/icon-resolver.d.ts +72 -0
  168. package/dist/atoms/utils/icon-resolver.d.ts.map +1 -0
  169. package/dist/atoms/utils/metric-engine.d.ts +30 -0
  170. package/dist/atoms/utils/metric-engine.d.ts.map +1 -0
  171. package/dist/atoms/utils/tooltip-helpers.d.ts +71 -0
  172. package/dist/atoms/utils/tooltip-helpers.d.ts.map +1 -0
  173. package/dist/atoms/utils/utils.d.ts +6 -0
  174. package/dist/atoms/utils/utils.d.ts.map +1 -0
  175. package/dist/features/auth/components/LoginForm.d.ts +2 -0
  176. package/dist/features/auth/components/LoginForm.d.ts.map +1 -0
  177. package/dist/features/auth/components/LogoutButton.d.ts +2 -0
  178. package/dist/features/auth/components/LogoutButton.d.ts.map +1 -0
  179. package/dist/features/auth/components/ProtectedRoute.d.ts +10 -0
  180. package/dist/features/auth/components/ProtectedRoute.d.ts.map +1 -0
  181. package/dist/features/auth/components/index.d.ts +4 -0
  182. package/dist/features/auth/components/index.d.ts.map +1 -0
  183. package/dist/features/auth/hooks/index.d.ts +3 -0
  184. package/dist/features/auth/hooks/index.d.ts.map +1 -0
  185. package/dist/features/auth/hooks/useAuth.d.ts +10 -0
  186. package/dist/features/auth/hooks/useAuth.d.ts.map +1 -0
  187. package/dist/features/auth/hooks/usePermissions.d.ts +13 -0
  188. package/dist/features/auth/hooks/usePermissions.d.ts.map +1 -0
  189. package/dist/features/auth/index.d.ts +3 -0
  190. package/dist/features/auth/index.d.ts.map +1 -0
  191. package/dist/features/index.d.ts +2 -0
  192. package/dist/features/index.d.ts.map +1 -0
  193. package/dist/frontend-patterns.css +1 -1
  194. package/dist/index.d.ts +10 -0
  195. package/dist/index.d.ts.map +1 -0
  196. package/dist/index.es.js +131 -1658
  197. package/dist/index.es.js.map +1 -1
  198. package/dist/index.js +131 -1658
  199. package/dist/index.js.map +1 -1
  200. package/dist/molecules/forms/FormGroup.d.ts +17 -0
  201. package/dist/molecules/forms/FormGroup.d.ts.map +1 -0
  202. package/dist/molecules/forms/SearchInput.d.ts +36 -0
  203. package/dist/molecules/forms/SearchInput.d.ts.map +1 -0
  204. package/dist/molecules/forms/index.d.ts +3 -0
  205. package/dist/molecules/forms/index.d.ts.map +1 -0
  206. package/dist/molecules/index.d.ts +4 -0
  207. package/dist/molecules/index.d.ts.map +1 -0
  208. package/dist/molecules/layout/AppHeader/AppHeader.d.ts +7 -0
  209. package/dist/molecules/layout/AppHeader/AppHeader.d.ts.map +1 -0
  210. package/dist/molecules/layout/AppHeader/index.d.ts +2 -0
  211. package/dist/molecules/layout/AppHeader/index.d.ts.map +1 -0
  212. package/dist/molecules/layout/AppLayout.d.ts +2 -0
  213. package/dist/molecules/layout/AppLayout.d.ts.map +1 -0
  214. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts +16 -0
  215. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts.map +1 -0
  216. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts +2 -0
  217. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts.map +1 -0
  218. package/dist/molecules/layout/NavigationContext.d.ts +15 -0
  219. package/dist/molecules/layout/NavigationContext.d.ts.map +1 -0
  220. package/dist/molecules/layout/PageTemplate.d.ts +19 -0
  221. package/dist/molecules/layout/PageTemplate.d.ts.map +1 -0
  222. package/dist/molecules/layout/SectionHeader/SectionHeader.d.ts +24 -0
  223. package/dist/molecules/layout/SectionHeader/SectionHeader.d.ts.map +1 -0
  224. package/dist/molecules/layout/SectionHeader/index.d.ts +2 -0
  225. package/dist/molecules/layout/SectionHeader/index.d.ts.map +1 -0
  226. package/dist/molecules/layout/ShowcaseSection.d.ts +22 -0
  227. package/dist/molecules/layout/ShowcaseSection.d.ts.map +1 -0
  228. package/dist/molecules/layout/Sidebar.d.ts +6 -0
  229. package/dist/molecules/layout/Sidebar.d.ts.map +1 -0
  230. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts +15 -0
  231. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts.map +1 -0
  232. package/dist/molecules/layout/SidebarButton/index.d.ts +2 -0
  233. package/dist/molecules/layout/SidebarButton/index.d.ts.map +1 -0
  234. package/dist/molecules/layout/SidebarContext.d.ts +12 -0
  235. package/dist/molecules/layout/SidebarContext.d.ts.map +1 -0
  236. package/dist/molecules/layout/index.d.ts +11 -0
  237. package/dist/molecules/layout/index.d.ts.map +1 -0
  238. package/dist/molecules/navigation/NavMenu.d.ts +20 -0
  239. package/dist/molecules/navigation/NavMenu.d.ts.map +1 -0
  240. package/dist/molecules/navigation/Pagination.d.ts +14 -0
  241. package/dist/molecules/navigation/Pagination.d.ts.map +1 -0
  242. package/dist/molecules/navigation/index.d.ts +3 -0
  243. package/dist/molecules/navigation/index.d.ts.map +1 -0
  244. package/dist/organisms/index.d.ts +2 -0
  245. package/dist/organisms/index.d.ts.map +1 -0
  246. package/dist/organisms/showcase/ComponentShowcasePage.d.ts +3 -0
  247. package/dist/organisms/showcase/ComponentShowcasePage.d.ts.map +1 -0
  248. package/dist/templates/AuthTemplate.d.ts +68 -0
  249. package/dist/templates/AuthTemplate.d.ts.map +1 -0
  250. package/dist/templates/ComponentShowcaseTemplate.d.ts +53 -0
  251. package/dist/templates/ComponentShowcaseTemplate.d.ts.map +1 -0
  252. package/dist/templates/DashboardTemplate.d.ts +62 -0
  253. package/dist/templates/DashboardTemplate.d.ts.map +1 -0
  254. package/dist/templates/DataTemplate.d.ts +78 -0
  255. package/dist/templates/DataTemplate.d.ts.map +1 -0
  256. package/dist/templates/admin/AdminCRUDTemplate.d.ts +105 -0
  257. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -0
  258. package/dist/templates/admin/AdminDashboardTemplate.d.ts +89 -0
  259. package/dist/templates/admin/AdminDashboardTemplate.d.ts.map +1 -0
  260. package/dist/templates/admin/AdminDetailTemplate.d.ts +132 -0
  261. package/dist/templates/admin/AdminDetailTemplate.d.ts.map +1 -0
  262. package/dist/templates/admin/index.d.ts +4 -0
  263. package/dist/templates/admin/index.d.ts.map +1 -0
  264. package/dist/templates/factory.d.ts +29 -0
  265. package/dist/templates/factory.d.ts.map +1 -0
  266. package/dist/templates/index.d.ts +7 -0
  267. package/dist/templates/index.d.ts.map +1 -0
  268. package/package.json +3 -2
  269. package/src/__tests__/atoms/composed/databadge.test.tsx +106 -0
  270. package/src/__tests__/atoms/composed/statcard.test.tsx +133 -0
  271. package/src/__tests__/atoms/utils/icon-resolver.test.tsx +140 -0
  272. package/src/atoms/types/index.ts +1 -0
  273. package/src/atoms/types/navigation.ts +43 -0
  274. package/src/atoms/utils/icon-resolver.tsx +54 -0
  275. package/src/atoms/utils/utils.ts +3 -2
  276. package/src/molecules/layout/NavigationContext.tsx +63 -0
  277. package/src/molecules/layout/Sidebar.tsx +10 -31
  278. package/src/molecules/layout/SidebarButton/SidebarButton.tsx +32 -10
  279. package/src/molecules/layout/index.ts +3 -1
  280. package/src/organisms/index.ts +2 -1
  281. package/src/templates/factory.tsx +14 -7
  282. package/src/templates/index.ts +2 -1
package/dist/index.js CHANGED
@@ -7,19 +7,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  const clsx = require("clsx");
8
8
  const tailwindMerge = require("tailwind-merge");
9
9
  const React = require("react");
10
+ const jsxRuntime = require("react/jsx-runtime");
11
+ const lucideReact = require("lucide-react");
10
12
  const classVarianceAuthority = require("class-variance-authority");
11
13
  const axios = require("axios");
12
14
  const reactQuery = require("@tanstack/react-query");
13
- const jsxRuntime = require("react/jsx-runtime");
14
15
  const reactSlot = require("@radix-ui/react-slot");
15
16
  const LabelPrimitive = require("@radix-ui/react-label");
16
17
  const AvatarPrimitive = require("@radix-ui/react-avatar");
17
18
  const DropdownMenuPrimitive = require("@radix-ui/react-dropdown-menu");
18
- const lucideReact = require("lucide-react");
19
19
  const reactDom = require("react-dom");
20
20
  const reactRouterDom = require("react-router-dom");
21
21
  const client = require("react-dom/client");
22
- require("@tanstack/react-query-devtools");
23
22
  function _interopNamespaceDefault(e) {
24
23
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
25
24
  if (e) {
@@ -434,6 +433,71 @@ class MetricCalculationEngine {
434
433
  return insights.slice(0, 5);
435
434
  }
436
435
  }
436
+ const iconMap = {
437
+ Palette: lucideReact.Palette,
438
+ Menu: lucideReact.Menu,
439
+ X: lucideReact.X,
440
+ Shield: lucideReact.Shield,
441
+ Users: lucideReact.Users,
442
+ BarChart3: lucideReact.BarChart3,
443
+ Database: lucideReact.Database,
444
+ TrendingUp: lucideReact.TrendingUp,
445
+ Layout: lucideReact.Layout,
446
+ Home: lucideReact.Home,
447
+ Settings: lucideReact.Settings,
448
+ Bell: lucideReact.Bell,
449
+ Search: lucideReact.Search,
450
+ Plus: lucideReact.Plus,
451
+ Edit: lucideReact.Edit,
452
+ Trash2: lucideReact.Trash2,
453
+ Eye: lucideReact.Eye,
454
+ Download: lucideReact.Download,
455
+ Upload: lucideReact.Upload,
456
+ Share: lucideReact.Share,
457
+ Lock: lucideReact.Lock,
458
+ Unlock: lucideReact.Unlock,
459
+ Mail: lucideReact.Mail,
460
+ Phone: lucideReact.Phone,
461
+ Calendar: lucideReact.Calendar,
462
+ Clock: lucideReact.Clock,
463
+ MapPin: lucideReact.MapPin,
464
+ Star: lucideReact.Star,
465
+ Heart: lucideReact.Heart,
466
+ Bookmark: lucideReact.Bookmark,
467
+ Tag: lucideReact.Tag,
468
+ Flag: lucideReact.Flag,
469
+ File: lucideReact.File,
470
+ Folder: lucideReact.Folder,
471
+ Image: lucideReact.Image,
472
+ Video: lucideReact.Video,
473
+ Music: lucideReact.Music,
474
+ ChevronRight: lucideReact.ChevronRight,
475
+ ChevronDown: lucideReact.ChevronDown,
476
+ ChevronLeft: lucideReact.ChevronLeft,
477
+ ChevronUp: lucideReact.ChevronUp,
478
+ ArrowRight: lucideReact.ArrowRight,
479
+ ArrowLeft: lucideReact.ArrowLeft,
480
+ ArrowUp: lucideReact.ArrowUp,
481
+ ArrowDown: lucideReact.ArrowDown,
482
+ Check: lucideReact.Check,
483
+ AlertCircle: lucideReact.AlertCircle,
484
+ Info: lucideReact.Info,
485
+ HelpCircle: lucideReact.HelpCircle
486
+ };
487
+ const Icon = ({ name, className = "w-5 h-5", size, ...props }) => {
488
+ const IconComponent = iconMap[name];
489
+ if (!IconComponent) {
490
+ console.warn(`Icon "${name}" not found. Using default Menu icon.`);
491
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className, size, ...props });
492
+ }
493
+ return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className, size, ...props });
494
+ };
495
+ const getIcon = (name) => {
496
+ return iconMap[name] || lucideReact.Menu;
497
+ };
498
+ const isValidIcon = (name) => {
499
+ return name in iconMap;
500
+ };
437
501
  function cn(...inputs) {
438
502
  return tailwindMerge.twMerge(clsx.clsx(inputs));
439
503
  }
@@ -5796,6 +5860,42 @@ const useSidebar = () => {
5796
5860
  }
5797
5861
  return context;
5798
5862
  };
5863
+ const NavigationContext = React.createContext(void 0);
5864
+ const defaultShowcaseNavigation = [
5865
+ { value: "showcase", label: "Showcase", icon: "Palette", path: "/showcase", category: 5 },
5866
+ { value: "admin-dashboard", label: "Admin Dashboard", icon: "Shield", path: "/admin/dashboard", category: 2 },
5867
+ { value: "admin-users", label: "User Management", icon: "Users", path: "/admin/users", category: 3 },
5868
+ { value: "admin-sales", label: "Sales Dashboard", icon: "TrendingUp", path: "/admin/sales", category: 4 },
5869
+ { value: "entity-performance", label: "Performance Dashboard", icon: "BarChart3", path: "/entity/performance", category: 6 },
5870
+ { value: "entity-management", label: "Entity Management", icon: "Database", path: "/entity/management", category: 7 },
5871
+ { value: "entity-template", label: "Template Example", icon: "Layout", path: "/entity/template-example", category: 1 }
5872
+ ];
5873
+ const NavigationProvider = ({ children, initialNavigation }) => {
5874
+ const [navigation, setNavigation] = React.useState(
5875
+ initialNavigation || {
5876
+ items: defaultShowcaseNavigation,
5877
+ showDefaultNavigation: true,
5878
+ defaultExpanded: true
5879
+ }
5880
+ );
5881
+ return /* @__PURE__ */ jsxRuntime.jsx(NavigationContext.Provider, { value: { navigation, setNavigation }, children });
5882
+ };
5883
+ const useNavigation = () => {
5884
+ const context = React.useContext(NavigationContext);
5885
+ if (context === void 0) {
5886
+ throw new Error("useNavigation must be used within a NavigationProvider");
5887
+ }
5888
+ return context;
5889
+ };
5890
+ const getNavigationItems = (config) => {
5891
+ if (config.items.length > 0) {
5892
+ return config.items;
5893
+ }
5894
+ if (config.showDefaultNavigation !== false) {
5895
+ return defaultShowcaseNavigation;
5896
+ }
5897
+ return [];
5898
+ };
5799
5899
  const SidebarButton = ({
5800
5900
  icon,
5801
5901
  label,
@@ -5803,13 +5903,16 @@ const SidebarButton = ({
5803
5903
  category = 1,
5804
5904
  expanded = false,
5805
5905
  onClick,
5806
- className
5906
+ className,
5907
+ badge,
5908
+ disabled = false
5807
5909
  }) => {
5808
5910
  return /* @__PURE__ */ jsxRuntime.jsxs(
5809
5911
  Button,
5810
5912
  {
5811
5913
  variant: active ? "secondary" : "ghost",
5812
5914
  onClick,
5915
+ disabled,
5813
5916
  tooltip: !expanded ? label : void 0,
5814
5917
  className: cn(
5815
5918
  "relative w-full justify-start gap-3 h-12",
@@ -5843,12 +5946,19 @@ const SidebarButton = ({
5843
5946
  "text-sm font-medium flex-1 text-left",
5844
5947
  active ? `text-category-${category}` : "text-foreground"
5845
5948
  ), children: label }),
5846
- active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
5949
+ badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
5950
+ "px-2 py-0.5 text-xs font-medium rounded-full flex-shrink-0",
5951
+ "bg-primary/10 text-primary"
5952
+ ), children: badge }) : active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
5847
5953
  "w-2 h-2 rounded-full flex-shrink-0",
5848
5954
  `bg-category-${category}`
5849
5955
  ) })
5850
5956
  ] }),
5851
- !expanded && active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -right-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
5957
+ !expanded && (badge || active) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -right-1", children: badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
5958
+ "px-1.5 py-0.5 text-xs font-bold rounded-full",
5959
+ "bg-primary text-primary-foreground",
5960
+ "ring-2 ring-background"
5961
+ ), children: badge }) : active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
5852
5962
  "w-2.5 h-2.5 rounded-full",
5853
5963
  `bg-category-${category}`,
5854
5964
  "ring-2 ring-background"
@@ -5859,18 +5969,11 @@ const SidebarButton = ({
5859
5969
  };
5860
5970
  const Sidebar = ({ className }) => {
5861
5971
  const { isExpanded, toggleSidebar } = useSidebar();
5972
+ const { navigation } = useNavigation();
5862
5973
  const location = reactRouterDom.useLocation();
5863
5974
  const navigate = reactRouterDom.useNavigate();
5864
5975
  const [searchParams] = reactRouterDom.useSearchParams();
5865
- const items = [
5866
- { value: "showcase", label: "Showcase", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: "w-5 h-5" }), path: "/showcase", category: 5 },
5867
- { value: "admin-dashboard", label: "Admin Dashboard", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Shield, { className: "w-5 h-5" }), path: "/admin/dashboard", category: 2 },
5868
- { value: "admin-users", label: "User Management", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Users, { className: "w-5 h-5" }), path: "/admin/users", category: 3 },
5869
- { value: "admin-sales", label: "Sales Dashboard", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingUp, { className: "w-5 h-5" }), path: "/admin/sales", category: 4 },
5870
- { value: "entity-performance", label: "Performance Dashboard", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "w-5 h-5" }), path: "/entity/performance", category: 6 },
5871
- { value: "entity-management", label: "Entity Management", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Database, { className: "w-5 h-5" }), path: "/entity/management", category: 7 },
5872
- { value: "entity-template", label: "Template Example", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Layout, { className: "w-5 h-5" }), path: "/entity/template-example", category: 1 }
5873
- ];
5976
+ const items = getNavigationItems(navigation);
5874
5977
  const handleNavigation = (path) => {
5875
5978
  if (path.includes("?")) {
5876
5979
  const [basePath, query] = path.split("?");
@@ -5926,12 +6029,14 @@ const Sidebar = ({ className }) => {
5926
6029
  return /* @__PURE__ */ jsxRuntime.jsx(
5927
6030
  SidebarButton,
5928
6031
  {
5929
- icon: item.icon,
6032
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: "w-5 h-5" }),
5930
6033
  label: item.label,
5931
6034
  active: isActive,
5932
6035
  category: item.category,
5933
6036
  expanded: isExpanded,
5934
- onClick: () => handleNavigation(item.path)
6037
+ onClick: () => handleNavigation(item.path),
6038
+ badge: item.badge,
6039
+ disabled: item.disabled
5935
6040
  },
5936
6041
  item.value
5937
6042
  );
@@ -8031,1636 +8136,6 @@ const AdminDetailTemplate = ({
8031
8136
  ] }) }) })
8032
8137
  ] });
8033
8138
  };
8034
- const MetricsOverviewPanel = ({
8035
- metrics,
8036
- data,
8037
- previousData,
8038
- isLoading = false,
8039
- onMetricClick,
8040
- className,
8041
- layout = "grid",
8042
- columns = 4,
8043
- category,
8044
- renderCustomMetric,
8045
- renderHeader,
8046
- renderFooter,
8047
- headerSlot,
8048
- footerSlot
8049
- }) => {
8050
- const calculatedMetrics = React.useMemo(() => {
8051
- if (isLoading || !(data == null ? void 0 : data.length) || !(metrics == null ? void 0 : metrics.length)) return {};
8052
- return metrics.reduce((acc, metric) => {
8053
- acc[metric.key] = MetricCalculationEngine.calculateMetric(
8054
- metric,
8055
- data,
8056
- previousData
8057
- );
8058
- return acc;
8059
- }, {});
8060
- }, [metrics, data, previousData, isLoading]);
8061
- const getLayoutClasses = () => {
8062
- switch (layout) {
8063
- case "horizontal":
8064
- return "flex flex-wrap gap-4";
8065
- case "vertical":
8066
- return "flex flex-col gap-4";
8067
- case "grid":
8068
- default:
8069
- return cn(
8070
- "grid gap-4",
8071
- {
8072
- "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4": columns === 4,
8073
- "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3": columns === 3,
8074
- "grid-cols-1 sm:grid-cols-2": columns === 2
8075
- }
8076
- );
8077
- }
8078
- };
8079
- const renderMetricCard = (metric, index) => {
8080
- if (renderCustomMetric) {
8081
- const customContent = renderCustomMetric(metric, calculatedMetrics[metric.key], index);
8082
- if (customContent) return customContent;
8083
- }
8084
- const metricValue = calculatedMetrics[metric.key];
8085
- if (isLoading || !metricValue) {
8086
- return /* @__PURE__ */ jsxRuntime.jsx(
8087
- StatCard,
8088
- {
8089
- title: metric.label,
8090
- value: "",
8091
- isLoading: true,
8092
- category,
8093
- icon: metric.icon ? /* @__PURE__ */ jsxRuntime.jsx(metric.icon, {}) : void 0
8094
- },
8095
- metric.key
8096
- );
8097
- }
8098
- const trend = metricValue.trend !== "neutral" && metricValue.previous ? {
8099
- value: Number(((metricValue.current - metricValue.previous) / Math.abs(metricValue.previous) * 100).toFixed(1)),
8100
- label: "vs last period"
8101
- } : void 0;
8102
- const formatTargetValue = (value) => {
8103
- switch (metric.type) {
8104
- case "currency":
8105
- return new Intl.NumberFormat("en-US", {
8106
- style: "currency",
8107
- currency: "USD"
8108
- }).format(value);
8109
- case "percentage":
8110
- return `${value}%`;
8111
- default:
8112
- return value.toString();
8113
- }
8114
- };
8115
- const subtitle = metricValue.target ? `Target: ${formatTargetValue(metricValue.target)}` : void 0;
8116
- return /* @__PURE__ */ jsxRuntime.jsx(
8117
- StatCard,
8118
- {
8119
- title: metric.label,
8120
- value: metricValue.formattedValue,
8121
- subtitle,
8122
- trend,
8123
- category,
8124
- icon: metric.icon ? /* @__PURE__ */ jsxRuntime.jsx(metric.icon, {}) : void 0,
8125
- onClick: onMetricClick ? () => onMetricClick(metric, metricValue) : void 0,
8126
- valueTooltip: `Current: ${metricValue.formattedValue}${metricValue.previous ? ` | Previous: ${formatTargetValue(metricValue.previous)}` : ""}`,
8127
- iconTooltip: `View ${metric.label} details`
8128
- },
8129
- metric.key
8130
- );
8131
- };
8132
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", className), "data-component-name": "MetricsOverviewPanel", children: [
8133
- headerSlot,
8134
- renderHeader && renderHeader(),
8135
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: getLayoutClasses(), children: metrics.map((metric, index) => renderMetricCard(metric, index)) }),
8136
- renderFooter && renderFooter(),
8137
- footerSlot
8138
- ] });
8139
- };
8140
- const MetricsOverviewWithInsightsPanel = ({
8141
- showInsights = true,
8142
- insightThresholds,
8143
- renderInsight,
8144
- ...props
8145
- }) => {
8146
- const safeMetrics = props.metrics || [];
8147
- const safeData = props.data || [];
8148
- const calculatedMetrics = React.useMemo(() => {
8149
- if (props.isLoading || !safeData.length || !safeMetrics.length) return {};
8150
- return safeMetrics.reduce((acc, metric) => {
8151
- acc[metric.key] = MetricCalculationEngine.calculateMetric(
8152
- metric,
8153
- safeData,
8154
- props.previousData
8155
- );
8156
- return acc;
8157
- }, {});
8158
- }, [safeMetrics, safeData, props.previousData, props.isLoading]);
8159
- const insights = React.useMemo(() => {
8160
- if (!showInsights || props.isLoading || Object.keys(calculatedMetrics).length === 0) {
8161
- return [];
8162
- }
8163
- return MetricCalculationEngine.detectInsights(calculatedMetrics, insightThresholds);
8164
- }, [calculatedMetrics, showInsights, insightThresholds, props.isLoading]);
8165
- const renderInsightsSection = () => {
8166
- if (!showInsights || insights.length === 0) return null;
8167
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8168
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Key Insights" }),
8169
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: insights.map((insight, index) => {
8170
- if (renderInsight) {
8171
- const customInsight = renderInsight(insight, index);
8172
- if (customInsight) return customInsight;
8173
- }
8174
- const colorClass = {
8175
- positive: "text-status-success",
8176
- negative: "text-status-error",
8177
- neutral: "text-muted-foreground"
8178
- }[insight.type];
8179
- return /* @__PURE__ */ jsxRuntime.jsxs(
8180
- "div",
8181
- {
8182
- className: cn("text-sm", colorClass),
8183
- children: [
8184
- "• ",
8185
- insight.message
8186
- ]
8187
- },
8188
- index
8189
- );
8190
- }) })
8191
- ] });
8192
- };
8193
- return /* @__PURE__ */ jsxRuntime.jsx(
8194
- MetricsOverviewPanel,
8195
- {
8196
- ...props,
8197
- footerSlot: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8198
- renderInsightsSection(),
8199
- props.footerSlot
8200
- ] })
8201
- }
8202
- );
8203
- };
8204
- const EntityListPanel = ({
8205
- config,
8206
- data,
8207
- isLoading = false,
8208
- onRowClick,
8209
- onAction,
8210
- className,
8211
- columns: customColumns,
8212
- showSearch = true,
8213
- showPagination = true,
8214
- pageSize = 10,
8215
- searchPlaceholder,
8216
- enableSelection = false,
8217
- enableBulkActions = false,
8218
- enableExport = true,
8219
- enableFiltering = false,
8220
- enableRefresh = true,
8221
- renderToolbar,
8222
- renderBulkActions,
8223
- renderCustomColumn,
8224
- renderEmptyState,
8225
- headerSlot,
8226
- footerSlot,
8227
- onExport,
8228
- onRefresh
8229
- }) => {
8230
- const [selectedItems, setSelectedItems] = React.useState([]);
8231
- const [showFilters, setShowFilters] = React.useState(false);
8232
- const tableColumns = React.useMemo(() => {
8233
- if (customColumns) return customColumns;
8234
- const generatedColumns = [];
8235
- if (enableSelection) {
8236
- generatedColumns.push({
8237
- key: "__selection",
8238
- header: /* @__PURE__ */ jsxRuntime.jsx(
8239
- "input",
8240
- {
8241
- type: "checkbox",
8242
- checked: selectedItems.length === data.length && data.length > 0,
8243
- onChange: (e) => {
8244
- if (e.target.checked) {
8245
- setSelectedItems([...data]);
8246
- } else {
8247
- setSelectedItems([]);
8248
- }
8249
- }
8250
- }
8251
- ),
8252
- cell: (item) => /* @__PURE__ */ jsxRuntime.jsx(
8253
- "input",
8254
- {
8255
- type: "checkbox",
8256
- checked: selectedItems.some((selected) => selected.id === item.id),
8257
- onChange: (e) => {
8258
- if (e.target.checked) {
8259
- setSelectedItems((prev) => [...prev, item]);
8260
- } else {
8261
- setSelectedItems((prev) => prev.filter((selected) => selected.id !== item.id));
8262
- }
8263
- }
8264
- }
8265
- ),
8266
- sortable: false,
8267
- width: "50px"
8268
- });
8269
- }
8270
- if (data.length > 0) {
8271
- const sampleItem = data[0];
8272
- Object.keys(sampleItem).forEach((key) => {
8273
- if (key === "id") return;
8274
- const isStatus = key.toLowerCase().includes("status");
8275
- const isCategory = key.toLowerCase().includes("category") || key.toLowerCase().includes("type");
8276
- const isDate = key.toLowerCase().includes("date") || key.toLowerCase().includes("time");
8277
- const isAmount = key.toLowerCase().includes("amount") || key.toLowerCase().includes("price") || key.toLowerCase().includes("cost");
8278
- generatedColumns.push({
8279
- key,
8280
- header: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, " $1"),
8281
- type: isStatus ? "status" : isCategory ? "category" : "default",
8282
- sortable: true,
8283
- cell: renderCustomColumn ? (item) => {
8284
- const column = { key, header: "", type: isStatus ? "status" : isCategory ? "category" : "default" };
8285
- const customContent = renderCustomColumn(column, item);
8286
- if (customContent) return customContent;
8287
- const value = item[key];
8288
- if (isDate && value) {
8289
- return new Date(value).toLocaleDateString();
8290
- }
8291
- if (isAmount && typeof value === "number") {
8292
- return new Intl.NumberFormat("en-US", {
8293
- style: "currency",
8294
- currency: "USD"
8295
- }).format(value);
8296
- }
8297
- return (value == null ? void 0 : value.toString()) || "-";
8298
- } : void 0
8299
- });
8300
- });
8301
- }
8302
- return generatedColumns;
8303
- }, [customColumns, data, enableSelection, selectedItems, renderCustomColumn]);
8304
- const handleExport = () => {
8305
- if (onExport) {
8306
- onExport(selectedItems.length > 0 ? selectedItems : data);
8307
- } else {
8308
- const headers = tableColumns.filter((col) => col.key !== "__selection").map((col) => col.key);
8309
- const csvContent = [
8310
- headers.join(","),
8311
- ...(selectedItems.length > 0 ? selectedItems : data).map(
8312
- (item) => headers.map((header) => item[header] || "").join(",")
8313
- )
8314
- ].join("\n");
8315
- const blob = new Blob([csvContent], { type: "text/csv" });
8316
- const url = URL.createObjectURL(blob);
8317
- const a = document.createElement("a");
8318
- a.href = url;
8319
- a.download = `${config.display.title.toLowerCase().replace(/\s+/g, "-")}-export.csv`;
8320
- a.click();
8321
- URL.revokeObjectURL(url);
8322
- }
8323
- };
8324
- const renderToolbarSection = () => {
8325
- var _a;
8326
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 mb-4", children: [
8327
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8328
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: config.display.title }),
8329
- config.display.description && /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "outline", className: "text-xs", children: [
8330
- data.length,
8331
- " items"
8332
- ] })
8333
- ] }),
8334
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8335
- renderToolbar && renderToolbar(),
8336
- enableFiltering && /* @__PURE__ */ jsxRuntime.jsxs(
8337
- Button,
8338
- {
8339
- variant: "outline",
8340
- size: "sm",
8341
- onClick: () => setShowFilters(!showFilters),
8342
- className: cn(showFilters && "bg-muted"),
8343
- children: [
8344
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "w-4 h-4 mr-2" }),
8345
- "Filters"
8346
- ]
8347
- }
8348
- ),
8349
- enableRefresh && /* @__PURE__ */ jsxRuntime.jsxs(
8350
- Button,
8351
- {
8352
- variant: "outline",
8353
- size: "sm",
8354
- onClick: onRefresh,
8355
- disabled: isLoading,
8356
- children: [
8357
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: cn("w-4 h-4 mr-2", isLoading && "animate-spin") }),
8358
- "Refresh"
8359
- ]
8360
- }
8361
- ),
8362
- enableExport && /* @__PURE__ */ jsxRuntime.jsxs(
8363
- Button,
8364
- {
8365
- variant: "outline",
8366
- size: "sm",
8367
- onClick: handleExport,
8368
- disabled: data.length === 0,
8369
- children: [
8370
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-4 h-4 mr-2" }),
8371
- "Export"
8372
- ]
8373
- }
8374
- ),
8375
- (_a = config.actions) == null ? void 0 : _a.filter((action) => action.type === "primary").map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
8376
- Button,
8377
- {
8378
- size: "sm",
8379
- onClick: () => onAction == null ? void 0 : onAction(action, []),
8380
- disabled: isLoading,
8381
- children: [
8382
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(action.icon, { className: "w-4 h-4 mr-2" }),
8383
- action.label
8384
- ]
8385
- },
8386
- action.label
8387
- ))
8388
- ] })
8389
- ] });
8390
- };
8391
- const renderBulkActionsSection = () => {
8392
- var _a;
8393
- if (!enableBulkActions || selectedItems.length === 0) return null;
8394
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between bg-muted/50 p-3 rounded-md mb-4", children: [
8395
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8396
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground", children: [
8397
- selectedItems.length,
8398
- " items selected"
8399
- ] }),
8400
- /* @__PURE__ */ jsxRuntime.jsx(
8401
- Button,
8402
- {
8403
- variant: "ghost",
8404
- size: "sm",
8405
- onClick: () => setSelectedItems([]),
8406
- children: "Clear selection"
8407
- }
8408
- )
8409
- ] }),
8410
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8411
- renderBulkActions && renderBulkActions(selectedItems),
8412
- (_a = config.actions) == null ? void 0 : _a.filter((action) => action.type !== "primary").map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
8413
- Button,
8414
- {
8415
- variant: action.type === "danger" ? "destructive" : "outline",
8416
- size: "sm",
8417
- onClick: () => onAction == null ? void 0 : onAction(action, selectedItems),
8418
- children: [
8419
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(action.icon, { className: "w-4 h-4 mr-2" }),
8420
- action.label
8421
- ]
8422
- },
8423
- action.label
8424
- ))
8425
- ] })
8426
- ] });
8427
- };
8428
- const renderEmptyStateSection = () => {
8429
- var _a;
8430
- if (data.length > 0) return null;
8431
- if (renderEmptyState) {
8432
- return renderEmptyState();
8433
- }
8434
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
8435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-muted-foreground mb-4", children: [
8436
- "No ",
8437
- config.display.title.toLowerCase(),
8438
- " found"
8439
- ] }),
8440
- ((_a = config.actions) == null ? void 0 : _a.find((action) => action.type === "primary")) && /* @__PURE__ */ jsxRuntime.jsxs(Button, { onClick: () => {
8441
- var _a2;
8442
- const primaryAction = (_a2 = config.actions) == null ? void 0 : _a2.find((action) => action.type === "primary");
8443
- if (primaryAction) onAction == null ? void 0 : onAction(primaryAction, []);
8444
- }, children: [
8445
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "w-4 h-4 mr-2" }),
8446
- "Add ",
8447
- config.display.title.slice(0, -1)
8448
- ] })
8449
- ] });
8450
- };
8451
- return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: cn("p-6", className), category: config.display.category, "data-component-name": "EntityListPanel", children: [
8452
- headerSlot,
8453
- renderToolbarSection(),
8454
- renderBulkActionsSection(),
8455
- data.length === 0 ? renderEmptyStateSection() : /* @__PURE__ */ jsxRuntime.jsx(
8456
- DataTable,
8457
- {
8458
- data,
8459
- columns: tableColumns,
8460
- isLoading,
8461
- showSearch,
8462
- showPagination,
8463
- pageSize,
8464
- searchPlaceholder: searchPlaceholder || `Search ${config.display.title.toLowerCase()}...`,
8465
- onRowClick,
8466
- hover: !!onRowClick,
8467
- emptyMessage: `No ${config.display.title.toLowerCase()} found`
8468
- }
8469
- ),
8470
- footerSlot
8471
- ] });
8472
- };
8473
- const TrendAnalysisPanel = ({
8474
- metrics,
8475
- data,
8476
- temporal,
8477
- isLoading = false,
8478
- className,
8479
- category,
8480
- defaultChartType = "line",
8481
- dateField = "date",
8482
- enablePeriodSelection = true,
8483
- enableChartTypeSelection = true,
8484
- enableMetricSelection = true,
8485
- showComparisons = true,
8486
- renderHeader,
8487
- renderFooter,
8488
- renderCustomChart,
8489
- headerSlot,
8490
- footerSlot,
8491
- onMetricChange,
8492
- onPeriodChange,
8493
- onChartTypeChange,
8494
- onExport
8495
- }) => {
8496
- const [selectedMetric, setSelectedMetric] = React.useState(metrics[0]);
8497
- const [selectedPeriod, setSelectedPeriod] = React.useState((temporal == null ? void 0 : temporal.defaultCycle) || "monthly");
8498
- const [selectedChartType, setSelectedChartType] = React.useState(defaultChartType);
8499
- const [showForecast, setShowForecast] = React.useState(false);
8500
- const trendData = React.useMemo(() => {
8501
- if (!selectedMetric || !data.length) return [];
8502
- const periods = selectedPeriod === "yearly" ? 5 : selectedPeriod === "quarterly" ? 8 : selectedPeriod === "monthly" ? 12 : selectedPeriod === "weekly" ? 12 : 30;
8503
- return MetricCalculationEngine.calculateTrendData(
8504
- selectedMetric,
8505
- data,
8506
- dateField,
8507
- periods
8508
- );
8509
- }, [selectedMetric, data, dateField, selectedPeriod]);
8510
- const chartData = React.useMemo(() => {
8511
- return trendData.map((point) => ({
8512
- label: point.label || point.date,
8513
- value: point.value,
8514
- category
8515
- }));
8516
- }, [trendData, category]);
8517
- const trendPercentage = React.useMemo(() => {
8518
- if (chartData.length < 2) return null;
8519
- const first = chartData[0].value;
8520
- const last = chartData[chartData.length - 1].value;
8521
- if (first === 0) return null;
8522
- return (last - first) / Math.abs(first) * 100;
8523
- }, [chartData]);
8524
- const forecastData = React.useMemo(() => {
8525
- var _a, _b;
8526
- if (!showForecast || !((_a = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _a.enabled) || chartData.length < 3) {
8527
- return [];
8528
- }
8529
- const periods = ((_b = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _b.periods) || 3;
8530
- const lastValue = chartData[chartData.length - 1].value;
8531
- const trend = trendPercentage ? trendPercentage / 100 : 0;
8532
- return Array.from({ length: periods }, (_, index) => ({
8533
- label: `Future ${index + 1}`,
8534
- value: lastValue * (1 + trend * (index + 1) / chartData.length),
8535
- category: 8
8536
- // Use category 8 for forecast
8537
- }));
8538
- }, [showForecast, temporal == null ? void 0 : temporal.forecasting, chartData, trendPercentage]);
8539
- const combinedChartData = React.useMemo(() => {
8540
- if (forecastData.length === 0) return chartData;
8541
- return [...chartData, ...forecastData];
8542
- }, [chartData, forecastData]);
8543
- const handleMetricChange = (metricKey) => {
8544
- const metric = metrics.find((m) => m.key === metricKey);
8545
- if (metric) {
8546
- setSelectedMetric(metric);
8547
- onMetricChange == null ? void 0 : onMetricChange(metric);
8548
- }
8549
- };
8550
- const handlePeriodChange = (period) => {
8551
- setSelectedPeriod(period);
8552
- onPeriodChange == null ? void 0 : onPeriodChange(period);
8553
- };
8554
- const handleChartTypeChange = (chartType) => {
8555
- setSelectedChartType(chartType);
8556
- onChartTypeChange == null ? void 0 : onChartTypeChange(chartType);
8557
- };
8558
- const handleExport = () => {
8559
- if (onExport) {
8560
- onExport(combinedChartData, selectedMetric);
8561
- } else {
8562
- const csvContent = [
8563
- "Date,Value",
8564
- ...combinedChartData.map((point) => `${point.label},${point.value}`)
8565
- ].join("\n");
8566
- const blob = new Blob([csvContent], { type: "text/csv" });
8567
- const url = URL.createObjectURL(blob);
8568
- const a = document.createElement("a");
8569
- a.href = url;
8570
- a.download = `${selectedMetric.label}-trend-data.csv`;
8571
- a.click();
8572
- URL.revokeObjectURL(url);
8573
- }
8574
- };
8575
- const renderControls = () => {
8576
- var _a;
8577
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
8578
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
8579
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8580
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingUp, { className: "w-4 h-4 text-muted-foreground" }),
8581
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: "Trend Analysis" })
8582
- ] }),
8583
- trendPercentage !== null && /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: trendPercentage > 0 ? "default" : "destructive", children: [
8584
- trendPercentage > 0 ? "+" : "",
8585
- trendPercentage.toFixed(1),
8586
- "%"
8587
- ] })
8588
- ] }),
8589
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8590
- enableMetricSelection && metrics.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
8591
- Select,
8592
- {
8593
- value: selectedMetric.key,
8594
- onValueChange: handleMetricChange,
8595
- children: metrics.map((metric) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: metric.key, children: metric.label }, metric.key))
8596
- }
8597
- ),
8598
- enablePeriodSelection && /* @__PURE__ */ jsxRuntime.jsx(
8599
- Select,
8600
- {
8601
- value: selectedPeriod,
8602
- onValueChange: (value) => handlePeriodChange(value),
8603
- children: ((temporal == null ? void 0 : temporal.cycles) || ["daily", "weekly", "monthly", "quarterly", "yearly"]).map((cycle) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: cycle, children: cycle.charAt(0).toUpperCase() + cycle.slice(1) }, cycle))
8604
- }
8605
- ),
8606
- enableChartTypeSelection && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border rounded", children: [
8607
- /* @__PURE__ */ jsxRuntime.jsx(
8608
- Button,
8609
- {
8610
- variant: selectedChartType === "line" ? "default" : "ghost",
8611
- size: "sm",
8612
- onClick: () => handleChartTypeChange("line"),
8613
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LineChart, { className: "w-4 h-4" })
8614
- }
8615
- ),
8616
- /* @__PURE__ */ jsxRuntime.jsx(
8617
- Button,
8618
- {
8619
- variant: selectedChartType === "bar" ? "default" : "ghost",
8620
- size: "sm",
8621
- onClick: () => handleChartTypeChange("bar"),
8622
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "w-4 h-4" })
8623
- }
8624
- ),
8625
- /* @__PURE__ */ jsxRuntime.jsx(
8626
- Button,
8627
- {
8628
- variant: selectedChartType === "area" ? "default" : "ghost",
8629
- size: "sm",
8630
- onClick: () => handleChartTypeChange("area"),
8631
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AreaChart, { className: "w-4 h-4" })
8632
- }
8633
- )
8634
- ] }),
8635
- ((_a = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _a.enabled) && /* @__PURE__ */ jsxRuntime.jsx(
8636
- Button,
8637
- {
8638
- variant: showForecast ? "default" : "outline",
8639
- size: "sm",
8640
- onClick: () => setShowForecast(!showForecast),
8641
- children: "Forecast"
8642
- }
8643
- ),
8644
- /* @__PURE__ */ jsxRuntime.jsx(
8645
- Button,
8646
- {
8647
- variant: "outline",
8648
- size: "sm",
8649
- onClick: handleExport,
8650
- disabled: chartData.length === 0,
8651
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-4 h-4" })
8652
- }
8653
- )
8654
- ] })
8655
- ] });
8656
- };
8657
- const renderChart = () => {
8658
- if (renderCustomChart) {
8659
- const customChart = renderCustomChart(selectedMetric, combinedChartData, selectedChartType);
8660
- if (customChart) return customChart;
8661
- }
8662
- return /* @__PURE__ */ jsxRuntime.jsx(
8663
- Chart,
8664
- {
8665
- title: selectedMetric.label,
8666
- subtitle: `${selectedPeriod} trend analysis`,
8667
- data: combinedChartData,
8668
- type: selectedChartType,
8669
- category,
8670
- showTrend: true,
8671
- trend: trendPercentage !== null ? {
8672
- value: trendPercentage,
8673
- label: "overall trend"
8674
- } : void 0,
8675
- height: "large",
8676
- isLoading,
8677
- noWrapper: true,
8678
- showLegend: forecastData.length > 0
8679
- }
8680
- );
8681
- };
8682
- const renderComparisons = () => {
8683
- var _a, _b;
8684
- if (!showComparisons || !(temporal == null ? void 0 : temporal.enableComparisons) || chartData.length === 0) {
8685
- return null;
8686
- }
8687
- const currentValue = ((_a = chartData[chartData.length - 1]) == null ? void 0 : _a.value) || 0;
8688
- const previousValue = ((_b = chartData[chartData.length - 2]) == null ? void 0 : _b.value) || 0;
8689
- const periodChange = previousValue !== 0 ? (currentValue - previousValue) / Math.abs(previousValue) * 100 : 0;
8690
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t pt-4 mt-4", children: [
8691
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Period Comparisons" }),
8692
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-4", children: [
8693
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
8694
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold", children: currentValue.toFixed(0) }),
8695
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "Current" })
8696
- ] }),
8697
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
8698
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold", children: previousValue.toFixed(0) }),
8699
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "Previous" })
8700
- ] }),
8701
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
8702
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
8703
- "text-2xl font-bold",
8704
- periodChange > 0 ? "text-status-success" : periodChange < 0 ? "text-status-error" : "text-muted-foreground"
8705
- ), children: [
8706
- periodChange > 0 ? "+" : "",
8707
- periodChange.toFixed(1),
8708
- "%"
8709
- ] }),
8710
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "Change" })
8711
- ] })
8712
- ] })
8713
- ] });
8714
- };
8715
- return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: cn("p-6", className), category, "data-component-name": "TrendAnalysisPanel", children: [
8716
- headerSlot,
8717
- renderHeader && renderHeader(),
8718
- renderControls(),
8719
- renderChart(),
8720
- renderComparisons(),
8721
- renderFooter && renderFooter(),
8722
- footerSlot
8723
- ] });
8724
- };
8725
- const CategoryBreakdownPanel = ({
8726
- data,
8727
- categoryConfig,
8728
- valueField,
8729
- isLoading = false,
8730
- className,
8731
- category,
8732
- title = "Category Breakdown",
8733
- subtitle,
8734
- defaultView = "both",
8735
- defaultChartType = "pie",
8736
- maxCategories = 8,
8737
- showPercentages = true,
8738
- enableDrillDown = true,
8739
- renderHeader,
8740
- renderFooter,
8741
- renderCustomCategory,
8742
- renderDrillDownContent,
8743
- headerSlot,
8744
- footerSlot,
8745
- onCategoryClick,
8746
- onDrillDown,
8747
- onExport
8748
- }) => {
8749
- const [currentView, setCurrentView] = React.useState(defaultView);
8750
- const [chartType, setChartType] = React.useState(defaultChartType);
8751
- const [expandedCategories, setExpandedCategories] = React.useState(/* @__PURE__ */ new Set());
8752
- const [drillDownLevel, setDrillDownLevel] = React.useState(0);
8753
- const [drillDownPath, setDrillDownPath] = React.useState([]);
8754
- const categoryBreakdown = React.useMemo(() => {
8755
- var _a;
8756
- if (!data.length) return [];
8757
- const currentCategoryField = ((_a = categoryConfig == null ? void 0 : categoryConfig.hierarchy) == null ? void 0 : _a[drillDownLevel]) || (categoryConfig == null ? void 0 : categoryConfig.defaultGroupBy) || "category";
8758
- return MetricCalculationEngine.calculateCategoryBreakdown(
8759
- data,
8760
- currentCategoryField,
8761
- valueField,
8762
- maxCategories
8763
- );
8764
- }, [data, categoryConfig, valueField, maxCategories, drillDownLevel]);
8765
- const chartData = React.useMemo(() => {
8766
- return categoryBreakdown.map((item, index) => ({
8767
- label: item.category,
8768
- value: item.value,
8769
- category: index % 8 + 1
8770
- }));
8771
- }, [categoryBreakdown]);
8772
- const totalValue = React.useMemo(() => {
8773
- return categoryBreakdown.reduce((sum, item) => sum + item.value, 0);
8774
- }, [categoryBreakdown]);
8775
- const handleCategoryClick = (categoryItem) => {
8776
- var _a;
8777
- onCategoryClick == null ? void 0 : onCategoryClick(categoryItem);
8778
- if (enableDrillDown && (categoryConfig == null ? void 0 : categoryConfig.enableDrillDown) && drillDownLevel < (((_a = categoryConfig == null ? void 0 : categoryConfig.hierarchy) == null ? void 0 : _a.length) || 0) - 1) {
8779
- setDrillDownLevel((prev) => prev + 1);
8780
- setDrillDownPath((prev) => [...prev, categoryItem.category]);
8781
- onDrillDown == null ? void 0 : onDrillDown(categoryItem.category, drillDownLevel + 1);
8782
- }
8783
- };
8784
- const handleDrillUp = (level) => {
8785
- if (level < drillDownLevel) {
8786
- setDrillDownLevel(level);
8787
- setDrillDownPath((prev) => prev.slice(0, level));
8788
- onDrillDown == null ? void 0 : onDrillDown(level > 0 ? drillDownPath[level - 1] : "", level);
8789
- }
8790
- };
8791
- const toggleCategoryExpansion = (categoryName) => {
8792
- setExpandedCategories((prev) => {
8793
- const newSet = new Set(prev);
8794
- if (newSet.has(categoryName)) {
8795
- newSet.delete(categoryName);
8796
- } else {
8797
- newSet.add(categoryName);
8798
- }
8799
- return newSet;
8800
- });
8801
- };
8802
- const handleExport = () => {
8803
- if (onExport) {
8804
- onExport(categoryBreakdown);
8805
- } else {
8806
- const csvContent = [
8807
- "Category,Value,Percentage",
8808
- ...categoryBreakdown.map(
8809
- (item) => `${item.category},${item.value},${item.percentage.toFixed(2)}%`
8810
- )
8811
- ].join("\n");
8812
- const blob = new Blob([csvContent], { type: "text/csv" });
8813
- const url = URL.createObjectURL(blob);
8814
- const a = document.createElement("a");
8815
- a.href = url;
8816
- a.download = `category-breakdown-${Date.now()}.csv`;
8817
- a.click();
8818
- URL.revokeObjectURL(url);
8819
- }
8820
- };
8821
- const renderControls = () => {
8822
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
8823
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
8824
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8825
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PieChart, { className: "w-4 h-4 text-muted-foreground" }),
8826
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: title })
8827
- ] }),
8828
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "text-xs", children: subtitle }),
8829
- totalValue > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "outline", children: [
8830
- "Total: ",
8831
- new Intl.NumberFormat().format(totalValue)
8832
- ] })
8833
- ] }),
8834
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8835
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border rounded", children: [
8836
- /* @__PURE__ */ jsxRuntime.jsx(
8837
- Button,
8838
- {
8839
- variant: currentView === "chart" ? "default" : "ghost",
8840
- size: "sm",
8841
- onClick: () => setCurrentView("chart"),
8842
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PieChart, { className: "w-4 h-4" })
8843
- }
8844
- ),
8845
- /* @__PURE__ */ jsxRuntime.jsx(
8846
- Button,
8847
- {
8848
- variant: currentView === "list" ? "default" : "ghost",
8849
- size: "sm",
8850
- onClick: () => setCurrentView("list"),
8851
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "w-4 h-4" })
8852
- }
8853
- ),
8854
- /* @__PURE__ */ jsxRuntime.jsx(
8855
- Button,
8856
- {
8857
- variant: currentView === "both" ? "default" : "ghost",
8858
- size: "sm",
8859
- onClick: () => setCurrentView("both"),
8860
- children: "Both"
8861
- }
8862
- )
8863
- ] }),
8864
- (currentView === "chart" || currentView === "both") && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border rounded", children: [
8865
- /* @__PURE__ */ jsxRuntime.jsx(
8866
- Button,
8867
- {
8868
- variant: chartType === "pie" ? "default" : "ghost",
8869
- size: "sm",
8870
- onClick: () => setChartType("pie"),
8871
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PieChart, { className: "w-4 h-4" })
8872
- }
8873
- ),
8874
- /* @__PURE__ */ jsxRuntime.jsx(
8875
- Button,
8876
- {
8877
- variant: chartType === "bar" ? "default" : "ghost",
8878
- size: "sm",
8879
- onClick: () => setChartType("bar"),
8880
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "w-4 h-4" })
8881
- }
8882
- )
8883
- ] }),
8884
- /* @__PURE__ */ jsxRuntime.jsx(
8885
- Button,
8886
- {
8887
- variant: "outline",
8888
- size: "sm",
8889
- onClick: handleExport,
8890
- disabled: categoryBreakdown.length === 0,
8891
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-4 h-4" })
8892
- }
8893
- )
8894
- ] })
8895
- ] });
8896
- };
8897
- const renderBreadcrumb = () => {
8898
- if (drillDownLevel === 0) return null;
8899
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4 text-sm text-muted-foreground", children: [
8900
- /* @__PURE__ */ jsxRuntime.jsx(
8901
- Button,
8902
- {
8903
- variant: "ghost",
8904
- size: "sm",
8905
- onClick: () => handleDrillUp(0),
8906
- className: "p-0 h-auto font-normal",
8907
- children: "All"
8908
- }
8909
- ),
8910
- drillDownPath.map((segment, index) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
8911
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3" }),
8912
- /* @__PURE__ */ jsxRuntime.jsx(
8913
- Button,
8914
- {
8915
- variant: "ghost",
8916
- size: "sm",
8917
- onClick: () => handleDrillUp(index + 1),
8918
- className: "p-0 h-auto font-normal",
8919
- children: segment
8920
- }
8921
- )
8922
- ] }, index))
8923
- ] });
8924
- };
8925
- const renderChart = () => {
8926
- if (currentView === "list") return null;
8927
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(currentView === "both" && "mb-6"), children: /* @__PURE__ */ jsxRuntime.jsx(
8928
- Chart,
8929
- {
8930
- title: "",
8931
- data: chartData,
8932
- type: chartType,
8933
- category,
8934
- showLegend: true,
8935
- height: "medium",
8936
- isLoading,
8937
- noWrapper: true,
8938
- onClick: () => {
8939
- }
8940
- }
8941
- ) });
8942
- };
8943
- const renderCategoryList = () => {
8944
- if (currentView === "chart") return null;
8945
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: categoryBreakdown.map((item, index) => {
8946
- if (renderCustomCategory) {
8947
- const customContent = renderCustomCategory(item, index);
8948
- if (customContent) return customContent;
8949
- }
8950
- const canExpand = enableDrillDown && categoryConfig.enableDrillDown && "subcategories" in item && item.subcategories && Array.isArray(item.subcategories) && item.subcategories.length > 0;
8951
- const isExpanded = expandedCategories.has(item.category);
8952
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border rounded-lg", children: [
8953
- /* @__PURE__ */ jsxRuntime.jsxs(
8954
- "div",
8955
- {
8956
- className: cn(
8957
- "flex items-center justify-between p-3 cursor-pointer hover:bg-muted/50",
8958
- canExpand && "cursor-pointer"
8959
- ),
8960
- onClick: () => handleCategoryClick(item),
8961
- children: [
8962
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8963
- canExpand && /* @__PURE__ */ jsxRuntime.jsx(
8964
- Button,
8965
- {
8966
- variant: "ghost",
8967
- size: "sm",
8968
- className: "p-0 w-4 h-4",
8969
- onClick: (e) => {
8970
- e.stopPropagation();
8971
- toggleCategoryExpansion(item.category);
8972
- },
8973
- children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3" })
8974
- }
8975
- ),
8976
- /* @__PURE__ */ jsxRuntime.jsx(
8977
- DataBadge,
8978
- {
8979
- variant: "category",
8980
- category: index % 8 + 1,
8981
- size: "sm",
8982
- children: item.category
8983
- }
8984
- )
8985
- ] }),
8986
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8987
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
8988
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold", children: new Intl.NumberFormat().format(item.value) }),
8989
- showPercentages && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground", children: [
8990
- item.percentage.toFixed(1),
8991
- "%"
8992
- ] })
8993
- ] }),
8994
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-20 h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
8995
- "div",
8996
- {
8997
- className: cn(
8998
- "h-full transition-all duration-300",
8999
- `bg-category-${index % 8 + 1}`
9000
- ),
9001
- style: { width: `${item.percentage}%` }
9002
- }
9003
- ) })
9004
- ] })
9005
- ]
9006
- }
9007
- ),
9008
- canExpand && isExpanded && "subcategories" in item && item.subcategories && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t bg-muted/20", children: renderDrillDownContent ? renderDrillDownContent(item.category, item.subcategories) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 space-y-1", children: Array.isArray(item.subcategories) && item.subcategories.map((subItem) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm pl-4", children: [
9009
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: subItem.category }),
9010
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: new Intl.NumberFormat().format(subItem.value) })
9011
- ] }, subItem.category)) }) })
9012
- ] }, item.category);
9013
- }) });
9014
- };
9015
- const renderEmptyState = () => {
9016
- if (categoryBreakdown.length > 0) return null;
9017
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
9018
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "w-8 h-8 text-muted-foreground mx-auto mb-4" }),
9019
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children: "No category data available" })
9020
- ] });
9021
- };
9022
- return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: cn("p-6", className), category, "data-component-name": "CategoryBreakdownPanel", children: [
9023
- headerSlot,
9024
- renderHeader && renderHeader(),
9025
- renderControls(),
9026
- renderBreadcrumb(),
9027
- categoryBreakdown.length === 0 ? renderEmptyState() : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9028
- renderChart(),
9029
- renderCategoryList()
9030
- ] }),
9031
- renderFooter && renderFooter(),
9032
- footerSlot
9033
- ] });
9034
- };
9035
- const EntityPerformanceDashboardTemplate = ({
9036
- config,
9037
- data,
9038
- previousData,
9039
- isLoading = false,
9040
- className,
9041
- layout = "standard",
9042
- showInsights = true,
9043
- showTrends = true,
9044
- showCategories = true,
9045
- renderCustomActions,
9046
- renderAdditionalMetrics,
9047
- renderCustomTrendChart,
9048
- renderCustomCategoryView,
9049
- headerSlot,
9050
- footerSlot,
9051
- metricsHeaderSlot,
9052
- metricsFooterSlot,
9053
- trendsHeaderSlot,
9054
- trendsFooterSlot,
9055
- categoriesHeaderSlot,
9056
- categoriesFooterSlot,
9057
- onMetricClick,
9058
- onCategoryClick,
9059
- onTrendPeriodChange,
9060
- onExport
9061
- }) => {
9062
- const getLayoutClasses = () => {
9063
- switch (layout) {
9064
- case "compact":
9065
- return "space-y-4";
9066
- case "detailed":
9067
- return "space-y-8";
9068
- case "standard":
9069
- default:
9070
- return "space-y-6";
9071
- }
9072
- };
9073
- const renderPageHeader = () => {
9074
- return /* @__PURE__ */ jsxRuntime.jsx(
9075
- SectionHeader,
9076
- {
9077
- title: config.display.title,
9078
- description: config.display.description,
9079
- category: config.display.category,
9080
- actions: renderCustomActions ? renderCustomActions() : void 0
9081
- }
9082
- );
9083
- };
9084
- const renderMetricsSection = () => {
9085
- if (!config.metrics.length) return null;
9086
- const MetricsComponent = showInsights ? MetricsOverviewWithInsightsPanel : MetricsOverviewPanel;
9087
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9088
- metricsHeaderSlot,
9089
- /* @__PURE__ */ jsxRuntime.jsx(
9090
- MetricsComponent,
9091
- {
9092
- metrics: config.metrics,
9093
- data,
9094
- previousData,
9095
- isLoading,
9096
- onMetricClick,
9097
- category: config.display.category,
9098
- columns: layout === "compact" ? 2 : layout === "detailed" ? 4 : 3,
9099
- headerSlot: renderAdditionalMetrics ? renderAdditionalMetrics() : void 0
9100
- }
9101
- ),
9102
- metricsFooterSlot
9103
- ] });
9104
- };
9105
- const renderTrendsSection = () => {
9106
- if (!showTrends || !config.temporal || !config.metrics.length) return null;
9107
- if (renderCustomTrendChart) {
9108
- const customChart = renderCustomTrendChart(config, data);
9109
- if (customChart) {
9110
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9111
- trendsHeaderSlot,
9112
- customChart,
9113
- trendsFooterSlot
9114
- ] });
9115
- }
9116
- }
9117
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9118
- trendsHeaderSlot,
9119
- /* @__PURE__ */ jsxRuntime.jsx(
9120
- TrendAnalysisPanel,
9121
- {
9122
- metrics: config.metrics,
9123
- data,
9124
- temporal: config.temporal,
9125
- isLoading,
9126
- category: config.display.category,
9127
- enablePeriodSelection: true,
9128
- enableChartTypeSelection: layout === "detailed",
9129
- showComparisons: layout !== "compact",
9130
- onPeriodChange: onTrendPeriodChange,
9131
- onExport: (chartData, metric) => onExport == null ? void 0 : onExport("trends", { chartData, metric })
9132
- }
9133
- ),
9134
- trendsFooterSlot
9135
- ] });
9136
- };
9137
- const renderCategoriesSection = () => {
9138
- var _a;
9139
- if (!showCategories || !config.categories || !data.length) return null;
9140
- const valueField = ((_a = config.metrics.find((m) => m.type === "currency" || m.type === "count")) == null ? void 0 : _a.key) || Object.keys(data[0]).find((key) => typeof data[0][key] === "number") || "value";
9141
- if (renderCustomCategoryView) {
9142
- const customView = renderCustomCategoryView(config, data);
9143
- if (customView) {
9144
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9145
- categoriesHeaderSlot,
9146
- customView,
9147
- categoriesFooterSlot
9148
- ] });
9149
- }
9150
- }
9151
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9152
- categoriesHeaderSlot,
9153
- /* @__PURE__ */ jsxRuntime.jsx(
9154
- CategoryBreakdownPanel,
9155
- {
9156
- data,
9157
- categoryConfig: config.categories,
9158
- valueField,
9159
- isLoading,
9160
- category: config.display.category,
9161
- title: `${config.display.title} by ${config.categories.defaultGroupBy}`,
9162
- defaultView: layout === "compact" ? "list" : "both",
9163
- enableDrillDown: config.categories.enableDrillDown,
9164
- onCategoryClick,
9165
- onExport: (categoryData) => onExport == null ? void 0 : onExport("categories", categoryData)
9166
- }
9167
- ),
9168
- categoriesFooterSlot
9169
- ] });
9170
- };
9171
- const renderLayoutContent = () => {
9172
- const sections = [
9173
- renderMetricsSection(),
9174
- renderTrendsSection(),
9175
- renderCategoriesSection()
9176
- ].filter(Boolean);
9177
- if (layout === "detailed" && sections.length > 1) {
9178
- const [metricsSection, ...otherSections] = sections;
9179
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: getLayoutClasses(), children: [
9180
- metricsSection,
9181
- otherSections.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: otherSections })
9182
- ] });
9183
- }
9184
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: getLayoutClasses(), children: sections });
9185
- };
9186
- return /* @__PURE__ */ jsxRuntime.jsx(AppLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(
9187
- PageTemplate,
9188
- {
9189
- className: cn("container mx-auto px-4 py-6", className),
9190
- "data-component-name": "EntityPerformanceDashboardTemplate",
9191
- children: [
9192
- headerSlot,
9193
- renderPageHeader(),
9194
- renderLayoutContent(),
9195
- footerSlot
9196
- ]
9197
- }
9198
- ) });
9199
- };
9200
- const EntityPerformanceDashboardTemplateWithRealTime = ({
9201
- enableRealTime = false,
9202
- refreshInterval = 3e4,
9203
- // 30 seconds
9204
- onDataUpdate,
9205
- ...props
9206
- }) => {
9207
- React.useEffect(() => {
9208
- if (!enableRealTime) return;
9209
- const interval = setInterval(() => {
9210
- if (onDataUpdate) {
9211
- onDataUpdate(props.data);
9212
- }
9213
- }, refreshInterval);
9214
- return () => clearInterval(interval);
9215
- }, [enableRealTime, refreshInterval, onDataUpdate, props.data]);
9216
- return /* @__PURE__ */ jsxRuntime.jsx(EntityPerformanceDashboardTemplate, { ...props });
9217
- };
9218
- const EntityManagementTemplate = ({
9219
- config,
9220
- data,
9221
- isLoading = false,
9222
- className,
9223
- enableSearch = true,
9224
- enableFiltering = true,
9225
- enableBulkActions = true,
9226
- enableExport = true,
9227
- pageSize = 10,
9228
- onCreate,
9229
- onUpdate,
9230
- onDelete,
9231
- onBulkDelete,
9232
- onView,
9233
- renderCreateForm,
9234
- renderEditForm,
9235
- renderDetailView,
9236
- renderCustomActions,
9237
- renderEmptyState,
9238
- renderFilterPanel,
9239
- headerSlot,
9240
- footerSlot,
9241
- toolbarSlot,
9242
- listHeaderSlot,
9243
- listFooterSlot,
9244
- onRefresh,
9245
- onFilter,
9246
- onExport
9247
- }) => {
9248
- const [showCreateModal, setShowCreateModal] = React.useState(false);
9249
- const [showEditModal, setShowEditModal] = React.useState(false);
9250
- const [showDetailModal, setShowDetailModal] = React.useState(false);
9251
- const [showFilterPanel, setShowFilterPanel] = React.useState(false);
9252
- const [selectedItem, setSelectedItem] = React.useState(null);
9253
- const [selectedItems, setSelectedItems] = React.useState([]);
9254
- const handleCreate = async (item) => {
9255
- if (onCreate) {
9256
- try {
9257
- await onCreate(item);
9258
- setShowCreateModal(false);
9259
- onRefresh == null ? void 0 : onRefresh();
9260
- } catch (error) {
9261
- console.error("Create failed:", error);
9262
- }
9263
- }
9264
- };
9265
- const handleUpdate = async (item) => {
9266
- if (onUpdate && selectedItem) {
9267
- try {
9268
- await onUpdate(selectedItem.id, item);
9269
- setShowEditModal(false);
9270
- setSelectedItem(null);
9271
- onRefresh == null ? void 0 : onRefresh();
9272
- } catch (error) {
9273
- console.error("Update failed:", error);
9274
- }
9275
- }
9276
- };
9277
- const handleBulkDelete = async () => {
9278
- if (onBulkDelete && selectedItems.length > 0 && confirm(`Are you sure you want to delete ${selectedItems.length} ${config.display.title.toLowerCase()}?`)) {
9279
- try {
9280
- const ids = selectedItems.map((item) => item.id);
9281
- await onBulkDelete(ids);
9282
- setSelectedItems([]);
9283
- onRefresh == null ? void 0 : onRefresh();
9284
- } catch (error) {
9285
- console.error("Bulk delete failed:", error);
9286
- }
9287
- }
9288
- };
9289
- const handleView = (item) => {
9290
- if (onView) {
9291
- onView(item);
9292
- } else {
9293
- setSelectedItem(item);
9294
- setShowDetailModal(true);
9295
- }
9296
- };
9297
- const handleEdit = (item) => {
9298
- setSelectedItem(item);
9299
- setShowEditModal(true);
9300
- };
9301
- const handleRowClick = (item) => {
9302
- handleView(item);
9303
- };
9304
- const handleAction = (action, selectedItems2) => {
9305
- action.onClick({ selectedItems: selectedItems2, config });
9306
- };
9307
- const generateDefaultActions = () => {
9308
- const actions = [];
9309
- if (onCreate) {
9310
- actions.push({
9311
- label: `Add ${config.display.title.slice(0, -1)}`,
9312
- type: "primary",
9313
- icon: lucideReact.Plus,
9314
- onClick: () => setShowCreateModal(true)
9315
- });
9316
- }
9317
- return actions;
9318
- };
9319
- const renderPageHeader = () => {
9320
- const actions = [
9321
- ...generateDefaultActions(),
9322
- ...config.actions || []
9323
- ];
9324
- return /* @__PURE__ */ jsxRuntime.jsx(
9325
- SectionHeader,
9326
- {
9327
- title: config.display.title,
9328
- description: config.display.description,
9329
- category: config.display.category,
9330
- actions: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9331
- renderCustomActions && renderCustomActions(),
9332
- enableFiltering && /* @__PURE__ */ jsxRuntime.jsxs(
9333
- Button,
9334
- {
9335
- variant: "outline",
9336
- size: "sm",
9337
- onClick: () => setShowFilterPanel(!showFilterPanel),
9338
- className: cn(showFilterPanel && "bg-muted"),
9339
- children: [
9340
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "w-4 h-4 mr-2" }),
9341
- "Filters"
9342
- ]
9343
- }
9344
- ),
9345
- enableExport && /* @__PURE__ */ jsxRuntime.jsxs(
9346
- Button,
9347
- {
9348
- variant: "outline",
9349
- size: "sm",
9350
- onClick: () => onExport == null ? void 0 : onExport(selectedItems.length > 0 ? selectedItems : data, "csv"),
9351
- disabled: data.length === 0,
9352
- children: [
9353
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-4 h-4 mr-2" }),
9354
- "Export"
9355
- ]
9356
- }
9357
- ),
9358
- actions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
9359
- Button,
9360
- {
9361
- variant: action.type === "primary" ? "default" : "outline",
9362
- size: "sm",
9363
- onClick: () => action.onClick({ data, config }),
9364
- children: [
9365
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(action.icon, { className: "w-4 h-4 mr-2" }),
9366
- action.label
9367
- ]
9368
- },
9369
- action.label
9370
- ))
9371
- ] })
9372
- }
9373
- );
9374
- };
9375
- const renderToolbar = () => {
9376
- if (selectedItems.length === 0) return null;
9377
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted/50 p-4 rounded-lg mb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9378
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9379
- /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "secondary", children: [
9380
- selectedItems.length,
9381
- " selected"
9382
- ] }),
9383
- /* @__PURE__ */ jsxRuntime.jsx(
9384
- Button,
9385
- {
9386
- variant: "ghost",
9387
- size: "sm",
9388
- onClick: () => setSelectedItems([]),
9389
- children: "Clear selection"
9390
- }
9391
- )
9392
- ] }),
9393
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9394
- onBulkDelete && /* @__PURE__ */ jsxRuntime.jsxs(
9395
- Button,
9396
- {
9397
- variant: "destructive",
9398
- size: "sm",
9399
- onClick: handleBulkDelete,
9400
- children: [
9401
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-4 h-4 mr-2" }),
9402
- "Delete Selected"
9403
- ]
9404
- }
9405
- ),
9406
- enableExport && /* @__PURE__ */ jsxRuntime.jsxs(
9407
- Button,
9408
- {
9409
- variant: "outline",
9410
- size: "sm",
9411
- onClick: () => onExport == null ? void 0 : onExport(selectedItems, "csv"),
9412
- children: [
9413
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "w-4 h-4 mr-2" }),
9414
- "Export Selected"
9415
- ]
9416
- }
9417
- )
9418
- ] })
9419
- ] }) });
9420
- };
9421
- const renderFilterPanelSection = () => {
9422
- if (!showFilterPanel) return null;
9423
- return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 mb-4", children: renderFilterPanel ? renderFilterPanel(onFilter || (() => {
9424
- })) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center text-muted-foreground py-4", children: "Filter functionality not implemented yet" }) });
9425
- };
9426
- const renderCreateModal = () => {
9427
- if (!showCreateModal) return null;
9428
- return /* @__PURE__ */ jsxRuntime.jsx(
9429
- Modal,
9430
- {
9431
- isOpen: showCreateModal,
9432
- onClose: () => setShowCreateModal(false),
9433
- title: `Create ${config.display.title.slice(0, -1)}`,
9434
- category: config.display.category,
9435
- children: renderCreateForm ? renderCreateForm(handleCreate, () => setShowCreateModal(false)) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6 text-center text-muted-foreground", children: "Create form not implemented yet" })
9436
- }
9437
- );
9438
- };
9439
- const renderEditModal = () => {
9440
- if (!showEditModal || !selectedItem) return null;
9441
- return /* @__PURE__ */ jsxRuntime.jsx(
9442
- Modal,
9443
- {
9444
- isOpen: showEditModal,
9445
- onClose: () => {
9446
- setShowEditModal(false);
9447
- setSelectedItem(null);
9448
- },
9449
- title: `Edit ${config.display.title.slice(0, -1)}`,
9450
- category: config.display.category,
9451
- children: renderEditForm ? renderEditForm(
9452
- selectedItem,
9453
- handleUpdate,
9454
- () => {
9455
- setShowEditModal(false);
9456
- setSelectedItem(null);
9457
- }
9458
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6 text-center text-muted-foreground", children: "Edit form not implemented yet" })
9459
- }
9460
- );
9461
- };
9462
- const renderDetailModal = () => {
9463
- if (!showDetailModal || !selectedItem) return null;
9464
- return /* @__PURE__ */ jsxRuntime.jsx(
9465
- Modal,
9466
- {
9467
- isOpen: showDetailModal,
9468
- onClose: () => {
9469
- setShowDetailModal(false);
9470
- setSelectedItem(null);
9471
- },
9472
- title: `${config.display.title.slice(0, -1)} Details`,
9473
- category: config.display.category,
9474
- size: "large",
9475
- children: renderDetailView ? renderDetailView(
9476
- selectedItem,
9477
- () => {
9478
- setShowDetailModal(false);
9479
- handleEdit(selectedItem);
9480
- },
9481
- () => {
9482
- setShowDetailModal(false);
9483
- setSelectedItem(null);
9484
- }
9485
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: Object.entries(selectedItem).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
9486
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium capitalize", children: [
9487
- key,
9488
- ":"
9489
- ] }),
9490
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (value == null ? void 0 : value.toString()) || "-" })
9491
- ] }, key)) }) })
9492
- }
9493
- );
9494
- };
9495
- return /* @__PURE__ */ jsxRuntime.jsx(AppLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(
9496
- PageTemplate,
9497
- {
9498
- className: cn("container mx-auto px-4 py-6", className),
9499
- "data-component-name": "EntityManagementTemplate",
9500
- children: [
9501
- headerSlot,
9502
- renderPageHeader(),
9503
- toolbarSlot,
9504
- renderFilterPanelSection(),
9505
- renderToolbar(),
9506
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
9507
- listHeaderSlot,
9508
- /* @__PURE__ */ jsxRuntime.jsx(
9509
- EntityListPanel,
9510
- {
9511
- config,
9512
- data,
9513
- isLoading,
9514
- onRowClick: handleRowClick,
9515
- onAction: handleAction,
9516
- enableSelection: enableBulkActions,
9517
- enableBulkActions,
9518
- enableExport,
9519
- enableRefresh: !!onRefresh,
9520
- showSearch: enableSearch,
9521
- showPagination: true,
9522
- pageSize,
9523
- renderEmptyState,
9524
- onExport,
9525
- onRefresh
9526
- }
9527
- ),
9528
- listFooterSlot
9529
- ] }),
9530
- renderCreateModal(),
9531
- renderEditModal(),
9532
- renderDetailModal(),
9533
- footerSlot
9534
- ]
9535
- }
9536
- ) });
9537
- };
9538
- const financialConfig = {
9539
- entityType: "transactional",
9540
- display: {
9541
- title: "Financial Dashboard",
9542
- description: "Personal finance overview and transaction management",
9543
- category: 2
9544
- // Green theme for financial success
9545
- },
9546
- metrics: [
9547
- {
9548
- key: "totalBalance",
9549
- label: "Total Balance",
9550
- type: "currency",
9551
- trend: true,
9552
- icon: lucideReact.DollarSign,
9553
- aggregation: "sum"
9554
- },
9555
- {
9556
- key: "monthlyIncome",
9557
- label: "Monthly Income",
9558
- type: "currency",
9559
- trend: true,
9560
- icon: lucideReact.TrendingUp,
9561
- aggregation: "sum"
9562
- },
9563
- {
9564
- key: "monthlyExpenses",
9565
- label: "Monthly Expenses",
9566
- type: "currency",
9567
- trend: true,
9568
- icon: lucideReact.Wallet,
9569
- aggregation: "sum"
9570
- },
9571
- {
9572
- key: "savingsRate",
9573
- label: "Savings Rate",
9574
- type: "percentage",
9575
- target: 20,
9576
- icon: lucideReact.Target
9577
- }
9578
- ],
9579
- temporal: {
9580
- cycles: ["monthly", "quarterly", "yearly"],
9581
- defaultCycle: "monthly",
9582
- enableComparisons: true,
9583
- forecasting: {
9584
- enabled: true,
9585
- periods: 3,
9586
- algorithm: "seasonal"
9587
- }
9588
- },
9589
- categories: {
9590
- hierarchy: ["account", "category", "type"],
9591
- defaultGroupBy: "category",
9592
- enableDrillDown: true,
9593
- colorCoding: true
9594
- },
9595
- actions: [
9596
- {
9597
- label: "Add Transaction",
9598
- type: "primary",
9599
- onClick: ({ data, config }) => {
9600
- console.log("Adding new transaction", { data, config });
9601
- }
9602
- },
9603
- {
9604
- label: "Generate Report",
9605
- type: "secondary",
9606
- onClick: ({ selectedItems, data, config }) => {
9607
- console.log("Generating report", { selectedItems, data, config });
9608
- }
9609
- }
9610
- ]
9611
- };
9612
- const sampleFinancialData = [
9613
- {
9614
- id: "1",
9615
- amount: 5e3,
9616
- category: "Salary",
9617
- account: "Checking",
9618
- date: "2024-01-15",
9619
- description: "Monthly salary",
9620
- type: "income",
9621
- status: "completed"
9622
- },
9623
- {
9624
- id: "2",
9625
- amount: -1200,
9626
- category: "Rent",
9627
- account: "Checking",
9628
- date: "2024-01-01",
9629
- description: "Monthly rent payment",
9630
- type: "expense",
9631
- status: "completed"
9632
- },
9633
- {
9634
- id: "3",
9635
- amount: -300,
9636
- category: "Groceries",
9637
- account: "Checking",
9638
- date: "2024-01-10",
9639
- description: "Weekly groceries",
9640
- type: "expense",
9641
- status: "completed"
9642
- },
9643
- {
9644
- id: "4",
9645
- amount: -80,
9646
- category: "Utilities",
9647
- account: "Checking",
9648
- date: "2024-01-05",
9649
- description: "Electric bill",
9650
- type: "expense",
9651
- status: "completed"
9652
- },
9653
- {
9654
- id: "5",
9655
- amount: -45,
9656
- category: "Entertainment",
9657
- account: "Checking",
9658
- date: "2024-01-12",
9659
- description: "Movie tickets",
9660
- type: "expense",
9661
- status: "completed"
9662
- }
9663
- ];
9664
8139
  function createReactApp(config) {
9665
8140
  const appConfig = typeof config === "string" ? { title: config } : config;
9666
8141
  const {
@@ -9671,6 +8146,7 @@ function createReactApp(config) {
9671
8146
  enableQuery = true,
9672
8147
  enableRouting = true,
9673
8148
  auth,
8149
+ navigation,
9674
8150
  customProviders = []
9675
8151
  } = appConfig;
9676
8152
  const queryClient = new reactQuery.QueryClient({
@@ -9705,7 +8181,7 @@ function createReactApp(config) {
9705
8181
  tree = /* @__PURE__ */ jsxRuntime.jsx(Provider, { children: tree }, Provider.name);
9706
8182
  });
9707
8183
  if (enableRouting) {
9708
- tree = /* @__PURE__ */ jsxRuntime.jsx(SidebarProvider, { children: tree });
8184
+ tree = /* @__PURE__ */ jsxRuntime.jsx(NavigationProvider, { initialNavigation: navigation, children: /* @__PURE__ */ jsxRuntime.jsx(SidebarProvider, { children: tree }) });
9709
8185
  }
9710
8186
  if (enableAuth) {
9711
8187
  tree = /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { config: auth, children: tree });
@@ -11960,7 +10436,6 @@ exports.CardDescription = CardDescription;
11960
10436
  exports.CardFooter = CardFooter;
11961
10437
  exports.CardHeader = CardHeader;
11962
10438
  exports.CardTitle = CardTitle;
11963
- exports.CategoryBreakdownPanel = CategoryBreakdownPanel;
11964
10439
  exports.Chart = Chart;
11965
10440
  exports.ColorSwatch = ColorSwatch;
11966
10441
  exports.ComponentShowcasePage = ComponentShowcasePage;
@@ -11995,15 +10470,12 @@ exports.DropdownMenuSubContent = DropdownMenuSubContent;
11995
10470
  exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger;
11996
10471
  exports.DropdownMenuTrigger = DropdownMenuTrigger;
11997
10472
  exports.EmptyState = EmptyState;
11998
- exports.EntityListPanel = EntityListPanel;
11999
- exports.EntityManagementTemplate = EntityManagementTemplate;
12000
- exports.EntityPerformanceDashboardTemplate = EntityPerformanceDashboardTemplate;
12001
- exports.EntityPerformanceDashboardTemplateWithRealTime = EntityPerformanceDashboardTemplateWithRealTime;
12002
10473
  exports.ErrorBoundary = ErrorBoundary;
12003
10474
  exports.FileUpload = FileUpload;
12004
10475
  exports.FormField = FormField;
12005
10476
  exports.FormGroup = FormGroup;
12006
10477
  exports.GlobalSearch = GlobalSearch;
10478
+ exports.Icon = Icon;
12007
10479
  exports.IconBadge = IconBadge;
12008
10480
  exports.Input = Input;
12009
10481
  exports.Label = Label;
@@ -12011,10 +10483,9 @@ exports.Loading = Loading;
12011
10483
  exports.LoginForm = LoginForm;
12012
10484
  exports.LogoutButton = LogoutButton;
12013
10485
  exports.MetricCalculationEngine = MetricCalculationEngine;
12014
- exports.MetricsOverviewPanel = MetricsOverviewPanel;
12015
- exports.MetricsOverviewWithInsightsPanel = MetricsOverviewWithInsightsPanel;
12016
10486
  exports.Modal = Modal;
12017
10487
  exports.NavMenu = NavMenu;
10488
+ exports.NavigationProvider = NavigationProvider;
12018
10489
  exports.PageTemplate = PageTemplate;
12019
10490
  exports.Pagination = Pagination;
12020
10491
  exports.PaletteSwitcher = PaletteSwitcher;
@@ -12031,6 +10502,7 @@ exports.SelectItem = SelectItem;
12031
10502
  exports.SelectTrigger = SelectTrigger;
12032
10503
  exports.SelectValue = SelectValue;
12033
10504
  exports.ShowcaseSection = ShowcaseSection;
10505
+ exports.Sidebar = Sidebar;
12034
10506
  exports.SidebarButton = SidebarButton;
12035
10507
  exports.SidebarProvider = SidebarProvider;
12036
10508
  exports.Skeleton = Skeleton;
@@ -12053,7 +10525,6 @@ exports.TabsTrigger = TabsTrigger;
12053
10525
  exports.Toast = Toast;
12054
10526
  exports.ToastContainer = ToastContainer;
12055
10527
  exports.Tooltip = Tooltip;
12056
- exports.TrendAnalysisPanel = TrendAnalysisPanel;
12057
10528
  exports.UI_CONFIG = UI_CONFIG;
12058
10529
  exports.UserAvatar = UserAvatar;
12059
10530
  exports.UserMenu = UserMenu;
@@ -12063,14 +10534,15 @@ exports.cn = cn;
12063
10534
  exports.createReactApp = createReactApp;
12064
10535
  exports.createSimpleApp = createSimpleApp;
12065
10536
  exports.env = env;
12066
- exports.financialConfig = financialConfig;
12067
10537
  exports.formatNumberWithTooltip = formatNumberWithTooltip;
12068
10538
  exports.getAnimationClasses = getAnimationClasses;
12069
10539
  exports.getChartHeight = getChartHeight;
12070
10540
  exports.getContainerHeightClass = getContainerHeightClass;
10541
+ exports.getIcon = getIcon;
10542
+ exports.getNavigationItems = getNavigationItems;
12071
10543
  exports.interactionVariants = interactionVariants;
10544
+ exports.isValidIcon = isValidIcon;
12072
10545
  exports.legacyPatterns = legacyPatterns;
12073
- exports.sampleFinancialData = sampleFinancialData;
12074
10546
  exports.setGlobalAuthService = setGlobalAuthService;
12075
10547
  exports.tooltipContent = tooltipContent;
12076
10548
  exports.useApiMutation = useApiMutation;
@@ -12079,6 +10551,7 @@ exports.useAuth = useAuth;
12079
10551
  exports.useCreateExample = useCreateExample;
12080
10552
  exports.useDeleteExample = useDeleteExample;
12081
10553
  exports.useGetExample = useGetExample;
10554
+ exports.useNavigation = useNavigation;
12082
10555
  exports.usePermissions = usePermissions;
12083
10556
  exports.useSidebar = useSidebar;
12084
10557
  exports.useTextOverflow = useTextOverflow;