@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,394 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaQuestCard, WakaQuestList, WakaQuestCardSkeleton, useQuests } from './index'
3
+ import type { Quest, QuestObjective, QuestReward } from './index'
4
+ import * as React from 'react'
5
+ import { Sword, Shield, Target, Gem, Star, Trophy } from 'lucide-react'
6
+
7
+ const sampleQuest: Quest = {
8
+ id: 'quest-1',
9
+ title: 'Dragon Slayer',
10
+ description: 'Defeat the ancient dragon terrorizing the village and claim your reward.',
11
+ type: 'story',
12
+ difficulty: 'hard',
13
+ objectives: [
14
+ { id: 'obj-1', text: 'Find the dragon\'s lair', completed: true },
15
+ { id: 'obj-2', text: 'Defeat the dragon', completed: false, current: 0, target: 1 },
16
+ { id: 'obj-3', text: 'Collect dragon scales', completed: false, current: 3, target: 5 },
17
+ ],
18
+ rewards: [
19
+ { type: 'xp', value: 500 },
20
+ { type: 'badge', value: 'Dragon Slayer' },
21
+ { type: 'item', value: 'Dragon Sword' },
22
+ ],
23
+ progress: 40,
24
+ status: 'in_progress',
25
+ expiresAt: new Date(Date.now() + 2 * 24 * 60 * 60 * 1000),
26
+ }
27
+
28
+ const questTypes: Quest[] = [
29
+ {
30
+ id: 'daily-1',
31
+ title: 'Daily Login',
32
+ description: 'Log in to the app today.',
33
+ type: 'daily',
34
+ difficulty: 'easy',
35
+ objectives: [{ id: 'obj-1', text: 'Log in', completed: true }],
36
+ rewards: [{ type: 'xp', value: 50 }],
37
+ progress: 100,
38
+ status: 'completed',
39
+ },
40
+ {
41
+ id: 'weekly-1',
42
+ title: 'Weekly Warrior',
43
+ description: 'Complete 10 battles this week.',
44
+ type: 'weekly',
45
+ difficulty: 'medium',
46
+ objectives: [{ id: 'obj-1', text: 'Complete battles', completed: false, current: 7, target: 10 }],
47
+ rewards: [{ type: 'xp', value: 200 }, { type: 'currency', value: 500 }],
48
+ progress: 70,
49
+ status: 'in_progress',
50
+ expiresAt: new Date(Date.now() + 4 * 24 * 60 * 60 * 1000),
51
+ },
52
+ {
53
+ id: 'challenge-1',
54
+ title: 'Speed Run',
55
+ description: 'Complete a level in under 60 seconds.',
56
+ type: 'challenge',
57
+ difficulty: 'legendary',
58
+ objectives: [{ id: 'obj-1', text: 'Beat the clock', completed: false }],
59
+ rewards: [{ type: 'badge', value: 'Speed Demon' }],
60
+ progress: 0,
61
+ status: 'available',
62
+ },
63
+ {
64
+ id: 'achievement-1',
65
+ title: 'First Blood',
66
+ description: 'Win your first PvP battle.',
67
+ type: 'achievement',
68
+ difficulty: 'easy',
69
+ objectives: [{ id: 'obj-1', text: 'Win a PvP battle', completed: true }],
70
+ rewards: [{ type: 'badge', value: 'Fighter' }, { type: 'xp', value: 100 }],
71
+ progress: 100,
72
+ status: 'claimed',
73
+ },
74
+ ]
75
+
76
+ const meta: Meta<typeof WakaQuestCard> = {
77
+ title: 'Components/Gamification/WakaQuestCard',
78
+ component: WakaQuestCard,
79
+ parameters: {
80
+ layout: 'centered',
81
+ docs: {
82
+ description: {
83
+ component: 'A quest card with objectives tracking, progress bar, difficulty indicators, rewards display, and celebration effects.',
84
+ },
85
+ },
86
+ },
87
+ tags: ['autodocs'],
88
+ argTypes: {
89
+ variant: {
90
+ control: 'select',
91
+ options: ['compact', 'detailed'],
92
+ description: 'Display variant',
93
+ },
94
+ showAbandonConfirm: {
95
+ control: 'boolean',
96
+ description: 'Show abandon confirmation dialog',
97
+ },
98
+ },
99
+ }
100
+
101
+ export default meta
102
+ type Story = StoryObj<typeof WakaQuestCard>
103
+
104
+ export const Default: Story = {
105
+ args: {
106
+ quest: sampleQuest,
107
+ variant: 'default',
108
+ showProgress: true,
109
+ showRewards: true,
110
+ showTimer: true,
111
+ animated: true,
112
+ },
113
+ render: (args) => (
114
+ <div className="w-[450px]">
115
+ <WakaQuestCard {...args} />
116
+ </div>
117
+ ),
118
+ }
119
+
120
+ export const Variants: Story = {
121
+ render: () => (
122
+ <div className="space-y-6">
123
+ <div>
124
+ <p className="text-sm text-muted-foreground mb-2">Detailed (Default)</p>
125
+ <div className="w-[450px]">
126
+ <WakaQuestCard quest={sampleQuest} variant="detailed" />
127
+ </div>
128
+ </div>
129
+ <div>
130
+ <p className="text-sm text-muted-foreground mb-2">Compact</p>
131
+ <div className="w-[350px]">
132
+ <WakaQuestCard quest={sampleQuest} variant="compact" />
133
+ </div>
134
+ </div>
135
+ </div>
136
+ ),
137
+ }
138
+
139
+ export const QuestTypes: Story = {
140
+ render: () => (
141
+ <div className="space-y-4 w-[450px]">
142
+ {questTypes.map((quest) => (
143
+ <WakaQuestCard key={quest.id} quest={quest} variant="compact" />
144
+ ))}
145
+ </div>
146
+ ),
147
+ }
148
+
149
+ export const DifficultyLevels: Story = {
150
+ render: () => {
151
+ const difficulties: Quest['difficulty'][] = ['easy', 'medium', 'hard', 'legendary']
152
+
153
+ return (
154
+ <div className="grid grid-cols-2 gap-4 w-[800px]">
155
+ {difficulties.map((difficulty) => (
156
+ <WakaQuestCard
157
+ key={difficulty}
158
+ quest={{
159
+ ...sampleQuest,
160
+ id: difficulty,
161
+ difficulty,
162
+ title: `${difficulty.charAt(0).toUpperCase() + difficulty.slice(1)} Quest`,
163
+ }}
164
+ variant="compact"
165
+ />
166
+ ))}
167
+ </div>
168
+ )
169
+ },
170
+ }
171
+
172
+ export const QuestStatuses: Story = {
173
+ render: () => {
174
+ const statuses: Quest['status'][] = ['available', 'in_progress', 'completed', 'claimed', 'expired']
175
+
176
+ return (
177
+ <div className="space-y-4 w-[450px]">
178
+ {statuses.map((status) => (
179
+ <WakaQuestCard
180
+ key={status}
181
+ quest={{
182
+ ...sampleQuest,
183
+ id: status,
184
+ status,
185
+ title: `Quest - ${status.replace('_', ' ')}`,
186
+ progress: status === 'completed' || status === 'claimed' ? 100 : sampleQuest.progress,
187
+ expiresAt: status === 'expired' ? new Date(Date.now() - 1000) : sampleQuest.expiresAt,
188
+ }}
189
+ variant="compact"
190
+ />
191
+ ))}
192
+ </div>
193
+ )
194
+ },
195
+ }
196
+
197
+ export const WithCountdown: Story = {
198
+ render: () => {
199
+ const urgentQuest: Quest = {
200
+ ...sampleQuest,
201
+ expiresAt: new Date(Date.now() + 30 * 60 * 1000), // 30 minutes
202
+ }
203
+
204
+ return (
205
+ <div className="w-[450px] space-y-4">
206
+ <p className="text-sm text-muted-foreground">Urgent quest - expires in 30 minutes</p>
207
+ <WakaQuestCard quest={urgentQuest} />
208
+ </div>
209
+ )
210
+ },
211
+ }
212
+
213
+ export const CompletedWithClaim: Story = {
214
+ render: () => {
215
+ const completedQuest: Quest = {
216
+ ...sampleQuest,
217
+ status: 'completed',
218
+ progress: 100,
219
+ objectives: sampleQuest.objectives.map(obj => ({ ...obj, completed: true })),
220
+ }
221
+
222
+ return (
223
+ <div className="w-[450px]">
224
+ <WakaQuestCard
225
+ quest={completedQuest}
226
+ onClaim={(id) => console.log('Claimed:', id)}
227
+ />
228
+ </div>
229
+ )
230
+ },
231
+ }
232
+
233
+ export const Interactive: Story = {
234
+ render: () => {
235
+ const [quest, setQuest] = React.useState<Quest>({
236
+ ...sampleQuest,
237
+ objectives: [
238
+ { id: 'obj-1', text: 'Kill 10 enemies', completed: false, current: 0, target: 10 },
239
+ { id: 'obj-2', text: 'Collect 5 gems', completed: false, current: 0, target: 5 },
240
+ { id: 'obj-3', text: 'Find the treasure', completed: false },
241
+ ],
242
+ progress: 0,
243
+ status: 'in_progress',
244
+ })
245
+
246
+ const incrementProgress = (objectiveId: string) => {
247
+ setQuest(prev => {
248
+ const newObjectives = prev.objectives.map(obj => {
249
+ if (obj.id !== objectiveId) return obj
250
+ if (obj.target !== undefined && obj.current !== undefined) {
251
+ const newCurrent = Math.min(obj.target, obj.current + 1)
252
+ return { ...obj, current: newCurrent, completed: newCurrent >= obj.target }
253
+ }
254
+ return { ...obj, completed: true }
255
+ })
256
+
257
+ const completedCount = newObjectives.filter(o => o.completed).length
258
+ const progress = (completedCount / newObjectives.length) * 100
259
+ const allComplete = completedCount === newObjectives.length
260
+
261
+ return {
262
+ ...prev,
263
+ objectives: newObjectives,
264
+ progress,
265
+ status: allComplete ? 'completed' : 'in_progress',
266
+ }
267
+ })
268
+ }
269
+
270
+ return (
271
+ <div className="w-[450px] space-y-4">
272
+ <WakaQuestCard
273
+ quest={quest}
274
+ onObjectiveClick={(_, objId) => incrementProgress(objId)}
275
+ onClaim={(id) => setQuest(prev => ({ ...prev, status: 'claimed' }))}
276
+ />
277
+
278
+ <div className="p-4 rounded-lg border text-sm">
279
+ <p className="text-muted-foreground mb-2">Click on objectives to progress them</p>
280
+ <div className="flex gap-2">
281
+ {quest.objectives.map(obj => (
282
+ <button
283
+ key={obj.id}
284
+ onClick={() => incrementProgress(obj.id)}
285
+ disabled={obj.completed}
286
+ className="px-2 py-1 text-xs rounded bg-muted hover:bg-muted/80 disabled:opacity-50"
287
+ >
288
+ +1 {obj.text.split(' ')[0]}
289
+ </button>
290
+ ))}
291
+ </div>
292
+ </div>
293
+ </div>
294
+ )
295
+ },
296
+ }
297
+
298
+ export const WithHook: Story = {
299
+ render: () => {
300
+ const {
301
+ quests,
302
+ updateObjective,
303
+ incrementObjective,
304
+ claimQuest,
305
+ activeQuests,
306
+ completedQuests,
307
+ } = useQuests({
308
+ initialQuests: questTypes,
309
+ onQuestComplete: (quest) => console.log('Completed:', quest.title),
310
+ onQuestClaimed: (quest) => console.log('Claimed:', quest.title),
311
+ })
312
+
313
+ return (
314
+ <div className="w-[500px] space-y-6">
315
+ <div>
316
+ <div className="flex justify-between items-center mb-3">
317
+ <h3 className="font-semibold">Active Quests ({activeQuests.length})</h3>
318
+ </div>
319
+ <WakaQuestList
320
+ quests={activeQuests}
321
+ variant="compact"
322
+ onClaim={claimQuest}
323
+ onObjectiveClick={updateObjective}
324
+ />
325
+ </div>
326
+
327
+ <div>
328
+ <h3 className="font-semibold mb-3">Completed ({completedQuests.length})</h3>
329
+ <WakaQuestList
330
+ quests={completedQuests}
331
+ variant="compact"
332
+ onClaim={claimQuest}
333
+ />
334
+ </div>
335
+ </div>
336
+ )
337
+ },
338
+ }
339
+
340
+ export const QuestList: Story = {
341
+ render: () => (
342
+ <div className="w-[450px]">
343
+ <h3 className="font-semibold mb-4">Available Quests</h3>
344
+ <WakaQuestList
345
+ quests={questTypes}
346
+ variant="compact"
347
+ onClaim={(id) => console.log('Claimed:', id)}
348
+ />
349
+ </div>
350
+ ),
351
+ }
352
+
353
+ export const EmptyList: Story = {
354
+ render: () => (
355
+ <div className="w-[450px]">
356
+ <WakaQuestList
357
+ quests={[]}
358
+ emptyMessage="No quests available right now. Check back later!"
359
+ />
360
+ </div>
361
+ ),
362
+ }
363
+
364
+ export const Skeleton: Story = {
365
+ render: () => (
366
+ <div className="space-y-4 w-[450px]">
367
+ <WakaQuestCardSkeleton variant="detailed" />
368
+ <WakaQuestCardSkeleton variant="compact" />
369
+ <WakaQuestCardSkeleton variant="compact" />
370
+ </div>
371
+ ),
372
+ }
373
+
374
+ export const QuestJournal: Story = {
375
+ render: () => (
376
+ <div className="w-[550px] p-6 rounded-xl border bg-gradient-to-br from-amber-500/5 to-orange-500/5">
377
+ <div className="flex items-center gap-3 mb-6">
378
+ <div className="w-10 h-10 rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 flex items-center justify-center">
379
+ <Trophy className="h-5 w-5 text-white" />
380
+ </div>
381
+ <div>
382
+ <h2 className="text-xl font-bold">Quest Journal</h2>
383
+ <p className="text-sm text-muted-foreground">3 active • 12 completed</p>
384
+ </div>
385
+ </div>
386
+
387
+ <div className="space-y-3">
388
+ {questTypes.filter(q => q.status !== 'claimed').map(quest => (
389
+ <WakaQuestCard key={quest.id} quest={quest} variant="compact" />
390
+ ))}
391
+ </div>
392
+ </div>
393
+ ),
394
+ }