@wakastellar/ui 2.3.4 → 2.4.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 (194) hide show
  1. package/dist/blocks/dashboard/index.d.ts +4 -1
  2. package/dist/blocks/empty-states/index.d.ts +4 -1
  3. package/dist/blocks/error-pages/index.d.ts +4 -1
  4. package/dist/blocks/index.d.ts +1 -1
  5. package/dist/blocks/landing/index.d.ts +4 -1
  6. package/dist/blocks/pricing/index.d.ts +5 -1
  7. package/dist/blocks/sidebar/index.d.ts +5 -1
  8. package/dist/index.cjs.js +130 -130
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.es.js +7905 -7856
  11. package/dist/stories/Button.d.ts +14 -0
  12. package/dist/stories/Button.stories.d.ts +8 -0
  13. package/dist/stories/Header.d.ts +11 -0
  14. package/dist/stories/Header.stories.d.ts +6 -0
  15. package/dist/stories/Page.d.ts +2 -0
  16. package/dist/stories/Page.stories.d.ts +6 -0
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/link.d.ts +23 -0
  19. package/package.json +11 -3
  20. package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
  21. package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
  22. package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
  23. package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
  24. package/src/blocks/chat/Chat.stories.tsx +466 -0
  25. package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
  26. package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
  27. package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
  28. package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
  29. package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
  30. package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
  31. package/src/blocks/dashboard/index.tsx +68 -27
  32. package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
  33. package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
  34. package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
  35. package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
  36. package/src/blocks/empty-states/index.tsx +26 -8
  37. package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
  38. package/src/blocks/error-pages/index.tsx +26 -8
  39. package/src/blocks/faq/FAQ.stories.tsx +416 -0
  40. package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
  41. package/src/blocks/footer/Footer.stories.tsx +328 -0
  42. package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
  43. package/src/blocks/header/WakaHeader.stories.tsx +455 -0
  44. package/src/blocks/headtab/Headtab.stories.tsx +369 -0
  45. package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
  46. package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
  47. package/src/blocks/index.ts +1 -1
  48. package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
  49. package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
  50. package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
  51. package/src/blocks/landing/index.tsx +125 -66
  52. package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
  53. package/src/blocks/layout/Layout.stories.tsx +373 -0
  54. package/src/blocks/login/Login.stories.tsx +443 -0
  55. package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
  56. package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
  57. package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
  58. package/src/blocks/pricing/index.tsx +38 -4
  59. package/src/blocks/profile/Profile.stories.tsx +371 -0
  60. package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
  61. package/src/blocks/settings/Settings.stories.tsx +520 -0
  62. package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
  63. package/src/blocks/sidebar/index.tsx +49 -20
  64. package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
  65. package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
  66. package/src/blocks/wizard/Wizard.stories.tsx +683 -0
  67. package/src/components/accordion/Accordion.stories.tsx +93 -0
  68. package/src/components/alert/Alert.stories.tsx +95 -0
  69. package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
  70. package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
  71. package/src/components/avatar/Avatar.stories.tsx +104 -0
  72. package/src/components/button/Button.stories.tsx +12 -1
  73. package/src/components/calendar/Calendar.stories.tsx +102 -0
  74. package/src/components/card/Card.stories.tsx +125 -0
  75. package/src/components/checkbox/Checkbox.stories.tsx +100 -0
  76. package/src/components/code/Code.stories.tsx +402 -0
  77. package/src/components/collapsible/Collapsible.stories.tsx +123 -0
  78. package/src/components/command/Command.stories.tsx +207 -0
  79. package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
  80. package/src/components/dialog/Dialog.stories.tsx +157 -0
  81. package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
  82. package/src/components/form/Form.stories.tsx +413 -0
  83. package/src/components/hover-card/HoverCard.stories.tsx +148 -0
  84. package/src/components/input-otp/InputOTP.stories.tsx +255 -0
  85. package/src/components/label/Label.stories.tsx +68 -0
  86. package/src/components/menubar/Menubar.stories.tsx +278 -0
  87. package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
  88. package/src/components/popover/Popover.stories.tsx +199 -0
  89. package/src/components/progress/Progress.stories.tsx +104 -0
  90. package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
  91. package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
  92. package/src/components/select/Select.stories.tsx +146 -0
  93. package/src/components/separator/Separator.stories.tsx +117 -0
  94. package/src/components/sheet/Sheet.stories.tsx +195 -0
  95. package/src/components/skeleton/Skeleton.stories.tsx +114 -0
  96. package/src/components/slider/Slider.stories.tsx +157 -0
  97. package/src/components/switch/Switch.stories.tsx +114 -0
  98. package/src/components/table/Table.stories.tsx +153 -0
  99. package/src/components/tabs/Tabs.stories.tsx +155 -0
  100. package/src/components/textarea/Textarea.stories.tsx +116 -0
  101. package/src/components/toast/Toast.stories.tsx +160 -0
  102. package/src/components/toggle/Toggle.stories.tsx +125 -0
  103. package/src/components/tooltip/Tooltip.stories.tsx +133 -0
  104. package/src/components/typography/Typography.stories.tsx +207 -0
  105. package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
  106. package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
  107. package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
  108. package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
  109. package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
  110. package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
  111. package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
  112. package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
  113. package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
  114. package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
  115. package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
  116. package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
  117. package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
  118. package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
  119. package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
  120. package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
  121. package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
  122. package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
  123. package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
  124. package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
  125. package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
  126. package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
  127. package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
  128. package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
  129. package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
  130. package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
  131. package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
  132. package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
  133. package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
  134. package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
  135. package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
  136. package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
  137. package/src/components/waka-image/WakaImage.stories.tsx +255 -0
  138. package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
  139. package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
  140. package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
  141. package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
  142. package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
  143. package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
  144. package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
  145. package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
  146. package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
  147. package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
  148. package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
  149. package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
  150. package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
  151. package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
  152. package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
  153. package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
  154. package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
  155. package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
  156. package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
  157. package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
  158. package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
  159. package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
  160. package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
  161. package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
  162. package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
  163. package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
  164. package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
  165. package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
  166. package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
  167. package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
  168. package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
  169. package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
  170. package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
  171. package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
  172. package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
  173. package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
  174. package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
  175. package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
  176. package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
  177. package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
  178. package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
  179. package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
  180. package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
  181. package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
  182. package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
  183. package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
  184. package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
  185. package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
  186. package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
  187. package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
  188. package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
  189. package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
  190. package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
  191. package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
  192. package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
  193. package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
  194. package/src/components/waka-xp-bar/WakaXPBar.stories.tsx +305 -0
