@wakastellar/ui 2.0.0 → 2.1.0

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 (290) hide show
  1. package/dist/cli/commands/add.d.ts +7 -0
  2. package/dist/cli/commands/init.d.ts +6 -0
  3. package/dist/cli/commands/list.d.ts +5 -0
  4. package/dist/cli/commands/search.d.ts +1 -0
  5. package/dist/cli/index.cjs +4844 -0
  6. package/dist/cli/index.d.ts +1 -0
  7. package/dist/cli/utils/config.d.ts +29 -0
  8. package/dist/cli/utils/logger.d.ts +20 -0
  9. package/dist/cli/utils/registry.d.ts +23 -0
  10. package/package.json +14 -3
  11. package/src/blocks/activity-timeline/index.tsx +586 -0
  12. package/src/blocks/calendar-view/index.tsx +756 -0
  13. package/src/blocks/chat/index.tsx +1018 -0
  14. package/src/blocks/chat/widget.tsx +504 -0
  15. package/src/blocks/dashboard/index.tsx +522 -0
  16. package/src/blocks/empty-states/index.tsx +452 -0
  17. package/src/blocks/error-pages/index.tsx +426 -0
  18. package/src/blocks/faq/index.tsx +479 -0
  19. package/src/blocks/file-manager/index.tsx +890 -0
  20. package/src/blocks/footer/index.tsx +133 -0
  21. package/src/blocks/header/index.tsx +357 -0
  22. package/src/blocks/headtab/index.tsx +139 -0
  23. package/src/blocks/i18n-editor/index.tsx +1016 -0
  24. package/src/blocks/index.ts +80 -0
  25. package/src/blocks/kanban-board/index.tsx +779 -0
  26. package/src/blocks/landing/index.tsx +677 -0
  27. package/src/blocks/language-selector/index.tsx +88 -0
  28. package/src/blocks/layout/index.tsx +159 -0
  29. package/src/blocks/login/index.tsx +339 -0
  30. package/src/blocks/login/types.ts +131 -0
  31. package/src/blocks/pricing/index.tsx +564 -0
  32. package/src/blocks/profile/index.tsx +746 -0
  33. package/src/blocks/settings/index.tsx +558 -0
  34. package/src/blocks/sidebar/index.tsx +713 -0
  35. package/src/blocks/theme-creator-block/index.tsx +835 -0
  36. package/src/blocks/user-management/index.tsx +1037 -0
  37. package/src/blocks/wizard/index.tsx +719 -0
  38. package/src/components/DataTable/DataTable.tsx +406 -0
  39. package/src/components/DataTable/DataTableAdvanced.tsx +720 -0
  40. package/src/components/DataTable/DataTableBody.tsx +216 -0
  41. package/src/components/DataTable/DataTableCell.tsx +172 -0
  42. package/src/components/DataTable/DataTableColumnResizer.tsx +62 -0
  43. package/src/components/DataTable/DataTableConflictResolver.tsx +478 -0
  44. package/src/components/DataTable/DataTableContextMenu.tsx +219 -0
  45. package/src/components/DataTable/DataTableEditCell.tsx +279 -0
  46. package/src/components/DataTable/DataTableFilterBuilder.tsx +519 -0
  47. package/src/components/DataTable/DataTableFilters.tsx +535 -0
  48. package/src/components/DataTable/DataTableGrouping.tsx +147 -0
  49. package/src/components/DataTable/DataTableHeader.tsx +172 -0
  50. package/src/components/DataTable/DataTablePagination.tsx +125 -0
  51. package/src/components/DataTable/DataTableSelection.tsx +269 -0
  52. package/src/components/DataTable/DataTableSyncStatus.tsx +281 -0
  53. package/src/components/DataTable/DataTableToolbar.tsx +262 -0
  54. package/src/components/DataTable/README.md +446 -0
  55. package/src/components/DataTable/__tests__/DataTableAdvanced.test.tsx +426 -0
  56. package/src/components/DataTable/__tests__/DataTableEdit.test.tsx +329 -0
  57. package/src/components/DataTable/__tests__/useDataTableAdvanced.test.ts +455 -0
  58. package/src/components/DataTable/examples/EditExample.tsx +166 -0
  59. package/src/components/DataTable/formatters/index.ts +335 -0
  60. package/src/components/DataTable/hooks/__tests__/useDataTableEdit.test.ts +239 -0
  61. package/src/components/DataTable/hooks/useDataTable.ts +145 -0
  62. package/src/components/DataTable/hooks/useDataTableAdvanced.ts +342 -0
  63. package/src/components/DataTable/hooks/useDataTableAdvancedFilters.ts +637 -0
  64. package/src/components/DataTable/hooks/useDataTableColumnTemplates.ts +186 -0
  65. package/src/components/DataTable/hooks/useDataTableEdit.ts +167 -0
  66. package/src/components/DataTable/hooks/useDataTableExport.ts +227 -0
  67. package/src/components/DataTable/hooks/useDataTableImport.ts +216 -0
  68. package/src/components/DataTable/hooks/useDataTableOffline.ts +481 -0
  69. package/src/components/DataTable/hooks/useDataTableTheme.ts +213 -0
  70. package/src/components/DataTable/hooks/useDataTableVirtualization.ts +99 -0
  71. package/src/components/DataTable/hooks/useTableLayout.ts +85 -0
  72. package/src/components/DataTable/index.ts +81 -0
  73. package/src/components/DataTable/services/IndexedDBService.ts +504 -0
  74. package/src/components/DataTable/templates/index.tsx +803 -0
  75. package/src/components/DataTable/types.ts +504 -0
  76. package/src/components/DataTable/utils.ts +164 -0
  77. package/src/components/DataTable/workers/exportWorker.ts +213 -0
  78. package/src/components/accordion/index.tsx +61 -0
  79. package/src/components/alert/index.tsx +61 -0
  80. package/src/components/alert-dialog/index.tsx +146 -0
  81. package/src/components/aspect-ratio/index.tsx +12 -0
  82. package/src/components/avatar/index.tsx +54 -0
  83. package/src/components/badge/Badge.stories.tsx +64 -0
  84. package/src/components/badge/index.tsx +38 -0
  85. package/src/components/button/Button.stories.tsx +173 -0
  86. package/src/components/button/index.tsx +56 -0
  87. package/src/components/calendar/index.tsx +73 -0
  88. package/src/components/card/index.tsx +78 -0
  89. package/src/components/checkbox/index.tsx +34 -0
  90. package/src/components/code/index.tsx +229 -0
  91. package/src/components/collapsible/index.tsx +16 -0
  92. package/src/components/command/index.tsx +162 -0
  93. package/src/components/context-menu/index.tsx +204 -0
  94. package/src/components/dialog/index.tsx +126 -0
  95. package/src/components/dropdown-menu/index.tsx +204 -0
  96. package/src/components/error-boundary/ErrorBoundary.tsx +281 -0
  97. package/src/components/error-boundary/index.ts +7 -0
  98. package/src/components/form/index.tsx +183 -0
  99. package/src/components/hover-card/index.tsx +33 -0
  100. package/src/components/index.ts +368 -0
  101. package/src/components/input/Input.stories.tsx +100 -0
  102. package/src/components/input/index.tsx +27 -0
  103. package/src/components/input-otp/index.tsx +277 -0
  104. package/src/components/label/index.tsx +30 -0
  105. package/src/components/language-selector/index.tsx +341 -0
  106. package/src/components/menubar/index.tsx +240 -0
  107. package/src/components/navigation-menu/index.tsx +134 -0
  108. package/src/components/popover/index.tsx +35 -0
  109. package/src/components/progress/index.tsx +32 -0
  110. package/src/components/radio-group/index.tsx +48 -0
  111. package/src/components/scroll-area/index.tsx +52 -0
  112. package/src/components/select/index.tsx +164 -0
  113. package/src/components/separator/index.tsx +35 -0
  114. package/src/components/sheet/index.tsx +147 -0
  115. package/src/components/skeleton/index.tsx +22 -0
  116. package/src/components/slider/index.tsx +32 -0
  117. package/src/components/switch/index.tsx +33 -0
  118. package/src/components/table/index.tsx +117 -0
  119. package/src/components/tabs/index.tsx +59 -0
  120. package/src/components/textarea/index.tsx +30 -0
  121. package/src/components/theme-selector/index.tsx +327 -0
  122. package/src/components/toast/index.tsx +133 -0
  123. package/src/components/toaster/index.tsx +34 -0
  124. package/src/components/toggle/index.tsx +49 -0
  125. package/src/components/tooltip/index.tsx +34 -0
  126. package/src/components/typography/index.tsx +276 -0
  127. package/src/components/waka-3d-pie-chart/index.tsx +486 -0
  128. package/src/components/waka-achievement-unlock/index.tsx +716 -0
  129. package/src/components/waka-activity-feed/index.tsx +686 -0
  130. package/src/components/waka-address-autocomplete/index.tsx +1202 -0
  131. package/src/components/waka-admincrumb/index.tsx +349 -0
  132. package/src/components/waka-alert-stack/index.tsx +827 -0
  133. package/src/components/waka-allocation-matrix/index.tsx +1278 -0
  134. package/src/components/waka-approval-chain/index.tsx +766 -0
  135. package/src/components/waka-audit-log/index.tsx +1475 -0
  136. package/src/components/waka-autocomplete/index.tsx +358 -0
  137. package/src/components/waka-badge-showcase/index.tsx +704 -0
  138. package/src/components/waka-barcode/index.tsx +260 -0
  139. package/src/components/waka-biometric-prompt/index.tsx +765 -0
  140. package/src/components/waka-bottom-sheet/index.tsx +495 -0
  141. package/src/components/waka-breadcrumb/index.tsx +376 -0
  142. package/src/components/waka-breadcrumb-path/index.tsx +513 -0
  143. package/src/components/waka-budget-burn/index.tsx +1234 -0
  144. package/src/components/waka-capacity-planner/index.tsx +1107 -0
  145. package/src/components/waka-carousel/index.tsx +893 -0
  146. package/src/components/waka-cart-summary/index.tsx +1055 -0
  147. package/src/components/waka-challenge-timer/index.tsx +1044 -0
  148. package/src/components/waka-charts/WakaAreaChart.tsx +251 -0
  149. package/src/components/waka-charts/WakaBarChart.tsx +222 -0
  150. package/src/components/waka-charts/WakaChart.tsx +124 -0
  151. package/src/components/waka-charts/WakaLineChart.tsx +219 -0
  152. package/src/components/waka-charts/WakaMiniChart.tsx +133 -0
  153. package/src/components/waka-charts/WakaPieChart.tsx +214 -0
  154. package/src/components/waka-charts/WakaSparkline.tsx +229 -0
  155. package/src/components/waka-charts/dataTableHelpers.ts +109 -0
  156. package/src/components/waka-charts/hooks/useChartTheme.ts +123 -0
  157. package/src/components/waka-charts/hooks/useRechartsLoader.ts +234 -0
  158. package/src/components/waka-charts/index.ts +90 -0
  159. package/src/components/waka-charts/types.ts +330 -0
  160. package/src/components/waka-chat-bubble/index.tsx +1060 -0
  161. package/src/components/waka-checklist/index.tsx +1067 -0
  162. package/src/components/waka-checkout-stepper/index.tsx +976 -0
  163. package/src/components/waka-cohort-table/index.tsx +1011 -0
  164. package/src/components/waka-color-picker/index.tsx +447 -0
  165. package/src/components/waka-combo-counter/index.tsx +864 -0
  166. package/src/components/waka-combobox/index.tsx +497 -0
  167. package/src/components/waka-command-bar/index.tsx +403 -0
  168. package/src/components/waka-compare-period/index.tsx +1230 -0
  169. package/src/components/waka-connection-matrix/index.tsx +1053 -0
  170. package/src/components/waka-contribution-graph/index.tsx +552 -0
  171. package/src/components/waka-cost-breakdown/index.tsx +1065 -0
  172. package/src/components/waka-coupon-input/index.tsx +592 -0
  173. package/src/components/waka-credit-card-input/index.tsx +982 -0
  174. package/src/components/waka-daily-reward/index.tsx +762 -0
  175. package/src/components/waka-date-range-picker/index.tsx +378 -0
  176. package/src/components/waka-datetime-picker/index.tsx +793 -0
  177. package/src/components/waka-datetime-picker.form-integration/index.tsx +402 -0
  178. package/src/components/waka-deployment-lane/index.tsx +673 -0
  179. package/src/components/waka-device-trust/index.tsx +1259 -0
  180. package/src/components/waka-dock/index.tsx +285 -0
  181. package/src/components/waka-drawer/index.tsx +319 -0
  182. package/src/components/waka-empty-state/index.tsx +545 -0
  183. package/src/components/waka-error-shake/index.tsx +398 -0
  184. package/src/components/waka-feature-announcement/index.tsx +991 -0
  185. package/src/components/waka-file-upload/index.tsx +437 -0
  186. package/src/components/waka-floating-nav/index.tsx +413 -0
  187. package/src/components/waka-flow-diagram/index.tsx +508 -0
  188. package/src/components/waka-funnel-chart/index.tsx +823 -0
  189. package/src/components/waka-glow-card/index.tsx +246 -0
  190. package/src/components/waka-goal-progress/index.tsx +1025 -0
  191. package/src/components/waka-haptic-button/index.tsx +388 -0
  192. package/src/components/waka-health-pulse/index.tsx +451 -0
  193. package/src/components/waka-heatmap/index.tsx +1026 -0
  194. package/src/components/waka-hotspot/index.tsx +682 -0
  195. package/src/components/waka-image/index.tsx +373 -0
  196. package/src/components/waka-incident-timeline/index.tsx +686 -0
  197. package/src/components/waka-invoice-preview/index.tsx +829 -0
  198. package/src/components/waka-kanban/index.tsx +646 -0
  199. package/src/components/waka-kpi-dashboard/index.tsx +755 -0
  200. package/src/components/waka-leaderboard/index.tsx +746 -0
  201. package/src/components/waka-level-progress/index.tsx +665 -0
  202. package/src/components/waka-liquid-button/index.tsx +520 -0
  203. package/src/components/waka-loading-orbit/index.tsx +478 -0
  204. package/src/components/waka-loot-box/index.tsx +1091 -0
  205. package/src/components/waka-magic-link/index.tsx +321 -0
  206. package/src/components/waka-magnetic-button/index.tsx +567 -0
  207. package/src/components/waka-mention-input/index.tsx +953 -0
  208. package/src/components/waka-metric-sparkline/index.tsx +627 -0
  209. package/src/components/waka-milestone-road/index.tsx +1064 -0
  210. package/src/components/waka-modal/index.tsx +374 -0
  211. package/src/components/waka-morph-button/index.tsx +495 -0
  212. package/src/components/waka-network-topology/index.tsx +801 -0
  213. package/src/components/waka-notifications/index.tsx +414 -0
  214. package/src/components/waka-number-input/index.tsx +373 -0
  215. package/src/components/waka-orbital-menu/index.tsx +445 -0
  216. package/src/components/waka-order-tracker/index.tsx +1041 -0
  217. package/src/components/waka-pagination/index.tsx +393 -0
  218. package/src/components/waka-password-strength/index.tsx +824 -0
  219. package/src/components/waka-payment-method-picker/index.tsx +715 -0
  220. package/src/components/waka-permission-matrix/index.tsx +1302 -0
  221. package/src/components/waka-phone-input/index.tsx +801 -0
  222. package/src/components/waka-pipeline-view/index.tsx +604 -0
  223. package/src/components/waka-player-card/index.tsx +691 -0
  224. package/src/components/waka-points-popup/index.tsx +366 -0
  225. package/src/components/waka-power-up/index.tsx +1155 -0
  226. package/src/components/waka-presence-indicator/index.tsx +1181 -0
  227. package/src/components/waka-pricing-table/index.tsx +755 -0
  228. package/src/components/waka-product-card/index.tsx +786 -0
  229. package/src/components/waka-progress-onboarding/index.tsx +878 -0
  230. package/src/components/waka-pull-to-refresh/index.tsx +451 -0
  231. package/src/components/waka-qrcode/index.tsx +232 -0
  232. package/src/components/waka-quest-card/index.tsx +1275 -0
  233. package/src/components/waka-quota-bar/index.tsx +693 -0
  234. package/src/components/waka-radar-score/index.tsx +512 -0
  235. package/src/components/waka-rank-badge/index.tsx +813 -0
  236. package/src/components/waka-rating-input/index.tsx +560 -0
  237. package/src/components/waka-reaction-picker/index.tsx +1062 -0
  238. package/src/components/waka-region-map/index.tsx +730 -0
  239. package/src/components/waka-resource-gauge/index.tsx +654 -0
  240. package/src/components/waka-resource-pool/index.tsx +1035 -0
  241. package/src/components/waka-rich-text-editor/index.tsx +594 -0
  242. package/src/components/waka-rollback-slider/index.tsx +891 -0
  243. package/src/components/waka-sankey-diagram/index.tsx +1032 -0
  244. package/src/components/waka-schedule-picker/index.tsx +1060 -0
  245. package/src/components/waka-scratch-card/index.tsx +914 -0
  246. package/src/components/waka-season-pass/index.tsx +886 -0
  247. package/src/components/waka-security-score/index.tsx +1126 -0
  248. package/src/components/waka-segmented-control/index.tsx +238 -0
  249. package/src/components/waka-server-rack/index.tsx +764 -0
  250. package/src/components/waka-session-manager/index.tsx +815 -0
  251. package/src/components/waka-signature-pad/index.tsx +744 -0
  252. package/src/components/waka-skeleton-wave/index.tsx +454 -0
  253. package/src/components/waka-skill-tree/index.tsx +1031 -0
  254. package/src/components/waka-sla-tracker/index.tsx +798 -0
  255. package/src/components/waka-slider-range/index.tsx +765 -0
  256. package/src/components/waka-spin-wheel/index.tsx +671 -0
  257. package/src/components/waka-spinner/index.tsx +284 -0
  258. package/src/components/waka-spotlight/index.tsx +410 -0
  259. package/src/components/waka-stat/index.tsx +428 -0
  260. package/src/components/waka-stats-hexagon/index.tsx +824 -0
  261. package/src/components/waka-status-matrix/index.tsx +565 -0
  262. package/src/components/waka-stepper/index.tsx +489 -0
  263. package/src/components/waka-streak-counter/index.tsx +334 -0
  264. package/src/components/waka-success-explosion/index.tsx +453 -0
  265. package/src/components/waka-swipe-card/index.tsx +574 -0
  266. package/src/components/waka-tabs-morph/index.tsx +509 -0
  267. package/src/components/waka-tag-input/index.tsx +877 -0
  268. package/src/components/waka-team-banner/index.tsx +1183 -0
  269. package/src/components/waka-terminal-output/index.tsx +836 -0
  270. package/src/components/waka-theme-creator/index.tsx +762 -0
  271. package/src/components/waka-theme-manager/index.tsx +654 -0
  272. package/src/components/waka-thread-view/index.tsx +874 -0
  273. package/src/components/waka-tilt-card/index.tsx +250 -0
  274. package/src/components/waka-time-picker/index.tsx +479 -0
  275. package/src/components/waka-timeline/index.tsx +385 -0
  276. package/src/components/waka-tooltip-tour/index.tsx +855 -0
  277. package/src/components/waka-tour-guide/index.tsx +920 -0
  278. package/src/components/waka-tournament-bracket/index.tsx +1276 -0
  279. package/src/components/waka-tree/index.tsx +557 -0
  280. package/src/components/waka-treemap-chart/index.tsx +1031 -0
  281. package/src/components/waka-two-factor-setup/index.tsx +995 -0
  282. package/src/components/waka-typewriter/index.tsx +566 -0
  283. package/src/components/waka-typing-indicator/index.tsx +649 -0
  284. package/src/components/waka-versus-card/index.tsx +1026 -0
  285. package/src/components/waka-video/index.tsx +557 -0
  286. package/src/components/waka-video-call/index.tsx +1087 -0
  287. package/src/components/waka-virtual-list/index.tsx +327 -0
  288. package/src/components/waka-voice-message/index.tsx +1019 -0
  289. package/src/components/waka-welcome-modal/index.tsx +790 -0
  290. package/src/components/waka-xp-bar/index.tsx +799 -0
