@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,683 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { WakaWizard, defaultWizardSteps } from './index'
|
|
3
|
+
import type { WizardStep, WizardSubmitData } from './index'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
import { User, Settings, Shield, CheckCircle, Mail, CreditCard, Package, Rocket } from 'lucide-react'
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof WakaWizard> = {
|
|
8
|
+
title: 'Blocks/Wizard',
|
|
9
|
+
component: WakaWizard,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
'A multi-step wizard component with validation, progress tracking, step navigation, and multiple layouts (card, page, minimal).',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
tags: ['autodocs'],
|
|
20
|
+
argTypes: {
|
|
21
|
+
layout: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: ['card', 'page', 'minimal'],
|
|
24
|
+
},
|
|
25
|
+
stepperPosition: {
|
|
26
|
+
control: 'select',
|
|
27
|
+
options: ['top', 'left'],
|
|
28
|
+
},
|
|
29
|
+
showProgress: {
|
|
30
|
+
control: 'boolean',
|
|
31
|
+
},
|
|
32
|
+
showStepper: {
|
|
33
|
+
control: 'boolean',
|
|
34
|
+
},
|
|
35
|
+
showStepNumbers: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
},
|
|
38
|
+
showCancelButton: {
|
|
39
|
+
control: 'boolean',
|
|
40
|
+
},
|
|
41
|
+
allowBackNavigation: {
|
|
42
|
+
control: 'boolean',
|
|
43
|
+
},
|
|
44
|
+
confirmCancel: {
|
|
45
|
+
control: 'boolean',
|
|
46
|
+
},
|
|
47
|
+
submitting: {
|
|
48
|
+
control: 'boolean',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default meta
|
|
54
|
+
type Story = StoryObj<typeof WakaWizard>
|
|
55
|
+
|
|
56
|
+
export const Default: Story = {
|
|
57
|
+
render: () => (
|
|
58
|
+
<div className="w-[700px]">
|
|
59
|
+
<WakaWizard
|
|
60
|
+
steps={defaultWizardSteps}
|
|
61
|
+
title="Assistant de configuration"
|
|
62
|
+
description="Suivez les étapes pour configurer votre compte."
|
|
63
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
64
|
+
onCancel={() => console.log('Cancel')}
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const CardLayout: Story = {
|
|
71
|
+
render: () => (
|
|
72
|
+
<div className="w-[700px]">
|
|
73
|
+
<WakaWizard
|
|
74
|
+
steps={defaultWizardSteps}
|
|
75
|
+
layout="card"
|
|
76
|
+
title="Créer un compte"
|
|
77
|
+
description="Complétez ces étapes pour créer votre compte."
|
|
78
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
),
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const PageLayout: Story = {
|
|
85
|
+
render: () => (
|
|
86
|
+
<div className="w-full max-w-4xl">
|
|
87
|
+
<WakaWizard
|
|
88
|
+
steps={defaultWizardSteps}
|
|
89
|
+
layout="page"
|
|
90
|
+
title="Onboarding"
|
|
91
|
+
description="Bienvenue ! Configurons votre espace de travail."
|
|
92
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
),
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const MinimalLayout: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<div className="w-[600px] p-6 border rounded-lg">
|
|
101
|
+
<WakaWizard
|
|
102
|
+
steps={defaultWizardSteps}
|
|
103
|
+
layout="minimal"
|
|
104
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const LeftStepper: Story = {
|
|
111
|
+
render: () => (
|
|
112
|
+
<div className="w-[900px]">
|
|
113
|
+
<WakaWizard
|
|
114
|
+
steps={defaultWizardSteps}
|
|
115
|
+
stepperPosition="left"
|
|
116
|
+
title="Configuration du projet"
|
|
117
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
),
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const WithIcons: Story = {
|
|
124
|
+
render: () => {
|
|
125
|
+
const stepsWithIcons: WizardStep[] = [
|
|
126
|
+
{
|
|
127
|
+
id: 'account',
|
|
128
|
+
title: 'Compte',
|
|
129
|
+
description: 'Créez votre compte utilisateur',
|
|
130
|
+
icon: <User className="h-4 w-4" />,
|
|
131
|
+
content: (
|
|
132
|
+
<div className="space-y-4">
|
|
133
|
+
<h3 className="text-lg font-medium">Créer votre compte</h3>
|
|
134
|
+
<p className="text-muted-foreground">Entrez votre email et créez un mot de passe.</p>
|
|
135
|
+
<div className="grid gap-4 max-w-md">
|
|
136
|
+
<input type="email" placeholder="Email" className="px-3 py-2 border rounded-md" />
|
|
137
|
+
<input type="password" placeholder="Mot de passe" className="px-3 py-2 border rounded-md" />
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
),
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'preferences',
|
|
144
|
+
title: 'Préférences',
|
|
145
|
+
description: 'Personnalisez votre expérience',
|
|
146
|
+
icon: <Settings className="h-4 w-4" />,
|
|
147
|
+
optional: true,
|
|
148
|
+
content: (
|
|
149
|
+
<div className="space-y-4">
|
|
150
|
+
<h3 className="text-lg font-medium">Préférences</h3>
|
|
151
|
+
<p className="text-muted-foreground">Configurez vos préférences (optionnel).</p>
|
|
152
|
+
<div className="space-y-2">
|
|
153
|
+
<label className="flex items-center gap-2">
|
|
154
|
+
<input type="checkbox" className="rounded" />
|
|
155
|
+
<span>Recevoir les notifications par email</span>
|
|
156
|
+
</label>
|
|
157
|
+
<label className="flex items-center gap-2">
|
|
158
|
+
<input type="checkbox" className="rounded" />
|
|
159
|
+
<span>Activer le mode sombre</span>
|
|
160
|
+
</label>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
),
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'security',
|
|
167
|
+
title: 'Sécurité',
|
|
168
|
+
description: 'Renforcez la sécurité de votre compte',
|
|
169
|
+
icon: <Shield className="h-4 w-4" />,
|
|
170
|
+
content: (
|
|
171
|
+
<div className="space-y-4">
|
|
172
|
+
<h3 className="text-lg font-medium">Sécurité</h3>
|
|
173
|
+
<p className="text-muted-foreground">Configurez l'authentification à deux facteurs.</p>
|
|
174
|
+
<div className="p-4 bg-muted rounded-lg">
|
|
175
|
+
<p className="text-sm">Scannez ce QR code avec votre application d'authentification.</p>
|
|
176
|
+
<div className="mt-4 w-32 h-32 bg-background border rounded flex items-center justify-center">
|
|
177
|
+
[QR Code]
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
),
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: 'complete',
|
|
185
|
+
title: 'Terminé',
|
|
186
|
+
description: 'Votre compte est prêt',
|
|
187
|
+
icon: <CheckCircle className="h-4 w-4" />,
|
|
188
|
+
content: (
|
|
189
|
+
<div className="space-y-4 text-center py-8">
|
|
190
|
+
<CheckCircle className="h-16 w-16 text-green-500 mx-auto" />
|
|
191
|
+
<h3 className="text-lg font-medium">Configuration terminée !</h3>
|
|
192
|
+
<p className="text-muted-foreground">Votre compte est maintenant configuré et prêt à l'emploi.</p>
|
|
193
|
+
</div>
|
|
194
|
+
),
|
|
195
|
+
},
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<div className="w-[700px]">
|
|
200
|
+
<WakaWizard
|
|
201
|
+
steps={stepsWithIcons}
|
|
202
|
+
title="Création de compte"
|
|
203
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
)
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const WithValidation: Story = {
|
|
211
|
+
render: () => {
|
|
212
|
+
const [email, setEmail] = React.useState('')
|
|
213
|
+
const [name, setName] = React.useState('')
|
|
214
|
+
|
|
215
|
+
const validatedSteps: WizardStep[] = [
|
|
216
|
+
{
|
|
217
|
+
id: 'name',
|
|
218
|
+
title: 'Nom',
|
|
219
|
+
content: (
|
|
220
|
+
<div className="space-y-4">
|
|
221
|
+
<h3 className="text-lg font-medium">Comment vous appelez-vous ?</h3>
|
|
222
|
+
<input
|
|
223
|
+
type="text"
|
|
224
|
+
placeholder="Votre nom"
|
|
225
|
+
value={name}
|
|
226
|
+
onChange={(e) => setName(e.target.value)}
|
|
227
|
+
className="px-3 py-2 border rounded-md w-full max-w-md"
|
|
228
|
+
/>
|
|
229
|
+
<p className="text-sm text-muted-foreground">Le nom est requis pour continuer.</p>
|
|
230
|
+
</div>
|
|
231
|
+
),
|
|
232
|
+
validate: () => {
|
|
233
|
+
if (name.length < 2) {
|
|
234
|
+
alert('Le nom doit contenir au moins 2 caractères')
|
|
235
|
+
return false
|
|
236
|
+
}
|
|
237
|
+
return true
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'email',
|
|
242
|
+
title: 'Email',
|
|
243
|
+
content: (
|
|
244
|
+
<div className="space-y-4">
|
|
245
|
+
<h3 className="text-lg font-medium">Quel est votre email ?</h3>
|
|
246
|
+
<input
|
|
247
|
+
type="email"
|
|
248
|
+
placeholder="votre@email.com"
|
|
249
|
+
value={email}
|
|
250
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
251
|
+
className="px-3 py-2 border rounded-md w-full max-w-md"
|
|
252
|
+
/>
|
|
253
|
+
</div>
|
|
254
|
+
),
|
|
255
|
+
validate: () => {
|
|
256
|
+
if (!email.includes('@')) {
|
|
257
|
+
alert('Veuillez entrer un email valide')
|
|
258
|
+
return false
|
|
259
|
+
}
|
|
260
|
+
return true
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
id: 'confirm',
|
|
265
|
+
title: 'Confirmation',
|
|
266
|
+
content: (
|
|
267
|
+
<div className="space-y-4">
|
|
268
|
+
<h3 className="text-lg font-medium">Confirmer vos informations</h3>
|
|
269
|
+
<div className="p-4 bg-muted rounded-lg space-y-2">
|
|
270
|
+
<p><strong>Nom:</strong> {name || '(non renseigné)'}</p>
|
|
271
|
+
<p><strong>Email:</strong> {email || '(non renseigné)'}</p>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
),
|
|
275
|
+
},
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
return (
|
|
279
|
+
<div className="w-[600px]">
|
|
280
|
+
<WakaWizard
|
|
281
|
+
steps={validatedSteps}
|
|
282
|
+
title="Inscription avec validation"
|
|
283
|
+
onSubmit={(data) => {
|
|
284
|
+
console.log('Submit:', data, { name, email })
|
|
285
|
+
alert(`Inscription réussie pour ${name} (${email})`)
|
|
286
|
+
}}
|
|
287
|
+
/>
|
|
288
|
+
</div>
|
|
289
|
+
)
|
|
290
|
+
},
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export const ManySteps: Story = {
|
|
294
|
+
render: () => {
|
|
295
|
+
const manySteps: WizardStep[] = [
|
|
296
|
+
{
|
|
297
|
+
id: 'step-1',
|
|
298
|
+
title: 'Introduction',
|
|
299
|
+
content: <div className="py-4"><p>Bienvenue dans l'assistant de configuration.</p></div>,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'step-2',
|
|
303
|
+
title: 'Profil',
|
|
304
|
+
content: <div className="py-4"><p>Configurez votre profil utilisateur.</p></div>,
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
id: 'step-3',
|
|
308
|
+
title: 'Organisation',
|
|
309
|
+
content: <div className="py-4"><p>Ajoutez votre organisation.</p></div>,
|
|
310
|
+
optional: true,
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: 'step-4',
|
|
314
|
+
title: 'Équipe',
|
|
315
|
+
content: <div className="py-4"><p>Invitez des membres de votre équipe.</p></div>,
|
|
316
|
+
optional: true,
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
id: 'step-5',
|
|
320
|
+
title: 'Intégrations',
|
|
321
|
+
content: <div className="py-4"><p>Connectez vos outils existants.</p></div>,
|
|
322
|
+
optional: true,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
id: 'step-6',
|
|
326
|
+
title: 'Notifications',
|
|
327
|
+
content: <div className="py-4"><p>Configurez vos préférences de notification.</p></div>,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: 'step-7',
|
|
331
|
+
title: 'Finalisation',
|
|
332
|
+
content: <div className="py-4"><p>Vérifiez et confirmez votre configuration.</p></div>,
|
|
333
|
+
},
|
|
334
|
+
]
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<div className="w-[900px]">
|
|
338
|
+
<WakaWizard
|
|
339
|
+
steps={manySteps}
|
|
340
|
+
stepperPosition="left"
|
|
341
|
+
title="Configuration complète"
|
|
342
|
+
description="Un assistant en 7 étapes"
|
|
343
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
344
|
+
/>
|
|
345
|
+
</div>
|
|
346
|
+
)
|
|
347
|
+
},
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export const NoProgress: Story = {
|
|
351
|
+
render: () => (
|
|
352
|
+
<div className="w-[600px]">
|
|
353
|
+
<WakaWizard
|
|
354
|
+
steps={defaultWizardSteps}
|
|
355
|
+
showProgress={false}
|
|
356
|
+
title="Sans barre de progression"
|
|
357
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
358
|
+
/>
|
|
359
|
+
</div>
|
|
360
|
+
),
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export const NoStepper: Story = {
|
|
364
|
+
render: () => (
|
|
365
|
+
<div className="w-[600px]">
|
|
366
|
+
<WakaWizard
|
|
367
|
+
steps={defaultWizardSteps}
|
|
368
|
+
showStepper={false}
|
|
369
|
+
title="Sans stepper visuel"
|
|
370
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
371
|
+
/>
|
|
372
|
+
</div>
|
|
373
|
+
),
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export const NoBackNavigation: Story = {
|
|
377
|
+
render: () => (
|
|
378
|
+
<div className="w-[600px]">
|
|
379
|
+
<WakaWizard
|
|
380
|
+
steps={defaultWizardSteps}
|
|
381
|
+
allowBackNavigation={false}
|
|
382
|
+
title="Navigation avant uniquement"
|
|
383
|
+
description="Vous ne pouvez pas revenir aux étapes précédentes."
|
|
384
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
385
|
+
/>
|
|
386
|
+
</div>
|
|
387
|
+
),
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export const NoCancelButton: Story = {
|
|
391
|
+
render: () => (
|
|
392
|
+
<div className="w-[600px]">
|
|
393
|
+
<WakaWizard
|
|
394
|
+
steps={defaultWizardSteps}
|
|
395
|
+
showCancelButton={false}
|
|
396
|
+
title="Sans bouton annuler"
|
|
397
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
398
|
+
/>
|
|
399
|
+
</div>
|
|
400
|
+
),
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export const Submitting: Story = {
|
|
404
|
+
render: () => (
|
|
405
|
+
<div className="w-[600px]">
|
|
406
|
+
<WakaWizard
|
|
407
|
+
steps={defaultWizardSteps}
|
|
408
|
+
submitting
|
|
409
|
+
title="En cours de soumission"
|
|
410
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
411
|
+
/>
|
|
412
|
+
</div>
|
|
413
|
+
),
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export const CustomButtonTexts: Story = {
|
|
417
|
+
render: () => (
|
|
418
|
+
<div className="w-[600px]">
|
|
419
|
+
<WakaWizard
|
|
420
|
+
steps={defaultWizardSteps}
|
|
421
|
+
title="Textes personnalisés"
|
|
422
|
+
prevButtonText="Back"
|
|
423
|
+
nextButtonText="Continue"
|
|
424
|
+
finishButtonText="Complete Setup"
|
|
425
|
+
cancelButtonText="Exit"
|
|
426
|
+
skipButtonText="Skip this step"
|
|
427
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
428
|
+
onCancel={() => console.log('Cancel')}
|
|
429
|
+
/>
|
|
430
|
+
</div>
|
|
431
|
+
),
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export const Interactive: Story = {
|
|
435
|
+
render: () => {
|
|
436
|
+
const [currentStep, setCurrentStep] = React.useState(0)
|
|
437
|
+
const [submitting, setSubmitting] = React.useState(false)
|
|
438
|
+
const [completed, setCompleted] = React.useState(false)
|
|
439
|
+
|
|
440
|
+
const handleSubmit = async (data: WizardSubmitData) => {
|
|
441
|
+
setSubmitting(true)
|
|
442
|
+
console.log('Submitting:', data)
|
|
443
|
+
await new Promise((r) => setTimeout(r, 2000))
|
|
444
|
+
setSubmitting(false)
|
|
445
|
+
setCompleted(true)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (completed) {
|
|
449
|
+
return (
|
|
450
|
+
<div className="w-[600px] p-8 text-center border rounded-lg">
|
|
451
|
+
<CheckCircle className="h-16 w-16 text-green-500 mx-auto mb-4" />
|
|
452
|
+
<h2 className="text-xl font-bold mb-2">Wizard terminé !</h2>
|
|
453
|
+
<p className="text-muted-foreground mb-4">Toutes les étapes ont été complétées avec succès.</p>
|
|
454
|
+
<button
|
|
455
|
+
onClick={() => {
|
|
456
|
+
setCurrentStep(0)
|
|
457
|
+
setCompleted(false)
|
|
458
|
+
}}
|
|
459
|
+
className="px-4 py-2 bg-primary text-primary-foreground rounded-md"
|
|
460
|
+
>
|
|
461
|
+
Recommencer
|
|
462
|
+
</button>
|
|
463
|
+
</div>
|
|
464
|
+
)
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return (
|
|
468
|
+
<div className="w-[600px]">
|
|
469
|
+
<div className="mb-4 p-4 bg-muted rounded-lg">
|
|
470
|
+
<p className="text-sm text-muted-foreground">
|
|
471
|
+
Étape actuelle: {currentStep + 1} / {defaultWizardSteps.length}
|
|
472
|
+
</p>
|
|
473
|
+
</div>
|
|
474
|
+
<WakaWizard
|
|
475
|
+
steps={defaultWizardSteps}
|
|
476
|
+
currentStep={currentStep}
|
|
477
|
+
onStepChange={setCurrentStep}
|
|
478
|
+
submitting={submitting}
|
|
479
|
+
title="Wizard interactif"
|
|
480
|
+
onSubmit={handleSubmit}
|
|
481
|
+
onCancel={() => {
|
|
482
|
+
setCurrentStep(0)
|
|
483
|
+
alert('Wizard annulé')
|
|
484
|
+
}}
|
|
485
|
+
/>
|
|
486
|
+
</div>
|
|
487
|
+
)
|
|
488
|
+
},
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export const CheckoutWizard: Story = {
|
|
492
|
+
render: () => {
|
|
493
|
+
const checkoutSteps: WizardStep[] = [
|
|
494
|
+
{
|
|
495
|
+
id: 'shipping',
|
|
496
|
+
title: 'Livraison',
|
|
497
|
+
description: 'Adresse de livraison',
|
|
498
|
+
icon: <Package className="h-4 w-4" />,
|
|
499
|
+
content: (
|
|
500
|
+
<div className="space-y-4">
|
|
501
|
+
<h3 className="text-lg font-medium">Adresse de livraison</h3>
|
|
502
|
+
<div className="grid gap-4 max-w-md">
|
|
503
|
+
<input type="text" placeholder="Nom complet" className="px-3 py-2 border rounded-md" />
|
|
504
|
+
<input type="text" placeholder="Adresse" className="px-3 py-2 border rounded-md" />
|
|
505
|
+
<div className="grid grid-cols-2 gap-4">
|
|
506
|
+
<input type="text" placeholder="Ville" className="px-3 py-2 border rounded-md" />
|
|
507
|
+
<input type="text" placeholder="Code postal" className="px-3 py-2 border rounded-md" />
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
),
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
id: 'payment',
|
|
515
|
+
title: 'Paiement',
|
|
516
|
+
description: 'Informations de paiement',
|
|
517
|
+
icon: <CreditCard className="h-4 w-4" />,
|
|
518
|
+
content: (
|
|
519
|
+
<div className="space-y-4">
|
|
520
|
+
<h3 className="text-lg font-medium">Informations de paiement</h3>
|
|
521
|
+
<div className="grid gap-4 max-w-md">
|
|
522
|
+
<input type="text" placeholder="Numéro de carte" className="px-3 py-2 border rounded-md" />
|
|
523
|
+
<div className="grid grid-cols-2 gap-4">
|
|
524
|
+
<input type="text" placeholder="MM/AA" className="px-3 py-2 border rounded-md" />
|
|
525
|
+
<input type="text" placeholder="CVC" className="px-3 py-2 border rounded-md" />
|
|
526
|
+
</div>
|
|
527
|
+
</div>
|
|
528
|
+
</div>
|
|
529
|
+
),
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: 'contact',
|
|
533
|
+
title: 'Contact',
|
|
534
|
+
description: 'Email de confirmation',
|
|
535
|
+
icon: <Mail className="h-4 w-4" />,
|
|
536
|
+
optional: true,
|
|
537
|
+
content: (
|
|
538
|
+
<div className="space-y-4">
|
|
539
|
+
<h3 className="text-lg font-medium">Email de confirmation</h3>
|
|
540
|
+
<p className="text-muted-foreground">Recevez les mises à jour de votre commande (optionnel).</p>
|
|
541
|
+
<input type="email" placeholder="votre@email.com" className="px-3 py-2 border rounded-md max-w-md w-full" />
|
|
542
|
+
</div>
|
|
543
|
+
),
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
id: 'confirm',
|
|
547
|
+
title: 'Confirmation',
|
|
548
|
+
description: 'Vérifier la commande',
|
|
549
|
+
icon: <CheckCircle className="h-4 w-4" />,
|
|
550
|
+
content: (
|
|
551
|
+
<div className="space-y-4">
|
|
552
|
+
<h3 className="text-lg font-medium">Résumé de la commande</h3>
|
|
553
|
+
<div className="border rounded-lg divide-y">
|
|
554
|
+
<div className="p-4 flex justify-between">
|
|
555
|
+
<span>Produit A x 2</span>
|
|
556
|
+
<span>€59.98</span>
|
|
557
|
+
</div>
|
|
558
|
+
<div className="p-4 flex justify-between">
|
|
559
|
+
<span>Produit B x 1</span>
|
|
560
|
+
<span>€29.99</span>
|
|
561
|
+
</div>
|
|
562
|
+
<div className="p-4 flex justify-between">
|
|
563
|
+
<span>Livraison</span>
|
|
564
|
+
<span>€5.00</span>
|
|
565
|
+
</div>
|
|
566
|
+
<div className="p-4 flex justify-between font-bold">
|
|
567
|
+
<span>Total</span>
|
|
568
|
+
<span>€94.97</span>
|
|
569
|
+
</div>
|
|
570
|
+
</div>
|
|
571
|
+
</div>
|
|
572
|
+
),
|
|
573
|
+
},
|
|
574
|
+
]
|
|
575
|
+
|
|
576
|
+
return (
|
|
577
|
+
<div className="w-[700px]">
|
|
578
|
+
<WakaWizard
|
|
579
|
+
steps={checkoutSteps}
|
|
580
|
+
title="Finaliser la commande"
|
|
581
|
+
finishButtonText="Payer €94.97"
|
|
582
|
+
onSubmit={(data) => {
|
|
583
|
+
console.log('Order submitted:', data)
|
|
584
|
+
alert('Commande validée !')
|
|
585
|
+
}}
|
|
586
|
+
onCancel={() => console.log('Checkout cancelled')}
|
|
587
|
+
/>
|
|
588
|
+
</div>
|
|
589
|
+
)
|
|
590
|
+
},
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
export const OnboardingWizard: Story = {
|
|
594
|
+
render: () => {
|
|
595
|
+
const onboardingSteps: WizardStep[] = [
|
|
596
|
+
{
|
|
597
|
+
id: 'welcome',
|
|
598
|
+
title: 'Bienvenue',
|
|
599
|
+
icon: <Rocket className="h-4 w-4" />,
|
|
600
|
+
content: (
|
|
601
|
+
<div className="text-center py-8">
|
|
602
|
+
<Rocket className="h-16 w-16 text-primary mx-auto mb-4" />
|
|
603
|
+
<h3 className="text-2xl font-bold mb-2">Bienvenue sur notre plateforme !</h3>
|
|
604
|
+
<p className="text-muted-foreground max-w-md mx-auto">
|
|
605
|
+
Nous allons vous guider pour configurer votre espace de travail en quelques étapes simples.
|
|
606
|
+
</p>
|
|
607
|
+
</div>
|
|
608
|
+
),
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
id: 'profile',
|
|
612
|
+
title: 'Profil',
|
|
613
|
+
icon: <User className="h-4 w-4" />,
|
|
614
|
+
content: (
|
|
615
|
+
<div className="space-y-4">
|
|
616
|
+
<h3 className="text-lg font-medium">Créez votre profil</h3>
|
|
617
|
+
<div className="flex items-center gap-4">
|
|
618
|
+
<div className="w-20 h-20 rounded-full bg-muted flex items-center justify-center">
|
|
619
|
+
<User className="h-8 w-8 text-muted-foreground" />
|
|
620
|
+
</div>
|
|
621
|
+
<button className="px-4 py-2 border rounded-md hover:bg-muted">
|
|
622
|
+
Ajouter une photo
|
|
623
|
+
</button>
|
|
624
|
+
</div>
|
|
625
|
+
<div className="grid gap-4 max-w-md">
|
|
626
|
+
<input type="text" placeholder="Nom d'affichage" className="px-3 py-2 border rounded-md" />
|
|
627
|
+
<textarea placeholder="Bio (optionnel)" className="px-3 py-2 border rounded-md" rows={3} />
|
|
628
|
+
</div>
|
|
629
|
+
</div>
|
|
630
|
+
),
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
id: 'workspace',
|
|
634
|
+
title: 'Espace de travail',
|
|
635
|
+
icon: <Settings className="h-4 w-4" />,
|
|
636
|
+
content: (
|
|
637
|
+
<div className="space-y-4">
|
|
638
|
+
<h3 className="text-lg font-medium">Configurez votre espace</h3>
|
|
639
|
+
<div className="grid gap-4 max-w-md">
|
|
640
|
+
<input type="text" placeholder="Nom de l'espace" className="px-3 py-2 border rounded-md" />
|
|
641
|
+
<select className="px-3 py-2 border rounded-md">
|
|
642
|
+
<option>Personnel</option>
|
|
643
|
+
<option>Équipe (2-10)</option>
|
|
644
|
+
<option>Organisation (10+)</option>
|
|
645
|
+
</select>
|
|
646
|
+
</div>
|
|
647
|
+
</div>
|
|
648
|
+
),
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
id: 'ready',
|
|
652
|
+
title: 'Prêt !',
|
|
653
|
+
icon: <CheckCircle className="h-4 w-4" />,
|
|
654
|
+
content: (
|
|
655
|
+
<div className="text-center py-8">
|
|
656
|
+
<CheckCircle className="h-16 w-16 text-green-500 mx-auto mb-4" />
|
|
657
|
+
<h3 className="text-2xl font-bold mb-2">Tout est prêt !</h3>
|
|
658
|
+
<p className="text-muted-foreground max-w-md mx-auto">
|
|
659
|
+
Votre espace de travail est configuré. Cliquez sur "Commencer" pour accéder à votre tableau de bord.
|
|
660
|
+
</p>
|
|
661
|
+
</div>
|
|
662
|
+
),
|
|
663
|
+
},
|
|
664
|
+
]
|
|
665
|
+
|
|
666
|
+
return (
|
|
667
|
+
<div className="min-h-screen bg-muted/30 flex items-center justify-center p-8">
|
|
668
|
+
<div className="w-full max-w-3xl">
|
|
669
|
+
<WakaWizard
|
|
670
|
+
steps={onboardingSteps}
|
|
671
|
+
layout="card"
|
|
672
|
+
showCancelButton={false}
|
|
673
|
+
finishButtonText="Commencer"
|
|
674
|
+
onSubmit={(data) => {
|
|
675
|
+
console.log('Onboarding complete:', data)
|
|
676
|
+
alert('Bienvenue ! Redirection vers le tableau de bord...')
|
|
677
|
+
}}
|
|
678
|
+
/>
|
|
679
|
+
</div>
|
|
680
|
+
</div>
|
|
681
|
+
)
|
|
682
|
+
},
|
|
683
|
+
}
|