@@ -0,0 +1,559 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaDashboard, defaultDashboardStats } from './index'
3
+ import type { DashboardStatConfig, DashboardChartConfig, DashboardTableConfig, DashboardActivityItem, DashboardQuickAction } from './index'
4
+ import * as React from 'react'
5
+ import { Plus, Download, Users, DollarSign, ShoppingCart, Activity } from 'lucide-react'
6
+
7
+ const MockLink = ({ href, children, ...props }: any) => (
8
+ <a href={href} {...props} onClick={(e) => e.preventDefault()}>
9
+ {children}
10
+ </a>
11
+ )
12
+
13
+ const meta: Meta<typeof WakaDashboard> = {
14
+ title: 'Blocks/Dashboard',
15
+ component: WakaDashboard,
16
+ parameters: {
17
+ layout: 'fullscreen',
18
+ docs: {
19
+ description: {
20
+ component:
21
+ 'A comprehensive dashboard component with stats, charts, tables, activity feed, and quick actions. Supports period filtering and refresh.',
22
+ },
23
+ },
24
+ },
25
+ tags: ['autodocs'],
26
+ argTypes: {
27
+ statsLayout: {
28
+ control: 'select',
29
+ options: ['row', 'grid'],
30
+ },
31
+ statsColumns: {
32
+ control: 'select',
33
+ options: [2, 3, 4],
34
+ },
35
+ showHeader: {
36
+ control: 'boolean',
37
+ },
38
+ loading: {
39
+ control: 'boolean',
40
+ },
41
+ },
42
+ }
43
+
44
+ export default meta
45
+ type Story = StoryObj<typeof WakaDashboard>
46
+
47
+ // Mock chart component
48
+ const MockChart = ({ height = 200, title }: { height?: number; title: string }) => (
49
+ <div
50
+ className="bg-muted/30 rounded-lg flex items-center justify-center"
51
+ style={{ height }}
52
+ >
53
+ <span className="text-muted-foreground text-sm">{title}</span>
54
+ </div>
55
+ )
56
+
57
+ // Mock table component
58
+ const MockTable = () => (
59
+ <div className="space-y-2">
60
+ {[1, 2, 3, 4, 5].map((i) => (
61
+ <div key={i} className="flex justify-between py-2 border-b last:border-0">
62
+ <span className="text-sm">Item {i}</span>
63
+ <span className="text-sm text-muted-foreground">Value {i * 100}</span>
64
+ </div>
65
+ ))}
66
+ </div>
67
+ )
68
+
69
+ export const Default: Story = {
70
+ render: () => (
71
+ <div className="p-6">
72
+ <WakaDashboard
73
+ title="Tableau de bord"
74
+ description="Vue d'ensemble de votre activité"
75
+ stats={defaultDashboardStats}
76
+ period="month"
77
+ onPeriodChange={(period) => console.log('Period:', period)}
78
+ onRefresh={() => console.log('Refresh')}
79
+ LinkComponent={MockLink}
80
+ />
81
+ </div>
82
+ ),
83
+ }
84
+
85
+ export const WithCharts: Story = {
86
+ render: () => {
87
+ const charts: DashboardChartConfig[] = [
88
+ {
89
+ id: 'revenue-chart',
90
+ title: 'Revenus',
91
+ description: 'Évolution des revenus sur la période',
92
+ chart: <MockChart title="Line Chart - Revenus" />,
93
+ actions: [
94
+ { label: 'Exporter', onClick: () => console.log('Export') },
95
+ ],
96
+ },
97
+ {
98
+ id: 'users-chart',
99
+ title: 'Utilisateurs',
100
+ description: 'Nouveaux utilisateurs par jour',
101
+ chart: <MockChart title="Bar Chart - Utilisateurs" />,
102
+ actions: [
103
+ { label: 'Voir détails', onClick: () => console.log('Details') },
104
+ ],
105
+ },
106
+ ]
107
+
108
+ return (
109
+ <div className="p-6">
110
+ <WakaDashboard
111
+ title="Dashboard avec graphiques"
112
+ stats={defaultDashboardStats}
113
+ charts={charts}
114
+ period="month"
115
+ onPeriodChange={(period) => console.log('Period:', period)}
116
+ LinkComponent={MockLink}
117
+ />
118
+ </div>
119
+ )
120
+ },
121
+ }
122
+
123
+ export const WithTables: Story = {
124
+ render: () => {
125
+ const tables: DashboardTableConfig[] = [
126
+ {
127
+ id: 'recent-orders',
128
+ title: 'Commandes récentes',
129
+ description: 'Les 5 dernières commandes',
130
+ table: <MockTable />,
131
+ actions: [
132
+ { label: 'Voir tout', href: '/orders' },
133
+ ],
134
+ },
135
+ ]
136
+
137
+ return (
138
+ <div className="p-6">
139
+ <WakaDashboard
140
+ title="Dashboard avec tableau"
141
+ stats={defaultDashboardStats}
142
+ tables={tables}
143
+ period="month"
144
+ onPeriodChange={(period) => console.log('Period:', period)}
145
+ LinkComponent={MockLink}
146
+ />
147
+ </div>
148
+ )
149
+ },
150
+ }
151
+
152
+ export const WithActivity: Story = {
153
+ render: () => {
154
+ const activities: DashboardActivityItem[] = [
155
+ {
156
+ id: '1',
157
+ title: 'Nouvelle commande #1234',
158
+ description: 'Jean Dupont a passé une commande de €150',
159
+ timestamp: new Date(Date.now() - 1000 * 60 * 5),
160
+ type: 'success',
161
+ },
162
+ {
163
+ id: '2',
164
+ title: 'Nouvel utilisateur',
165
+ description: 'Marie Martin s\'est inscrite',
166
+ timestamp: new Date(Date.now() - 1000 * 60 * 30),
167
+ type: 'info',
168
+ },
169
+ {
170
+ id: '3',
171
+ title: 'Paiement échoué',
172
+ description: 'Le paiement de la commande #1233 a échoué',
173
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2),
174
+ type: 'error',
175
+ },
176
+ {
177
+ id: '4',
178
+ title: 'Stock faible',
179
+ description: 'Le produit "Widget Pro" est presque en rupture',
180
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 5),
181
+ type: 'warning',
182
+ },
183
+ ]
184
+
185
+ return (
186
+ <div className="p-6">
187
+ <WakaDashboard
188
+ title="Dashboard avec activité"
189
+ stats={defaultDashboardStats}
190
+ activities={activities}
191
+ period="month"
192
+ onPeriodChange={(period) => console.log('Period:', period)}
193
+ LinkComponent={MockLink}
194
+ />
195
+ </div>
196
+ )
197
+ },
198
+ }
199
+
200
+ export const WithQuickActions: Story = {
201
+ render: () => {
202
+ const quickActions: DashboardQuickAction[] = [
203
+ {
204
+ id: 'add-product',
205
+ label: 'Ajouter produit',
206
+ icon: <Plus className="h-4 w-4" />,
207
+ onClick: () => console.log('Add product'),
208
+ },
209
+ {
210
+ id: 'export',
211
+ label: 'Exporter',
212
+ icon: <Download className="h-4 w-4" />,
213
+ variant: 'outline',
214
+ onClick: () => console.log('Export'),
215
+ },
216
+ ]
217
+
218
+ return (
219
+ <div className="p-6">
220
+ <WakaDashboard
221
+ title="Dashboard avec actions rapides"
222
+ stats={defaultDashboardStats}
223
+ quickActions={quickActions}
224
+ period="month"
225
+ onPeriodChange={(period) => console.log('Period:', period)}
226
+ onRefresh={() => console.log('Refresh')}
227
+ LinkComponent={MockLink}
228
+ />
229
+ </div>
230
+ )
231
+ },
232
+ }
233
+
234
+ export const Complete: Story = {
235
+ render: () => {
236
+ const charts: DashboardChartConfig[] = [
237
+ {
238
+ id: 'revenue-chart',
239
+ title: 'Revenus',
240
+ description: 'Évolution des revenus',
241
+ chart: <MockChart title="Line Chart" height={250} />,
242
+ },
243
+ {
244
+ id: 'orders-chart',
245
+ title: 'Commandes',
246
+ description: 'Commandes par catégorie',
247
+ chart: <MockChart title="Pie Chart" height={250} />,
248
+ },
249
+ ]
250
+
251
+ const tables: DashboardTableConfig[] = [
252
+ {
253
+ id: 'top-products',
254
+ title: 'Produits populaires',
255
+ description: 'Les plus vendus ce mois',
256
+ table: <MockTable />,
257
+ actions: [{ label: 'Voir tout', href: '/products' }],
258
+ },
259
+ ]
260
+
261
+ const activities: DashboardActivityItem[] = [
262
+ {
263
+ id: '1',
264
+ title: 'Commande #1234 expédiée',
265
+ timestamp: new Date(Date.now() - 1000 * 60 * 10),
266
+ type: 'success',
267
+ },
268
+ {
269
+ id: '2',
270
+ title: 'Nouveau client enregistré',
271
+ timestamp: new Date(Date.now() - 1000 * 60 * 45),
272
+ type: 'info',
273
+ },
274
+ {
275
+ id: '3',
276
+ title: 'Stock mis à jour',
277
+ timestamp: new Date(Date.now() - 1000 * 60 * 120),
278
+ type: 'info',
279
+ },
280
+ ]
281
+
282
+ const quickActions: DashboardQuickAction[] = [
283
+ {
284
+ id: 'new-order',
285
+ label: 'Nouvelle commande',
286
+ icon: <Plus className="h-4 w-4" />,
287
+ href: '/orders/new',
288
+ },
289
+ ]
290
+
291
+ return (
292
+ <div className="p-6">
293
+ <WakaDashboard
294
+ title="Dashboard complet"
295
+ description="Vue d'ensemble de votre activité commerciale"
296
+ stats={defaultDashboardStats}
297
+ charts={charts}
298
+ tables={tables}
299
+ activities={activities}
300
+ quickActions={quickActions}
301
+ period="month"
302
+ onPeriodChange={(period) => console.log('Period:', period)}
303
+ onRefresh={() => console.log('Refresh')}
304
+ LinkComponent={MockLink}
305
+ />
306
+ </div>
307
+ )
308
+ },
309
+ }
310
+
311
+ export const StatsOnly: Story = {
312
+ render: () => (
313
+ <div className="p-6">
314
+ <WakaDashboard
315
+ title="Statistiques"
316
+ stats={defaultDashboardStats}
317
+ showHeader
318
+ LinkComponent={MockLink}
319
+ />
320
+ </div>
321
+ ),
322
+ }
323
+
324
+ export const GridStats: Story = {
325
+ render: () => (
326
+ <div className="p-6">
327
+ <WakaDashboard
328
+ title="Stats en grille"
329
+ stats={defaultDashboardStats}
330
+ statsLayout="grid"
331
+ statsColumns={4}
332
+ LinkComponent={MockLink}
333
+ />
334
+ </div>
335
+ ),
336
+ }
337
+
338
+ export const TwoColumnStats: Story = {
339
+ render: () => (
340
+ <div className="p-6">
341
+ <WakaDashboard
342
+ title="Stats 2 colonnes"
343
+ stats={defaultDashboardStats.slice(0, 2)}
344
+ statsLayout="grid"
345
+ statsColumns={2}
346
+ LinkComponent={MockLink}
347
+ />
348
+ </div>
349
+ ),
350
+ }
351
+
352
+ export const Loading: Story = {
353
+ render: () => (
354
+ <div className="p-6">
355
+ <WakaDashboard
356
+ title="Chargement..."
357
+ stats={defaultDashboardStats}
358
+ loading
359
+ period="month"
360
+ onPeriodChange={(period) => console.log('Period:', period)}
361
+ onRefresh={() => console.log('Refresh')}
362
+ LinkComponent={MockLink}
363
+ />
364
+ </div>
365
+ ),
366
+ }
367
+
368
+ export const NoHeader: Story = {
369
+ render: () => (
370
+ <div className="p-6">
371
+ <WakaDashboard
372
+ stats={defaultDashboardStats}
373
+ showHeader={false}
374
+ LinkComponent={MockLink}
375
+ />
376
+ </div>
377
+ ),
378
+ }
379
+
380
+ export const CustomStats: Story = {
381
+ render: () => {
382
+ const customStats: DashboardStatConfig[] = [
383
+ {
384
+ id: 'visitors',
385
+ label: 'Visiteurs',
386
+ value: '12,345',
387
+ trend: 'up',
388
+ trendValue: '+15%',
389
+ trendText: 'vs semaine dernière',
390
+ icon: <Users className="h-5 w-5" />,
391
+ color: 'blue',
392
+ },
393
+ {
394
+ id: 'revenue',
395
+ label: 'Revenus',
396
+ value: '€89,432',
397
+ trend: 'up',
398
+ trendValue: '+8.2%',
399
+ icon: <DollarSign className="h-5 w-5" />,
400
+ color: 'success',
401
+ },
402
+ {
403
+ id: 'orders',
404
+ label: 'Commandes',
405
+ value: '432',
406
+ trend: 'down',
407
+ trendValue: '-3%',
408
+ icon: <ShoppingCart className="h-5 w-5" />,
409
+ color: 'warning',
410
+ },
411
+ {
412
+ id: 'conversion',
413
+ label: 'Taux de conversion',
414
+ value: '3.5%',
415
+ trend: 'neutral',
416
+ icon: <Activity className="h-5 w-5" />,
417
+ color: 'purple',
418
+ },
419
+ ]
420
+
421
+ return (
422
+ <div className="p-6">
423
+ <WakaDashboard
424
+ title="Dashboard personnalisé"
425
+ stats={customStats}
426
+ period="week"
427
+ onPeriodChange={(period) => console.log('Period:', period)}
428
+ LinkComponent={MockLink}
429
+ />
430
+ </div>
431
+ )
432
+ },
433
+ }
434
+
435
+ export const Interactive: Story = {
436
+ render: () => {
437
+ const [period, setPeriod] = React.useState('month')
438
+ const [loading, setLoading] = React.useState(false)
439
+
440
+ const handleRefresh = () => {
441
+ setLoading(true)
442
+ setTimeout(() => setLoading(false), 1500)
443
+ }
444
+
445
+ return (
446
+ <div className="p-6">
447
+ <WakaDashboard
448
+ title="Dashboard interactif"
449
+ description={`Période sélectionnée: ${period}`}
450
+ stats={defaultDashboardStats}
451
+ period={period}
452
+ onPeriodChange={setPeriod}
453
+ onRefresh={handleRefresh}
454
+ loading={loading}
455
+ LinkComponent={MockLink}
456
+ />
457
+ </div>
458
+ )
459
+ },
460
+ }
461
+
462
+ export const EcommerceDashboard: Story = {
463
+ render: () => {
464
+ const ecommerceStats: DashboardStatConfig[] = [
465
+ {
466
+ id: 'sales',
467
+ label: 'Ventes du jour',
468
+ value: '€3,421',
469
+ trend: 'up',
470
+ trendValue: '+12%',
471
+ icon: <DollarSign className="h-5 w-5" />,
472
+ color: 'success',
473
+ },
474
+ {
475
+ id: 'orders',
476
+ label: 'Commandes',
477
+ value: '48',
478
+ trend: 'up',
479
+ trendValue: '+5',
480
+ icon: <ShoppingCart className="h-5 w-5" />,
481
+ color: 'blue',
482
+ },
483
+ {
484
+ id: 'customers',
485
+ label: 'Nouveaux clients',
486
+ value: '12',
487
+ trend: 'down',
488
+ trendValue: '-2',
489
+ icon: <Users className="h-5 w-5" />,
490
+ color: 'purple',
491
+ },
492
+ {
493
+ id: 'aov',
494
+ label: 'Panier moyen',
495
+ value: '€71.27',
496
+ trend: 'up',
497
+ trendValue: '+€5.30',
498
+ icon: <Activity className="h-5 w-5" />,
499
+ color: 'primary',
500
+ },
501
+ ]
502
+
503
+ const charts: DashboardChartConfig[] = [
504
+ {
505
+ id: 'sales-chart',
506
+ title: 'Ventes',
507
+ description: 'Ventes des 7 derniers jours',
508
+ chart: <MockChart title="Sales Chart" height={300} />,
509
+ },
510
+ {
511
+ id: 'categories',
512
+ title: 'Par catégorie',
513
+ description: 'Répartition des ventes',
514
+ chart: <MockChart title="Category Pie Chart" height={300} />,
515
+ },
516
+ ]
517
+
518
+ return (
519
+ <div className="min-h-screen bg-muted/30">
520
+ <header className="bg-background border-b px-6 py-4">
521
+ <div className="flex items-center justify-between">
522
+ <span className="font-bold text-xl">MyShop Admin</span>
523
+ <nav className="flex gap-4 text-sm">
524
+ <a href="#" className="text-foreground font-medium">Dashboard</a>
525
+ <a href="#" className="text-muted-foreground hover:text-foreground">Produits</a>
526
+ <a href="#" className="text-muted-foreground hover:text-foreground">Commandes</a>
527
+ <a href="#" className="text-muted-foreground hover:text-foreground">Clients</a>
528
+ </nav>
529
+ </div>
530
+ </header>
531
+ <main className="p-6">
532
+ <WakaDashboard
533
+ title="Tableau de bord"
534
+ description="Bienvenue ! Voici un aperçu de votre boutique."
535
+ stats={ecommerceStats}
536
+ charts={charts}
537
+ period="today"
538
+ periods={[
539
+ { value: 'today', label: "Aujourd'hui" },
540
+ { value: 'week', label: 'Cette semaine' },
541
+ { value: 'month', label: 'Ce mois' },
542
+ ]}
543
+ onPeriodChange={(period) => console.log('Period:', period)}
544
+ onRefresh={() => console.log('Refresh')}
545
+ quickActions={[
546
+ {
547
+ id: 'add-product',
548
+ label: 'Ajouter produit',
549
+ icon: <Plus className="h-4 w-4" />,
550
+ href: '/products/new',
551
+ },
552
+ ]}
553
+ LinkComponent={MockLink}
554
+ />
555
+ </main>
556
+ </div>
557
+ )
558
+ },
559
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as React from "react"
4
4
  import { cn } from "../../utils"
5
+ import type { LinkComponentProps } from "../../types/link"
5
6
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../../components/card"
6
7
  import { Button } from "../../components/button"
7
8
  import { Badge } from "../../components/badge"
@@ -119,6 +120,22 @@ export interface WakaDashboardProps {
119
120
  statsColumns?: 2 | 3 | 4
120
121
  /** Classes CSS additionnelles */
121
122
  className?: string
123
+ /** Composant de lien personnalisé (ex: next/link) pour navigation SPA */
124
+ LinkComponent?: React.ComponentType<LinkComponentProps>
125
+ }
126
+
127
+ // ============================================
128
+ // CONTEXT
129
+ // ============================================
130
+
131
+ interface DashboardContextValue {
132
+ LinkComponent?: React.ComponentType<LinkComponentProps>
133
+ }
134
+
135
+ const DashboardContext = React.createContext<DashboardContextValue>({})
136
+
137
+ function useDashboardContext() {
138
+ return React.useContext(DashboardContext)
122
139
  }
123
140
 
124
141
  // ============================================
@@ -196,27 +213,37 @@ function DashboardHeader({
196
213
  )}
197
214
 
198
215
  {/* Actions rapides */}
199
- {quickActions?.map((action) => (
200
- <Button
201
- key={action.id}
202
- variant={action.variant || "default"}
203
- size="sm"
204
- onClick={action.onClick}
205
- asChild={!!action.href}
206
- >
207
- {action.href ? (
208
- <a href={action.href}>
209
- {action.icon && <span className="mr-2">{action.icon}</span>}
210
- {action.label}
211
- </a>
212
- ) : (
213
- <>
214
- {action.icon && <span className="mr-2">{action.icon}</span>}
215
- {action.label}
216
- </>
217
- )}
218
- </Button>
219
- ))}
216
+ {quickActions?.map((action) => {
217
+ const { LinkComponent } = useDashboardContext()
218
+ return (
219
+ <Button
220
+ key={action.id}
221
+ variant={action.variant || "default"}
222
+ size="sm"
223
+ onClick={action.onClick}
224
+ asChild={!!action.href}
225
+ >
226
+ {action.href ? (
227
+ LinkComponent ? (
228
+ <LinkComponent href={action.href}>
229
+ {action.icon && <span className="mr-2">{action.icon}</span>}
230
+ {action.label}
231
+ </LinkComponent>
232
+ ) : (
233
+ <a href={action.href}>
234
+ {action.icon && <span className="mr-2">{action.icon}</span>}
235
+ {action.label}
236
+ </a>
237
+ )
238
+ ) : (
239
+ <>
240
+ {action.icon && <span className="mr-2">{action.icon}</span>}
241
+ {action.label}
242
+ </>
243
+ )}
244
+ </Button>
245
+ )
246
+ })}
220
247
  </div>
221
248
  </div>
222
249
  )