@@ -0,0 +1,426 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "../../utils"
5
+ import { Button } from "../../components/button"
6
+ import {
7
+ Home,
8
+ ArrowLeft,
9
+ RefreshCw,
10
+ Search,
11
+ ShieldX,
12
+ ServerCrash,
13
+ FileQuestion,
14
+ Construction,
15
+ Wifi,
16
+ Lock,
17
+ } from "lucide-react"
18
+
19
+ // ============================================
20
+ // TYPES
21
+ // ============================================
22
+
23
+ export type ErrorType = "404" | "500" | "403" | "503" | "offline" | "maintenance" | "custom"
24
+
25
+ export interface ErrorAction {
26
+ label: string
27
+ onClick?: () => void
28
+ href?: string
29
+ variant?: "default" | "outline" | "secondary" | "ghost"
30
+ icon?: React.ReactNode
31
+ }
32
+
33
+ export interface WakaErrorPageProps {
34
+ /** Type d'erreur */
35
+ type?: ErrorType
36
+ /** Code d'erreur personnalisé */
37
+ code?: string | number
38
+ /** Titre */
39
+ title?: string
40
+ /** Description */
41
+ description?: string
42
+ /** Actions disponibles */
43
+ actions?: ErrorAction[]
44
+ /** Illustration personnalisée */
45
+ illustration?: React.ReactNode
46
+ /** Afficher le code d'erreur */
47
+ showCode?: boolean
48
+ /** Afficher l'illustration par défaut */
49
+ showIllustration?: boolean
50
+ /** Afficher le bouton retour */
51
+ showBackButton?: boolean
52
+ /** Callback retour */
53
+ onBack?: () => void
54
+ /** Afficher le bouton accueil */
55
+ showHomeButton?: boolean
56
+ /** URL de la page d'accueil */
57
+ homeUrl?: string
58
+ /** Afficher le bouton rafraîchir */
59
+ showRefreshButton?: boolean
60
+ /** Contenu additionnel */
61
+ children?: React.ReactNode
62
+ /** Layout */
63
+ layout?: "centered" | "split"
64
+ /** Taille */
65
+ size?: "sm" | "md" | "lg"
66
+ /** Classes CSS additionnelles */
67
+ className?: string
68
+ }
69
+
70
+ // ============================================
71
+ // ERROR CONFIGS
72
+ // ============================================
73
+
74
+ interface ErrorConfig {
75
+ code: string
76
+ title: string
77
+ description: string
78
+ icon: React.ElementType
79
+ }
80
+
81
+ const errorConfigs: Record<ErrorType, ErrorConfig> = {
82
+ "404": {
83
+ code: "404",
84
+ title: "Page non trouvée",
85
+ description: "Désolé, la page que vous recherchez n'existe pas ou a été déplacée.",
86
+ icon: FileQuestion,
87
+ },
88
+ "500": {
89
+ code: "500",
90
+ title: "Erreur serveur",
91
+ description: "Une erreur inattendue s'est produite. Notre équipe a été notifiée.",
92
+ icon: ServerCrash,
93
+ },
94
+ "403": {
95
+ code: "403",
96
+ title: "Accès refusé",
97
+ description: "Vous n'avez pas les permissions nécessaires pour accéder à cette page.",
98
+ icon: ShieldX,
99
+ },
100
+ "503": {
101
+ code: "503",
102
+ title: "Service indisponible",
103
+ description: "Le service est temporairement indisponible. Veuillez réessayer plus tard.",
104
+ icon: ServerCrash,
105
+ },
106
+ offline: {
107
+ code: "Hors ligne",
108
+ title: "Vous êtes hors ligne",
109
+ description: "Vérifiez votre connexion internet et réessayez.",
110
+ icon: Wifi,
111
+ },
112
+ maintenance: {
113
+ code: "Maintenance",
114
+ title: "Maintenance en cours",
115
+ description: "Nous effectuons une maintenance. Nous serons bientôt de retour.",
116
+ icon: Construction,
117
+ },
118
+ custom: {
119
+ code: "",
120
+ title: "Erreur",
121
+ description: "Une erreur s'est produite.",
122
+ icon: FileQuestion,
123
+ },
124
+ }
125
+
126
+ // ============================================
127
+ // ILLUSTRATIONS
128
+ // ============================================
129
+
130
+ interface IllustrationProps {
131
+ type: ErrorType
132
+ className?: string
133
+ }
134
+
135
+ function ErrorIllustration({ type, className }: IllustrationProps) {
136
+ const config = errorConfigs[type]
137
+ const Icon = config.icon
138
+
139
+ return (
140
+ <div
141
+ className={cn(
142
+ "relative flex items-center justify-center",
143
+ className
144
+ )}
145
+ >
146
+ {/* Background circle */}
147
+ <div className="absolute inset-0 flex items-center justify-center">
148
+ <div className="h-48 w-48 rounded-full bg-muted/50" />
149
+ </div>
150
+ <div className="absolute inset-0 flex items-center justify-center">
151
+ <div className="h-32 w-32 rounded-full bg-muted" />
152
+ </div>
153
+
154
+ {/* Icon */}
155
+ <div className="relative z-10 flex h-20 w-20 items-center justify-center rounded-full bg-background shadow-lg">
156
+ <Icon className="h-10 w-10 text-muted-foreground" />
157
+ </div>
158
+
159
+ {/* Decorative elements */}
160
+ <div className="absolute -right-4 top-4 h-3 w-3 rounded-full bg-primary/20" />
161
+ <div className="absolute -left-2 bottom-8 h-2 w-2 rounded-full bg-primary/30" />
162
+ <div className="absolute right-8 bottom-2 h-4 w-4 rounded-full bg-primary/10" />
163
+ </div>
164
+ )
165
+ }
166
+
167
+ // ============================================
168
+ // MAIN COMPONENT
169
+ // ============================================
170
+
171
+ export function WakaErrorPage({
172
+ type = "404",
173
+ code,
174
+ title,
175
+ description,
176
+ actions,
177
+ illustration,
178
+ showCode = true,
179
+ showIllustration = true,
180
+ showBackButton = true,
181
+ onBack,
182
+ showHomeButton = true,
183
+ homeUrl = "/",
184
+ showRefreshButton = false,
185
+ children,
186
+ layout = "centered",
187
+ size = "md",
188
+ className,
189
+ }: WakaErrorPageProps) {
190
+ const config = errorConfigs[type]
191
+ const displayCode = code ?? config.code
192
+ const displayTitle = title ?? config.title
193
+ const displayDescription = description ?? config.description
194
+
195
+ const sizeClasses = {
196
+ sm: {
197
+ container: "py-12 px-4",
198
+ code: "text-6xl",
199
+ title: "text-xl",
200
+ description: "text-sm",
201
+ illustration: "h-32 w-32",
202
+ },
203
+ md: {
204
+ container: "py-16 px-6",
205
+ code: "text-8xl",
206
+ title: "text-2xl",
207
+ description: "text-base",
208
+ illustration: "h-48 w-48",
209
+ },
210
+ lg: {
211
+ container: "py-24 px-8",
212
+ code: "text-9xl",
213
+ title: "text-3xl",
214
+ description: "text-lg",
215
+ illustration: "h-64 w-64",
216
+ },
217
+ }
218
+
219
+ const defaultActions: ErrorAction[] = []
220
+
221
+ if (showBackButton) {
222
+ defaultActions.push({
223
+ label: "Retour",
224
+ onClick: onBack || (() => window.history.back()),
225
+ variant: "outline",
226
+ icon: <ArrowLeft className="h-4 w-4" />,
227
+ })
228
+ }
229
+
230
+ if (showHomeButton) {
231
+ defaultActions.push({
232
+ label: "Accueil",
233
+ href: homeUrl,
234
+ variant: "default",
235
+ icon: <Home className="h-4 w-4" />,
236
+ })
237
+ }
238
+
239
+ if (showRefreshButton) {
240
+ defaultActions.push({
241
+ label: "Réessayer",
242
+ onClick: () => window.location.reload(),
243
+ variant: "secondary",
244
+ icon: <RefreshCw className="h-4 w-4" />,
245
+ })
246
+ }
247
+
248
+ const allActions = actions || defaultActions
249
+
250
+ const renderContent = () => (
251
+ <div className="flex flex-col items-center text-center">
252
+ {/* Illustration */}
253
+ {showIllustration && (
254
+ <div className={cn("mb-8", sizeClasses[size].illustration)}>
255
+ {illustration || <ErrorIllustration type={type} />}
256
+ </div>
257
+ )}
258
+
259
+ {/* Code */}
260
+ {showCode && displayCode && (
261
+ <div
262
+ className={cn(
263
+ "font-bold text-muted-foreground/20 mb-4",
264
+ sizeClasses[size].code
265
+ )}
266
+ >
267
+ {displayCode}
268
+ </div>
269
+ )}
270
+
271
+ {/* Title */}
272
+ <h1 className={cn("font-bold tracking-tight mb-4", sizeClasses[size].title)}>
273
+ {displayTitle}
274
+ </h1>
275
+
276
+ {/* Description */}
277
+ <p
278
+ className={cn(
279
+ "text-muted-foreground max-w-md mb-8",
280
+ sizeClasses[size].description
281
+ )}
282
+ >
283
+ {displayDescription}
284
+ </p>
285
+
286
+ {/* Custom content */}
287
+ {children && <div className="mb-8">{children}</div>}
288
+
289
+ {/* Actions */}
290
+ {allActions.length > 0 && (
291
+ <div className="flex flex-wrap gap-3 justify-center">
292
+ {allActions.map((action, index) => (
293
+ <Button
294
+ key={index}
295
+ variant={action.variant || "default"}
296
+ onClick={action.onClick}
297
+ asChild={!!action.href}
298
+ >
299
+ {action.href ? (
300
+ <a href={action.href}>
301
+ {action.icon && <span className="mr-2">{action.icon}</span>}
302
+ {action.label}
303
+ </a>
304
+ ) : (
305
+ <>
306
+ {action.icon && <span className="mr-2">{action.icon}</span>}
307
+ {action.label}
308
+ </>
309
+ )}
310
+ </Button>
311
+ ))}
312
+ </div>
313
+ )}
314
+ </div>
315
+ )
316
+
317
+ if (layout === "split") {
318
+ return (
319
+ <div
320
+ className={cn(
321
+ "min-h-screen flex flex-col lg:flex-row",
322
+ className
323
+ )}
324
+ >
325
+ {/* Left side - Illustration */}
326
+ <div className="flex-1 bg-muted/30 flex items-center justify-center p-8 lg:p-16">
327
+ <div className={sizeClasses[size].illustration}>
328
+ {illustration || <ErrorIllustration type={type} />}
329
+ </div>
330
+ </div>
331
+
332
+ {/* Right side - Content */}
333
+ <div className="flex-1 flex items-center justify-center p-8 lg:p-16">
334
+ <div className="max-w-md">
335
+ {showCode && displayCode && (
336
+ <div
337
+ className={cn(
338
+ "font-bold text-primary mb-4",
339
+ size === "sm" ? "text-4xl" : size === "md" ? "text-5xl" : "text-6xl"
340
+ )}
341
+ >
342
+ {displayCode}
343
+ </div>
344
+ )}
345
+ <h1 className={cn("font-bold tracking-tight mb-4", sizeClasses[size].title)}>
346
+ {displayTitle}
347
+ </h1>
348
+ <p className={cn("text-muted-foreground mb-8", sizeClasses[size].description)}>
349
+ {displayDescription}
350
+ </p>
351
+ {children && <div className="mb-8">{children}</div>}
352
+ {allActions.length > 0 && (
353
+ <div className="flex flex-wrap gap-3">
354
+ {allActions.map((action, index) => (
355
+ <Button
356
+ key={index}
357
+ variant={action.variant || "default"}
358
+ onClick={action.onClick}
359
+ asChild={!!action.href}
360
+ >
361
+ {action.href ? (
362
+ <a href={action.href}>
363
+ {action.icon && <span className="mr-2">{action.icon}</span>}
364
+ {action.label}
365
+ </a>
366
+ ) : (
367
+ <>
368
+ {action.icon && <span className="mr-2">{action.icon}</span>}
369
+ {action.label}
370
+ </>
371
+ )}
372
+ </Button>
373
+ ))}
374
+ </div>
375
+ )}
376
+ </div>
377
+ </div>
378
+ </div>
379
+ )
380
+ }
381
+
382
+ return (
383
+ <div
384
+ className={cn(
385
+ "min-h-screen flex items-center justify-center",
386
+ sizeClasses[size].container,
387
+ className
388
+ )}
389
+ >
390
+ {renderContent()}
391
+ </div>
392
+ )
393
+ }
394
+
395
+ // ============================================
396
+ // PRESET COMPONENTS
397
+ // ============================================
398
+
399
+ export function Error404Page(props: Omit<WakaErrorPageProps, "type">) {
400
+ return <WakaErrorPage type="404" {...props} />
401
+ }
402
+
403
+ export function Error500Page(props: Omit<WakaErrorPageProps, "type">) {
404
+ return <WakaErrorPage type="500" showRefreshButton {...props} />
405
+ }
406
+
407
+ export function Error403Page(props: Omit<WakaErrorPageProps, "type">) {
408
+ return <WakaErrorPage type="403" {...props} />
409
+ }
410
+
411
+ export function MaintenancePage(props: Omit<WakaErrorPageProps, "type">) {
412
+ return (
413
+ <WakaErrorPage
414
+ type="maintenance"
415
+ showBackButton={false}
416
+ showHomeButton={false}
417
+ {...props}
418
+ />
419
+ )
420
+ }
421
+
422
+ export function OfflinePage(props: Omit<WakaErrorPageProps, "type">) {
423
+ return <WakaErrorPage type="offline" showRefreshButton {...props} />
424
+ }
425
+
426
+ export default WakaErrorPage