@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,306 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaDatabaseCard, defaultDatabase, defaultDatabases } from './index'
3
+ import type { DatabaseInfo, DatabaseType, DatabaseStatus } from './index'
4
+ import * as React from 'react'
5
+
6
+ const criticalDatabase: DatabaseInfo = {
7
+ id: 'critical',
8
+ name: 'overloaded-db',
9
+ type: 'postgresql',
10
+ version: '15.4',
11
+ host: 'db.example.com',
12
+ port: 5432,
13
+ status: 'critical',
14
+ role: 'primary',
15
+ metrics: {
16
+ connectionsActive: 95,
17
+ connectionsMax: 100,
18
+ queriesPerSecond: 2500,
19
+ slowQueries: 45,
20
+ avgQueryTime: 250,
21
+ cacheHitRate: 75.5,
22
+ storageUsed: 180 * 1024 * 1024 * 1024,
23
+ storageTotal: 200 * 1024 * 1024 * 1024,
24
+ replicationLag: 2500,
25
+ uptime: 5 * 24 * 3600,
26
+ },
27
+ replicas: 2,
28
+ tags: ['production', 'critical'],
29
+ }
30
+
31
+ const warningDatabase: DatabaseInfo = {
32
+ id: 'warning',
33
+ name: 'busy-db',
34
+ type: 'mysql',
35
+ version: '8.0',
36
+ host: 'mysql.example.com',
37
+ port: 3306,
38
+ status: 'warning',
39
+ role: 'primary',
40
+ metrics: {
41
+ connectionsActive: 72,
42
+ connectionsMax: 100,
43
+ queriesPerSecond: 800,
44
+ slowQueries: 15,
45
+ avgQueryTime: 85,
46
+ storageUsed: 150 * 1024 * 1024 * 1024,
47
+ storageTotal: 200 * 1024 * 1024 * 1024,
48
+ uptime: 30 * 24 * 3600,
49
+ },
50
+ tags: ['staging'],
51
+ }
52
+
53
+ const offlineDatabase: DatabaseInfo = {
54
+ id: 'offline',
55
+ name: 'maintenance-db',
56
+ type: 'postgresql',
57
+ version: '14.9',
58
+ host: 'backup-db.example.com',
59
+ port: 5432,
60
+ status: 'offline',
61
+ role: 'standalone',
62
+ metrics: {
63
+ connectionsActive: 0,
64
+ connectionsMax: 50,
65
+ queriesPerSecond: 0,
66
+ slowQueries: 0,
67
+ avgQueryTime: 0,
68
+ storageUsed: 50 * 1024 * 1024 * 1024,
69
+ storageTotal: 100 * 1024 * 1024 * 1024,
70
+ },
71
+ lastBackup: new Date(Date.now() - 24 * 3600000),
72
+ tags: ['backup', 'maintenance'],
73
+ }
74
+
75
+ const syncingDatabase: DatabaseInfo = {
76
+ id: 'syncing',
77
+ name: 'replica-db-1',
78
+ type: 'postgresql',
79
+ version: '15.4',
80
+ host: 'replica-1.example.com',
81
+ port: 5432,
82
+ status: 'syncing',
83
+ role: 'replica',
84
+ metrics: {
85
+ connectionsActive: 15,
86
+ connectionsMax: 100,
87
+ queriesPerSecond: 250,
88
+ slowQueries: 0,
89
+ avgQueryTime: 8,
90
+ storageUsed: 85 * 1024 * 1024 * 1024,
91
+ storageTotal: 200 * 1024 * 1024 * 1024,
92
+ replicationLag: 500,
93
+ uptime: 2 * 24 * 3600,
94
+ },
95
+ }
96
+
97
+ const meta: Meta<typeof WakaDatabaseCard> = {
98
+ title: 'Components/DevOps/WakaDatabaseCard',
99
+ component: WakaDatabaseCard,
100
+ parameters: {
101
+ layout: 'centered',
102
+ docs: {
103
+ description: {
104
+ component: 'A database status card with connection metrics, storage usage, query stats, replication info, and health indicators.',
105
+ },
106
+ },
107
+ },
108
+ tags: ['autodocs'],
109
+ argTypes: {
110
+ detailed: {
111
+ control: 'boolean',
112
+ description: 'Show detailed metrics',
113
+ },
114
+ compact: {
115
+ control: 'boolean',
116
+ description: 'Compact row mode',
117
+ },
118
+ },
119
+ }
120
+
121
+ export default meta
122
+ type Story = StoryObj<typeof WakaDatabaseCard>
123
+
124
+ export const Default: Story = {
125
+ args: {
126
+ database: defaultDatabase,
127
+ },
128
+ render: (args) => (
129
+ <div className="w-[450px]">
130
+ <WakaDatabaseCard
131
+ {...args}
132
+ onRefresh={() => console.log('Refresh')}
133
+ onClick={() => console.log('Click')}
134
+ />
135
+ </div>
136
+ ),
137
+ }
138
+
139
+ export const Detailed: Story = {
140
+ render: () => (
141
+ <div className="w-[450px]">
142
+ <WakaDatabaseCard
143
+ database={defaultDatabase}
144
+ detailed
145
+ onRefresh={() => console.log('Refresh')}
146
+ />
147
+ </div>
148
+ ),
149
+ }
150
+
151
+ export const AllStatuses: Story = {
152
+ render: () => {
153
+ const databases: DatabaseInfo[] = [
154
+ { ...defaultDatabase, status: 'healthy' },
155
+ warningDatabase,
156
+ criticalDatabase,
157
+ offlineDatabase,
158
+ syncingDatabase,
159
+ ]
160
+
161
+ return (
162
+ <div className="grid grid-cols-1 gap-4 w-[450px]">
163
+ {databases.map((db) => (
164
+ <WakaDatabaseCard key={db.id} database={db} compact />
165
+ ))}
166
+ </div>
167
+ )
168
+ },
169
+ }
170
+
171
+ export const AllTypes: Story = {
172
+ render: () => {
173
+ const types: DatabaseType[] = ['postgresql', 'mysql', 'mongodb', 'redis', 'elasticsearch']
174
+
175
+ return (
176
+ <div className="grid grid-cols-1 gap-4 w-[500px]">
177
+ {types.map((type) => (
178
+ <WakaDatabaseCard
179
+ key={type}
180
+ database={{
181
+ ...defaultDatabase,
182
+ id: type,
183
+ name: `${type}-db`,
184
+ type,
185
+ }}
186
+ compact
187
+ />
188
+ ))}
189
+ </div>
190
+ )
191
+ },
192
+ }
193
+
194
+ export const Critical: Story = {
195
+ render: () => (
196
+ <div className="w-[450px]">
197
+ <p className="text-sm text-muted-foreground mb-4">
198
+ Database with critical status (high connections, storage, slow queries)
199
+ </p>
200
+ <WakaDatabaseCard
201
+ database={criticalDatabase}
202
+ detailed
203
+ onRefresh={() => console.log('Refresh')}
204
+ />
205
+ </div>
206
+ ),
207
+ }
208
+
209
+ export const Warning: Story = {
210
+ render: () => (
211
+ <div className="w-[450px]">
212
+ <WakaDatabaseCard
213
+ database={warningDatabase}
214
+ detailed
215
+ onRefresh={() => console.log('Refresh')}
216
+ />
217
+ </div>
218
+ ),
219
+ }
220
+
221
+ export const Offline: Story = {
222
+ render: () => (
223
+ <div className="w-[450px]">
224
+ <WakaDatabaseCard
225
+ database={offlineDatabase}
226
+ detailed
227
+ />
228
+ </div>
229
+ ),
230
+ }
231
+
232
+ export const Syncing: Story = {
233
+ render: () => (
234
+ <div className="w-[450px]">
235
+ <p className="text-sm text-muted-foreground mb-4">
236
+ Replica database currently syncing with primary
237
+ </p>
238
+ <WakaDatabaseCard
239
+ database={syncingDatabase}
240
+ detailed
241
+ onRefresh={() => console.log('Refresh')}
242
+ />
243
+ </div>
244
+ ),
245
+ }
246
+
247
+ export const Compact: Story = {
248
+ render: () => (
249
+ <div className="space-y-2 w-[500px]">
250
+ {defaultDatabases.map((db) => (
251
+ <WakaDatabaseCard
252
+ key={db.id}
253
+ database={db}
254
+ compact
255
+ onClick={() => console.log('Click:', db.name)}
256
+ />
257
+ ))}
258
+ </div>
259
+ ),
260
+ }
261
+
262
+ export const NoActions: Story = {
263
+ render: () => (
264
+ <div className="w-[450px]">
265
+ <p className="text-sm text-muted-foreground mb-4">
266
+ Read-only view without action buttons
267
+ </p>
268
+ <WakaDatabaseCard database={defaultDatabase} detailed />
269
+ </div>
270
+ ),
271
+ }
272
+
273
+ export const DatabaseDashboard: Story = {
274
+ render: () => {
275
+ const allDatabases = [...defaultDatabases, criticalDatabase, syncingDatabase]
276
+
277
+ return (
278
+ <div className="p-6 rounded-xl border bg-card">
279
+ <div className="flex items-center justify-between mb-6">
280
+ <div>
281
+ <h2 className="text-xl font-bold">Database Fleet</h2>
282
+ <p className="text-sm text-muted-foreground">Production Environment</p>
283
+ </div>
284
+ <div className="flex items-center gap-2 text-sm">
285
+ <span className="text-green-500 font-medium">3 healthy</span>
286
+ <span className="text-muted-foreground">•</span>
287
+ <span className="text-yellow-500 font-medium">1 warning</span>
288
+ <span className="text-muted-foreground">•</span>
289
+ <span className="text-red-500 font-medium">1 critical</span>
290
+ </div>
291
+ </div>
292
+
293
+ <div className="space-y-2 w-[550px]">
294
+ {allDatabases.map((db) => (
295
+ <WakaDatabaseCard
296
+ key={db.id}
297
+ database={db}
298
+ compact
299
+ onClick={() => console.log('Click:', db.name)}
300
+ />
301
+ ))}
302
+ </div>
303
+ </div>
304
+ )
305
+ },
306
+ }
@@ -0,0 +1,339 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaDateRangePicker, type WakaDateRange } from './index'
3
+ import * as React from 'react'
4
+ import { subDays, startOfMonth, endOfMonth } from 'date-fns'
5
+
6
+ const meta: Meta<typeof WakaDateRangePicker> = {
7
+ title: 'Components/Forms/WakaDateRangePicker',
8
+ component: WakaDateRangePicker,
9
+ parameters: {
10
+ layout: 'centered',
11
+ docs: {
12
+ description: {
13
+ component: 'A date range picker with presets, dual calendar view, and day count.',
14
+ },
15
+ },
16
+ },
17
+ tags: ['autodocs'],
18
+ argTypes: {
19
+ size: {
20
+ control: 'select',
21
+ options: ['sm', 'md', 'lg'],
22
+ description: 'Size of the component',
23
+ },
24
+ numberOfMonths: {
25
+ control: 'number',
26
+ description: 'Number of months to display',
27
+ },
28
+ showPresets: {
29
+ control: 'boolean',
30
+ description: 'Show preset date ranges',
31
+ },
32
+ clearable: {
33
+ control: 'boolean',
34
+ description: 'Allow clearing the selection',
35
+ },
36
+ disabled: {
37
+ control: 'boolean',
38
+ description: 'Disable the picker',
39
+ },
40
+ },
41
+ }
42
+
43
+ export default meta
44
+ type Story = StoryObj<typeof WakaDateRangePicker>
45
+
46
+ export const Default: Story = {
47
+ render: function DateRangePickerDemo() {
48
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
49
+
50
+ return (
51
+ <div className="w-[300px]">
52
+ <WakaDateRangePicker
53
+ value={range}
54
+ onChange={setRange}
55
+ placeholder="Select date range"
56
+ />
57
+ </div>
58
+ )
59
+ },
60
+ }
61
+
62
+ export const WithPresets: Story = {
63
+ render: function PresetsDemo() {
64
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
65
+
66
+ return (
67
+ <div className="w-[300px]">
68
+ <WakaDateRangePicker
69
+ value={range}
70
+ onChange={setRange}
71
+ showPresets
72
+ placeholder="Select date range"
73
+ />
74
+ </div>
75
+ )
76
+ },
77
+ }
78
+
79
+ export const WithInitialValue: Story = {
80
+ render: function InitialValueDemo() {
81
+ const [range, setRange] = React.useState<WakaDateRange | undefined>({
82
+ from: subDays(new Date(), 7),
83
+ to: new Date(),
84
+ })
85
+
86
+ return (
87
+ <div className="w-[300px]">
88
+ <WakaDateRangePicker
89
+ value={range}
90
+ onChange={setRange}
91
+ showPresets
92
+ />
93
+ </div>
94
+ )
95
+ },
96
+ }
97
+
98
+ export const SingleMonth: Story = {
99
+ render: function SingleMonthDemo() {
100
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
101
+
102
+ return (
103
+ <div className="w-[300px]">
104
+ <WakaDateRangePicker
105
+ value={range}
106
+ onChange={setRange}
107
+ numberOfMonths={1}
108
+ showPresets={false}
109
+ placeholder="Single month view"
110
+ />
111
+ </div>
112
+ )
113
+ },
114
+ }
115
+
116
+ export const WithMinMax: Story = {
117
+ render: function MinMaxDemo() {
118
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
119
+ const today = new Date()
120
+ const minDate = startOfMonth(today)
121
+ const maxDate = endOfMonth(today)
122
+
123
+ return (
124
+ <div className="w-[300px]">
125
+ <WakaDateRangePicker
126
+ value={range}
127
+ onChange={setRange}
128
+ minDate={minDate}
129
+ maxDate={maxDate}
130
+ showPresets={false}
131
+ placeholder="This month only"
132
+ />
133
+ <p className="text-xs text-muted-foreground mt-2">
134
+ Restricted to current month
135
+ </p>
136
+ </div>
137
+ )
138
+ },
139
+ }
140
+
141
+ export const CustomPresets: Story = {
142
+ render: function CustomPresetsDemo() {
143
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
144
+
145
+ const customPresets = [
146
+ {
147
+ label: 'Last 3 days',
148
+ getValue: () => ({
149
+ from: subDays(new Date(), 2),
150
+ to: new Date(),
151
+ }),
152
+ },
153
+ {
154
+ label: 'Last 14 days',
155
+ getValue: () => ({
156
+ from: subDays(new Date(), 13),
157
+ to: new Date(),
158
+ }),
159
+ },
160
+ {
161
+ label: 'Last 90 days',
162
+ getValue: () => ({
163
+ from: subDays(new Date(), 89),
164
+ to: new Date(),
165
+ }),
166
+ },
167
+ ]
168
+
169
+ return (
170
+ <div className="w-[300px]">
171
+ <WakaDateRangePicker
172
+ value={range}
173
+ onChange={setRange}
174
+ showPresets
175
+ presets={customPresets}
176
+ placeholder="Custom presets"
177
+ />
178
+ </div>
179
+ )
180
+ },
181
+ }
182
+
183
+ export const Sizes: Story = {
184
+ render: function SizesDemo() {
185
+ const [range, setRange] = React.useState<WakaDateRange | undefined>()
186
+
187
+ return (
188
+ <div className="space-y-4 w-[300px]">
189
+ <div>
190
+ <p className="text-sm text-muted-foreground mb-1">Small</p>
191
+ <WakaDateRangePicker
192
+ value={range}
193
+ onChange={setRange}
194
+ size="sm"
195
+ showPresets={false}
196
+ />
197
+ </div>
198
+ <div>
199
+ <p className="text-sm text-muted-foreground mb-1">Medium</p>
200
+ <WakaDateRangePicker
201
+ value={range}
202
+ onChange={setRange}
203
+ size="md"
204
+ showPresets={false}
205
+ />
206
+ </div>
207
+ <div>
208
+ <p className="text-sm text-muted-foreground mb-1">Large</p>
209
+ <WakaDateRangePicker
210
+ value={range}
211
+ onChange={setRange}
212
+ size="lg"
213
+ showPresets={false}
214
+ />
215
+ </div>
216
+ </div>
217
+ )
218
+ },
219
+ }
220
+
221
+ export const CustomFormat: Story = {
222
+ render: function CustomFormatDemo() {
223
+ const [range, setRange] = React.useState<WakaDateRange | undefined>({
224
+ from: subDays(new Date(), 7),
225
+ to: new Date(),
226
+ })
227
+
228
+ return (
229
+ <div className="w-[300px]">
230
+ <WakaDateRangePicker
231
+ value={range}
232
+ onChange={setRange}
233
+ dateFormat="MMM d, yyyy"
234
+ showPresets={false}
235
+ />
236
+ <p className="text-xs text-muted-foreground mt-2">
237
+ Custom date format: MMM d, yyyy
238
+ </p>
239
+ </div>
240
+ )
241
+ },
242
+ }
243
+
244
+ export const WithError: Story = {
245
+ render: () => (
246
+ <div className="w-[300px]">
247
+ <WakaDateRangePicker
248
+ error
249
+ showPresets={false}
250
+ placeholder="Required field"
251
+ />
252
+ <p className="text-sm text-destructive mt-1">
253
+ Please select a date range
254
+ </p>
255
+ </div>
256
+ ),
257
+ }
258
+
259
+ export const NotClearable: Story = {
260
+ render: function NotClearableDemo() {
261
+ const [range, setRange] = React.useState<WakaDateRange | undefined>({
262
+ from: subDays(new Date(), 7),
263
+ to: new Date(),
264
+ })
265
+
266
+ return (
267
+ <div className="w-[300px]">
268
+ <WakaDateRangePicker
269
+ value={range}
270
+ onChange={setRange}
271
+ clearable={false}
272
+ showPresets={false}
273
+ />
274
+ <p className="text-xs text-muted-foreground mt-2">
275
+ Cannot clear selection
276
+ </p>
277
+ </div>
278
+ )
279
+ },
280
+ }
281
+
282
+ export const Disabled: Story = {
283
+ render: () => (
284
+ <div className="w-[300px]">
285
+ <WakaDateRangePicker
286
+ value={{
287
+ from: subDays(new Date(), 7),
288
+ to: new Date(),
289
+ }}
290
+ disabled
291
+ showPresets={false}
292
+ />
293
+ </div>
294
+ ),
295
+ }
296
+
297
+ export const AnalyticsExample: Story = {
298
+ render: function AnalyticsDemo() {
299
+ const [range, setRange] = React.useState<WakaDateRange | undefined>({
300
+ from: subDays(new Date(), 30),
301
+ to: new Date(),
302
+ })
303
+
304
+ const getDayCount = () => {
305
+ if (!range?.from || !range?.to) return 0
306
+ return Math.ceil(
307
+ (range.to.getTime() - range.from.getTime()) / (1000 * 60 * 60 * 24)
308
+ ) + 1
309
+ }
310
+
311
+ return (
312
+ <div className="space-y-4 w-[400px] p-4 border rounded-lg">
313
+ <div className="flex items-center justify-between">
314
+ <h3 className="font-semibold">Analytics Overview</h3>
315
+ <WakaDateRangePicker
316
+ value={range}
317
+ onChange={setRange}
318
+ showPresets
319
+ className="w-[200px]"
320
+ />
321
+ </div>
322
+ <div className="grid grid-cols-3 gap-4">
323
+ <div className="p-3 bg-muted rounded">
324
+ <p className="text-sm text-muted-foreground">Days</p>
325
+ <p className="text-2xl font-bold">{getDayCount()}</p>
326
+ </div>
327
+ <div className="p-3 bg-muted rounded">
328
+ <p className="text-sm text-muted-foreground">Visitors</p>
329
+ <p className="text-2xl font-bold">12,847</p>
330
+ </div>
331
+ <div className="p-3 bg-muted rounded">
332
+ <p className="text-sm text-muted-foreground">Page Views</p>
333
+ <p className="text-2xl font-bold">45,392</p>
334
+ </div>
335
+ </div>
336
+ </div>
337
+ )
338
+ },
339
+ }