@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.es.js CHANGED
@@ -6,19 +6,18 @@ import { clsx } from "clsx";
6
6
  import { twMerge } from "tailwind-merge";
7
7
  import * as React from "react";
8
8
  import React__default, { useRef, useState, useEffect, Component, createContext, useContext, useMemo, useId, useCallback } from "react";
9
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
10
+ import { Menu, HelpCircle, Info, AlertCircle, Check, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, ChevronUp, ChevronLeft, ChevronDown, ChevronRight, Music, Video, Image, Folder, File, Flag, Tag, Bookmark, Heart, Star, MapPin, Clock, Calendar, Phone, Mail, Unlock, Lock, Share, Upload, Download, Eye, Trash2, Edit, Plus, Search, Bell, Settings, Home, Layout, TrendingUp, Database, BarChart3, Users, Shield, X, Palette, Circle, Loader2, Target, ExternalLink, TrendingDown, Minus, FileX, Sparkles, User, Sun, Moon, UserCircle, LogOut, ChevronsUpDown, AreaChart, LineChart, CheckCircle, AlertTriangle, Square, Waves, Zap, TreePine, Sunset, Building2, DollarSign, ShoppingCart, MoreHorizontal, Filter, Activity, RefreshCw, FileText, History, Save, Copy, Grid3X3, Layers, XCircle } from "lucide-react";
9
11
  import { cva } from "class-variance-authority";
10
12
  import axios from "axios";
11
13
  import { useQuery, useQueryClient, useMutation, QueryClient, QueryClientProvider } from "@tanstack/react-query";
12
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
13
14
  import { Slot } from "@radix-ui/react-slot";
14
15
  import * as LabelPrimitive from "@radix-ui/react-label";
15
16
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
16
17
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
17
- import { ChevronRight, Check, Circle, Loader2, Target, ExternalLink, ArrowRight, TrendingUp, TrendingDown, Minus, FileX, AlertCircle, Search, Database, Sparkles, Mail, Lock, Shield, User, Sun, Moon, UserCircle, Settings, LogOut, X, ChevronsUpDown, ChevronUp, ChevronDown, ChevronLeft, Clock, Calendar, BarChart3, AreaChart, LineChart, Upload, Image, File, CheckCircle, Info, AlertTriangle, Home, Palette, Square, Waves, Zap, TreePine, Sunset, Building2, Users, DollarSign, ShoppingCart, Menu, Layout, MoreHorizontal, Plus, Filter, Download, Activity, RefreshCw, Eye, Edit, Trash2, FileText, History, ArrowLeft, Save, Copy, PieChart, List, Wallet, Grid3X3, Layers, XCircle } from "lucide-react";
18
18
  import { createPortal } from "react-dom";
19
19
  import { useLocation, useNavigate, useSearchParams, Outlet, BrowserRouter, Routes, Route } from "react-router-dom";
20
20
  import { createRoot } from "react-dom/client";
21
- import "@tanstack/react-query-devtools";
22
21
  const APP_NAME = "Design System Showcase";
23
22
  const API_ENDPOINTS = {
24
23
  HEALTH: "/health"
@@ -413,6 +412,71 @@ class MetricCalculationEngine {
413
412
  return insights.slice(0, 5);
414
413
  }
415
414
  }
415
+ const iconMap = {
416
+ Palette,
417
+ Menu,
418
+ X,
419
+ Shield,
420
+ Users,
421
+ BarChart3,
422
+ Database,
423
+ TrendingUp,
424
+ Layout,
425
+ Home,
426
+ Settings,
427
+ Bell,
428
+ Search,
429
+ Plus,
430
+ Edit,
431
+ Trash2,
432
+ Eye,
433
+ Download,
434
+ Upload,
435
+ Share,
436
+ Lock,
437
+ Unlock,
438
+ Mail,
439
+ Phone,
440
+ Calendar,
441
+ Clock,
442
+ MapPin,
443
+ Star,
444
+ Heart,
445
+ Bookmark,
446
+ Tag,
447
+ Flag,
448
+ File,
449
+ Folder,
450
+ Image,
451
+ Video,
452
+ Music,
453
+ ChevronRight,
454
+ ChevronDown,
455
+ ChevronLeft,
456
+ ChevronUp,
457
+ ArrowRight,
458
+ ArrowLeft,
459
+ ArrowUp,
460
+ ArrowDown,
461
+ Check,
462
+ AlertCircle,
463
+ Info,
464
+ HelpCircle
465
+ };
466
+ const Icon = ({ name, className = "w-5 h-5", size, ...props }) => {
467
+ const IconComponent = iconMap[name];
468
+ if (!IconComponent) {
469
+ console.warn(`Icon "${name}" not found. Using default Menu icon.`);
470
+ return /* @__PURE__ */ jsx(Menu, { className, size, ...props });
471
+ }
472
+ return /* @__PURE__ */ jsx(IconComponent, { className, size, ...props });
473
+ };
474
+ const getIcon = (name) => {
475
+ return iconMap[name] || Menu;
476
+ };
477
+ const isValidIcon = (name) => {
478
+ return name in iconMap;
479
+ };
416
480
  function cn(...inputs) {
417
481
  return twMerge(clsx(inputs));
418
482
  }
@@ -5775,6 +5839,42 @@ const useSidebar = () => {
5775
5839
  }
5776
5840
  return context;
5777
5841
  };
