@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.
- package/dist/blocks/dashboard/index.d.ts +4 -1
- package/dist/blocks/empty-states/index.d.ts +4 -1
- package/dist/blocks/error-pages/index.d.ts +4 -1
- package/dist/blocks/index.d.ts +1 -1
- package/dist/blocks/landing/index.d.ts +4 -1
- package/dist/blocks/pricing/index.d.ts +5 -1
- package/dist/blocks/sidebar/index.d.ts +5 -1
- package/dist/index.cjs.js +130 -130
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +7905 -7856
- package/dist/stories/Button.d.ts +14 -0
- package/dist/stories/Button.stories.d.ts +8 -0
- package/dist/stories/Header.d.ts +11 -0
- package/dist/stories/Header.stories.d.ts +6 -0
- package/dist/stories/Page.d.ts +2 -0
- package/dist/stories/Page.stories.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/link.d.ts +23 -0
- package/package.json +11 -3
- package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
- package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
- package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
- package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
- package/src/blocks/chat/Chat.stories.tsx +466 -0
- package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
- package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
- package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
- package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
- package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
- package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
- package/src/blocks/dashboard/index.tsx +68 -27
- package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
- package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
- package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
- package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
- package/src/blocks/empty-states/index.tsx +26 -8
- package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
- package/src/blocks/error-pages/index.tsx +26 -8
- package/src/blocks/faq/FAQ.stories.tsx +416 -0
- package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
- package/src/blocks/footer/Footer.stories.tsx +328 -0
- package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
- package/src/blocks/header/WakaHeader.stories.tsx +455 -0
- package/src/blocks/headtab/Headtab.stories.tsx +369 -0
- package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
- package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
- package/src/blocks/index.ts +1 -1
- package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
- package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
- package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
- package/src/blocks/landing/index.tsx +125 -66
- package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
- package/src/blocks/layout/Layout.stories.tsx +373 -0
- package/src/blocks/login/Login.stories.tsx +443 -0
- package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
- package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
- package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
- package/src/blocks/pricing/index.tsx +38 -4
- package/src/blocks/profile/Profile.stories.tsx +371 -0
- package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
- package/src/blocks/settings/Settings.stories.tsx +520 -0
- package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
- package/src/blocks/sidebar/index.tsx +49 -20
- package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
- package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
- package/src/blocks/wizard/Wizard.stories.tsx +683 -0
- package/src/components/accordion/Accordion.stories.tsx +93 -0
- package/src/components/alert/Alert.stories.tsx +95 -0
- package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
- package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
- package/src/components/avatar/Avatar.stories.tsx +104 -0
- package/src/components/button/Button.stories.tsx +12 -1
- package/src/components/calendar/Calendar.stories.tsx +102 -0
- package/src/components/card/Card.stories.tsx +125 -0
- package/src/components/checkbox/Checkbox.stories.tsx +100 -0
- package/src/components/code/Code.stories.tsx +402 -0
- package/src/components/collapsible/Collapsible.stories.tsx +123 -0
- package/src/components/command/Command.stories.tsx +207 -0
- package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
- package/src/components/dialog/Dialog.stories.tsx +157 -0
- package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
- package/src/components/form/Form.stories.tsx +413 -0
- package/src/components/hover-card/HoverCard.stories.tsx +148 -0
- package/src/components/input-otp/InputOTP.stories.tsx +255 -0
- package/src/components/label/Label.stories.tsx +68 -0
- package/src/components/menubar/Menubar.stories.tsx +278 -0
- package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
- package/src/components/popover/Popover.stories.tsx +199 -0
- package/src/components/progress/Progress.stories.tsx +104 -0
- package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
- package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
- package/src/components/select/Select.stories.tsx +146 -0
- package/src/components/separator/Separator.stories.tsx +117 -0
- package/src/components/sheet/Sheet.stories.tsx +195 -0
- package/src/components/skeleton/Skeleton.stories.tsx +114 -0
- package/src/components/slider/Slider.stories.tsx +157 -0
- package/src/components/switch/Switch.stories.tsx +114 -0
- package/src/components/table/Table.stories.tsx +153 -0
- package/src/components/tabs/Tabs.stories.tsx +155 -0
- package/src/components/textarea/Textarea.stories.tsx +116 -0
- package/src/components/toast/Toast.stories.tsx +160 -0
- package/src/components/toggle/Toggle.stories.tsx +125 -0
- package/src/components/tooltip/Tooltip.stories.tsx +133 -0
- package/src/components/typography/Typography.stories.tsx +207 -0
- package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
- package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
- package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
- package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
- package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
- package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
- package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
- package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
- package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
- package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
- package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
- package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
- package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
- package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
- package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
- package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
- package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
- package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
- package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
- package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
- package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
- package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
- package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
- package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
- package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
- package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
- package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
- package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
- package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
- package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
- package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
- package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
- package/src/components/waka-image/WakaImage.stories.tsx +255 -0
- package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
- package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
- package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
- package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
- package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
- package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
- package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
- package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
- package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
- package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
- package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
- package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
- package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
- package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
- package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
- package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
- package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
- package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
- package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
- package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
- package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
- package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
- package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
- package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
- package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
- package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
- package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
- package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
- package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
- package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
- package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
- package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
- package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
- package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
- package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
- package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
- package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
- package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
- package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
- package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
- package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
- package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
- package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
- package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
- package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
- package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
- package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
- package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
- package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
- package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
- package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
- package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
- package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
- package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
- package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
- package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
- 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
|
+
}
|