@@ -296,6 +323,8 @@ interface DashboardTableCardProps {
296
323
  }
297
324
 
298
325
  function DashboardTableCard({ config }: DashboardTableCardProps) {
326
+ const { LinkComponent } = useDashboardContext()
327
+
299
328
  return (
300
329
  <Card>
301
330
  <CardHeader className="flex flex-row items-center justify-between pb-2">
@@ -316,10 +345,17 @@ function DashboardTableCard({ config }: DashboardTableCardProps) {
316
345
  asChild={!!action.href}
317
346
  >
318
347
  {action.href ? (
319
- <a href={action.href}>
320
- {action.label}
321
- <ArrowUpRight className="ml-1 h-3 w-3" />
322
- </a>
348
+ LinkComponent ? (
349
+ <LinkComponent href={action.href}>
350
+ {action.label}
351
+ <ArrowUpRight className="ml-1 h-3 w-3" />
352
+ </LinkComponent>
353
+ ) : (
354
+ <a href={action.href}>
355
+ {action.label}
356
+ <ArrowUpRight className="ml-1 h-3 w-3" />
357
+ </a>
358
+ )
323
359
  ) : (
324
360
  action.label
325
361
  )}
@@ -415,9 +451,13 @@ export function WakaDashboard({
415
451
  statsLayout = "grid",
416
452
  statsColumns = 4,
417
453
  className,
454
+ LinkComponent,
418
455
  }: WakaDashboardProps) {
456
+ const contextValue = React.useMemo(() => ({ LinkComponent }), [LinkComponent])
457
+
419
458
  return (
420
- <div className={cn("space-y-6", className)}>
459
+ <DashboardContext.Provider value={contextValue}>
460
+ <div className={cn("space-y-6", className)}>
421
461
  {/* Header */}
422
462
  {showHeader && (
423
463
  <DashboardHeader
@@ -469,7 +509,8 @@ export function WakaDashboard({
469
509
  </div>
470
510
  )}
471
511
  </div>
472
- </div>
512
+ </div>
513
+ </DashboardContext.Provider>
473
514
  )
474
515
  }
475
516