@goplusvn/core 0.1.1 → 0.1.3

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 (223) hide show
  1. package/package.json +31 -175
  2. package/dist/audit/index.d.mts +0 -115
  3. package/dist/audit/index.d.ts +0 -115
  4. package/dist/audit/index.js +0 -204
  5. package/dist/audit/index.js.map +0 -1
  6. package/dist/audit/index.mjs +0 -200
  7. package/dist/audit/index.mjs.map +0 -1
  8. package/dist/auth/index.d.mts +0 -86
  9. package/dist/auth/index.d.ts +0 -86
  10. package/dist/auth/index.js +0 -210
  11. package/dist/auth/index.js.map +0 -1
  12. package/dist/auth/index.mjs +0 -198
  13. package/dist/auth/index.mjs.map +0 -1
  14. package/dist/button-1dWvP9Ib.d.mts +0 -30
  15. package/dist/button-1dWvP9Ib.d.ts +0 -30
  16. package/dist/calendar-2QzdEo1z.d.mts +0 -20
  17. package/dist/calendar-2QzdEo1z.d.ts +0 -20
  18. package/dist/code-generation/index.d.mts +0 -30
  19. package/dist/code-generation/index.d.ts +0 -30
  20. package/dist/code-generation/index.js +0 -31
  21. package/dist/code-generation/index.js.map +0 -1
  22. package/dist/code-generation/index.mjs +0 -28
  23. package/dist/code-generation/index.mjs.map +0 -1
  24. package/dist/configs/index.d.mts +0 -175
  25. package/dist/configs/index.d.ts +0 -175
  26. package/dist/configs/index.js +0 -254
  27. package/dist/configs/index.js.map +0 -1
  28. package/dist/configs/index.mjs +0 -233
  29. package/dist/configs/index.mjs.map +0 -1
  30. package/dist/crud/index.d.mts +0 -646
  31. package/dist/crud/index.d.ts +0 -646
  32. package/dist/crud/index.js +0 -11772
  33. package/dist/crud/index.js.map +0 -1
  34. package/dist/crud/index.mjs +0 -11665
  35. package/dist/crud/index.mjs.map +0 -1
  36. package/dist/crud/server.d.mts +0 -20
  37. package/dist/crud/server.d.ts +0 -20
  38. package/dist/crud/server.js +0 -123
  39. package/dist/crud/server.js.map +0 -1
  40. package/dist/crud/server.mjs +0 -120
  41. package/dist/crud/server.mjs.map +0 -1
  42. package/dist/data-table-skeleton-12NA8Mjx.d.mts +0 -39
  43. package/dist/data-table-skeleton-12NA8Mjx.d.ts +0 -39
  44. package/dist/dialog-bKfjZMTd.d.mts +0 -22
  45. package/dist/dialog-bKfjZMTd.d.ts +0 -22
  46. package/dist/dynamic-icon-DrGIiu2N.d.mts +0 -10
  47. package/dist/dynamic-icon-DrGIiu2N.d.ts +0 -10
  48. package/dist/home/index.d.mts +0 -269
  49. package/dist/home/index.d.ts +0 -269
  50. package/dist/home/index.js +0 -1678
  51. package/dist/home/index.js.map +0 -1
  52. package/dist/home/index.mjs +0 -1635
  53. package/dist/home/index.mjs.map +0 -1
  54. package/dist/hooks/index.d.mts +0 -7
  55. package/dist/hooks/index.d.ts +0 -7
  56. package/dist/hooks/index.js +0 -8316
  57. package/dist/hooks/index.js.map +0 -1
  58. package/dist/hooks/index.mjs +0 -8255
  59. package/dist/hooks/index.mjs.map +0 -1
  60. package/dist/index-50hpiPrV.d.ts +0 -116
  61. package/dist/index-B9zQVEVi.d.mts +0 -116
  62. package/dist/index.d.mts +0 -5
  63. package/dist/index.d.ts +0 -5
  64. package/dist/index.js +0 -123
  65. package/dist/index.js.map +0 -1
  66. package/dist/index.mjs +0 -118
  67. package/dist/index.mjs.map +0 -1
  68. package/dist/infrastructure/index.d.mts +0 -423
  69. package/dist/infrastructure/index.d.ts +0 -423
  70. package/dist/infrastructure/index.js +0 -633
  71. package/dist/infrastructure/index.js.map +0 -1
  72. package/dist/infrastructure/index.mjs +0 -619
  73. package/dist/infrastructure/index.mjs.map +0 -1
  74. package/dist/label-DWTEkNPo.d.ts +0 -226
  75. package/dist/label-LPpdcoBx.d.mts +0 -226
  76. package/dist/layout/index.d.mts +0 -48
  77. package/dist/layout/index.d.ts +0 -48
  78. package/dist/layout/index.js +0 -117
  79. package/dist/layout/index.js.map +0 -1
  80. package/dist/layout/index.mjs +0 -90
  81. package/dist/layout/index.mjs.map +0 -1
  82. package/dist/navigation/index.d.mts +0 -16
  83. package/dist/navigation/index.d.ts +0 -16
  84. package/dist/navigation/index.js +0 -53
  85. package/dist/navigation/index.js.map +0 -1
  86. package/dist/navigation/index.mjs +0 -50
  87. package/dist/navigation/index.mjs.map +0 -1
  88. package/dist/notification/index.d.mts +0 -105
  89. package/dist/notification/index.d.ts +0 -105
  90. package/dist/notification/index.js +0 -278
  91. package/dist/notification/index.js.map +0 -1
  92. package/dist/notification/index.mjs +0 -274
  93. package/dist/notification/index.mjs.map +0 -1
  94. package/dist/organization/index.d.mts +0 -99
  95. package/dist/organization/index.d.ts +0 -99
  96. package/dist/organization/index.js +0 -360
  97. package/dist/organization/index.js.map +0 -1
  98. package/dist/organization/index.mjs +0 -352
  99. package/dist/organization/index.mjs.map +0 -1
  100. package/dist/plugin/index.d.mts +0 -83
  101. package/dist/plugin/index.d.ts +0 -83
  102. package/dist/plugin/index.js +0 -86
  103. package/dist/plugin/index.js.map +0 -1
  104. package/dist/plugin/index.mjs +0 -84
  105. package/dist/plugin/index.mjs.map +0 -1
  106. package/dist/providers/index.d.mts +0 -25
  107. package/dist/providers/index.d.ts +0 -25
  108. package/dist/providers/index.js +0 -84
  109. package/dist/providers/index.js.map +0 -1
  110. package/dist/providers/index.mjs +0 -77
  111. package/dist/providers/index.mjs.map +0 -1
  112. package/dist/rbac/index.d.mts +0 -226
  113. package/dist/rbac/index.d.ts +0 -226
  114. package/dist/rbac/index.js +0 -4784
  115. package/dist/rbac/index.js.map +0 -1
  116. package/dist/rbac/index.mjs +0 -4722
  117. package/dist/rbac/index.mjs.map +0 -1
  118. package/dist/rbac/permissions.d.mts +0 -26
  119. package/dist/rbac/permissions.d.ts +0 -26
  120. package/dist/rbac/permissions.js +0 -94
  121. package/dist/rbac/permissions.js.map +0 -1
  122. package/dist/rbac/permissions.mjs +0 -90
  123. package/dist/rbac/permissions.mjs.map +0 -1
  124. package/dist/rbac/server.d.mts +0 -1
  125. package/dist/rbac/server.d.ts +0 -1
  126. package/dist/rbac/server.js +0 -128
  127. package/dist/rbac/server.js.map +0 -1
  128. package/dist/rbac/server.mjs +0 -124
  129. package/dist/rbac/server.mjs.map +0 -1
  130. package/dist/schemas/index.d.mts +0 -1257
  131. package/dist/schemas/index.d.ts +0 -1257
  132. package/dist/schemas/index.js +0 -572
  133. package/dist/schemas/index.js.map +0 -1
  134. package/dist/schemas/index.mjs +0 -523
  135. package/dist/schemas/index.mjs.map +0 -1
  136. package/dist/server-QuYCTa89.d.mts +0 -83
  137. package/dist/server-QuYCTa89.d.ts +0 -83
  138. package/dist/sonner-C74GlRDQ.d.mts +0 -71
  139. package/dist/sonner-C74GlRDQ.d.ts +0 -71
  140. package/dist/status-BOXZgIqX.d.mts +0 -12
  141. package/dist/status-BOXZgIqX.d.ts +0 -12
  142. package/dist/system/index.d.mts +0 -77
  143. package/dist/system/index.d.ts +0 -77
  144. package/dist/system/index.js +0 -102
  145. package/dist/system/index.js.map +0 -1
  146. package/dist/system/index.mjs +0 -100
  147. package/dist/system/index.mjs.map +0 -1
  148. package/dist/tabs-C6FfBwPY.d.mts +0 -18
  149. package/dist/tabs-C6FfBwPY.d.ts +0 -18
  150. package/dist/tenant-provider-B8eC_Wpb.d.mts +0 -27
  151. package/dist/tenant-provider-B8eC_Wpb.d.ts +0 -27
  152. package/dist/types/index.d.mts +0 -469
  153. package/dist/types/index.d.ts +0 -469
  154. package/dist/types/index.js +0 -25
  155. package/dist/types/index.js.map +0 -1
  156. package/dist/types/index.mjs +0 -21
  157. package/dist/types/index.mjs.map +0 -1
  158. package/dist/ui/auth.d.mts +0 -39
  159. package/dist/ui/auth.d.ts +0 -39
  160. package/dist/ui/auth.js +0 -4941
  161. package/dist/ui/auth.js.map +0 -1
  162. package/dist/ui/auth.mjs +0 -4896
  163. package/dist/ui/auth.mjs.map +0 -1
  164. package/dist/ui/crud.d.mts +0 -2
  165. package/dist/ui/crud.d.ts +0 -2
  166. package/dist/ui/crud.js +0 -4
  167. package/dist/ui/crud.js.map +0 -1
  168. package/dist/ui/crud.mjs +0 -3
  169. package/dist/ui/crud.mjs.map +0 -1
  170. package/dist/ui/data-display.d.mts +0 -596
  171. package/dist/ui/data-display.d.ts +0 -596
  172. package/dist/ui/data-display.js +0 -5307
  173. package/dist/ui/data-display.js.map +0 -1
  174. package/dist/ui/data-display.mjs +0 -5212
  175. package/dist/ui/data-display.mjs.map +0 -1
  176. package/dist/ui/feedback.d.mts +0 -55
  177. package/dist/ui/feedback.d.ts +0 -55
  178. package/dist/ui/feedback.js +0 -2608
  179. package/dist/ui/feedback.js.map +0 -1
  180. package/dist/ui/feedback.mjs +0 -2526
  181. package/dist/ui/feedback.mjs.map +0 -1
  182. package/dist/ui/forms.d.mts +0 -309
  183. package/dist/ui/forms.d.ts +0 -309
  184. package/dist/ui/forms.js +0 -4656
  185. package/dist/ui/forms.js.map +0 -1
  186. package/dist/ui/forms.mjs +0 -4571
  187. package/dist/ui/forms.mjs.map +0 -1
  188. package/dist/ui/index.d.mts +0 -331
  189. package/dist/ui/index.d.ts +0 -331
  190. package/dist/ui/index.js +0 -16953
  191. package/dist/ui/index.js.map +0 -1
  192. package/dist/ui/index.mjs +0 -16598
  193. package/dist/ui/index.mjs.map +0 -1
  194. package/dist/ui/primitives/client.d.mts +0 -61
  195. package/dist/ui/primitives/client.d.ts +0 -61
  196. package/dist/ui/primitives/client.js +0 -3408
  197. package/dist/ui/primitives/client.js.map +0 -1
  198. package/dist/ui/primitives/client.mjs +0 -3256
  199. package/dist/ui/primitives/client.mjs.map +0 -1
  200. package/dist/ui/primitives.d.mts +0 -113
  201. package/dist/ui/primitives.d.ts +0 -113
  202. package/dist/ui/primitives.js +0 -3356
  203. package/dist/ui/primitives.js.map +0 -1
  204. package/dist/ui/primitives.mjs +0 -3227
  205. package/dist/ui/primitives.mjs.map +0 -1
  206. package/dist/user/index.d.mts +0 -228
  207. package/dist/user/index.d.ts +0 -228
  208. package/dist/user/index.js +0 -4306
  209. package/dist/user/index.js.map +0 -1
  210. package/dist/user/index.mjs +0 -4260
  211. package/dist/user/index.mjs.map +0 -1
  212. package/dist/utils/index.d.mts +0 -205
  213. package/dist/utils/index.d.ts +0 -205
  214. package/dist/utils/index.js +0 -574
  215. package/dist/utils/index.js.map +0 -1
  216. package/dist/utils/index.mjs +0 -514
  217. package/dist/utils/index.mjs.map +0 -1
  218. package/dist/workflow/index.d.mts +0 -40
  219. package/dist/workflow/index.d.ts +0 -40
  220. package/dist/workflow/index.js +0 -3710
  221. package/dist/workflow/index.js.map +0 -1
  222. package/dist/workflow/index.mjs +0 -3677
  223. package/dist/workflow/index.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/index.ts","../../src/home/welcome-card.tsx","../../src/home/types.ts","../../src/home/widgets/base-widget.tsx","../../src/home/widgets/revenue-widget.tsx","../../src/home/widgets/orders-widget.tsx","../../src/home/widgets/customers-widget.tsx","../../src/home/widgets/stock-widget.tsx","../../src/home/widget-container.tsx","../../src/home/feature-showcase.tsx","../../src/home/constants.tsx","../../src/home/quick-access-dialog.tsx","../../src/home/quick-access-menu.tsx","../../src/home/hooks/useWidgetPreferences.ts","../../src/home/home-page.tsx"],"names":["twMerge","clsx","format","vi","jsxs","jsx","TrendingUp","Zap","useSortable","CSS","motion","GripVertical","Eye","EyeOff","Settings","X","DollarSign","ShoppingCart","Users","Package","AlertTriangle","useState","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","useCallback","arrayMove","RotateCcw","AnimatePresence","Plus","DndContext","closestCenter","SortableContext","rectSortingStrategy","useEmblaCarousel","Autoplay","useEffect","ChevronLeft","ChevronRight","z","useForm","zodResolver","DialogPrimitive","Fragment","Pencil","useSWR","useRouter"],"mappings":"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","file":"index.js","sourcesContent":["// @goerp/core/utils\n// Utility functions for GoERP platform\n\nimport { clsx } from \"clsx\";\nimport type { ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n// Import types from core/types\nimport type { LocaleType, FormatStyleType } from \"../types\";\n\n// ============================================================================\n// Class Names\n// ============================================================================\n\n/**\n * Merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\n// ============================================================================\n// String Utilities\n// ============================================================================\n\n/**\n * Get initials from full name\n */\nexport function getInitials(fullName: string): string {\n if (fullName.length === 0) return \"\";\n const names = fullName.split(\" \");\n const initials = names.map((name) => name.charAt(0).toUpperCase()).join(\"\");\n return initials;\n}\n\n/**\n * Slugify string\n */\nexport function slugify(text: string): string {\n return text\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/(^-|-$)/g, \"\");\n}\n\n/**\n * Convert camelCase to Title Case\n */\nexport function camelCaseToTitleCase(camelCaseStr: string): string {\n return camelCaseStr\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (char) => char.toUpperCase());\n}\n\n/**\n * Convert Title Case to camelCase\n */\nexport function titleCaseToCamelCase(titleCaseStr: string): string {\n return titleCaseStr\n .toLowerCase()\n .replace(/[-_\\s]+(.)/g, (_, char) => char.toUpperCase())\n .replace(/[-_]/g, \"\");\n}\n\n// ============================================================================\n// Number Utilities\n// ============================================================================\n\nexport const isEven = (num: number) => num % 2 === 0;\nexport const isNonNegative = (num: number) => num >= 0;\n\n/**\n * Đọc số tiền thành chữ tiếng Việt\n * Dùng chung cho tất cả các phiếu in (hợp đồng, phiếu thu, phiếu chi, phiếu nhập/xuất kho, v.v.)\n * @param amount - Số tiền (VND)\n * @returns Chuỗi đọc bằng chữ, VD: \"Bảy mươi hai triệu một trăm năm mươi chín nghìn tám trăm hai mươi đồng\"\n */\nexport function readMoney(amount: number): string {\n if (!Number.isFinite(amount)) return \"Không đồng\"\n\n const isNegative = amount < 0\n\n // Bỏ phần thập phân - VND không có đơn vị lẻ\n amount = Math.floor(Math.abs(amount))\n\n if (amount === 0) return \"Không đồng\"\n\n const unit = [\"\", \"nghìn\", \"triệu\", \"tỷ\", \"nghìn tỷ\", \"triệu tỷ\"]\n const digit = [\n \"không\",\n \"một\",\n \"hai\",\n \"ba\",\n \"bốn\",\n \"năm\",\n \"sáu\",\n \"bảy\",\n \"tám\",\n \"chín\",\n ]\n\n let str = amount.toString()\n const groups: string[] = []\n while (str.length > 0) {\n groups.push(str.slice(-3))\n str = str.slice(0, -3)\n }\n\n let result = \"\"\n for (let i = 0; i < groups.length; i++) {\n const group = groups[i]\n if (group === \"000\") continue\n\n const [a, b, c] = group.padStart(3, \"0\").split(\"\").map(Number)\n let groupResult = \"\"\n\n const hasHundreds = a !== 0 || groups.length > 1\n\n if (hasHundreds) {\n groupResult += `${digit[a]} trăm `\n }\n\n if (b === 0 && c !== 0) {\n if (hasHundreds) groupResult += \"lẻ \"\n } else if (b === 1) {\n groupResult += \"mười \"\n } else if (b > 1) {\n groupResult += `${digit[b]} mươi `\n }\n\n if (c === 1 && b > 1) {\n groupResult += \"mốt \"\n } else if (c === 5 && b > 0) {\n groupResult += \"lăm \"\n } else if (c !== 0) {\n groupResult += `${digit[c]} `\n }\n\n if (i === groups.length - 1 && a === 0) {\n groupResult = groupResult.replace(\"không trăm \", \"\")\n if (b === 0) groupResult = groupResult.replace(\"lẻ \", \"\")\n }\n\n if (groupResult.trim() !== \"\") {\n result = `${groupResult.trim()} ${unit[i]} ${result}`\n }\n }\n\n result = result.trim() + \" đồng\"\n\n if (isNegative) {\n return \"Âm \" + result\n }\n\n return result.charAt(0).toUpperCase() + result.slice(1)\n}\n\n/**\n * Format currency with locale\n */\nexport function formatCurrency(\n value: number,\n locales: LocaleType = \"vi\",\n currency: string = \"VND\",\n): string {\n return new Intl.NumberFormat(locales === \"vi\" ? \"vi-VN\" : locales, {\n style: \"decimal\",\n maximumFractionDigits: 0,\n }).format(value);\n}\n\n/**\n * Format number with locale\n */\nexport function formatNumber(\n value: number,\n options?: {\n locale?: string;\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n },\n): string {\n const {\n locale = \"vi-VN\",\n minimumFractionDigits = 0,\n maximumFractionDigits = 2,\n } = options || {};\n\n return new Intl.NumberFormat(locale, {\n minimumFractionDigits,\n maximumFractionDigits,\n }).format(value);\n}\n\n/**\n * Format percent\n */\nexport function formatPercent(\n value: number,\n locales: LocaleType = \"vi\",\n): string {\n return new Intl.NumberFormat(locales === \"vi\" ? \"vi-VN\" : locales, {\n style: \"percent\",\n maximumFractionDigits: 0,\n }).format(value);\n}\n\n/**\n * Format number to compact (e.g., 1K, 1M)\n */\nexport function formatNumberToCompact(\n value: number,\n locales: LocaleType = \"vi\",\n): string {\n return new Intl.NumberFormat(locales === \"vi\" ? \"vi-VN\" : locales, {\n notation: \"compact\",\n compactDisplay: \"short\",\n }).format(value);\n}\n\n/**\n * Format file size\n */\nexport function formatFileSize(bytes: number, decimals: number = 2): string {\n if (bytes === 0) return \"0 Bytes\";\n\n const k = 1000;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + \" \" + sizes[i];\n}\n\n/**\n * Format unread count\n */\nexport function formatUnreadCount(unreadCount: number): string | number {\n return unreadCount >= 100 ? \"+99\" : unreadCount;\n}\n\n// ============================================================================\n// Date Utilities\n// ============================================================================\n\n/**\n * Format date with Vietnamese locale (Asia/Ho_Chi_Minh timezone)\n */\nexport function formatDate(\n date: Date | string,\n options?: {\n locale?: string;\n format?: \"short\" | \"medium\" | \"long\" | \"full\";\n },\n): string {\n const { locale = \"vi-VN\", format = \"medium\" } = options || {};\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n const formatOptions: Record<string, Intl.DateTimeFormatOptions> = {\n short: { day: \"2-digit\", month: \"2-digit\", year: \"numeric\", timeZone: \"Asia/Ho_Chi_Minh\" },\n medium: { day: \"2-digit\", month: \"short\", year: \"numeric\", timeZone: \"Asia/Ho_Chi_Minh\" },\n long: { day: \"numeric\", month: \"long\", year: \"numeric\", timeZone: \"Asia/Ho_Chi_Minh\" },\n full: { weekday: \"long\", day: \"numeric\", month: \"long\", year: \"numeric\", timeZone: \"Asia/Ho_Chi_Minh\" },\n };\n\n return new Intl.DateTimeFormat(locale, formatOptions[format]).format(dateObj);\n}\n\n/**\n * Format datetime with Vietnamese locale (Asia/Ho_Chi_Minh timezone)\n */\nexport function formatDateTime(\n date: Date | string,\n options?: {\n locale?: string;\n },\n): string {\n const { locale = \"vi-VN\" } = options || {};\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n return new Intl.DateTimeFormat(locale, {\n day: \"2-digit\",\n month: \"2-digit\",\n year: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: \"Asia/Ho_Chi_Minh\",\n }).format(dateObj);\n}\n\n/**\n * Format relative date (Today, Yesterday, or date) - Asia/Ho_Chi_Minh timezone\n */\nexport function formatRelativeDate(value?: string | number | Date): string {\n if (!value) return \"No Date\";\n\n const date = new Date(value);\n const today = new Date();\n const yesterday = new Date();\n yesterday.setDate(today.getDate() - 1);\n\n // Compare dates in Vietnam timezone\n const vnDateStr = new Intl.DateTimeFormat(\"en-CA\", { timeZone: \"Asia/Ho_Chi_Minh\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(date);\n const vnTodayStr = new Intl.DateTimeFormat(\"en-CA\", { timeZone: \"Asia/Ho_Chi_Minh\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(today);\n const vnYesterdayStr = new Intl.DateTimeFormat(\"en-CA\", { timeZone: \"Asia/Ho_Chi_Minh\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(yesterday);\n\n if (vnDateStr === vnTodayStr) return \"Today\";\n if (vnDateStr === vnYesterdayStr) return \"Yesterday\";\n\n return formatDate(date);\n}\n\n/**\n * Check if date is before today (Asia/Ho_Chi_Minh timezone)\n */\nexport function isBeforeToday(date: Date): boolean {\n const vnTodayStr = new Intl.DateTimeFormat(\"en-CA\", { timeZone: \"Asia/Ho_Chi_Minh\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(new Date());\n const vnDateStr = new Intl.DateTimeFormat(\"en-CA\", { timeZone: \"Asia/Ho_Chi_Minh\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(date);\n return vnDateStr < vnTodayStr;\n}\n\n// ============================================================================\n// Path Utilities\n// ============================================================================\n\n/**\n * Ensure path has prefix\n */\nexport function ensureWithPrefix(value: string, prefix: string): string {\n return value.startsWith(prefix) ? value : `${prefix}${value}`;\n}\n\n/**\n * Ensure path has suffix\n */\nexport function ensureWithSuffix(value: string, suffix: string): string {\n return value.endsWith(suffix) ? value : `${value}${suffix}`;\n}\n\n/**\n * Ensure path without prefix\n */\nexport function ensureWithoutPrefix(value: string, prefix: string): string {\n return value.startsWith(prefix) ? value.slice(prefix.length) : value;\n}\n\n/**\n * Ensure path without suffix\n */\nexport function ensureWithoutSuffix(value: string, suffix: string): string {\n return value.endsWith(suffix) ? value.slice(0, -suffix.length) : value;\n}\n\n/**\n * Check if pathname is active\n */\nexport function isActivePathname(\n basePathname: string,\n currentPathname: string,\n exactMatch: boolean = false,\n): boolean {\n if (typeof basePathname !== \"string\" || typeof currentPathname !== \"string\") {\n throw new Error(\"Both basePathname and currentPathname must be strings\");\n }\n\n if (exactMatch) {\n return basePathname === currentPathname;\n }\n\n return (\n currentPathname.startsWith(basePathname) &&\n (currentPathname.length === basePathname.length ||\n currentPathname[basePathname.length] === \"/\")\n );\n}\n\n// ============================================================================\n// General Utilities\n// ============================================================================\n\n/**\n * Wait/sleep function\n */\nexport function wait(ms: number = 250): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Debounce function\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n func: T,\n wait: number,\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return (...args: Parameters<T>) => {\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n\n/**\n * Deep clone object\n */\nexport function deepClone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\n/**\n * Check if value is empty\n */\nexport function isEmpty(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"object\") return Object.keys(value).length === 0;\n return false;\n}\n\n/**\n * Generate a random ID\n */\nexport function generateId(prefix?: string): string {\n const id = Math.random().toString(36).substring(2, 11);\n return prefix ? `${prefix}_${id}` : id;\n}\n\n/**\n * Get dictionary value safely\n */\nexport function getDictionaryValue(\n key: string,\n section: Record<string, unknown>,\n fallback?: string,\n): string {\n const value = section[key];\n\n if (typeof value !== \"string\") {\n if (fallback !== undefined) {\n return fallback;\n }\n\n const normalizedKey = key.replace(/[-_]/g, \"\");\n const normalizedValue = section[normalizedKey];\n\n if (typeof normalizedValue === \"string\") {\n return normalizedValue;\n }\n\n return key;\n }\n\n return value;\n}\n\n/**\n * Format overview card value based on style\n */\nexport function formatOverviewCardValue(\n value: number,\n formatStyle: FormatStyleType,\n): string | number {\n switch (formatStyle) {\n case \"percent\":\n return formatPercent(value);\n case \"currency\":\n return formatCurrency(value);\n default:\n return value.toLocaleString(\"vi-VN\", {\n maximumFractionDigits: 0,\n });\n }\n}\n\n// ============================================================================\n// Additional Utilities (migrated from shared-utils)\n// ============================================================================\n\n/**\n * Get credit card brand name from number\n */\nexport function getCreditCardBrandName(number: string): string {\n const re = {\n visa: /^4/,\n mastercard: /^5[1-5]/,\n amex: /^3[47]/,\n discover: /^6(?:011|5)/,\n };\n\n for (const [type, regex] of Object.entries(re)) {\n if (regex.test(number)) return type;\n }\n return \"unknown\";\n}\n\n/**\n * Convert rem to pixels\n */\nexport function remToPx(rem: number): number {\n if (typeof document === \"undefined\") return rem * 16;\n const rootFontSize = parseFloat(\n getComputedStyle(document.documentElement).fontSize,\n );\n return rem * rootFontSize;\n}\n\n/**\n * Check if string is a valid URL\n */\nexport function isUrl(text: string): boolean {\n try {\n new URL(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Rating to percentage string\n */\nexport function ratingToPercentage(\n rating: number,\n maxRating: number,\n fractionDigits: number = 0,\n): string {\n const value = ((rating / maxRating) * 100).toFixed(fractionDigits);\n return value + \"%\";\n}\n\n/**\n * Ensure redirect pathname with query params\n */\nexport function ensureRedirectPathname(\n basePathname: string,\n redirectPathname: string,\n): string {\n const searchParams = new URLSearchParams({\n redirectTo: ensureWithoutSuffix(redirectPathname, \"/\"),\n });\n\n return ensureWithSuffix(basePathname, \"?\" + searchParams.toString());\n}\n\n/**\n * Get discounted price\n */\nexport function getDiscountedPrice(\n price: number,\n discountRate: number,\n isAnnual: boolean = false,\n): number {\n if (isAnnual) {\n const annualPrice = price * 12;\n const discountedAnnualPrice = annualPrice * (1 - discountRate);\n return discountedAnnualPrice / 12;\n } else {\n return price * (1 - discountRate);\n }\n}\n\n/**\n * Convert time string to Date\n */\nexport function timeToDate(timeString: string, baseDate = new Date()): Date {\n if (!/^\\d{2}:\\d{2}$/.test(timeString)) {\n throw new Error(\"Invalid time format. Use 'HH:mm'.\");\n }\n\n const [hours, minutes] = timeString.split(\":\").map(Number);\n const date = new Date(baseDate);\n\n date.setHours(hours, minutes, 0, 0);\n\n return date;\n}\n\n/**\n * Format file type\n */\nexport function formatFileType(type: string): string {\n return type.slice(0, type.lastIndexOf(\"/\"));\n}\n\n/**\n * Format date with time (Asia/Ho_Chi_Minh timezone)\n */\nexport function formatDateWithTime(value: string | number | Date): string {\n const date = new Date(value);\n return new Intl.DateTimeFormat(\"vi-VN\", {\n day: \"2-digit\",\n month: \"2-digit\",\n year: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n timeZone: \"Asia/Ho_Chi_Minh\",\n }).format(date);\n}\n\n/**\n * Format date short (MMM dd) - Asia/Ho_Chi_Minh timezone\n */\nexport function formatDateShort(value: string | number | Date): string {\n const date = new Date(value);\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"2-digit\",\n timeZone: \"Asia/Ho_Chi_Minh\",\n }).format(date);\n}\n\n/**\n * Format time (Asia/Ho_Chi_Minh timezone)\n */\nexport function formatTime(value: string | number | Date): string {\n const date = new Date(value);\n return new Intl.DateTimeFormat(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n timeZone: \"Asia/Ho_Chi_Minh\",\n }).format(date);\n}\n\n/**\n * Format duration from milliseconds\n */\nexport function formatDuration(value: string | number | Date): string {\n const numberValue = Number(value);\n const isNegative = numberValue < 0;\n const absoluteValue = Math.abs(numberValue);\n\n const hours = Math.floor(absoluteValue / 3600000);\n const minutes = Math.floor((absoluteValue % 3600000) / 60000);\n const seconds = Math.floor((absoluteValue % 60000) / 1000);\n\n const parts = [];\n if (hours) parts.push(`${hours}h`);\n if (minutes) parts.push(`${minutes}m`);\n if (seconds) parts.push(`${seconds}s`);\n\n const formattedDuration = parts.join(\" \") || \"0s\";\n\n return isNegative ? `-${formattedDuration}` : formattedDuration;\n}\n\n/**\n * Format distance to now\n */\nexport function formatDistance(value: string | number | Date): string {\n const date = new Date(value);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"just now\";\n if (diffMins < 60) return `${diffMins} mins ago`;\n if (diffHours < 24) return `${diffHours} hrs ago`;\n if (diffDays < 30) return `${diffDays} days ago`;\n if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`;\n return `${Math.floor(diffDays / 365)} years ago`;\n}\n\n// Re-export status constants from configs\nexport {\n STATUS_COLORS,\n STATUS_ACTIVE,\n STATUS_INACTIVE,\n STATUS_OPTIONS,\n STATUS_VALUES,\n booleanToStatus,\n statusToBoolean,\n} from \"../configs/status\";\n\n// ============================================================================\n// Localization Utilities\n// ============================================================================\n\nconst LOCALE_LIST = [\"vi\", \"en\"];\n\nexport function isPathnameMissingLocale(pathname: string) {\n return !LOCALE_LIST.some((locale) => pathname.startsWith(`/${locale}`));\n}\n\nexport function getLocaleFromPathname(pathname: string) {\n return LOCALE_LIST.find((locale) => pathname.startsWith(`/${locale}`));\n}\n\nexport function ensureLocalizedPathname(pathname: string, locale: string) {\n if (!pathname || !locale)\n throw new Error(\"Pathname or Locale cannot be empty\");\n return isPathnameMissingLocale(pathname)\n ? `${ensureWithPrefix(locale, \"/\")}${ensureWithPrefix(pathname, \"/\")}`\n : pathname;\n}\n\nexport function relocalizePathname(pathname: string, locale: string) {\n if (!pathname || !locale)\n throw new Error(\"Pathname or Locale cannot be empty\");\n const segments = pathname.split(\"/\");\n segments[1] = locale;\n return segments.join(\"/\");\n}\n\n// ============================================================================\n// Logger\n// ============================================================================\n\ntype LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\n\ninterface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n context?: Record<string, unknown>;\n error?: Error | unknown;\n}\n\nclass Logger {\n private log(\n level: LogLevel,\n message: string,\n context?: Record<string, unknown>,\n error?: unknown,\n ) {\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n message,\n context,\n };\n\n if (error instanceof Error) {\n entry.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n } else if (error) {\n entry.error = error;\n }\n\n const logString = JSON.stringify(entry);\n switch (level) {\n case \"error\":\n console.error(logString);\n break;\n case \"warn\":\n console.warn(logString);\n break;\n case \"debug\":\n if (process.env.NODE_ENV === \"development\") console.debug(logString);\n break;\n default:\n console.log(logString);\n }\n }\n\n info(message: string, context?: Record<string, unknown>) {\n this.log(\"info\", message, context);\n }\n warn(message: string, context?: Record<string, unknown>) {\n this.log(\"warn\", message, context);\n }\n error(message: string, error?: unknown, context?: Record<string, unknown>) {\n this.log(\"error\", message, context, error);\n }\n debug(message: string, context?: Record<string, unknown>) {\n this.log(\"debug\", message, context);\n }\n}\n\nexport const logger = new Logger();\n\n// ============================================================================\n// Tab Navigation Utilities\n// ============================================================================\n\nimport type {\n NavigationType,\n NavigationNestedItemWithHrefType,\n NavigationNestedItemWithItemsType,\n DynamicIconNameType,\n} from \"../types\";\n\nexport function shouldExcludeFromTabs(pathname: string): boolean {\n const excludePatterns = [\n \"/sign-in\",\n \"/sign-out\",\n \"/forgot-password\",\n \"/new-password\",\n \"/verify-email\",\n \"/register\",\n \"/unauthorized\",\n \"/not-found\",\n \"/maintenance\",\n \"/coming-soon\",\n ];\n if (\n pathname.includes(\"/ui/\") ||\n pathname.includes(\"/colors\") ||\n pathname.includes(\"/typography\")\n )\n return true;\n return excludePatterns.some((pattern) => pathname.includes(pattern));\n}\n\nexport function normalizePathname(pathname: string): string {\n return pathname.replace(/^\\/[a-z]{2}(\\/|$)/, \"/\") || \"/\";\n}\n\nfunction formatSegmentLabel(segment: string): string {\n return segment\n .replace(/[-_]+/g, \" \")\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport function findRouteTitle(\n pathname: string,\n navigations: NavigationType[],\n): string | null {\n const result = findRouteInfo(pathname, navigations);\n return result?.title || null;\n}\n\nexport function findRouteIcon(\n pathname: string,\n navigations: NavigationType[],\n): DynamicIconNameType | null {\n const result = findRouteInfo(pathname, navigations);\n return (result?.iconName as DynamicIconNameType) || null;\n}\n\ninterface RouteInfo {\n title: string;\n iconName?: DynamicIconNameType;\n}\n\nfunction findRouteInfo(\n pathname: string,\n navigations: NavigationType[],\n): RouteInfo | null {\n const normalizedPath = normalizePathname(pathname);\n let exactMatch: RouteInfo | null = null;\n const prefixMatches: Array<{ itemPath: string; routeInfo: RouteInfo }> = [];\n\n function searchItems(\n items:\n | NavigationType[\"items\"]\n | Array<\n NavigationNestedItemWithHrefType | NavigationNestedItemWithItemsType\n >\n | undefined,\n ): void {\n if (!items) return;\n for (const item of items) {\n if (\"href\" in item && item.href) {\n const itemPath = normalizePathname(item.href);\n if (normalizedPath === itemPath) {\n exactMatch = {\n title: item.title,\n iconName:\n \"iconName\" in item\n ? (item.iconName as DynamicIconNameType | undefined)\n : undefined,\n };\n } else if (normalizedPath.startsWith(itemPath + \"/\")) {\n prefixMatches.push({\n itemPath,\n routeInfo: {\n title: item.title,\n iconName:\n \"iconName\" in item\n ? (item.iconName as DynamicIconNameType | undefined)\n : undefined,\n },\n });\n }\n }\n if (\"items\" in item && item.items) searchItems(item.items);\n }\n }\n\n for (const nav of navigations) {\n searchItems(nav.items);\n if (exactMatch) return exactMatch;\n }\n\n if (prefixMatches.length > 0) {\n prefixMatches.sort((a, b) => b.itemPath.length - a.itemPath.length);\n return prefixMatches[0].routeInfo;\n }\n\n const segments = normalizedPath.split(\"/\").filter(Boolean);\n return segments.length > 0\n ? { title: formatSegmentLabel(segments[segments.length - 1]) }\n : { title: \"Home\" };\n}\n","\"use client\";\n\nimport { format } from \"date-fns\";\nimport { vi } from \"date-fns/locale\";\nimport { TrendingUp, Zap } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\ninterface WelcomeCardProps {\n userName?: string;\n className?: string;\n}\n\nfunction getGreeting(hour: number): { text: string; emoji: string } {\n if (hour >= 5 && hour < 12) {\n return { text: \"Chào buổi sáng\", emoji: \"🌅\" };\n } else if (hour >= 12 && hour < 18) {\n return { text: \"Chào buổi chiều\", emoji: \"☀️\" };\n } else {\n return { text: \"Chào buổi tối\", emoji: \"🌙\" };\n }\n}\n\nexport function WelcomeCard({ userName = \"Bạn\", className }: WelcomeCardProps) {\n const now = new Date();\n const hour = now.getHours();\n const greeting = getGreeting(hour);\n\n const formattedDate = format(now, \"EEEE, dd/MM/yyyy\", { locale: vi });\n const formattedTime = format(now, \"HH:mm\");\n\n return (\n <div\n className={cn(\n \"w-full bg-gradient-to-r from-blue-900 to-primary rounded-xl overflow-hidden shadow-lg group relative animate-in fade-in slide-in-from-bottom-4 duration-500\",\n className,\n )}\n >\n {/* Background decoration */}\n <div\n className=\"absolute inset-0 opacity-20 pointer-events-none\"\n style={{\n backgroundImage:\n \"radial-gradient(circle at 80% 20%, white 0%, transparent 40%), radial-gradient(circle at 10% 80%, white 0%, transparent 30%)\",\n }}\n />\n\n <div className=\"flex flex-col md:flex-row items-center relative overflow-hidden\">\n {/* Content Left */}\n <div className=\"p-8 flex-1 z-10 w-full\">\n <div className=\"flex items-center gap-2 mb-4\">\n <span className=\"bg-white/20 text-white text-xs font-bold px-2 py-1 rounded uppercase tracking-wider backdrop-blur-sm\">\n {formattedDate}\n </span>\n </div>\n <h2 className=\"text-white text-2xl md:text-3xl font-bold mb-3\">\n {greeting.text}, {userName}\n </h2>\n <div className=\"text-blue-100 mb-6 max-w-lg\">\n Chúc bạn một ngày làm việc hiệu quả. Hệ thống đang hoạt động ổn\n định.\n </div>\n <div className=\"flex gap-3\">\n <div className=\"bg-white/10 text-white px-5 py-2.5 rounded-lg text-sm font-bold shadow-sm backdrop-blur-sm border border-white/20 flex items-center gap-2\">\n <span className=\"w-2 h-2 rounded-full bg-green-400 animate-pulse\" />\n <span>Online • {formattedTime}</span>\n </div>\n </div>\n </div>\n\n {/* Visuals Right (Hidden on mobile) */}\n <div className=\"hidden md:flex flex-1 justify-end items-end h-full p-8 z-10 self-stretch\">\n <div className=\"grid grid-cols-2 gap-3 opacity-90 transform translate-y-4\">\n <div className=\"bg-white/10 backdrop-blur-md border border-white/20 p-3 rounded-lg flex items-center gap-3\">\n <TrendingUp className=\"text-white w-6 h-6\" />\n <div>\n <div className=\"h-1.5 w-12 bg-white/40 rounded mb-1\" />\n <div className=\"h-1.5 w-8 bg-white/20 rounded\" />\n </div>\n </div>\n <div className=\"bg-white/10 backdrop-blur-md border border-white/20 p-3 rounded-lg flex items-center gap-3\">\n <Zap className=\"text-white w-6 h-6\" />\n <div>\n <div className=\"h-1.5 w-12 bg-white/40 rounded mb-1\" />\n <div className=\"h-1.5 w-8 bg-white/20 rounded\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","// Widget System Types for Home Page\n\nexport type WidgetType = \"revenue\" | \"orders\" | \"customers\" | \"stock\";\n\nexport type WidgetSize = \"small\" | \"medium\" | \"large\";\n\nexport interface WidgetConfig {\n id: string;\n type: WidgetType;\n position: number;\n visible: boolean;\n size: WidgetSize;\n settings?: Record<string, unknown>;\n}\n\nexport interface WidgetProps {\n config: WidgetConfig;\n onRemove?: () => void;\n onSettings?: () => void;\n className?: string;\n}\n\nexport interface WidgetData {\n value: number | string;\n label: string;\n change?: {\n value: number;\n type: \"increase\" | \"decrease\";\n period: string;\n };\n loading?: boolean;\n error?: string;\n}\n\nexport interface QuickAccessItem {\n id: string;\n label: string;\n href: string;\n icon: string;\n color?: string;\n}\n\nexport interface UserHomePreferences {\n widgets: WidgetConfig[];\n quickAccess: QuickAccessItem[]; // List of quick access items\n}\n\nexport const DEFAULT_WIDGETS: WidgetConfig[] = [\n {\n id: \"revenue\",\n type: \"revenue\",\n position: 0,\n visible: true,\n size: \"medium\",\n },\n { id: \"orders\", type: \"orders\", position: 1, visible: true, size: \"medium\" },\n {\n id: \"customers\",\n type: \"customers\",\n position: 2,\n visible: true,\n size: \"medium\",\n },\n { id: \"stock\", type: \"stock\", position: 3, visible: true, size: \"medium\" },\n];\n\nexport const WIDGET_LABELS: Record<WidgetType, string> = {\n revenue: \"Doanh thu\",\n orders: \"Đơn hàng\",\n customers: \"Khách hàng\",\n stock: \"Tồn kho\",\n};\n\nexport interface ERPFeature {\n id: string;\n icon: string;\n title: string;\n description: string;\n subFeatures: string[];\n color: string;\n}\n\nexport const ERP_FEATURES: ERPFeature[] = [\n {\n id: \"inventory\",\n icon: \"📦\",\n title: \"Quản lý Kho\",\n description: \"Quản lý toàn diện hàng hóa và tồn kho\",\n subFeatures: [\"Nhập/Xuất kho\", \"Kiểm kê\", \"Điều chuyển\", \"Cảnh báo tồn\"],\n color: \"from-blue-500 to-cyan-500\",\n },\n {\n id: \"sales\",\n icon: \"💰\",\n title: \"Quản lý Bán hàng\",\n description: \"Xử lý đơn hàng và bán hàng hiệu quả\",\n subFeatures: [\"POS\", \"Đơn hàng\", \"Hợp đồng\", \"Báo giá\"],\n color: \"from-green-500 to-emerald-500\",\n },\n {\n id: \"purchasing\",\n icon: \"🛒\",\n title: \"Quản lý Mua hàng\",\n description: \"Quản lý nhà cung cấp và đặt hàng\",\n subFeatures: [\"Đặt hàng NCC\", \"Nhập hàng\", \"Công nợ phải trả\"],\n color: \"from-orange-500 to-amber-500\",\n },\n {\n id: \"finance\",\n icon: \"💵\",\n title: \"Tài chính\",\n description: \"Quản lý dòng tiền và công nợ\",\n subFeatures: [\"Thu/Chi\", \"Sổ quỹ\", \"Công nợ\", \"Báo cáo tài chính\"],\n color: \"from-purple-500 to-violet-500\",\n },\n {\n id: \"crm\",\n icon: \"👥\",\n title: \"CRM\",\n description: \"Chăm sóc và quản lý khách hàng\",\n subFeatures: [\"Khách hàng\", \"Lịch sử giao dịch\", \"Phân loại\"],\n color: \"from-pink-500 to-rose-500\",\n },\n {\n id: \"hr\",\n icon: \"👨‍💼\",\n title: \"Nhân sự\",\n description: \"Quản lý người dùng và phân quyền\",\n subFeatures: [\"Users\", \"Phân quyền\", \"Roles\"],\n color: \"from-indigo-500 to-blue-500\",\n },\n {\n id: \"reports\",\n icon: \"📊\",\n title: \"Báo cáo\",\n description: \"Thống kê và phân tích dữ liệu\",\n subFeatures: [\"Dashboard\", \"Thống kê\", \"Export\"],\n color: \"from-teal-500 to-green-500\",\n },\n];\n","\"use client\";\n\nimport { motion } from \"framer-motion\";\nimport { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { GripVertical, Settings, X, Eye, EyeOff } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { WidgetConfig, WidgetSize } from \"../types\";\n\ninterface BaseWidgetProps {\n config: WidgetConfig;\n title: string;\n children: React.ReactNode;\n loading?: boolean;\n error?: string;\n onRemove?: () => void;\n onToggleVisibility?: () => void;\n onSettings?: () => void;\n className?: string;\n isDragging?: boolean;\n}\n\nconst sizeClasses: Record<WidgetSize, string> = {\n small: \"col-span-1\",\n medium: \"col-span-1 md:col-span-1\",\n large: \"col-span-1 md:col-span-2\",\n};\n\nexport function BaseWidget({\n config,\n title,\n children,\n loading = false,\n error,\n onRemove,\n onToggleVisibility,\n onSettings,\n className,\n isDragging = false,\n}: BaseWidgetProps) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging: isSortableDragging,\n } = useSortable({ id: config.id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n const isCurrentlyDragging = isDragging || isSortableDragging;\n\n if (!config.visible) {\n return null;\n }\n\n return (\n <motion.div\n ref={setNodeRef}\n style={style}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n // @ts-ignore className is valid for motion.div\n className={cn(\n \"group relative flex flex-col justify-between gap-3 rounded-xl border border-slate-200 bg-white p-5 shadow-sm transition-all hover:border-primary/30 hover:shadow-md dark:border-slate-700 dark:bg-slate-800\",\n sizeClasses[config.size],\n isCurrentlyDragging && \"z-50 shadow-lg ring-2 ring-primary/20\",\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between mb-1\">\n <div className=\"flex items-center gap-2\">\n {/* Drag handle */}\n <button\n {...attributes}\n {...listeners}\n className=\"cursor-grab touch-none rounded text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 active:cursor-grabbing opacity-0 group-hover:opacity-100 transition-opacity\"\n aria-label=\"Drag to reorder\"\n >\n <GripVertical className=\"h-4 w-4\" />\n </button>\n <h4 className=\"flex items-center gap-2 text-sm font-semibold text-slate-900 dark:text-white\">\n {title}\n </h4>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100\">\n {onToggleVisibility && (\n <button\n onClick={onToggleVisibility}\n className=\"rounded p-1 text-slate-400 hover:bg-slate-100 hover:text-slate-700 dark:hover:bg-slate-700 dark:hover:text-slate-300\"\n aria-label={config.visible ? \"Hide widget\" : \"Show widget\"}\n >\n {config.visible ? (\n <Eye className=\"h-4 w-4\" />\n ) : (\n <EyeOff className=\"h-4 w-4\" />\n )}\n </button>\n )}\n {onSettings && (\n <button\n onClick={onSettings}\n className=\"rounded p-1 text-slate-400 hover:bg-slate-100 hover:text-slate-700 dark:hover:bg-slate-700 dark:hover:text-slate-300\"\n aria-label=\"Widget settings\"\n >\n <Settings className=\"h-4 w-4\" />\n </button>\n )}\n {onRemove && (\n <button\n onClick={onRemove}\n className=\"rounded p-1 text-slate-400 hover:bg-red-50 hover:text-red-500 dark:hover:bg-red-900/20\"\n aria-label=\"Remove widget\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center py-4\">\n <div className=\"h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent\" />\n </div>\n ) : error ? (\n <div className=\"flex items-center justify-center py-4 text-xs text-red-500\">\n {error}\n </div>\n ) : (\n children\n )}\n </div>\n </motion.div>\n );\n}\n\n// Stat display component for widgets\ninterface WidgetStatProps {\n value: string | number;\n label?: string;\n change?: {\n value: number;\n type: \"increase\" | \"decrease\";\n period?: string;\n };\n valueClassName?: string;\n}\n\nexport function WidgetStat({\n value,\n label,\n change,\n valueClassName,\n}: WidgetStatProps) {\n return (\n <div className=\"space-y-2\">\n <div className={cn(\"text-3xl font-bold text-foreground\", valueClassName)}>\n {value}\n </div>\n {label && <p className=\"text-sm text-muted-foreground\">{label}</p>}\n {change && (\n <div\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium\",\n change.type === \"increase\"\n ? \"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\"\n : \"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\",\n )}\n >\n {change.type === \"increase\" ? (\n <svg className=\"h-3 w-3\" viewBox=\"0 0 12 12\" fill=\"currentColor\">\n <path d=\"M6 2L10 7H2L6 2Z\" />\n </svg>\n ) : (\n <svg className=\"h-3 w-3\" viewBox=\"0 0 12 12\" fill=\"currentColor\">\n <path d=\"M6 10L2 5H10L6 10Z\" />\n </svg>\n )}\n <span>\n {change.value > 0 ? \"+\" : \"\"}\n {change.value}%\n </span>\n {change.period && (\n <span className=\"text-muted-foreground\">vs {change.period}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { DollarSign } from \"lucide-react\";\nimport { BaseWidget, WidgetStat } from \"./base-widget\";\nimport type { WidgetConfig } from \"../types\";\n\ninterface RevenueWidgetProps {\n config: WidgetConfig;\n data?: {\n total: number;\n change?: number;\n changePeriod?: string;\n };\n loading?: boolean;\n error?: string;\n onRemove?: () => void;\n onToggleVisibility?: () => void;\n onSettings?: () => void;\n}\n\nfunction formatCurrency(value: number): string {\n return new Intl.NumberFormat(\"vi-VN\", {\n style: \"currency\",\n currency: \"VND\",\n maximumFractionDigits: 0,\n }).format(value);\n}\n\nexport function RevenueWidget({\n config,\n data,\n loading,\n error,\n onRemove,\n onToggleVisibility,\n onSettings,\n}: RevenueWidgetProps) {\n const formattedValue = data ? formatCurrency(data.total) : \"0 ₫\";\n\n return (\n <BaseWidget\n config={config}\n title=\"Doanh thu\"\n loading={loading}\n error={error}\n onRemove={onRemove}\n onToggleVisibility={onToggleVisibility}\n onSettings={onSettings}\n >\n <div className=\"flex items-start justify-between\">\n <WidgetStat\n value={formattedValue}\n label=\"Hôm nay\"\n change={\n data?.change !== undefined\n ? {\n value: data.change,\n type: data.change >= 0 ? \"increase\" : \"decrease\",\n period: data.changePeriod || \"hôm qua\",\n }\n : undefined\n }\n valueClassName=\"text-green-600 dark:text-green-400\"\n />\n <div className=\"rounded-full bg-green-100 p-3 dark:bg-green-900/30\">\n <DollarSign className=\"h-6 w-6 text-green-600 dark:text-green-400\" />\n </div>\n </div>\n </BaseWidget>\n );\n}\n","\"use client\";\n\nimport { ShoppingCart } from \"lucide-react\";\nimport { BaseWidget, WidgetStat } from \"./base-widget\";\nimport type { WidgetConfig } from \"../types\";\n\ninterface OrdersWidgetProps {\n config: WidgetConfig;\n data?: {\n total: number;\n pending?: number;\n completed?: number;\n change?: number;\n changePeriod?: string;\n };\n loading?: boolean;\n error?: string;\n onRemove?: () => void;\n onToggleVisibility?: () => void;\n onSettings?: () => void;\n}\n\nexport function OrdersWidget({\n config,\n data,\n loading,\n error,\n onRemove,\n onToggleVisibility,\n onSettings,\n}: OrdersWidgetProps) {\n return (\n <BaseWidget\n config={config}\n title=\"Đơn hàng\"\n loading={loading}\n error={error}\n onRemove={onRemove}\n onToggleVisibility={onToggleVisibility}\n onSettings={onSettings}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"space-y-3\">\n <WidgetStat\n value={data?.total ?? 0}\n label=\"Đơn hôm nay\"\n change={\n data?.change !== undefined\n ? {\n value: data.change,\n type: data.change >= 0 ? \"increase\" : \"decrease\",\n period: data.changePeriod || \"hôm qua\",\n }\n : undefined\n }\n valueClassName=\"text-blue-600 dark:text-blue-400\"\n />\n\n {(data?.pending !== undefined || data?.completed !== undefined) && (\n <div className=\"flex gap-4 text-sm\">\n {data?.pending !== undefined && (\n <div>\n <span className=\"text-muted-foreground\">Chờ xử lý: </span>\n <span className=\"font-medium text-amber-600 dark:text-amber-400\">\n {data.pending}\n </span>\n </div>\n )}\n {data?.completed !== undefined && (\n <div>\n <span className=\"text-muted-foreground\">Hoàn thành: </span>\n <span className=\"font-medium text-green-600 dark:text-green-400\">\n {data.completed}\n </span>\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"rounded-full bg-blue-100 p-3 dark:bg-blue-900/30\">\n <ShoppingCart className=\"h-6 w-6 text-blue-600 dark:text-blue-400\" />\n </div>\n </div>\n </BaseWidget>\n );\n}\n","\"use client\";\n\nimport { Users } from \"lucide-react\";\nimport { BaseWidget, WidgetStat } from \"./base-widget\";\nimport type { WidgetConfig } from \"../types\";\n\ninterface CustomersWidgetProps {\n config: WidgetConfig;\n data?: {\n total: number;\n newToday?: number;\n change?: number;\n changePeriod?: string;\n };\n loading?: boolean;\n error?: string;\n onRemove?: () => void;\n onToggleVisibility?: () => void;\n onSettings?: () => void;\n}\n\nexport function CustomersWidget({\n config,\n data,\n loading,\n error,\n onRemove,\n onToggleVisibility,\n onSettings,\n}: CustomersWidgetProps) {\n return (\n <BaseWidget\n config={config}\n title=\"Khách hàng\"\n loading={loading}\n error={error}\n onRemove={onRemove}\n onToggleVisibility={onToggleVisibility}\n onSettings={onSettings}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"space-y-3\">\n <WidgetStat\n value={data?.total ?? 0}\n label=\"Tổng khách hàng\"\n change={\n data?.change !== undefined\n ? {\n value: data.change,\n type: data.change >= 0 ? \"increase\" : \"decrease\",\n period: data.changePeriod || \"tháng trước\",\n }\n : undefined\n }\n valueClassName=\"text-purple-600 dark:text-purple-400\"\n />\n\n {data?.newToday !== undefined && data.newToday > 0 && (\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">Khách mới hôm nay: </span>\n <span className=\"font-medium text-green-600 dark:text-green-400\">\n +{data.newToday}\n </span>\n </div>\n )}\n </div>\n\n <div className=\"rounded-full bg-purple-100 p-3 dark:bg-purple-900/30\">\n <Users className=\"h-6 w-6 text-purple-600 dark:text-purple-400\" />\n </div>\n </div>\n </BaseWidget>\n );\n}\n","\"use client\";\n\nimport { Package, AlertTriangle } from \"lucide-react\";\nimport { BaseWidget } from \"./base-widget\";\nimport type { WidgetConfig } from \"../types\";\nimport { cn } from \"../../utils\";\n\ninterface StockItem {\n id: string;\n name: string;\n quantity: number;\n minStock: number;\n}\n\ninterface StockWidgetProps {\n config: WidgetConfig;\n data?: {\n totalItems: number;\n lowStockCount: number;\n lowStockItems?: StockItem[];\n };\n loading?: boolean;\n error?: string;\n onRemove?: () => void;\n onToggleVisibility?: () => void;\n onSettings?: () => void;\n}\n\nexport function StockWidget({\n config,\n data,\n loading,\n error,\n onRemove,\n onToggleVisibility,\n onSettings,\n}: StockWidgetProps) {\n const hasLowStock = (data?.lowStockCount ?? 0) > 0;\n\n return (\n <BaseWidget\n config={config}\n title=\"Tồn kho\"\n loading={loading}\n error={error}\n onRemove={onRemove}\n onToggleVisibility={onToggleVisibility}\n onSettings={onSettings}\n >\n <div className=\"space-y-4\">\n {/* Summary */}\n <div className=\"flex items-start justify-between\">\n <div className=\"space-y-1\">\n <div className=\"text-3xl font-bold text-foreground\">\n {data?.totalItems ?? 0}\n </div>\n <p className=\"text-sm text-muted-foreground\">Tổng mặt hàng</p>\n </div>\n\n <div className=\"rounded-full bg-orange-100 p-3 dark:bg-orange-900/30\">\n <Package className=\"h-6 w-6 text-orange-600 dark:text-orange-400\" />\n </div>\n </div>\n\n {/* Low stock alert */}\n {hasLowStock && (\n <div\n className={cn(\n \"flex items-center gap-2 rounded-lg px-3 py-2\",\n \"bg-amber-50 text-amber-800 dark:bg-amber-900/20 dark:text-amber-400\",\n )}\n >\n <AlertTriangle className=\"h-4 w-4 flex-shrink-0\" />\n <span className=\"text-sm font-medium\">\n {data?.lowStockCount} sản phẩm sắp hết hàng\n </span>\n </div>\n )}\n\n {/* Low stock items list */}\n {data?.lowStockItems && data.lowStockItems.length > 0 && (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n Cảnh báo tồn kho\n </p>\n <div className=\"space-y-1.5 max-h-32 overflow-y-auto\">\n {data.lowStockItems.slice(0, 5).map((item) => (\n <div\n key={item.id}\n className=\"flex items-center justify-between text-sm\"\n >\n <span className=\"truncate text-foreground\">{item.name}</span>\n <span className=\"flex-shrink-0 font-medium text-red-600 dark:text-red-400\">\n {item.quantity}/{item.minStock}\n </span>\n </div>\n ))}\n {data.lowStockItems.length > 5 && (\n <p className=\"text-xs text-muted-foreground\">\n +{data.lowStockItems.length - 5} sản phẩm khác\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n </BaseWidget>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport type { DragEndEvent } from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n rectSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { Plus, Eye, EyeOff, RotateCcw } from \"lucide-react\";\nimport { cn } from \"../utils\";\nimport type { WidgetConfig } from \"./types\";\nimport { DEFAULT_WIDGETS, WIDGET_LABELS } from \"./types\";\nimport { RevenueWidget } from \"./widgets/revenue-widget\";\nimport { OrdersWidget } from \"./widgets/orders-widget\";\nimport { CustomersWidget } from \"./widgets/customers-widget\";\nimport { StockWidget } from \"./widgets/stock-widget\";\n\ninterface WidgetContainerProps {\n widgets: WidgetConfig[];\n onWidgetsChange: (widgets: WidgetConfig[]) => void;\n widgetData?: {\n revenue?: { total: number; change?: number };\n orders?: {\n total: number;\n pending?: number;\n completed?: number;\n change?: number;\n };\n customers?: { total: number; newToday?: number; change?: number };\n stock?: {\n totalItems: number;\n lowStockCount: number;\n lowStockItems?: Array<{\n id: string;\n name: string;\n quantity: number;\n minStock: number;\n }>;\n };\n };\n loading?: boolean;\n className?: string;\n}\n\nexport function WidgetContainer({\n widgets,\n onWidgetsChange,\n widgetData,\n loading = false,\n className,\n}: WidgetContainerProps) {\n const [showHiddenWidgets, setShowHiddenWidgets] = useState(false);\n\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 8,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n\n if (over && active.id !== over.id) {\n const oldIndex = widgets.findIndex((w) => w.id === active.id);\n const newIndex = widgets.findIndex((w) => w.id === over.id);\n\n const newWidgets = arrayMove(widgets, oldIndex, newIndex).map(\n (widget, index) => ({\n ...widget,\n position: index,\n }),\n );\n\n onWidgetsChange(newWidgets);\n }\n },\n [widgets, onWidgetsChange],\n );\n\n const handleToggleVisibility = useCallback(\n (widgetId: string) => {\n const newWidgets = widgets.map((widget) =>\n widget.id === widgetId\n ? { ...widget, visible: !widget.visible }\n : widget,\n );\n onWidgetsChange(newWidgets);\n },\n [widgets, onWidgetsChange],\n );\n\n const handleRemoveWidget = useCallback(\n (widgetId: string) => {\n const newWidgets = widgets.map((widget) =>\n widget.id === widgetId ? { ...widget, visible: false } : widget,\n );\n onWidgetsChange(newWidgets);\n },\n [widgets, onWidgetsChange],\n );\n\n const handleResetWidgets = useCallback(() => {\n onWidgetsChange(DEFAULT_WIDGETS);\n }, [onWidgetsChange]);\n\n const visibleWidgets = widgets\n .filter((w) => w.visible)\n .sort((a, b) => a.position - b.position);\n\n const hiddenWidgets = widgets.filter((w) => !w.visible);\n\n const renderWidget = (config: WidgetConfig) => {\n const commonProps = {\n config,\n loading,\n onRemove: () => handleRemoveWidget(config.id),\n onToggleVisibility: () => handleToggleVisibility(config.id),\n };\n\n switch (config.type) {\n case \"revenue\":\n return <RevenueWidget {...commonProps} data={widgetData?.revenue} />;\n case \"orders\":\n return <OrdersWidget {...commonProps} data={widgetData?.orders} />;\n case \"customers\":\n return (\n <CustomersWidget {...commonProps} data={widgetData?.customers} />\n );\n case \"stock\":\n return <StockWidget {...commonProps} data={widgetData?.stock} />;\n default:\n return null;\n }\n };\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-xl font-semibold text-foreground\">\n Widget Dashboard\n </h2>\n <div className=\"flex items-center gap-2\">\n {hiddenWidgets.length > 0 && (\n <button\n onClick={() => setShowHiddenWidgets(!showHiddenWidgets)}\n className=\"inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors\"\n >\n {showHiddenWidgets ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n <span>{hiddenWidgets.length} ẩn</span>\n </button>\n )}\n <button\n onClick={handleResetWidgets}\n className=\"inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors\"\n title=\"Khôi phục mặc định\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n\n {/* Hidden widgets panel */}\n <AnimatePresence>\n {showHiddenWidgets && hiddenWidgets.length > 0 && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: \"auto\" }}\n exit={{ opacity: 0, height: 0 }}\n // @ts-ignore className is valid for motion.div\n className=\"overflow-hidden\"\n >\n <div className=\"rounded-lg border border-dashed border-border bg-muted/30 p-4\">\n <p className=\"mb-3 text-sm font-medium text-muted-foreground\">\n Widget đã ẩn - Click để hiển thị lại\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {hiddenWidgets.map((widget) => (\n <button\n key={widget.id}\n onClick={() => handleToggleVisibility(widget.id)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-background px-3 py-2 text-sm font-medium shadow-sm border border-border hover:bg-muted transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n {WIDGET_LABELS[widget.type]}\n </button>\n ))}\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Sortable widget grid */}\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={visibleWidgets.map((w) => w.id)}\n strategy={rectSortingStrategy}\n >\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <AnimatePresence mode=\"popLayout\">\n {visibleWidgets.map((widget) => (\n <div key={widget.id}>{renderWidget(widget)}</div>\n ))}\n </AnimatePresence>\n </div>\n </SortableContext>\n </DndContext>\n\n {/* Empty state */}\n {visibleWidgets.length === 0 && (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-border py-12 text-center\">\n <div className=\"rounded-full bg-muted p-3 mb-4\">\n <Plus className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n <h3 className=\"font-medium text-foreground mb-1\">\n Chưa có widget nào\n </h3>\n <p className=\"text-sm text-muted-foreground mb-4\">\n Thêm widget để theo dõi các chỉ số quan trọng\n </p>\n <button\n onClick={handleResetWidgets}\n className=\"inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Khôi phục mặc định\n </button>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport Autoplay from \"embla-carousel-autoplay\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../utils\";\nimport { ERP_FEATURES } from \"./types\";\nimport type { ERPFeature } from \"./types\";\n\ninterface FeatureShowcaseProps {\n className?: string;\n}\n\nexport function FeatureShowcase({ className }: FeatureShowcaseProps) {\n const [emblaRef, emblaApi] = useEmblaCarousel(\n { loop: true, align: \"start\" },\n [Autoplay({ delay: 5000, stopOnInteraction: true })],\n );\n const [prevBtnEnabled, setPrevBtnEnabled] = useState(false);\n const [nextBtnEnabled, setNextBtnEnabled] = useState(false);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);\n\n const scrollPrev = useCallback(\n () => emblaApi && emblaApi.scrollPrev(),\n [emblaApi],\n );\n const scrollNext = useCallback(\n () => emblaApi && emblaApi.scrollNext(),\n [emblaApi],\n );\n const scrollTo = useCallback(\n (index: number) => emblaApi && emblaApi.scrollTo(index),\n [emblaApi],\n );\n\n const onSelect = useCallback(() => {\n if (!emblaApi) return;\n setSelectedIndex(emblaApi.selectedScrollSnap());\n setPrevBtnEnabled(emblaApi.canScrollPrev());\n setNextBtnEnabled(emblaApi.canScrollNext());\n }, [emblaApi]);\n\n useEffect(() => {\n if (!emblaApi) return;\n onSelect();\n setScrollSnaps(emblaApi.scrollSnapList());\n emblaApi.on(\"select\", onSelect);\n emblaApi.on(\"reInit\", onSelect);\n return () => {\n emblaApi.off(\"select\", onSelect);\n emblaApi.off(\"reInit\", onSelect);\n };\n }, [emblaApi, onSelect]);\n\n return (\n <div\n className={cn(\n \"bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 shadow-sm relative overflow-hidden flex flex-col h-full\",\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-slate-100 dark:border-slate-700/50 bg-white/50 dark:bg-slate-800/50 backdrop-blur-sm z-20\">\n <div className=\"flex items-center gap-2\">\n <div className=\"bg-blue-100 dark:bg-blue-900/30 text-primary p-1 rounded-md\">\n <svg\n className=\"w-[18px] h-[18px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M12 2v20M2 12h20M12 2a10 10 0 0 1 10 10 10 10 0 0 1-10 10 10 10 0 0 1-10-10 10 10 0 0 1 10-10z\" />\n </svg>\n </div>\n <span className=\"text-sm font-bold text-slate-700 dark:text-slate-200\">\n Feature Tour\n </span>\n </div>\n <button className=\"text-xs font-medium text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200 px-3 py-1.5 rounded hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors\">\n Skip Tour\n </button>\n </div>\n\n {/* Carousel Content */}\n <div\n className=\"flex-1 relative overflow-hidden bg-slate-50/50 dark:bg-slate-800/50\"\n ref={emblaRef}\n >\n <div className=\"flex touch-pan-y h-full\">\n {ERP_FEATURES.map((feature, index) => (\n <div key={feature.id} className=\"flex-[0_0_100%] min-w-0\">\n <div className=\"p-6 sm:p-8 flex flex-col items-center text-center gap-6 h-full justify-center\">\n <div className=\"mb-2 text-xs font-semibold text-primary uppercase tracking-wider\">\n Step {index + 1} of {ERP_FEATURES.length}\n </div>\n\n <div\n className={cn(\n \"flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br text-3xl shadow-md\",\n feature.color,\n )}\n >\n {feature.icon}\n </div>\n\n <h2 className=\"text-2xl md:text-3xl font-bold text-slate-900 dark:text-white\">\n {feature.title}\n </h2>\n\n <p className=\"text-slate-500 dark:text-slate-400 text-sm md:text-base leading-relaxed max-w-md\">\n {feature.description}\n </p>\n\n <div className=\"flex gap-2 justify-center flex-wrap\">\n {feature.subFeatures.map((sub) => (\n <span\n key={sub}\n className=\"px-2 py-1 bg-white dark:bg-slate-700 border border-slate-200 dark:border-slate-600 rounded-md text-xs font-medium text-slate-600 dark:text-slate-300\"\n >\n {sub}\n </span>\n ))}\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n\n {/* Footer Navigation */}\n <div className=\"px-6 py-4 bg-white dark:bg-slate-800 border-t border-slate-100 dark:border-slate-700 flex items-center justify-between z-20\">\n {/* Dots */}\n <div className=\"flex gap-1.5\">\n {scrollSnaps.map((_, index) => (\n <button\n key={index}\n className={cn(\n \"h-1.5 rounded-full transition-all duration-300\",\n index === selectedIndex\n ? \"w-6 bg-primary\"\n : \"w-1.5 bg-slate-300 dark:bg-slate-600\",\n )}\n onClick={() => scrollTo(index)}\n />\n ))}\n </div>\n\n {/* Buttons */}\n <div className=\"flex gap-3\">\n <button\n onClick={scrollPrev}\n disabled={!prevBtnEnabled}\n className=\"w-9 h-9 flex items-center justify-center rounded-lg border border-slate-200 dark:border-slate-700 text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <ChevronLeft className=\"w-4 h-4\" />\n </button>\n <button\n onClick={scrollNext}\n className=\"h-9 px-4 rounded-lg bg-primary text-white text-sm font-medium flex items-center gap-2 hover:bg-primary/90 transition-colors shadow-sm\"\n >\n Next\n <ChevronRight className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import React from \"react\";\n\n// Icon mapping for common actions\nexport const iconMap: Record<string, React.ReactNode> = {\n \"shopping-cart\": (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z\"\n />\n </svg>\n ),\n users: (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z\"\n />\n </svg>\n ),\n package: (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4\"\n />\n </svg>\n ),\n \"chart-bar\": (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"\n />\n </svg>\n ),\n \"document-text\": (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n ),\n cog: (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n ),\n \"currency-dollar\": (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n ),\n \"clipboard-list\": (\n <svg\n className=\"h-5 w-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01\"\n />\n </svg>\n ),\n};\n\nexport const colorClasses: Record<string, string> = {\n blue: \"bg-blue-500 hover:bg-blue-600 text-white\",\n green: \"bg-green-500 hover:bg-green-600 text-white\",\n purple: \"bg-purple-500 hover:bg-purple-600 text-white\",\n orange: \"bg-orange-500 hover:bg-orange-600 text-white\",\n pink: \"bg-pink-500 hover:bg-pink-600 text-white\",\n indigo: \"bg-indigo-500 hover:bg-indigo-600 text-white\",\n teal: \"bg-teal-500 hover:bg-teal-600 text-white\",\n red: \"bg-red-500 hover:bg-red-600 text-white\",\n};\n","\"use client\";\nimport { useEffect } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\n\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"../utils\";\nimport type { QuickAccessItem } from \"./types\";\nimport { iconMap } from \"./constants\";\n\nconst AVAILABLE_ICONS = Object.keys(iconMap);\nconst AVAILABLE_COLORS = [\n \"blue\",\n \"green\",\n \"purple\",\n \"orange\",\n \"pink\",\n \"indigo\",\n \"teal\",\n \"red\",\n];\n\nconst formSchema = z.object({\n label: z.string().min(1, \"Vui lòng nhập tên lối tắt\"),\n href: z.string().min(1, \"Vui lòng nhập đường dẫn\"),\n icon: z.string(),\n color: z.string(),\n});\n\ntype FormValues = z.infer<typeof formSchema>;\n\ninterface QuickAccessDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubmit: (data: Omit<QuickAccessItem, \"id\">) => void;\n initialData?: QuickAccessItem;\n availableFeatures?: Array<{ label: string; href: string; icon?: string }>;\n}\n\nexport function QuickAccessDialog({\n open,\n onOpenChange,\n onSubmit,\n initialData,\n availableFeatures,\n}: QuickAccessDialogProps) {\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n label: \"\",\n href: \"\",\n icon: \"document-text\",\n color: \"blue\",\n },\n });\n\n // Reset form when dialog opens/closes or initialData changes\n useEffect(() => {\n if (open) {\n form.reset(\n initialData\n ? {\n label: initialData.label,\n href: initialData.href,\n icon: initialData.icon,\n color: initialData.color,\n }\n : {\n label: \"\",\n href: \"\",\n icon: \"document-text\",\n color: \"blue\",\n },\n );\n }\n }, [open, initialData, form]);\n\n const handleSubmit = (values: FormValues) => {\n onSubmit(values);\n onOpenChange(false);\n };\n\n const handleFeatureChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const selectedHref = e.target.value;\n const feature = availableFeatures?.find((f) => f.href === selectedHref);\n\n if (feature) {\n form.setValue(\"href\", feature.href);\n form.setValue(\"label\", feature.label);\n if (feature.icon && iconMap[feature.icon]) {\n form.setValue(\"icon\", feature.icon);\n } else if (feature.icon && iconMap[feature.icon.replace(/-/g, \"\")]) {\n // Attempt fuzzy match or mapping if needed, theoretically icon names should match\n }\n }\n };\n\n return (\n <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n <DialogPrimitive.Content className=\"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\">\n <div className=\"flex flex-col space-y-1.5 text-center sm:text-left\">\n <DialogPrimitive.Title className=\"text-lg font-semibold leading-none tracking-tight\">\n {initialData ? \"Sửa lối tắt\" : \"Thêm lối tắt mới\"}\n </DialogPrimitive.Title>\n <DialogPrimitive.Description className=\"text-sm text-muted-foreground\">\n Tạo lối tắt để truy cập nhanh các tính năng thường dùng\n </DialogPrimitive.Description>\n </div>\n\n <form\n onSubmit={form.handleSubmit(handleSubmit)}\n className=\"space-y-4\"\n >\n <div className=\"grid gap-4 py-4\">\n {/* Feature Selection if available */}\n {availableFeatures && availableFeatures.length > 0 && (\n <div className=\"grid grid-cols-4 items-center gap-4\">\n <label\n htmlFor=\"feature-select\"\n className=\"text-right text-sm font-medium\"\n >\n Chức năng\n </label>\n <div className=\"col-span-3\">\n <select\n id=\"feature-select\"\n className=\"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n onChange={handleFeatureChange}\n defaultValue={initialData?.href || \"\"}\n >\n <option value=\"\">Chọn chức năng...</option>\n {availableFeatures.map((f) => (\n <option key={f.href} value={f.href}>\n {f.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )}\n\n <div className=\"grid grid-cols-4 items-center gap-4\">\n <label\n htmlFor=\"label\"\n className=\"text-right text-sm font-medium\"\n >\n Tên lối tắt\n </label>\n <div className=\"col-span-3\">\n <input\n id=\"label\"\n className=\"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n {...form.register(\"label\")}\n />\n {form.formState.errors.label && (\n <p className=\"text-xs text-red-500 mt-1\">\n {form.formState.errors.label.message}\n </p>\n )}\n </div>\n </div>\n\n {/* Show HREF input only if NO features available (fallback) or if we want to show it as readonly? \n The requirement says \"only allow ... in the list\". \n So if list is present, HIDE the href input or make it readOnly hidden. \n Let's hide it but keep it registered in form so validation passes.\n */}\n <div\n className={cn(\n \"grid grid-cols-4 items-center gap-4\",\n availableFeatures?.length ? \"hidden\" : \"\",\n )}\n >\n <label\n htmlFor=\"href\"\n className=\"text-right text-sm font-medium\"\n >\n Đường dẫn\n </label>\n <div className=\"col-span-3\">\n <input\n id=\"href\"\n className=\"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n {...form.register(\"href\")}\n readOnly={!!availableFeatures?.length}\n />\n {form.formState.errors.href && (\n <p className=\"text-xs text-red-500 mt-1\">\n {form.formState.errors.href.message}\n </p>\n )}\n </div>\n </div>\n\n <div className=\"grid grid-cols-4 items-start gap-4\">\n <label className=\"text-right text-sm font-medium pt-2\">\n Icon\n </label>\n <div className=\"col-span-3 flex flex-wrap gap-2\">\n {AVAILABLE_ICONS.map((icon) => (\n <button\n key={icon}\n type=\"button\"\n onClick={() => form.setValue(\"icon\", icon)}\n className={cn(\n \"flex h-8 w-8 items-center justify-center rounded-md border transition-colors\",\n form.watch(\"icon\") === icon\n ? \"border-primary bg-primary/10 text-primary\"\n : \"border-input hover:bg-muted\",\n )}\n >\n {iconMap[icon]}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"grid grid-cols-4 items-start gap-4\">\n <label className=\"text-right text-sm font-medium pt-2\">\n Màu sắc\n </label>\n <div className=\"col-span-3 flex flex-wrap gap-2\">\n {AVAILABLE_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n onClick={() => form.setValue(\"color\", color)}\n className={cn(\n \"h-8 w-8 rounded-full border-2 transition-all\",\n `bg-${color}-500`,\n form.watch(\"color\") === color\n ? \"border-primary scale-110 shadow-sm\"\n : \"border-transparent hover:scale-105\",\n )}\n aria-label={color}\n />\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2\"\n >\n Hủy\n </button>\n </DialogPrimitive.Close>\n <button\n type=\"submit\"\n className=\"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2\"\n >\n {initialData ? \"Lưu thay đổi\" : \"Thêm mới\"}\n </button>\n </div>\n </form>\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { Plus, X, Pencil, GripVertical } from \"lucide-react\";\nimport { cn } from \"../utils\";\nimport type { QuickAccessItem } from \"./types\";\nimport { QuickAccessDialog } from \"./quick-access-dialog\";\n\ninterface QuickAccessMenuProps {\n items: QuickAccessItem[];\n onItemClick?: (item: QuickAccessItem) => void;\n onItemsChange?: (items: QuickAccessItem[]) => void;\n className?: string;\n editable?: boolean;\n availableFeatures?: Array<{ label: string; href: string; icon?: string }>;\n}\n\nconst containerVariants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.05,\n delayChildren: 0.1,\n },\n },\n};\n\nconst itemVariants = {\n hidden: { opacity: 0, scale: 0.9 },\n visible: {\n opacity: 1,\n scale: 1,\n transition: {\n duration: 0.2,\n ease: \"easeOut\",\n },\n },\n};\n\nimport { iconMap, colorClasses } from \"./constants\";\n\nexport function QuickAccessMenu({\n items,\n onItemClick,\n onItemsChange,\n className,\n editable = false,\n availableFeatures,\n}: QuickAccessMenuProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editingItem, setEditingItem] = useState<QuickAccessItem | undefined>(\n undefined,\n );\n\n const handleAddStart = () => {\n setEditingItem(undefined);\n setDialogOpen(true);\n };\n\n const handleEditStart = (item: QuickAccessItem, e: React.MouseEvent) => {\n e.stopPropagation();\n setEditingItem(item);\n setDialogOpen(true);\n };\n\n const handleDelete = (itemId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (confirm(\"Bạn có chắc muốn xóa lối tắt này?\")) {\n onItemsChange?.(items.filter((item) => item.id !== itemId));\n }\n };\n\n const handleSave = (data: Omit<QuickAccessItem, \"id\">) => {\n // Check for duplicates\n const isDuplicate = items.some(\n (item) => item.href === data.href && item.id !== editingItem?.id,\n );\n\n if (isDuplicate) {\n alert(\"Lối tắt này đã tồn tại!\");\n return;\n }\n\n if (editingItem) {\n // Edit existing\n onItemsChange?.(\n items.map((item) =>\n item.id === editingItem.id ? { ...item, ...data } : item,\n ),\n );\n } else {\n // Add new\n const newItem: QuickAccessItem = {\n ...data,\n id: `custom-${Date.now()}`,\n };\n onItemsChange?.([...items, newItem]);\n }\n };\n\n if (items.length === 0 && !editable) {\n return null;\n }\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-slate-900 dark:text-white text-lg font-bold\">\n Quick Shortcuts\n </h3>\n </div>\n\n <motion.div\n variants={containerVariants}\n initial=\"hidden\"\n animate=\"visible\"\n // @ts-ignore className is valid for motion.div\n className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\"\n >\n <AnimatePresence mode=\"popLayout\">\n {items.map((item) => (\n <motion.button\n key={item.id}\n variants={itemVariants}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n // @ts-ignore onClick and className are valid for motion.button\n onClick={() => {\n if (!isEditing) {\n onItemClick?.(item);\n }\n }}\n className={cn(\n \"group relative flex flex-col items-center justify-center gap-3 bg-white dark:bg-slate-800 p-5 rounded-xl border border-slate-200 dark:border-slate-700 shadow-sm hover:shadow-md hover:border-primary/50 transition-all text-left\",\n isEditing && \"cursor-default opacity-90 hover:opacity-100\",\n )}\n >\n {isEditing && (\n <>\n <div\n onClick={(e) => handleDelete(item.id, e)}\n className=\"absolute -right-2 -top-2 z-10 flex h-6 w-6 cursor-pointer items-center justify-center rounded-full bg-destructive text-white shadow-sm ring-2 ring-white hover:bg-destructive/90\"\n >\n <X className=\"h-3 w-3\" />\n </div>\n <div\n onClick={(e) => handleEditStart(item, e)}\n className=\"absolute -left-2 -top-2 z-10 flex h-6 w-6 cursor-pointer items-center justify-center rounded-full bg-background text-foreground shadow-sm ring-2 ring-white hover:bg-muted\"\n >\n <Pencil className=\"h-3 w-3\" />\n </div>\n </>\n )}\n\n {editable && (\n <span\n onClick={() => setIsEditing(!isEditing)}\n className=\"absolute top-2 right-2 text-slate-300 dark:text-slate-600 cursor-move opacity-100 hover:text-primary transition-colors\"\n >\n <GripVertical size={18} />\n </span>\n )}\n\n <div\n className={cn(\n \"size-12 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform\",\n colorClasses[item.color || \"blue\"] || colorClasses.blue,\n )}\n >\n {iconMap[item.icon] || iconMap[\"document-text\"]}\n </div>\n <span className=\"text-slate-700 dark:text-slate-200 font-semibold text-sm\">\n {item.label}\n </span>\n </motion.button>\n ))}\n\n {editable && (\n <motion.button\n variants={itemVariants}\n // @ts-ignore\n onClick={handleAddStart}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n // @ts-ignore\n className=\"flex flex-col items-center justify-center gap-2 bg-slate-50 dark:bg-slate-800/50 p-5 rounded-xl border-2 border-dashed border-slate-300 dark:border-slate-600 hover:border-primary hover:bg-slate-100 dark:hover:bg-slate-800 transition-all text-slate-500 hover:text-primary cursor-pointer group h-full min-h-[140px]\"\n >\n <Plus className=\"h-8 w-8 group-hover:scale-110 transition-transform\" />\n <span className=\"text-sm font-medium\">Add Shortcut</span>\n </motion.button>\n )}\n </AnimatePresence>\n </motion.div>\n\n <QuickAccessDialog\n open={dialogOpen}\n onOpenChange={setDialogOpen}\n onSubmit={handleSave}\n initialData={editingItem}\n availableFeatures={availableFeatures}\n />\n </div>\n );\n}\n\n// Default quick access items\nexport const DEFAULT_QUICK_ACCESS: QuickAccessItem[] = [\n {\n id: \"pos\",\n label: \"Bán hàng\",\n href: \"/sales/pos\",\n icon: \"shopping-cart\",\n color: \"green\",\n },\n {\n id: \"orders\",\n label: \"Đơn hàng\",\n href: \"/sales-orders\",\n icon: \"clipboard-list\",\n color: \"blue\",\n },\n {\n id: \"customers\",\n label: \"Khách hàng\",\n href: \"/customers\",\n icon: \"users\",\n color: \"purple\",\n },\n {\n id: \"inventory\",\n label: \"Tồn kho\",\n href: \"/inventory\",\n icon: \"package\",\n color: \"orange\",\n },\n {\n id: \"reports\",\n label: \"Báo cáo\",\n href: \"/reports\",\n icon: \"chart-bar\",\n color: \"teal\",\n },\n {\n id: \"finance\",\n label: \"Thu chi\",\n href: \"/finance\",\n icon: \"currency-dollar\",\n color: \"pink\",\n },\n {\n id: \"products\",\n label: \"Sản phẩm\",\n href: \"/crud/products\",\n icon: \"package\",\n color: \"indigo\",\n },\n {\n id: \"settings\",\n label: \"Cài đặt\",\n href: \"/admin\",\n icon: \"cog\",\n color: \"red\",\n },\n];\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport useSWR from \"swr\";\nimport type {\n WidgetConfig,\n UserHomePreferences,\n QuickAccessItem,\n} from \"../types\";\nimport { DEFAULT_WIDGETS } from \"../types\";\n\ninterface UseWidgetPreferencesOptions {\n userId?: string;\n apiEndpoint?: string;\n fallbackToLocalStorage?: boolean;\n}\n\ninterface UseWidgetPreferencesReturn {\n widgets: WidgetConfig[];\n quickAccess: QuickAccessItem[];\n loading: boolean;\n error: string | null;\n updateWidgets: (widgets: WidgetConfig[]) => Promise<void>;\n updateQuickAccess: (items: QuickAccessItem[]) => Promise<void>;\n resetToDefaults: () => Promise<void>;\n}\n\nconst LOCAL_STORAGE_KEY = \"goerp_home_preferences\";\n\nasync function fetchPreferences(url: string): Promise<UserHomePreferences> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(\"Failed to fetch preferences\");\n }\n return res.json();\n}\n\nexport function useWidgetPreferences({\n userId,\n apiEndpoint = \"/api/user/preferences\",\n fallbackToLocalStorage = false,\n}: UseWidgetPreferencesOptions = {}): UseWidgetPreferencesReturn {\n const [localPreferences, setLocalPreferences] =\n useState<UserHomePreferences | null>(null);\n\n // Use SWR for API fetching when userId is provided\n const { data, error, isLoading, mutate } = useSWR<UserHomePreferences>(\n userId ? `${apiEndpoint}?userId=${userId}` : null,\n fetchPreferences,\n {\n revalidateOnFocus: false,\n // Only use localPreferences as fallback if explicitly enabled\n fallbackData: fallbackToLocalStorage\n ? localPreferences || undefined\n : undefined,\n },\n );\n\n // Use a user-specific key for localStorage to prevent data leakage between users\n const storageKey = userId\n ? `${LOCAL_STORAGE_KEY}_${userId}`\n : LOCAL_STORAGE_KEY;\n\n // Load from localStorage ONLY if fallback is enabled\n useEffect(() => {\n if (fallbackToLocalStorage && typeof window !== \"undefined\") {\n try {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n setLocalPreferences(JSON.parse(stored));\n } else {\n setLocalPreferences(null);\n }\n } catch {\n // console.warn(\"Failed to load preferences from localStorage\");\n }\n }\n }, [fallbackToLocalStorage, storageKey]);\n\n // Get the current preferences\n const preferences = data ||\n localPreferences || {\n widgets: DEFAULT_WIDGETS,\n quickAccess: [],\n };\n\n // Save preferences\n const savePreferences = useCallback(\n async (newPreferences: UserHomePreferences) => {\n // Optimistic update\n mutate(newPreferences, false);\n\n // Save to localStorage (only if enabled)\n if (fallbackToLocalStorage && typeof window !== \"undefined\") {\n try {\n localStorage.setItem(storageKey, JSON.stringify(newPreferences));\n setLocalPreferences(newPreferences);\n } catch {\n // console.warn(\"Failed to save preferences to localStorage\");\n }\n }\n\n // Save to API if userId is provided\n if (userId) {\n try {\n const res = await fetch(apiEndpoint, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n userId,\n ...newPreferences,\n }),\n });\n\n if (!res.ok) {\n throw new Error(\"Failed to save preferences\");\n }\n\n // Revalidate from server\n mutate();\n } catch (err) {\n console.error(\"Failed to save preferences to API:\", err);\n // Rollback optimistic update\n mutate();\n }\n }\n },\n [userId, apiEndpoint, fallbackToLocalStorage, mutate, storageKey],\n );\n\n const updateWidgets = useCallback(\n async (widgets: WidgetConfig[]) => {\n await savePreferences({\n ...preferences,\n widgets,\n });\n },\n [preferences, savePreferences],\n );\n\n const updateQuickAccess = useCallback(\n async (quickAccess: QuickAccessItem[]) => {\n await savePreferences({\n ...preferences,\n quickAccess,\n });\n },\n [preferences, savePreferences],\n );\n\n const resetToDefaults = useCallback(async () => {\n await savePreferences({\n widgets: DEFAULT_WIDGETS,\n quickAccess: [],\n });\n }, [savePreferences]);\n\n return {\n widgets: preferences.widgets,\n quickAccess: preferences.quickAccess,\n loading: isLoading,\n error: error?.message || null,\n updateWidgets,\n updateQuickAccess,\n resetToDefaults,\n };\n}\n","\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport useSWR from \"swr\";\nimport { LayoutDashboard, Settings } from \"lucide-react\";\nimport { cn } from \"../utils\";\nimport { WelcomeCard } from \"./welcome-card\";\nimport { WidgetContainer } from \"./widget-container\";\nimport { FeatureShowcase } from \"./feature-showcase\";\nimport { QuickAccessMenu, DEFAULT_QUICK_ACCESS } from \"./quick-access-menu\";\nimport { useWidgetPreferences } from \"./hooks/useWidgetPreferences\";\nimport type { QuickAccessItem, WidgetConfig } from \"./types\";\n\ninterface HomePageProps {\n userName?: string;\n userId?: string;\n widgetData?: {\n revenue?: { total: number; change?: number };\n orders?: {\n total: number;\n pending?: number;\n completed?: number;\n change?: number;\n };\n customers?: { total: number; newToday?: number; change?: number };\n stock?: {\n totalItems: number;\n lowStockCount: number;\n lowStockItems?: Array<{\n id: string;\n name: string;\n quantity: number;\n minStock: number;\n }>;\n };\n };\n availableFeatures?: Array<{ label: string; href: string; icon?: string }>;\n widgetDataLoading?: boolean;\n showFeatureShowcase?: boolean;\n className?: string;\n basePath?: string;\n dashboardApiUrl?: string;\n}\n\nexport function HomePage({\n userName = \"Bạn\",\n userId,\n widgetData: initialWidgetData,\n availableFeatures,\n widgetDataLoading = false,\n showFeatureShowcase = false,\n className,\n basePath = \"\",\n dashboardApiUrl,\n}: HomePageProps & { dashboardApiUrl?: string }) {\n const router = useRouter();\n\n // ... hook logic remains ...\n const { data: fetchedWidgetData, isLoading: isFetching } = useSWR(\n initialWidgetData ? null : dashboardApiUrl,\n async (url) => {\n const res = await fetch(url);\n if (!res.ok) throw new Error(\"Failed to fetch widget data\");\n return res.json();\n },\n {\n revalidateOnFocus: false,\n dedupingInterval: 60000, // 1 minute\n },\n );\n\n const widgetData = initialWidgetData || fetchedWidgetData;\n const isLoading =\n widgetDataLoading || (dashboardApiUrl && !initialWidgetData && isFetching);\n\n const {\n widgets,\n quickAccess,\n loading: prefsLoading,\n updateWidgets,\n updateQuickAccess,\n } = useWidgetPreferences({\n userId,\n });\n\n // Filter out Home from available features to prevent adding it as a shortcut\n // and to exclude it from defaults\n const filteredFeatures = availableFeatures?.filter(\n (f) =>\n f.href !== \"/home\" && f.href !== basePath + \"/home\" && f.href !== \"/\",\n );\n\n const handleQuickAccessClick = (item: QuickAccessItem) => {\n router.push(`${basePath}${item.href}`);\n };\n\n const handleWidgetsChange = async (newWidgets: WidgetConfig[]) => {\n await updateWidgets(newWidgets);\n };\n\n // Calculate effective quick access items\n // If user has saved preferences (length > 0), use them.\n // Otherwise, if availableFeatures are provided, generate a default list from them (up to 5 items).\n // Finally, fallback to DEFAULT_QUICK_ACCESS.\n const getAuthorizedDefaults = (): QuickAccessItem[] => {\n if (filteredFeatures && filteredFeatures.length > 0) {\n const colors = [\n \"blue\",\n \"green\",\n \"purple\",\n \"orange\",\n \"teal\",\n \"pink\",\n \"indigo\",\n \"red\",\n ];\n return filteredFeatures.slice(0, 5).map((feature, index) => ({\n id: `default-${index}`,\n label: feature.label,\n href: feature.href,\n icon: feature.icon || \"document-text\",\n color: colors[index % colors.length],\n }));\n }\n // If no authorized features, return empty to avoid showing unauthorized default items\n return [];\n };\n\n const displayQuickAccess =\n quickAccess && quickAccess.length > 0\n ? quickAccess\n : getAuthorizedDefaults();\n\n return (\n <div\n className={cn(\n \"min-h-screen bg-slate-50/50 dark:bg-slate-900/50\",\n className,\n )}\n >\n <div className=\"w-full mx-auto px-4 md:px-6 lg:px-8 py-6 space-y-8\">\n {/* Header Section */}\n <WelcomeCard userName={userName} />\n\n {/* My Workspace Section - Temporarily Hidden via separate prop or conditional */}\n {/* Added explicit check to hide widgets if requested */}\n {false && (\n <div className=\"flex flex-col gap-4 animate-in fade-in slide-in-from-bottom-4 duration-500 delay-150\">\n <div className=\"flex items-center justify-between px-1\">\n <div className=\"flex items-center gap-2\">\n <LayoutDashboard className=\"w-5 h-5 text-primary\" />\n <h3 className=\"text-lg font-bold text-slate-900 dark:text-white\">\n My Workspace\n </h3>\n </div>\n <button className=\"text-xs font-medium text-slate-500 hover:text-primary transition-colors flex items-center gap-1 group\">\n <Settings className=\"w-4 h-4 group-hover:rotate-180 transition-transform duration-500\" />\n Configure Widgets\n </button>\n </div>\n\n <WidgetContainer\n widgets={widgets}\n onWidgetsChange={handleWidgetsChange}\n widgetData={widgetData}\n loading={isLoading || prefsLoading}\n />\n </div>\n )}\n\n {/* Quick Access Section */}\n <div className=\"animate-in fade-in slide-in-from-bottom-4 duration-500 delay-300\">\n <QuickAccessMenu\n items={displayQuickAccess}\n onItemClick={handleQuickAccessClick}\n editable={true}\n onItemsChange={updateQuickAccess}\n availableFeatures={filteredFeatures}\n />\n </div>\n\n {/* Feature Tour Section - Hidden by default prop or explicit false */}\n {showFeatureShowcase && (\n <div className=\"animate-in fade-in slide-in-from-bottom-4 duration-500 delay-500 min-h-[400px]\">\n <FeatureShowcase />\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}