5842
+ const NavigationContext = createContext(void 0);
5843
+ const defaultShowcaseNavigation = [
5844
+ { value: "showcase", label: "Showcase", icon: "Palette", path: "/showcase", category: 5 },
5845
+ { value: "admin-dashboard", label: "Admin Dashboard", icon: "Shield", path: "/admin/dashboard", category: 2 },
5846
+ { value: "admin-users", label: "User Management", icon: "Users", path: "/admin/users", category: 3 },
5847
+ { value: "admin-sales", label: "Sales Dashboard", icon: "TrendingUp", path: "/admin/sales", category: 4 },
5848
+ { value: "entity-performance", label: "Performance Dashboard", icon: "BarChart3", path: "/entity/performance", category: 6 },
5849
+ { value: "entity-management", label: "Entity Management", icon: "Database", path: "/entity/management", category: 7 },
5850
+ { value: "entity-template", label: "Template Example", icon: "Layout", path: "/entity/template-example", category: 1 }
5851
+ ];
5852
+ const NavigationProvider = ({ children, initialNavigation }) => {
5853
+ const [navigation, setNavigation] = React__default.useState(
5854
+ initialNavigation || {
5855
+ items: defaultShowcaseNavigation,
5856
+ showDefaultNavigation: true,
5857
+ defaultExpanded: true
5858
+ }
5859
+ );
5860
+ return /* @__PURE__ */ jsx(NavigationContext.Provider, { value: { navigation, setNavigation }, children });
5861
+ };
5862
+ const useNavigation = () => {
5863
+ const context = useContext(NavigationContext);
5864
+ if (context === void 0) {
5865
+ throw new Error("useNavigation must be used within a NavigationProvider");
5866
+ }
5867
+ return context;
5868
+ };
5869
+ const getNavigationItems = (config) => {
5870
+ if (config.items.length > 0) {
5871
+ return config.items;
5872
+ }
5873
+ if (config.showDefaultNavigation !== false) {
5874
+ return defaultShowcaseNavigation;
5875
+ }
5876
+ return [];
5877
+ };
5778
5878
  const SidebarButton = ({
5779
5879
  icon,
5780
5880
  label,
@@ -5782,13 +5882,16 @@ const SidebarButton = ({
5782
5882
  category = 1,
5783
5883
  expanded = false,
5784
5884
  onClick,
5785
- className
5885
+ className,
5886
+ badge,
5887
+ disabled = false
5786
5888
  }) => {
5787
5889
  return /* @__PURE__ */ jsxs(
5788
5890
  Button,
5789
5891
  {
5790
5892
  variant: active ? "secondary" : "ghost",
5791
5893
  onClick,
5894
+ disabled,
5792
5895
  tooltip: !expanded ? label : void 0,
5793
5896
  className: cn(
5794
5897
  "relative w-full justify-start gap-3 h-12",
@@ -5822,12 +5925,19 @@ const SidebarButton = ({
5822
5925
  "text-sm font-medium flex-1 text-left",
5823
5926
  active ? `text-category-${category}` : "text-foreground"
5824
5927
  ), children: label }),
5825
- active && /* @__PURE__ */ jsx("div", { className: cn(
5928
+ badge ? /* @__PURE__ */ jsx("span", { className: cn(
5929
+ "px-2 py-0.5 text-xs font-medium rounded-full flex-shrink-0",
5930
+ "bg-primary/10 text-primary"
5931
+ ), children: badge }) : active && /* @__PURE__ */ jsx("div", { className: cn(
5826
5932
  "w-2 h-2 rounded-full flex-shrink-0",
5827
5933
  `bg-category-${category}`
5828
5934
  ) })
5829
5935
  ] }),
5830
- !expanded && active && /* @__PURE__ */ jsx("div", { className: "absolute -top-1 -right-1", children: /* @__PURE__ */ jsx("div", { className: cn(
5936
+ !expanded && (badge || active) && /* @__PURE__ */ jsx("div", { className: "absolute -top-1 -right-1", children: badge ? /* @__PURE__ */ jsx("span", { className: cn(
5937
+ "px-1.5 py-0.5 text-xs font-bold rounded-full",
5938
+ "bg-primary text-primary-foreground",
5939
+ "ring-2 ring-background"
5940
+ ), children: badge }) : active && /* @__PURE__ */ jsx("div", { className: cn(
5831
5941
  "w-2.5 h-2.5 rounded-full",
5832
5942
  `bg-category-${category}`,
5833
5943
  "ring-2 ring-background"
@@ -5838,18 +5948,11 @@ const SidebarButton = ({
5838
5948
  };
5839
5949
  const Sidebar = ({ className }) => {
5840
5950
  const { isExpanded, toggleSidebar } = useSidebar();
5951
+ const { navigation } = useNavigation();
5841
5952
  const location = useLocation();
5842
5953
  const navigate = useNavigate();
5843
5954
  const [searchParams] = useSearchParams();
5844
- const items = [
5845
- { value: "showcase", label: "Showcase", icon: /* @__PURE__ */ jsx(Palette, { className: "w-5 h-5" }), path: "/showcase", category: 5 },
5846
- { value: "admin-dashboard", label: "Admin Dashboard", icon: /* @__PURE__ */ jsx(Shield, { className: "w-5 h-5" }), path: "/admin/dashboard", category: 2 },
5847
- { value: "admin-users", label: "User Management", icon: /* @__PURE__ */ jsx(Users, { className: "w-5 h-5" }), path: "/admin/users", category: 3 },
5848
- { value: "admin-sales", label: "Sales Dashboard", icon: /* @__PURE__ */ jsx(TrendingUp, { className: "w-5 h-5" }), path: "/admin/sales", category: 4 },
5849
- { value: "entity-performance", label: "Performance Dashboard", icon: /* @__PURE__ */ jsx(BarChart3, { className: "w-5 h-5" }), path: "/entity/performance", category: 6 },
5850
- { value: "entity-management", label: "Entity Management", icon: /* @__PURE__ */ jsx(Database, { className: "w-5 h-5" }), path: "/entity/management", category: 7 },
5851
- { value: "entity-template", label: "Template Example", icon: /* @__PURE__ */ jsx(Layout, { className: "w-5 h-5" }), path: "/entity/template-example", category: 1 }
5852
- ];
5955
+ const items = getNavigationItems(navigation);
5853
5956
  const handleNavigation = (path) => {
5854
5957
  if (path.includes("?")) {
5855
5958
  const [basePath, query] = path.split("?");
@@ -5905,12 +6008,14 @@ const Sidebar = ({ className }) => {
5905
6008
  return /* @__PURE__ */ jsx(
5906
6009
  SidebarButton,
5907
6010
  {
5908
- icon: item.icon,
6011
+ icon: /* @__PURE__ */ jsx(Icon, { name: item.icon, className: "w-5 h-5" }),
5909
6012
  label: item.label,
5910
6013
  active: isActive,
5911
6014
  category: item.category,
5912
6015
  expanded: isExpanded,
5913
- onClick: () => handleNavigation(item.path)
6016
+ onClick: () => handleNavigation(item.path),
6017
+ badge: item.badge,
6018
+ disabled: item.disabled
5914
6019
  },
5915
6020
  item.value
5916
6021
  );
@@ -8010,1636 +8115,6 @@ const AdminDetailTemplate = ({
8010
8115
  ] }) }) })
8011
8116
  ] });
8012
8117
  };
8013
- const MetricsOverviewPanel = ({
8014
- metrics,
8015
- data,
8016
- previousData,
8017
- isLoading = false,
8018
- onMetricClick,
8019
- className,
8020
- layout = "grid",
8021
- columns = 4,
8022
- category,
8023
- renderCustomMetric,
8024
- renderHeader,
8025
- renderFooter,
8026
- headerSlot,
8027
- footerSlot
8028
- }) => {
8029
- const calculatedMetrics = React__default.useMemo(() => {
8030
- if (isLoading || !(data == null ? void 0 : data.length) || !(metrics == null ? void 0 : metrics.length)) return {};
8031
- return metrics.reduce((acc, metric) => {
8032
- acc[metric.key] = MetricCalculationEngine.calculateMetric(
8033
- metric,
8034
- data,
8035
- previousData
8036
- );
8037
- return acc;
8038
- }, {});
8039
- }, [metrics, data, previousData, isLoading]);
8040
- const getLayoutClasses = () => {
8041
- switch (layout) {
8042
- case "horizontal":
8043
- return "flex flex-wrap gap-4";
8044
- case "vertical":
8045
- return "flex flex-col gap-4";
8046
- case "grid":
8047
- default:
8048
- return cn(
8049
- "grid gap-4",
8050
- {
8051
- "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4": columns === 4,
8052
- "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3": columns === 3,
8053
- "grid-cols-1 sm:grid-cols-2": columns === 2
8054
- }
8055
- );
8056
- }
8057
- };
8058
- const renderMetricCard = (metric, index) => {
8059
- if (renderCustomMetric) {
8060
- const customContent = renderCustomMetric(metric, calculatedMetrics[metric.key], index);
8061
- if (customContent) return customContent;
8062
- }
8063
- const metricValue = calculatedMetrics[metric.key];
8064
- if (isLoading || !metricValue) {
8065
- return /* @__PURE__ */ jsx(
8066
- StatCard,
8067
- {
8068
- title: metric.label,
8069
- value: "",
8070
- isLoading: true,
8071
- category,
8072
- icon: metric.icon ? /* @__PURE__ */ jsx(metric.icon, {}) : void 0
8073
- },
8074
- metric.key
8075
- );
8076
- }
8077
- const trend = metricValue.trend !== "neutral" && metricValue.previous ? {
8078
- value: Number(((metricValue.current - metricValue.previous) / Math.abs(metricValue.previous) * 100).toFixed(1)),
8079
- label: "vs last period"
8080
- } : void 0;
8081
- const formatTargetValue = (value) => {
8082
- switch (metric.type) {
8083
- case "currency":
8084
- return new Intl.NumberFormat("en-US", {
8085
- style: "currency",
8086
- currency: "USD"
8087
- }).format(value);
8088
- case "percentage":
8089
- return `${value}%`;
8090
- default:
8091
- return value.toString();
8092
- }
8093
- };
8094
- const subtitle = metricValue.target ? `Target: ${formatTargetValue(metricValue.target)}` : void 0;
8095
- return /* @__PURE__ */ jsx(
8096
- StatCard,
8097
- {
8098
- title: metric.label,
8099
- value: metricValue.formattedValue,
8100
- subtitle,
8101
- trend,
8102
- category,
8103
- icon: metric.icon ? /* @__PURE__ */ jsx(metric.icon, {}) : void 0,
8104
- onClick: onMetricClick ? () => onMetricClick(metric, metricValue) : void 0,
8105
- valueTooltip: `Current: ${metricValue.formattedValue}${metricValue.previous ? ` | Previous: ${formatTargetValue(metricValue.previous)}` : ""}`,
8106
- iconTooltip: `View ${metric.label} details`
8107
- },
8108
- metric.key
8109
- );
8110
- };
8111
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), "data-component-name": "MetricsOverviewPanel", children: [
8112
- headerSlot,
8113
- renderHeader && renderHeader(),
8114
- /* @__PURE__ */ jsx("div", { className: getLayoutClasses(), children: metrics.map((metric, index) => renderMetricCard(metric, index)) }),
8115
- renderFooter && renderFooter(),
8116
- footerSlot
8117
- ] });
8118
- };
8119
- const MetricsOverviewWithInsightsPanel = ({
8120
- showInsights = true,
8121
- insightThresholds,
8122
- renderInsight,
8123
- ...props
8124
- }) => {
8125
- const safeMetrics = props.metrics || [];
8126
- const safeData = props.data || [];
8127
- const calculatedMetrics = React__default.useMemo(() => {
8128
- if (props.isLoading || !safeData.length || !safeMetrics.length) return {};
8129
- return safeMetrics.reduce((acc, metric) => {
8130
- acc[metric.key] = MetricCalculationEngine.calculateMetric(
8131
- metric,
8132
- safeData,
8133
- props.previousData
8134
- );
8135
- return acc;
8136
- }, {});
8137
- }, [safeMetrics, safeData, props.previousData, props.isLoading]);
8138
- const insights = React__default.useMemo(() => {
8139
- if (!showInsights || props.isLoading || Object.keys(calculatedMetrics).length === 0) {
8140
- return [];
8141
- }
8142
- return MetricCalculationEngine.detectInsights(calculatedMetrics, insightThresholds);
8143
- }, [calculatedMetrics, showInsights, insightThresholds, props.isLoading]);
8144
- const renderInsightsSection = () => {
8145
- if (!showInsights || insights.length === 0) return null;
8146
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8147
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Key Insights" }),
8148
- /* @__PURE__ */ jsx("div", { className: "space-y-1", children: insights.map((insight, index) => {
8149
- if (renderInsight) {
8150
- const customInsight = renderInsight(insight, index);
8151
- if (customInsight) return customInsight;
8152
- }
8153
- const colorClass = {
8154
- positive: "text-status-success",
8155
- negative: "text-status-error",
8156
- neutral: "text-muted-foreground"
8157
- }[insight.type];
8158
- return /* @__PURE__ */ jsxs(
8159
- "div",
8160
- {
8161
- className: cn("text-sm", colorClass),
8162
- children: [
8163
- "• ",
8164
- insight.message
8165
- ]
8166
- },
8167
- index
8168
- );
8169
- }) })
8170
- ] });
8171
- };
8172
- return /* @__PURE__ */ jsx(
8173
- MetricsOverviewPanel,
8174
- {
8175
- ...props,
8176
- footerSlot: /* @__PURE__ */ jsxs(Fragment, { children: [
8177
- renderInsightsSection(),
8178
- props.footerSlot
8179
- ] })
8180
- }
8181
- );
8182
- };
8183
- const EntityListPanel = ({
8184
- config,
8185
- data,
8186
- isLoading = false,
8187
- onRowClick,
8188
- onAction,
8189
- className,
8190
- columns: customColumns,
8191
- showSearch = true,
8192
- showPagination = true,
8193
- pageSize = 10,
8194
- searchPlaceholder,
8195
- enableSelection = false,
8196
- enableBulkActions = false,
8197
- enableExport = true,
8198
- enableFiltering = false,
8199
- enableRefresh = true,
8200
- renderToolbar,
8201
- renderBulkActions,
8202
- renderCustomColumn,
8203
- renderEmptyState,
8204
- headerSlot,
8205
- footerSlot,
8206
- onExport,
8207
- onRefresh
8208
- }) => {
8209
- const [selectedItems, setSelectedItems] = React__default.useState([]);
8210
- const [showFilters, setShowFilters] = React__default.useState(false);
8211
- const tableColumns = useMemo(() => {
8212
- if (customColumns) return customColumns;
8213
- const generatedColumns = [];
8214
- if (enableSelection) {
8215
- generatedColumns.push({
8216
- key: "__selection",
8217
- header: /* @__PURE__ */ jsx(
8218
- "input",
8219
- {
8220
- type: "checkbox",
8221
- checked: selectedItems.length === data.length && data.length > 0,
8222
- onChange: (e) => {
8223
- if (e.target.checked) {
8224
- setSelectedItems([...data]);
8225
- } else {
8226
- setSelectedItems([]);
8227
- }
8228
- }
8229
- }
8230
- ),
8231
- cell: (item) => /* @__PURE__ */ jsx(
8232
- "input",
8233
- {
8234
- type: "checkbox",
8235
- checked: selectedItems.some((selected) => selected.id === item.id),
8236
- onChange: (e) => {
8237
- if (e.target.checked) {
8238
- setSelectedItems((prev) => [...prev, item]);
8239
- } else {
8240
- setSelectedItems((prev) => prev.filter((selected) => selected.id !== item.id));
8241
- }
8242
- }
8243
- }
8244
- ),
8245
- sortable: false,
8246
- width: "50px"
8247
- });
8248
- }
8249
- if (data.length > 0) {
8250
- const sampleItem = data[0];
8251
- Object.keys(sampleItem).forEach((key) => {
8252
- if (key === "id") return;
8253
- const isStatus = key.toLowerCase().includes("status");
8254
- const isCategory = key.toLowerCase().includes("category") || key.toLowerCase().includes("type");
8255
- const isDate = key.toLowerCase().includes("date") || key.toLowerCase().includes("time");
8256
- const isAmount = key.toLowerCase().includes("amount") || key.toLowerCase().includes("price") || key.toLowerCase().includes("cost");
8257
- generatedColumns.push({
8258
- key,
8259
- header: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, " $1"),
8260
- type: isStatus ? "status" : isCategory ? "category" : "default",
8261
- sortable: true,
8262
- cell: renderCustomColumn ? (item) => {
8263
- const column = { key, header: "", type: isStatus ? "status" : isCategory ? "category" : "default" };
8264
- const customContent = renderCustomColumn(column, item);
8265
- if (customContent) return customContent;
8266
- const value = item[key];
8267
- if (isDate && value) {
8268
- return new Date(value).toLocaleDateString();
8269
- }
8270
- if (isAmount && typeof value === "number") {
8271
- return new Intl.NumberFormat("en-US", {
8272
- style: "currency",
8273
- currency: "USD"
8274
- }).format(value);
8275
- }
8276
- return (value == null ? void 0 : value.toString()) || "-";
8277
- } : void 0
8278
- });
8279
- });
8280
- }
8281
- return generatedColumns;
8282
- }, [customColumns, data, enableSelection, selectedItems, renderCustomColumn]);
8283
- const handleExport = () => {
8284
- if (onExport) {
8285
- onExport(selectedItems.length > 0 ? selectedItems : data);
8286
- } else {
8287
- const headers = tableColumns.filter((col) => col.key !== "__selection").map((col) => col.key);
8288
- const csvContent = [
8289
- headers.join(","),
8290
- ...(selectedItems.length > 0 ? selectedItems : data).map(
8291
- (item) => headers.map((header) => item[header] || "").join(",")
8292
- )
8293
- ].join("\n");
8294
- const blob = new Blob([csvContent], { type: "text/csv" });
8295
- const url = URL.createObjectURL(blob);
8296
- const a = document.createElement("a");
8297
- a.href = url;
8298
- a.download = `${config.display.title.toLowerCase().replace(/\s+/g, "-")}-export.csv`;
8299
- a.click();
8300
- URL.revokeObjectURL(url);
8301
- }
8302
- };
8303
- const renderToolbarSection = () => {
8304
- var _a;
8305
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4 mb-4", children: [
8306
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8307
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: config.display.title }),
8308
- config.display.description && /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "text-xs", children: [
8309
- data.length,
8310
- " items"
8311
- ] })
8312
- ] }),
8313
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8314
- renderToolbar && renderToolbar(),
8315
- enableFiltering && /* @__PURE__ */ jsxs(
8316
- Button,
8317
- {
8318
- variant: "outline",
8319
- size: "sm",
8320
- onClick: () => setShowFilters(!showFilters),
8321
- className: cn(showFilters && "bg-muted"),
8322
- children: [
8323
- /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4 mr-2" }),
8324
- "Filters"
8325
- ]
8326
- }
8327
- ),
8328
- enableRefresh && /* @__PURE__ */ jsxs(
8329
- Button,
8330
- {
8331
- variant: "outline",
8332
- size: "sm",
8333
- onClick: onRefresh,
8334
- disabled: isLoading,
8335
- children: [
8336
- /* @__PURE__ */ jsx(RefreshCw, { className: cn("w-4 h-4 mr-2", isLoading && "animate-spin") }),
8337
- "Refresh"
8338
- ]
8339
- }
8340
- ),
8341
- enableExport && /* @__PURE__ */ jsxs(
8342
- Button,
8343
- {
8344
- variant: "outline",
8345
- size: "sm",
8346
- onClick: handleExport,
8347
- disabled: data.length === 0,
8348
- children: [
8349
- /* @__PURE__ */ jsx(Download, { className: "w-4 h-4 mr-2" }),
8350
- "Export"
8351
- ]
8352
- }
8353
- ),
8354
- (_a = config.actions) == null ? void 0 : _a.filter((action) => action.type === "primary").map((action) => /* @__PURE__ */ jsxs(
8355
- Button,
8356
- {
8357
- size: "sm",
8358
- onClick: () => onAction == null ? void 0 : onAction(action, []),
8359
- disabled: isLoading,
8360
- children: [
8361
- action.icon && /* @__PURE__ */ jsx(action.icon, { className: "w-4 h-4 mr-2" }),
8362
- action.label
8363
- ]
8364
- },
8365
- action.label
8366
- ))
8367
- ] })
8368
- ] });
8369
- };
8370
- const renderBulkActionsSection = () => {
8371
- var _a;
8372
- if (!enableBulkActions || selectedItems.length === 0) return null;
8373
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between bg-muted/50 p-3 rounded-md mb-4", children: [
8374
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8375
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
8376
- selectedItems.length,
8377
- " items selected"
8378
- ] }),
8379
- /* @__PURE__ */ jsx(
8380
- Button,
8381
- {
8382
- variant: "ghost",
8383
- size: "sm",
8384
- onClick: () => setSelectedItems([]),
8385
- children: "Clear selection"
8386
- }
8387
- )
8388
- ] }),
8389
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8390
- renderBulkActions && renderBulkActions(selectedItems),
8391
- (_a = config.actions) == null ? void 0 : _a.filter((action) => action.type !== "primary").map((action) => /* @__PURE__ */ jsxs(
8392
- Button,
8393
- {
8394
- variant: action.type === "danger" ? "destructive" : "outline",
8395
- size: "sm",
8396
- onClick: () => onAction == null ? void 0 : onAction(action, selectedItems),
8397
- children: [
8398
- action.icon && /* @__PURE__ */ jsx(action.icon, { className: "w-4 h-4 mr-2" }),
8399
- action.label
8400
- ]
8401
- },
8402
- action.label
8403
- ))
8404
- ] })
8405
- ] });
8406
- };
8407
- const renderEmptyStateSection = () => {
8408
- var _a;
8409
- if (data.length > 0) return null;
8410
- if (renderEmptyState) {
8411
- return renderEmptyState();
8412
- }
8413
- return /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
8414
- /* @__PURE__ */ jsxs("div", { className: "text-muted-foreground mb-4", children: [
8415
- "No ",
8416
- config.display.title.toLowerCase(),
8417
- " found"
8418
- ] }),
8419
- ((_a = config.actions) == null ? void 0 : _a.find((action) => action.type === "primary")) && /* @__PURE__ */ jsxs(Button, { onClick: () => {
8420
- var _a2;
8421
- const primaryAction = (_a2 = config.actions) == null ? void 0 : _a2.find((action) => action.type === "primary");
8422
- if (primaryAction) onAction == null ? void 0 : onAction(primaryAction, []);
8423
- }, children: [
8424
- /* @__PURE__ */ jsx(Plus, { className: "w-4 h-4 mr-2" }),
8425
- "Add ",
8426
- config.display.title.slice(0, -1)
8427
- ] })
8428
- ] });
8429
- };
8430
- return /* @__PURE__ */ jsxs(Card, { className: cn("p-6", className), category: config.display.category, "data-component-name": "EntityListPanel", children: [
8431
- headerSlot,
8432
- renderToolbarSection(),
8433
- renderBulkActionsSection(),
8434
- data.length === 0 ? renderEmptyStateSection() : /* @__PURE__ */ jsx(
8435
- DataTable,
8436
- {
8437
- data,
8438
- columns: tableColumns,
8439
- isLoading,
8440
- showSearch,
8441
- showPagination,
8442
- pageSize,
8443
- searchPlaceholder: searchPlaceholder || `Search ${config.display.title.toLowerCase()}...`,
8444
- onRowClick,
8445
- hover: !!onRowClick,
8446
- emptyMessage: `No ${config.display.title.toLowerCase()} found`
8447
- }
8448
- ),
8449
- footerSlot
8450
- ] });
8451
- };
8452
- const TrendAnalysisPanel = ({
8453
- metrics,
8454
- data,
8455
- temporal,
8456
- isLoading = false,
8457
- className,
8458
- category,
8459
- defaultChartType = "line",
8460
- dateField = "date",
8461
- enablePeriodSelection = true,
8462
- enableChartTypeSelection = true,
8463
- enableMetricSelection = true,
8464
- showComparisons = true,
8465
- renderHeader,
8466
- renderFooter,
8467
- renderCustomChart,
8468
- headerSlot,
8469
- footerSlot,
8470
- onMetricChange,
8471
- onPeriodChange,
8472
- onChartTypeChange,
8473
- onExport
8474
- }) => {
8475
- const [selectedMetric, setSelectedMetric] = useState(metrics[0]);
8476
- const [selectedPeriod, setSelectedPeriod] = useState((temporal == null ? void 0 : temporal.defaultCycle) || "monthly");
8477
- const [selectedChartType, setSelectedChartType] = useState(defaultChartType);
8478
- const [showForecast, setShowForecast] = useState(false);
8479
- const trendData = useMemo(() => {
8480
- if (!selectedMetric || !data.length) return [];
8481
- const periods = selectedPeriod === "yearly" ? 5 : selectedPeriod === "quarterly" ? 8 : selectedPeriod === "monthly" ? 12 : selectedPeriod === "weekly" ? 12 : 30;
8482
- return MetricCalculationEngine.calculateTrendData(
8483
- selectedMetric,
8484
- data,
8485
- dateField,
8486
- periods
8487
- );
8488
- }, [selectedMetric, data, dateField, selectedPeriod]);
8489
- const chartData = useMemo(() => {
8490
- return trendData.map((point) => ({
8491
- label: point.label || point.date,
8492
- value: point.value,
8493
- category
8494
- }));
8495
- }, [trendData, category]);
8496
- const trendPercentage = useMemo(() => {
8497
- if (chartData.length < 2) return null;
8498
- const first = chartData[0].value;
8499
- const last = chartData[chartData.length - 1].value;
8500
- if (first === 0) return null;
8501
- return (last - first) / Math.abs(first) * 100;
8502
- }, [chartData]);
8503
- const forecastData = useMemo(() => {
8504
- var _a, _b;
8505
- if (!showForecast || !((_a = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _a.enabled) || chartData.length < 3) {
8506
- return [];
8507
- }
8508
- const periods = ((_b = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _b.periods) || 3;
8509
- const lastValue = chartData[chartData.length - 1].value;
8510
- const trend = trendPercentage ? trendPercentage / 100 : 0;
8511
- return Array.from({ length: periods }, (_, index) => ({
8512
- label: `Future ${index + 1}`,
8513
- value: lastValue * (1 + trend * (index + 1) / chartData.length),
8514
- category: 8
8515
- // Use category 8 for forecast
8516
- }));
8517
- }, [showForecast, temporal == null ? void 0 : temporal.forecasting, chartData, trendPercentage]);
8518
- const combinedChartData = useMemo(() => {
8519
- if (forecastData.length === 0) return chartData;
8520
- return [...chartData, ...forecastData];
8521
- }, [chartData, forecastData]);
8522
- const handleMetricChange = (metricKey) => {
8523
- const metric = metrics.find((m) => m.key === metricKey);
8524
- if (metric) {
8525
- setSelectedMetric(metric);
8526
- onMetricChange == null ? void 0 : onMetricChange(metric);
8527
- }
8528
- };
8529
- const handlePeriodChange = (period) => {
8530
- setSelectedPeriod(period);
8531
- onPeriodChange == null ? void 0 : onPeriodChange(period);
8532
- };
8533
- const handleChartTypeChange = (chartType) => {
8534
- setSelectedChartType(chartType);
8535
- onChartTypeChange == null ? void 0 : onChartTypeChange(chartType);
8536
- };
8537
- const handleExport = () => {
8538
- if (onExport) {
8539
- onExport(combinedChartData, selectedMetric);
8540
- } else {
8541
- const csvContent = [
8542
- "Date,Value",
8543
- ...combinedChartData.map((point) => `${point.label},${point.value}`)
8544
- ].join("\n");
8545
- const blob = new Blob([csvContent], { type: "text/csv" });
8546
- const url = URL.createObjectURL(blob);
8547
- const a = document.createElement("a");
8548
- a.href = url;
8549
- a.download = `${selectedMetric.label}-trend-data.csv`;
8550
- a.click();
8551
- URL.revokeObjectURL(url);
8552
- }
8553
- };
8554
- const renderControls = () => {
8555
- var _a;
8556
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
8557
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
8558
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8559
- /* @__PURE__ */ jsx(TrendingUp, { className: "w-4 h-4 text-muted-foreground" }),
8560
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: "Trend Analysis" })
8561
- ] }),
8562
- trendPercentage !== null && /* @__PURE__ */ jsxs(Badge, { variant: trendPercentage > 0 ? "default" : "destructive", children: [
8563
- trendPercentage > 0 ? "+" : "",
8564
- trendPercentage.toFixed(1),
8565
- "%"
8566
- ] })
8567
- ] }),
8568
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8569
- enableMetricSelection && metrics.length > 1 && /* @__PURE__ */ jsx(
8570
- Select,
8571
- {
8572
- value: selectedMetric.key,
8573
- onValueChange: handleMetricChange,
8574
- children: metrics.map((metric) => /* @__PURE__ */ jsx("option", { value: metric.key, children: metric.label }, metric.key))
8575
- }
8576
- ),
8577
- enablePeriodSelection && /* @__PURE__ */ jsx(
8578
- Select,
8579
- {
8580
- value: selectedPeriod,
8581
- onValueChange: (value) => handlePeriodChange(value),
8582
- children: ((temporal == null ? void 0 : temporal.cycles) || ["daily", "weekly", "monthly", "quarterly", "yearly"]).map((cycle) => /* @__PURE__ */ jsx("option", { value: cycle, children: cycle.charAt(0).toUpperCase() + cycle.slice(1) }, cycle))
8583
- }
8584
- ),
8585
- enableChartTypeSelection && /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded", children: [
8586
- /* @__PURE__ */ jsx(
8587
- Button,
8588
- {
8589
- variant: selectedChartType === "line" ? "default" : "ghost",
8590
- size: "sm",
8591
- onClick: () => handleChartTypeChange("line"),
8592
- children: /* @__PURE__ */ jsx(LineChart, { className: "w-4 h-4" })
8593
- }
8594
- ),
8595
- /* @__PURE__ */ jsx(
8596
- Button,
8597
- {
8598
- variant: selectedChartType === "bar" ? "default" : "ghost",
8599
- size: "sm",
8600
- onClick: () => handleChartTypeChange("bar"),
8601
- children: /* @__PURE__ */ jsx(BarChart3, { className: "w-4 h-4" })
8602
- }
8603
- ),
8604
- /* @__PURE__ */ jsx(
8605
- Button,
8606
- {
8607
- variant: selectedChartType === "area" ? "default" : "ghost",
8608
- size: "sm",
8609
- onClick: () => handleChartTypeChange("area"),
8610
- children: /* @__PURE__ */ jsx(AreaChart, { className: "w-4 h-4" })
8611
- }
8612
- )
8613
- ] }),
8614
- ((_a = temporal == null ? void 0 : temporal.forecasting) == null ? void 0 : _a.enabled) && /* @__PURE__ */ jsx(
8615
- Button,
8616
- {
8617
- variant: showForecast ? "default" : "outline",
8618
- size: "sm",
8619
- onClick: () => setShowForecast(!showForecast),
8620
- children: "Forecast"
8621
- }
8622
- ),
8623
- /* @__PURE__ */ jsx(
8624
- Button,
8625
- {
8626
- variant: "outline",
8627
- size: "sm",
8628
- onClick: handleExport,
8629
- disabled: chartData.length === 0,
8630
- children: /* @__PURE__ */ jsx(Download, { className: "w-4 h-4" })
8631
- }
8632
- )
8633
- ] })
8634
- ] });
8635
- };
8636
- const renderChart = () => {
8637
- if (renderCustomChart) {
8638
- const customChart = renderCustomChart(selectedMetric, combinedChartData, selectedChartType);
8639
- if (customChart) return customChart;
8640
- }
8641
- return /* @__PURE__ */ jsx(
8642
- Chart,
8643
- {
8644
- title: selectedMetric.label,
8645
- subtitle: `${selectedPeriod} trend analysis`,
8646
- data: combinedChartData,
8647
- type: selectedChartType,
8648
- category,
8649
- showTrend: true,
8650
- trend: trendPercentage !== null ? {
8651
- value: trendPercentage,
8652
- label: "overall trend"
8653
- } : void 0,
8654
- height: "large",
8655
- isLoading,
8656
- noWrapper: true,
8657
- showLegend: forecastData.length > 0
8658
- }
8659
- );
8660
- };
8661
- const renderComparisons = () => {
8662
- var _a, _b;
8663
- if (!showComparisons || !(temporal == null ? void 0 : temporal.enableComparisons) || chartData.length === 0) {
8664
- return null;
8665
- }
8666
- const currentValue = ((_a = chartData[chartData.length - 1]) == null ? void 0 : _a.value) || 0;
8667
- const previousValue = ((_b = chartData[chartData.length - 2]) == null ? void 0 : _b.value) || 0;
8668
- const periodChange = previousValue !== 0 ? (currentValue - previousValue) / Math.abs(previousValue) * 100 : 0;
8669
- return /* @__PURE__ */ jsxs("div", { className: "border-t pt-4 mt-4", children: [
8670
- /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Period Comparisons" }),
8671
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-4", children: [
8672
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
8673
- /* @__PURE__ */ jsx("div", { className: "text-2xl font-bold", children: currentValue.toFixed(0) }),
8674
- /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Current" })
8675
- ] }),
8676
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
8677
- /* @__PURE__ */ jsx("div", { className: "text-2xl font-bold", children: previousValue.toFixed(0) }),
8678
- /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Previous" })
8679
- ] }),
8680
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
8681
- /* @__PURE__ */ jsxs("div", { className: cn(
8682
- "text-2xl font-bold",
8683
- periodChange > 0 ? "text-status-success" : periodChange < 0 ? "text-status-error" : "text-muted-foreground"
8684
- ), children: [
8685
- periodChange > 0 ? "+" : "",
8686
- periodChange.toFixed(1),
8687
- "%"
8688
- ] }),
8689
- /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Change" })
8690
- ] })
8691
- ] })
8692
- ] });
8693
- };
8694
- return /* @__PURE__ */ jsxs(Card, { className: cn("p-6", className), category, "data-component-name": "TrendAnalysisPanel", children: [
8695
- headerSlot,
8696
- renderHeader && renderHeader(),
8697
- renderControls(),
8698
- renderChart(),
8699
- renderComparisons(),
8700
- renderFooter && renderFooter(),
8701
- footerSlot
8702
- ] });
8703
- };
8704
- const CategoryBreakdownPanel = ({
8705
- data,
8706
- categoryConfig,
8707
- valueField,
8708
- isLoading = false,
8709
- className,
8710
- category,
8711
- title = "Category Breakdown",
8712
- subtitle,
8713
- defaultView = "both",
8714
- defaultChartType = "pie",
8715
- maxCategories = 8,
8716
- showPercentages = true,
8717
- enableDrillDown = true,
8718
- renderHeader,
8719
- renderFooter,
8720
- renderCustomCategory,
8721
- renderDrillDownContent,
8722
- headerSlot,
8723
- footerSlot,
8724
- onCategoryClick,
8725
- onDrillDown,
8726
- onExport
8727
- }) => {
8728
- const [currentView, setCurrentView] = useState(defaultView);
8729
- const [chartType, setChartType] = useState(defaultChartType);
8730
- const [expandedCategories, setExpandedCategories] = useState(/* @__PURE__ */ new Set());
8731
- const [drillDownLevel, setDrillDownLevel] = useState(0);
8732
- const [drillDownPath, setDrillDownPath] = useState([]);
8733
- const categoryBreakdown = useMemo(() => {
8734
- var _a;
8735
- if (!data.length) return [];
8736
- const currentCategoryField = ((_a = categoryConfig == null ? void 0 : categoryConfig.hierarchy) == null ? void 0 : _a[drillDownLevel]) || (categoryConfig == null ? void 0 : categoryConfig.defaultGroupBy) || "category";
8737
- return MetricCalculationEngine.calculateCategoryBreakdown(
8738
- data,
8739
- currentCategoryField,
8740
- valueField,
8741
- maxCategories
8742
- );
8743
- }, [data, categoryConfig, valueField, maxCategories, drillDownLevel]);
8744
- const chartData = useMemo(() => {
8745
- return categoryBreakdown.map((item, index) => ({
8746
- label: item.category,
8747
- value: item.value,
8748
- category: index % 8 + 1
8749
- }));
8750
- }, [categoryBreakdown]);
8751
- const totalValue = useMemo(() => {
8752
- return categoryBreakdown.reduce((sum, item) => sum + item.value, 0);
8753
- }, [categoryBreakdown]);
8754
- const handleCategoryClick = (categoryItem) => {
8755
- var _a;
8756
- onCategoryClick == null ? void 0 : onCategoryClick(categoryItem);
8757
- if (enableDrillDown && (categoryConfig == null ? void 0 : categoryConfig.enableDrillDown) && drillDownLevel < (((_a = categoryConfig == null ? void 0 : categoryConfig.hierarchy) == null ? void 0 : _a.length) || 0) - 1) {
8758
- setDrillDownLevel((prev) => prev + 1);
8759
- setDrillDownPath((prev) => [...prev, categoryItem.category]);
8760
- onDrillDown == null ? void 0 : onDrillDown(categoryItem.category, drillDownLevel + 1);
8761
- }
8762
- };
8763
- const handleDrillUp = (level) => {
8764
- if (level < drillDownLevel) {
8765
- setDrillDownLevel(level);
8766
- setDrillDownPath((prev) => prev.slice(0, level));
8767
- onDrillDown == null ? void 0 : onDrillDown(level > 0 ? drillDownPath[level - 1] : "", level);
8768
- }
8769
- };
8770
- const toggleCategoryExpansion = (categoryName) => {
8771
- setExpandedCategories((prev) => {
8772
- const newSet = new Set(prev);
8773
- if (newSet.has(categoryName)) {
8774
- newSet.delete(categoryName);
8775
- } else {
8776
- newSet.add(categoryName);
8777
- }
8778
- return newSet;
8779
- });
8780
- };
8781
- const handleExport = () => {
8782
- if (onExport) {
8783
- onExport(categoryBreakdown);
8784
- } else {
8785
- const csvContent = [
8786
- "Category,Value,Percentage",
8787
- ...categoryBreakdown.map(
8788
- (item) => `${item.category},${item.value},${item.percentage.toFixed(2)}%`
8789
- )
8790
- ].join("\n");
8791
- const blob = new Blob([csvContent], { type: "text/csv" });
8792
- const url = URL.createObjectURL(blob);
8793
- const a = document.createElement("a");
8794
- a.href = url;
8795
- a.download = `category-breakdown-${Date.now()}.csv`;
8796
- a.click();
8797
- URL.revokeObjectURL(url);
8798
- }
8799
- };
8800
- const renderControls = () => {
8801
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
8802
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
8803
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8804
- /* @__PURE__ */ jsx(PieChart, { className: "w-4 h-4 text-muted-foreground" }),
8805
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: title })
8806
- ] }),
8807
- subtitle && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs", children: subtitle }),
8808
- totalValue > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "outline", children: [
8809
- "Total: ",
8810
- new Intl.NumberFormat().format(totalValue)
8811
- ] })
8812
- ] }),
8813
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8814
- /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded", children: [
8815
- /* @__PURE__ */ jsx(
8816
- Button,
8817
- {
8818
- variant: currentView === "chart" ? "default" : "ghost",
8819
- size: "sm",
8820
- onClick: () => setCurrentView("chart"),
8821
- children: /* @__PURE__ */ jsx(PieChart, { className: "w-4 h-4" })
8822
- }
8823
- ),
8824
- /* @__PURE__ */ jsx(
8825
- Button,
8826
- {
8827
- variant: currentView === "list" ? "default" : "ghost",
8828
- size: "sm",
8829
- onClick: () => setCurrentView("list"),
8830
- children: /* @__PURE__ */ jsx(List, { className: "w-4 h-4" })
8831
- }
8832
- ),
8833
- /* @__PURE__ */ jsx(
8834
- Button,
8835
- {
8836
- variant: currentView === "both" ? "default" : "ghost",
8837
- size: "sm",
8838
- onClick: () => setCurrentView("both"),
8839
- children: "Both"
8840
- }
8841
- )
8842
- ] }),
8843
- (currentView === "chart" || currentView === "both") && /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded", children: [
8844
- /* @__PURE__ */ jsx(
8845
- Button,
8846
- {
8847
- variant: chartType === "pie" ? "default" : "ghost",
8848
- size: "sm",
8849
- onClick: () => setChartType("pie"),
8850
- children: /* @__PURE__ */ jsx(PieChart, { className: "w-4 h-4" })
8851
- }
8852
- ),
8853
- /* @__PURE__ */ jsx(
8854
- Button,
8855
- {
8856
- variant: chartType === "bar" ? "default" : "ghost",
8857
- size: "sm",
8858
- onClick: () => setChartType("bar"),
8859
- children: /* @__PURE__ */ jsx(BarChart3, { className: "w-4 h-4" })
8860
- }
8861
- )
8862
- ] }),
8863
- /* @__PURE__ */ jsx(
8864
- Button,
8865
- {
8866
- variant: "outline",
8867
- size: "sm",
8868
- onClick: handleExport,
8869
- disabled: categoryBreakdown.length === 0,
8870
- children: /* @__PURE__ */ jsx(Download, { className: "w-4 h-4" })
8871
- }
8872
- )
8873
- ] })
8874
- ] });
8875
- };
8876
- const renderBreadcrumb = () => {
8877
- if (drillDownLevel === 0) return null;
8878
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-4 text-sm text-muted-foreground", children: [
8879
- /* @__PURE__ */ jsx(
8880
- Button,
8881
- {
8882
- variant: "ghost",
8883
- size: "sm",
8884
- onClick: () => handleDrillUp(0),
8885
- className: "p-0 h-auto font-normal",
8886
- children: "All"
8887
- }
8888
- ),
8889
- drillDownPath.map((segment, index) => /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
8890
- /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3" }),
8891
- /* @__PURE__ */ jsx(
8892
- Button,
8893
- {
8894
- variant: "ghost",
8895
- size: "sm",
8896
- onClick: () => handleDrillUp(index + 1),
8897
- className: "p-0 h-auto font-normal",
8898
- children: segment
8899
- }
8900
- )
8901
- ] }, index))
8902
- ] });
8903
- };
8904
- const renderChart = () => {
8905
- if (currentView === "list") return null;
8906
- return /* @__PURE__ */ jsx("div", { className: cn(currentView === "both" && "mb-6"), children: /* @__PURE__ */ jsx(
8907
- Chart,
8908
- {
8909
- title: "",
8910
- data: chartData,
8911
- type: chartType,
8912
- category,
8913
- showLegend: true,
8914
- height: "medium",
8915
- isLoading,
8916
- noWrapper: true,
8917
- onClick: () => {
8918
- }
8919
- }
8920
- ) });
8921
- };
8922
- const renderCategoryList = () => {
8923
- if (currentView === "chart") return null;
8924
- return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: categoryBreakdown.map((item, index) => {
8925
- if (renderCustomCategory) {
8926
- const customContent = renderCustomCategory(item, index);
8927
- if (customContent) return customContent;
8928
- }
8929
- const canExpand = enableDrillDown && categoryConfig.enableDrillDown && "subcategories" in item && item.subcategories && Array.isArray(item.subcategories) && item.subcategories.length > 0;
8930
- const isExpanded = expandedCategories.has(item.category);
8931
- return /* @__PURE__ */ jsxs("div", { className: "border rounded-lg", children: [
8932
- /* @__PURE__ */ jsxs(
8933
- "div",
8934
- {
8935
- className: cn(
8936
- "flex items-center justify-between p-3 cursor-pointer hover:bg-muted/50",
8937
- canExpand && "cursor-pointer"
8938
- ),
8939
- onClick: () => handleCategoryClick(item),
8940
- children: [
8941
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
8942
- canExpand && /* @__PURE__ */ jsx(
8943
- Button,
8944
- {
8945
- variant: "ghost",
8946
- size: "sm",
8947
- className: "p-0 w-4 h-4",
8948
- onClick: (e) => {
8949
- e.stopPropagation();
8950
- toggleCategoryExpansion(item.category);
8951
- },
8952
- children: isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3" })
8953
- }
8954
- ),
8955
- /* @__PURE__ */ jsx(
8956
- DataBadge,
8957
- {
8958
- variant: "category",
8959
- category: index % 8 + 1,
8960
- size: "sm",
8961
- children: item.category
8962
- }
8963
- )
8964
- ] }),
8965
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
8966
- /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
8967
- /* @__PURE__ */ jsx("div", { className: "font-semibold", children: new Intl.NumberFormat().format(item.value) }),
8968
- showPercentages && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
8969
- item.percentage.toFixed(1),
8970
- "%"
8971
- ] })
8972
- ] }),
8973
- /* @__PURE__ */ jsx("div", { className: "w-20 h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
8974
- "div",
8975
- {
8976
- className: cn(
8977
- "h-full transition-all duration-300",
8978
- `bg-category-${index % 8 + 1}`
8979
- ),
8980
- style: { width: `${item.percentage}%` }
8981
- }
8982
- ) })
8983
- ] })
8984
- ]
8985
- }
8986
- ),
8987
- canExpand && isExpanded && "subcategories" in item && item.subcategories && /* @__PURE__ */ jsx("div", { className: "border-t bg-muted/20", children: renderDrillDownContent ? renderDrillDownContent(item.category, item.subcategories) : /* @__PURE__ */ jsx("div", { className: "p-3 space-y-1", children: Array.isArray(item.subcategories) && item.subcategories.map((subItem) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm pl-4", children: [
8988
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: subItem.category }),
8989
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: new Intl.NumberFormat().format(subItem.value) })
8990
- ] }, subItem.category)) }) })
8991
- ] }, item.category);
8992
- }) });
8993
- };
8994
- const renderEmptyState = () => {
8995
- if (categoryBreakdown.length > 0) return null;
8996
- return /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
8997
- /* @__PURE__ */ jsx(Filter, { className: "w-8 h-8 text-muted-foreground mx-auto mb-4" }),
8998
- /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: "No category data available" })
8999
- ] });
9000
- };
9001
- return /* @__PURE__ */ jsxs(Card, { className: cn("p-6", className), category, "data-component-name": "CategoryBreakdownPanel", children: [
9002
- headerSlot,
9003
- renderHeader && renderHeader(),
9004
- renderControls(),
9005
- renderBreadcrumb(),
9006
- categoryBreakdown.length === 0 ? renderEmptyState() : /* @__PURE__ */ jsxs(Fragment, { children: [
9007
- renderChart(),
9008
- renderCategoryList()
9009
- ] }),
9010
- renderFooter && renderFooter(),
9011
- footerSlot
9012
- ] });
9013
- };
9014
- const EntityPerformanceDashboardTemplate = ({
9015
- config,
9016
- data,
9017
- previousData,
9018
- isLoading = false,
9019
- className,
9020
- layout = "standard",
9021
- showInsights = true,
9022
- showTrends = true,
9023
- showCategories = true,
9024
- renderCustomActions,
9025
- renderAdditionalMetrics,
9026
- renderCustomTrendChart,
9027
- renderCustomCategoryView,
9028
- headerSlot,
9029
- footerSlot,
9030
- metricsHeaderSlot,
9031
- metricsFooterSlot,
9032
- trendsHeaderSlot,
9033
- trendsFooterSlot,
9034
- categoriesHeaderSlot,
9035
- categoriesFooterSlot,
9036
- onMetricClick,
9037
- onCategoryClick,
9038
- onTrendPeriodChange,
9039
- onExport
9040
- }) => {
9041
- const getLayoutClasses = () => {
9042
- switch (layout) {
9043
- case "compact":
9044
- return "space-y-4";
9045
- case "detailed":
9046
- return "space-y-8";
9047
- case "standard":
9048
- default:
9049
- return "space-y-6";
9050
- }
9051
- };
9052
- const renderPageHeader = () => {
9053
- return /* @__PURE__ */ jsx(
9054
- SectionHeader,
9055
- {
9056
- title: config.display.title,
9057
- description: config.display.description,
9058
- category: config.display.category,
9059
- actions: renderCustomActions ? renderCustomActions() : void 0
9060
- }
9061
- );
9062
- };
9063
- const renderMetricsSection = () => {
9064
- if (!config.metrics.length) return null;
9065
- const MetricsComponent = showInsights ? MetricsOverviewWithInsightsPanel : MetricsOverviewPanel;
9066
- return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9067
- metricsHeaderSlot,
9068
- /* @__PURE__ */ jsx(
9069
- MetricsComponent,
9070
- {
9071
- metrics: config.metrics,
9072
- data,
9073
- previousData,
9074
- isLoading,
9075
- onMetricClick,
9076
- category: config.display.category,
9077
- columns: layout === "compact" ? 2 : layout === "detailed" ? 4 : 3,
9078
- headerSlot: renderAdditionalMetrics ? renderAdditionalMetrics() : void 0
9079
- }
9080
- ),
9081
- metricsFooterSlot
9082
- ] });
9083
- };
9084
- const renderTrendsSection = () => {
9085
- if (!showTrends || !config.temporal || !config.metrics.length) return null;
9086
- if (renderCustomTrendChart) {
9087
- const customChart = renderCustomTrendChart(config, data);
9088
- if (customChart) {
9089
- return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9090
- trendsHeaderSlot,
9091
- customChart,
9092
- trendsFooterSlot
9093
- ] });
9094
- }
9095
- }
9096
- return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9097
- trendsHeaderSlot,
9098
- /* @__PURE__ */ jsx(
9099
- TrendAnalysisPanel,
9100
- {
9101
- metrics: config.metrics,
9102
- data,
9103
- temporal: config.temporal,
9104
- isLoading,
9105
- category: config.display.category,
9106
- enablePeriodSelection: true,
9107
- enableChartTypeSelection: layout === "detailed",
9108
- showComparisons: layout !== "compact",
9109
- onPeriodChange: onTrendPeriodChange,
9110
- onExport: (chartData, metric) => onExport == null ? void 0 : onExport("trends", { chartData, metric })
9111
- }
9112
- ),
9113
- trendsFooterSlot
9114
- ] });
9115
- };
9116
- const renderCategoriesSection = () => {
9117
- var _a;
9118
- if (!showCategories || !config.categories || !data.length) return null;
9119
- 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";
9120
- if (renderCustomCategoryView) {
9121
- const customView = renderCustomCategoryView(config, data);
9122
- if (customView) {
9123
- return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9124
- categoriesHeaderSlot,
9125
- customView,
9126
- categoriesFooterSlot
9127
- ] });
9128
- }
9129
- }
9130
- return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9131
- categoriesHeaderSlot,
9132
- /* @__PURE__ */ jsx(
9133
- CategoryBreakdownPanel,
9134
- {
9135
- data,
9136
- categoryConfig: config.categories,
9137
- valueField,
9138
- isLoading,
9139
- category: config.display.category,
9140
- title: `${config.display.title} by ${config.categories.defaultGroupBy}`,
9141
- defaultView: layout === "compact" ? "list" : "both",
9142
- enableDrillDown: config.categories.enableDrillDown,
9143
- onCategoryClick,
9144
- onExport: (categoryData) => onExport == null ? void 0 : onExport("categories", categoryData)
9145
- }
9146
- ),
9147
- categoriesFooterSlot
9148
- ] });
9149
- };
9150
- const renderLayoutContent = () => {
9151
- const sections = [
9152
- renderMetricsSection(),
9153
- renderTrendsSection(),
9154
- renderCategoriesSection()
9155
- ].filter(Boolean);
9156
- if (layout === "detailed" && sections.length > 1) {
9157
- const [metricsSection, ...otherSections] = sections;
9158
- return /* @__PURE__ */ jsxs("div", { className: getLayoutClasses(), children: [
9159
- metricsSection,
9160
- otherSections.length > 0 && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: otherSections })
9161
- ] });
9162
- }
9163
- return /* @__PURE__ */ jsx("div", { className: getLayoutClasses(), children: sections });
9164
- };
9165
- return /* @__PURE__ */ jsx(AppLayout, { children: /* @__PURE__ */ jsxs(
9166
- PageTemplate,
9167
- {
9168
- className: cn("container mx-auto px-4 py-6", className),
9169
- "data-component-name": "EntityPerformanceDashboardTemplate",
9170
- children: [
9171
- headerSlot,
9172
- renderPageHeader(),
9173
- renderLayoutContent(),
9174
- footerSlot
9175
- ]
9176
- }
9177
- ) });
9178
- };
9179
- const EntityPerformanceDashboardTemplateWithRealTime = ({
9180
- enableRealTime = false,
9181
- refreshInterval = 3e4,
9182
- // 30 seconds
9183
- onDataUpdate,
9184
- ...props
9185
- }) => {
9186
- React__default.useEffect(() => {
9187
- if (!enableRealTime) return;
9188
- const interval = setInterval(() => {
9189
- if (onDataUpdate) {
9190
- onDataUpdate(props.data);
9191
- }
9192
- }, refreshInterval);
9193
- return () => clearInterval(interval);
9194
- }, [enableRealTime, refreshInterval, onDataUpdate, props.data]);
9195
- return /* @__PURE__ */ jsx(EntityPerformanceDashboardTemplate, { ...props });
9196
- };
9197
- const EntityManagementTemplate = ({
9198
- config,
9199
- data,
9200
- isLoading = false,
9201
- className,
9202
- enableSearch = true,
9203
- enableFiltering = true,
9204
- enableBulkActions = true,
9205
- enableExport = true,
9206
- pageSize = 10,
9207
- onCreate,
9208
- onUpdate,
9209
- onDelete,
9210
- onBulkDelete,
9211
- onView,
9212
- renderCreateForm,
9213
- renderEditForm,
9214
- renderDetailView,
9215
- renderCustomActions,
9216
- renderEmptyState,
9217
- renderFilterPanel,
9218
- headerSlot,
9219
- footerSlot,
9220
- toolbarSlot,
9221
- listHeaderSlot,
9222
- listFooterSlot,
9223
- onRefresh,
9224
- onFilter,
9225
- onExport
9226
- }) => {
9227
- const [showCreateModal, setShowCreateModal] = useState(false);
9228
- const [showEditModal, setShowEditModal] = useState(false);
9229
- const [showDetailModal, setShowDetailModal] = useState(false);
9230
- const [showFilterPanel, setShowFilterPanel] = useState(false);
9231
- const [selectedItem, setSelectedItem] = useState(null);
9232
- const [selectedItems, setSelectedItems] = useState([]);
9233
- const handleCreate = async (item) => {
9234
- if (onCreate) {
9235
- try {
9236
- await onCreate(item);
9237
- setShowCreateModal(false);
9238
- onRefresh == null ? void 0 : onRefresh();
9239
- } catch (error) {
9240
- console.error("Create failed:", error);
9241
- }
9242
- }
9243
- };
9244
- const handleUpdate = async (item) => {
9245
- if (onUpdate && selectedItem) {
9246
- try {
9247
- await onUpdate(selectedItem.id, item);
9248
- setShowEditModal(false);
9249
- setSelectedItem(null);
9250
- onRefresh == null ? void 0 : onRefresh();
9251
- } catch (error) {
9252
- console.error("Update failed:", error);
9253
- }
9254
- }
9255
- };
9256
- const handleBulkDelete = async () => {
9257
- if (onBulkDelete && selectedItems.length > 0 && confirm(`Are you sure you want to delete ${selectedItems.length} ${config.display.title.toLowerCase()}?`)) {
9258
- try {
9259
- const ids = selectedItems.map((item) => item.id);
9260
- await onBulkDelete(ids);
9261
- setSelectedItems([]);
9262
- onRefresh == null ? void 0 : onRefresh();
9263
- } catch (error) {
9264
- console.error("Bulk delete failed:", error);
9265
- }
9266
- }
9267
- };
9268
- const handleView = (item) => {
9269
- if (onView) {
9270
- onView(item);
9271
- } else {
9272
- setSelectedItem(item);
9273
- setShowDetailModal(true);
9274
- }
9275
- };
9276
- const handleEdit = (item) => {
9277
- setSelectedItem(item);
9278
- setShowEditModal(true);
9279
- };
9280
- const handleRowClick = (item) => {
9281
- handleView(item);
9282
- };
9283
- const handleAction = (action, selectedItems2) => {
9284
- action.onClick({ selectedItems: selectedItems2, config });
9285
- };
9286
- const generateDefaultActions = () => {
9287
- const actions = [];
9288
- if (onCreate) {
9289
- actions.push({
9290
- label: `Add ${config.display.title.slice(0, -1)}`,
9291
- type: "primary",
9292
- icon: Plus,
9293
- onClick: () => setShowCreateModal(true)
9294
- });
9295
- }
9296
- return actions;
9297
- };
9298
- const renderPageHeader = () => {
9299
- const actions = [
9300
- ...generateDefaultActions(),
9301
- ...config.actions || []
9302
- ];
9303
- return /* @__PURE__ */ jsx(
9304
- SectionHeader,
9305
- {
9306
- title: config.display.title,
9307
- description: config.display.description,
9308
- category: config.display.category,
9309
- actions: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9310
- renderCustomActions && renderCustomActions(),
9311
- enableFiltering && /* @__PURE__ */ jsxs(
9312
- Button,
9313
- {
9314
- variant: "outline",
9315
- size: "sm",
9316
- onClick: () => setShowFilterPanel(!showFilterPanel),
9317
- className: cn(showFilterPanel && "bg-muted"),
9318
- children: [
9319
- /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4 mr-2" }),
9320
- "Filters"
9321
- ]
9322
- }
9323
- ),
9324
- enableExport && /* @__PURE__ */ jsxs(
9325
- Button,
9326
- {
9327
- variant: "outline",
9328
- size: "sm",
9329
- onClick: () => onExport == null ? void 0 : onExport(selectedItems.length > 0 ? selectedItems : data, "csv"),
9330
- disabled: data.length === 0,
9331
- children: [
9332
- /* @__PURE__ */ jsx(Download, { className: "w-4 h-4 mr-2" }),
9333
- "Export"
9334
- ]
9335
- }
9336
- ),
9337
- actions.map((action) => /* @__PURE__ */ jsxs(
9338
- Button,
9339
- {
9340
- variant: action.type === "primary" ? "default" : "outline",
9341
- size: "sm",
9342
- onClick: () => action.onClick({ data, config }),
9343
- children: [
9344
- action.icon && /* @__PURE__ */ jsx(action.icon, { className: "w-4 h-4 mr-2" }),
9345
- action.label
9346
- ]
9347
- },
9348
- action.label
9349
- ))
9350
- ] })
9351
- }
9352
- );
9353
- };
9354
- const renderToolbar = () => {
9355
- if (selectedItems.length === 0) return null;
9356
- return /* @__PURE__ */ jsx("div", { className: "bg-muted/50 p-4 rounded-lg mb-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9357
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9358
- /* @__PURE__ */ jsxs(Badge, { variant: "secondary", children: [
9359
- selectedItems.length,
9360
- " selected"
9361
- ] }),
9362
- /* @__PURE__ */ jsx(
9363
- Button,
9364
- {
9365
- variant: "ghost",
9366
- size: "sm",
9367
- onClick: () => setSelectedItems([]),
9368
- children: "Clear selection"
9369
- }
9370
- )
9371
- ] }),
9372
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9373
- onBulkDelete && /* @__PURE__ */ jsxs(
9374
- Button,
9375
- {
9376
- variant: "destructive",
9377
- size: "sm",
9378
- onClick: handleBulkDelete,
9379
- children: [
9380
- /* @__PURE__ */ jsx(Trash2, { className: "w-4 h-4 mr-2" }),
9381
- "Delete Selected"
9382
- ]
9383
- }
9384
- ),
9385
- enableExport && /* @__PURE__ */ jsxs(
9386
- Button,
9387
- {
9388
- variant: "outline",
9389
- size: "sm",
9390
- onClick: () => onExport == null ? void 0 : onExport(selectedItems, "csv"),
9391
- children: [
9392
- /* @__PURE__ */ jsx(Download, { className: "w-4 h-4 mr-2" }),
9393
- "Export Selected"
9394
- ]
9395
- }
9396
- )
9397
- ] })
9398
- ] }) });
9399
- };
9400
- const renderFilterPanelSection = () => {
9401
- if (!showFilterPanel) return null;
9402
- return /* @__PURE__ */ jsx(Card, { className: "p-4 mb-4", children: renderFilterPanel ? renderFilterPanel(onFilter || (() => {
9403
- })) : /* @__PURE__ */ jsx("div", { className: "text-center text-muted-foreground py-4", children: "Filter functionality not implemented yet" }) });
9404
- };
9405
- const renderCreateModal = () => {
9406
- if (!showCreateModal) return null;
9407
- return /* @__PURE__ */ jsx(
9408
- Modal,
9409
- {
9410
- isOpen: showCreateModal,
9411
- onClose: () => setShowCreateModal(false),
9412
- title: `Create ${config.display.title.slice(0, -1)}`,
9413
- category: config.display.category,
9414
- children: renderCreateForm ? renderCreateForm(handleCreate, () => setShowCreateModal(false)) : /* @__PURE__ */ jsx("div", { className: "p-6 text-center text-muted-foreground", children: "Create form not implemented yet" })
9415
- }
9416
- );
9417
- };
9418
- const renderEditModal = () => {
9419
- if (!showEditModal || !selectedItem) return null;
9420
- return /* @__PURE__ */ jsx(
9421
- Modal,
9422
- {
9423
- isOpen: showEditModal,
9424
- onClose: () => {
9425
- setShowEditModal(false);
9426
- setSelectedItem(null);
9427
- },
9428
- title: `Edit ${config.display.title.slice(0, -1)}`,
9429
- category: config.display.category,
9430
- children: renderEditForm ? renderEditForm(
9431
- selectedItem,
9432
- handleUpdate,
9433
- () => {
9434
- setShowEditModal(false);
9435
- setSelectedItem(null);
9436
- }
9437
- ) : /* @__PURE__ */ jsx("div", { className: "p-6 text-center text-muted-foreground", children: "Edit form not implemented yet" })
9438
- }
9439
- );
9440
- };
9441
- const renderDetailModal = () => {
9442
- if (!showDetailModal || !selectedItem) return null;
9443
- return /* @__PURE__ */ jsx(
9444
- Modal,
9445
- {
9446
- isOpen: showDetailModal,
9447
- onClose: () => {
9448
- setShowDetailModal(false);
9449
- setSelectedItem(null);
9450
- },
9451
- title: `${config.display.title.slice(0, -1)} Details`,
9452
- category: config.display.category,
9453
- size: "large",
9454
- children: renderDetailView ? renderDetailView(
9455
- selectedItem,
9456
- () => {
9457
- setShowDetailModal(false);
9458
- handleEdit(selectedItem);
9459
- },
9460
- () => {
9461
- setShowDetailModal(false);
9462
- setSelectedItem(null);
9463
- }
9464
- ) : /* @__PURE__ */ jsx("div", { className: "p-6", children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children: Object.entries(selectedItem).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
9465
- /* @__PURE__ */ jsxs("span", { className: "font-medium capitalize", children: [
9466
- key,
9467
- ":"
9468
- ] }),
9469
- /* @__PURE__ */ jsx("span", { children: (value == null ? void 0 : value.toString()) || "-" })
9470
- ] }, key)) }) })
9471
- }
9472
- );
9473
- };
9474
- return /* @__PURE__ */ jsx(AppLayout, { children: /* @__PURE__ */ jsxs(
9475
- PageTemplate,
9476
- {
9477
- className: cn("container mx-auto px-4 py-6", className),
9478
- "data-component-name": "EntityManagementTemplate",
9479
- children: [
9480
- headerSlot,
9481
- renderPageHeader(),
9482
- toolbarSlot,
9483
- renderFilterPanelSection(),
9484
- renderToolbar(),
9485
- /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
9486
- listHeaderSlot,
9487
- /* @__PURE__ */ jsx(
9488
- EntityListPanel,
9489
- {
9490
- config,
9491
- data,
9492
- isLoading,
9493
- onRowClick: handleRowClick,
9494
- onAction: handleAction,
9495
- enableSelection: enableBulkActions,
9496
- enableBulkActions,
9497
- enableExport,
9498
- enableRefresh: !!onRefresh,
9499
- showSearch: enableSearch,
9500
- showPagination: true,
9501
- pageSize,
9502
- renderEmptyState,
9503
- onExport,
9504
- onRefresh
9505
- }
9506
- ),
9507
- listFooterSlot
9508
- ] }),
9509
- renderCreateModal(),
9510
- renderEditModal(),
9511
- renderDetailModal(),
9512
- footerSlot
9513
- ]
9514
- }
9515
- ) });
9516
- };
9517
- const financialConfig = {
9518
- entityType: "transactional",
9519
- display: {
9520
- title: "Financial Dashboard",
9521
- description: "Personal finance overview and transaction management",
9522
- category: 2
9523
- // Green theme for financial success
9524
- },
9525
- metrics: [
9526
- {
9527
- key: "totalBalance",
9528
- label: "Total Balance",
9529
- type: "currency",
9530
- trend: true,
9531
- icon: DollarSign,
9532
- aggregation: "sum"
9533
- },
9534
- {
9535
- key: "monthlyIncome",
9536
- label: "Monthly Income",
9537
- type: "currency",
9538
- trend: true,
9539
- icon: TrendingUp,
9540
- aggregation: "sum"
9541
- },
9542
- {
9543
- key: "monthlyExpenses",
9544
- label: "Monthly Expenses",
9545
- type: "currency",
9546
- trend: true,
9547
- icon: Wallet,
9548
- aggregation: "sum"
9549
- },
9550
- {
9551
- key: "savingsRate",
9552
- label: "Savings Rate",
9553
- type: "percentage",
9554
- target: 20,
9555
- icon: Target
9556
- }
9557
- ],
9558
- temporal: {
9559
- cycles: ["monthly", "quarterly", "yearly"],
9560
- defaultCycle: "monthly",
9561
- enableComparisons: true,
9562
- forecasting: {
9563
- enabled: true,
9564
- periods: 3,
9565
- algorithm: "seasonal"
9566
- }
9567
- },
9568
- categories: {
9569
- hierarchy: ["account", "category", "type"],
9570
- defaultGroupBy: "category",
9571
- enableDrillDown: true,
9572
- colorCoding: true
9573
- },
9574
- actions: [
9575
- {
9576
- label: "Add Transaction",
9577
- type: "primary",
9578
- onClick: ({ data, config }) => {
9579
- console.log("Adding new transaction", { data, config });
9580
- }
9581
- },
9582
- {
9583
- label: "Generate Report",
9584
- type: "secondary",
9585
- onClick: ({ selectedItems, data, config }) => {
9586
- console.log("Generating report", { selectedItems, data, config });
9587
- }
9588
- }
9589
- ]
9590
- };
9591
- const sampleFinancialData = [
9592
- {
9593
- id: "1",
9594
- amount: 5e3,
9595
- category: "Salary",
9596
- account: "Checking",
9597
- date: "2024-01-15",
9598
- description: "Monthly salary",
9599
- type: "income",
9600
- status: "completed"
9601
- },
9602
- {
9603
- id: "2",
9604
- amount: -1200,
9605
- category: "Rent",
9606
- account: "Checking",
9607
- date: "2024-01-01",
9608
- description: "Monthly rent payment",
9609
- type: "expense",
9610
- status: "completed"
9611
- },
9612
- {
9613
- id: "3",
9614
- amount: -300,
9615
- category: "Groceries",
9616
- account: "Checking",
9617
- date: "2024-01-10",
9618
- description: "Weekly groceries",
9619
- type: "expense",
9620
- status: "completed"
9621
- },
9622
- {
9623
- id: "4",
9624
- amount: -80,
9625
- category: "Utilities",
9626
- account: "Checking",
9627
- date: "2024-01-05",
9628
- description: "Electric bill",
9629
- type: "expense",
9630
- status: "completed"
9631
- },
9632
- {
9633
- id: "5",
9634
- amount: -45,
9635
- category: "Entertainment",
9636
- account: "Checking",
9637
- date: "2024-01-12",
9638
- description: "Movie tickets",
9639
- type: "expense",
9640
- status: "completed"
9641
- }
9642
- ];
9643
8118
  function createReactApp(config) {
9644
8119
  const appConfig = typeof config === "string" ? { title: config } : config;
9645
8120
  const {
@@ -9650,6 +8125,7 @@ function createReactApp(config) {
9650
8125
  enableQuery = true,
9651
8126
  enableRouting = true,
9652
8127
  auth,
8128
+ navigation,
9653
8129
  customProviders = []
9654
8130
  } = appConfig;
9655
8131
  const queryClient = new QueryClient({
@@ -9684,7 +8160,7 @@ function createReactApp(config) {
9684
8160
  tree = /* @__PURE__ */ jsx(Provider, { children: tree }, Provider.name);
9685
8161
  });
9686
8162
  if (enableRouting) {
9687
- tree = /* @__PURE__ */ jsx(SidebarProvider, { children: tree });
8163
+ tree = /* @__PURE__ */ jsx(NavigationProvider, { initialNavigation: navigation, children: /* @__PURE__ */ jsx(SidebarProvider, { children: tree }) });
9688
8164
  }
9689
8165
  if (enableAuth) {
9690
8166
  tree = /* @__PURE__ */ jsx(AuthProvider, { config: auth, children: tree });
@@ -11940,7 +10416,6 @@ export {
11940
10416
  CardFooter,
11941
10417
  CardHeader,
11942
10418
  CardTitle,
11943
- CategoryBreakdownPanel,
11944
10419
  Chart,
11945
10420
  ColorSwatch,
11946
10421
  ComponentShowcasePage,
@@ -11975,15 +10450,12 @@ export {
11975
10450
  DropdownMenuSubTrigger,
11976
10451
  DropdownMenuTrigger,
11977
10452
  EmptyState,
11978
- EntityListPanel,
11979
- EntityManagementTemplate,
11980
- EntityPerformanceDashboardTemplate,
11981
- EntityPerformanceDashboardTemplateWithRealTime,
11982
10453
  ErrorBoundary,
11983
10454
  FileUpload,
11984
10455
  FormField,
11985
10456
  FormGroup,
11986
10457
  GlobalSearch,
10458
+ Icon,
11987
10459
  IconBadge,
11988
10460
  Input,
11989
10461
  Label,
@@ -11991,10 +10463,9 @@ export {
11991
10463
  LoginForm,
11992
10464
  LogoutButton,
11993
10465
  MetricCalculationEngine,
11994
- MetricsOverviewPanel,
11995
- MetricsOverviewWithInsightsPanel,
11996
10466
  Modal,
11997
10467
  NavMenu,
10468
+ NavigationProvider,
11998
10469
  PageTemplate,
11999
10470
  Pagination,
12000
10471
  PaletteSwitcher,
@@ -12011,6 +10482,7 @@ export {
12011
10482
  SelectTrigger,
12012
10483
  SelectValue,
12013
10484
  ShowcaseSection,
10485
+ Sidebar,
12014
10486
  SidebarButton,
12015
10487
  SidebarProvider,
12016
10488
  Skeleton,
@@ -12033,7 +10505,6 @@ export {
12033
10505
  Toast,
12034
10506
  ToastContainer,
12035
10507
  Tooltip,
12036
- TrendAnalysisPanel,
12037
10508
  UI_CONFIG,
12038
10509
  UserAvatar,
12039
10510
  UserMenu,
@@ -12043,14 +10514,15 @@ export {
12043
10514
  createReactApp,
12044
10515
  createSimpleApp,
12045
10516
  env,
12046
- financialConfig,
12047
10517
  formatNumberWithTooltip,
12048
10518
  getAnimationClasses,
12049
10519
  getChartHeight,
12050
10520
  getContainerHeightClass,
10521
+ getIcon,
10522
+ getNavigationItems,
12051
10523
  interactionVariants,
10524
+ isValidIcon,
12052
10525
  legacyPatterns,
12053
- sampleFinancialData,
12054
10526
  setGlobalAuthService,
12055
10527
  tooltipContent,
12056
10528
  useApiMutation,
@@ -12059,6 +10531,7 @@ export {
12059
10531
  useCreateExample,
12060
10532
  useDeleteExample,
12061
10533
  useGetExample,
10534
+ useNavigation,
12062
10535
  usePermissions,
12063
10536
  useSidebar,
12064
10537
  useTextOverflow,