@decido/shell 1.0.0 → 4.0.1

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 (208) hide show
  1. package/README.md +31 -0
  2. package/package.json +17 -14
  3. package/.turbo/turbo-build.log +0 -13
  4. package/src/AgentPlayer.tsx +0 -105
  5. package/src/DecidoPlayer.tsx +0 -117
  6. package/src/bridge/BridgeAgent.ts +0 -443
  7. package/src/components/DecidoIcon.tsx +0 -56
  8. package/src/components/JsonTreeEditor.tsx +0 -117
  9. package/src/components/PanelSplitter.tsx +0 -71
  10. package/src/components/PluginErrorBoundary.tsx +0 -69
  11. package/src/components/SafeLiquidUI.tsx +0 -114
  12. package/src/components/TransientLayer.tsx +0 -92
  13. package/src/components/agent/AgentChat.tsx +0 -134
  14. package/src/components/chat-extensions/IntentCatalogPanel.tsx +0 -81
  15. package/src/components/chat-extensions/chatSlashCommands.ts +0 -101
  16. package/src/components/controls/CreatorInputBar.tsx +0 -144
  17. package/src/components/controls/OSToolbar.tsx +0 -90
  18. package/src/components/controls/TimelineTape.tsx +0 -43
  19. package/src/components/debug/ActionTimelineTab.tsx +0 -111
  20. package/src/components/debug/CSSInspectorTab.tsx +0 -436
  21. package/src/components/debug/ExportTab.tsx +0 -192
  22. package/src/components/debug/FlowHealthTab.tsx +0 -86
  23. package/src/components/debug/LogsTab.tsx +0 -110
  24. package/src/components/debug/MorphStackTab.tsx +0 -241
  25. package/src/components/debug/NetworkTab.tsx +0 -173
  26. package/src/components/debug/PerformanceTab.tsx +0 -171
  27. package/src/components/debug/ProfilesTab.tsx +0 -238
  28. package/src/components/debug/ReplayTab.tsx +0 -70
  29. package/src/components/debug/StoresTab.tsx +0 -255
  30. package/src/components/debug/TopologyTab.tsx +0 -59
  31. package/src/components/debug/debugConfig.tsx +0 -66
  32. package/src/components/playground/DebugPanel.tsx +0 -112
  33. package/src/components/playground/HeaderCenterControls.tsx +0 -92
  34. package/src/components/playground/KeyframeListItem.tsx +0 -70
  35. package/src/components/playground/PlaygroundAppSidebar.tsx +0 -171
  36. package/src/components/playground/PlaygroundBottomControls.tsx +0 -132
  37. package/src/components/playground/PlaygroundCanvas.tsx +0 -87
  38. package/src/components/playground/PlaygroundChat.tsx +0 -236
  39. package/src/components/playground/PlaygroundErrorBoundary.tsx +0 -63
  40. package/src/components/playground/PlaygroundFloatingInput.tsx +0 -352
  41. package/src/components/playground/PlaygroundHeader.tsx +0 -222
  42. package/src/components/playground/PlaygroundSidebar.tsx +0 -136
  43. package/src/components/playground/PlaygroundTerminal.tsx +0 -44
  44. package/src/components/playground/SuggestionCards.tsx +0 -29
  45. package/src/components/playground/demos/ClinicaAINode.tsx +0 -221
  46. package/src/components/playground/demos/FinanceAINode.tsx +0 -226
  47. package/src/components/playground/demos/KiaAcademyNode.tsx +0 -250
  48. package/src/components/playground/demos/KiaBotNode.tsx +0 -207
  49. package/src/components/playground/demos/KiaCampaignNode.tsx +0 -191
  50. package/src/components/playground/demos/KiaComplianceNode.tsx +0 -140
  51. package/src/components/playground/demos/KiaCustomerJourneyNode.tsx +0 -220
  52. package/src/components/playground/demos/KiaCyberNode.tsx +0 -203
  53. package/src/components/playground/demos/KiaDashboardNode.tsx +0 -399
  54. package/src/components/playground/demos/KiaEmbudoOverviewNode.tsx +0 -168
  55. package/src/components/playground/demos/KiaExecutiveNode.tsx +0 -169
  56. package/src/components/playground/demos/KiaGamificationNode.tsx +0 -229
  57. package/src/components/playground/demos/KiaIntelligenceHubNode.tsx +0 -165
  58. package/src/components/playground/demos/KiaInventoryNode.tsx +0 -183
  59. package/src/components/playground/demos/KiaLeadScoringNode.tsx +0 -226
  60. package/src/components/playground/demos/KiaLiveSimulationNode.tsx +0 -177
  61. package/src/components/playground/demos/KiaMultiDealerNode.tsx +0 -223
  62. package/src/components/playground/demos/KiaNPSVoiceNode.tsx +0 -214
  63. package/src/components/playground/demos/KiaOmnichannelNode.tsx +0 -162
  64. package/src/components/playground/demos/KiaPBIBudgetNode.tsx +0 -152
  65. package/src/components/playground/demos/KiaPBIConversionNode.tsx +0 -206
  66. package/src/components/playground/demos/KiaPBIFunnelNode.tsx +0 -184
  67. package/src/components/playground/demos/KiaPBIOwnershipNode.tsx +0 -113
  68. package/src/components/playground/demos/KiaPBIPartnerNode.tsx +0 -143
  69. package/src/components/playground/demos/KiaPBIPreciosNode.tsx +0 -120
  70. package/src/components/playground/demos/KiaPBIRuntNode.tsx +0 -205
  71. package/src/components/playground/demos/KiaPartnerScoreNode.tsx +0 -206
  72. package/src/components/playground/demos/KiaPredictiveNode.tsx +0 -226
  73. package/src/components/playground/demos/KiaShowroomNode.tsx +0 -194
  74. package/src/components/playground/demos/KiaStoreNode.tsx +0 -215
  75. package/src/components/playground/demos/KiaSustainabilityNode.tsx +0 -173
  76. package/src/components/playground/demos/KiaUsedVehiclesNode.tsx +0 -163
  77. package/src/components/playground/demos/KiaWorkshopNode.tsx +0 -221
  78. package/src/components/playground/demos/SmartCityNode.tsx +0 -205
  79. package/src/components/playground/demos/kia_campaign_manifest.json +0 -112
  80. package/src/components/playground/input-parts/AIModelSelector.tsx +0 -156
  81. package/src/components/playground/input-parts/InputActions.tsx +0 -80
  82. package/src/components/playground/input-parts/InputToolbar.tsx +0 -245
  83. package/src/components/playground/input-parts/ResourceLibraryPanel.tsx +0 -287
  84. package/src/components/playground/sidebarDsdIO.ts +0 -82
  85. package/src/components/settings/SettingsPanel.tsx +0 -267
  86. package/src/components/shell/AppHeader.tsx +0 -9
  87. package/src/components/shell/AppShell.tsx +0 -139
  88. package/src/components/shell/ArtifactBar.tsx +0 -97
  89. package/src/components/shell/BootScreen.tsx +0 -19
  90. package/src/components/shell/CenterComposite.tsx +0 -87
  91. package/src/components/shell/CodeEditorPanel.tsx +0 -88
  92. package/src/components/shell/GlobalOverlays.tsx +0 -228
  93. package/src/components/shell/LayoutConfigurator.tsx +0 -209
  94. package/src/components/shell/LayoutGrid.tsx +0 -178
  95. package/src/components/shell/MorphShell.tsx +0 -368
  96. package/src/components/shell/PluginViewer.tsx +0 -147
  97. package/src/components/shell/ShellNexusPreview.tsx +0 -458
  98. package/src/components/shell/SlotRenderer.tsx +0 -115
  99. package/src/components/shell/TabBar.tsx +0 -94
  100. package/src/components/shell/TemplateLibrary.tsx +0 -195
  101. package/src/components/shell/layoutConstants.ts +0 -35
  102. package/src/components/shell/morphStageMeta.ts +0 -15
  103. package/src/components/shell/shells/BuiltInShells.tsx +0 -443
  104. package/src/components/shell/shells/DatawayChatShell.tsx +0 -42
  105. package/src/components/shell/shells/TokenPreview.tsx +0 -339
  106. package/src/components/shell/shells/bootShells.ts +0 -31
  107. package/src/components/shells/CreatorShell.tsx +0 -37
  108. package/src/components/shells/DecidoShell.tsx +0 -447
  109. package/src/components/shells/ExperimentalChatShell.tsx +0 -245
  110. package/src/components/shells/UserCanvas.tsx +0 -44
  111. package/src/components/studio/BlueprintManagerPanel.tsx +0 -137
  112. package/src/components/studio/DependencyTreePanel.tsx +0 -192
  113. package/src/components/studio/NodePalette.tsx +0 -92
  114. package/src/components/studio/NodePropertiesPanel.tsx +0 -81
  115. package/src/components/studio/ReactFlowEditor.tsx +0 -242
  116. package/src/components/studio/TimelineEditor.tsx +0 -122
  117. package/src/components/studio/TimelineKeyframeCard.tsx +0 -99
  118. package/src/components/studio/VariablePanel.tsx +0 -181
  119. package/src/components/studio/blueprint/BlueprintCard.tsx +0 -82
  120. package/src/components/studio/editor/CanvasContextMenu.tsx +0 -107
  121. package/src/components/studio/editor/EditorToolbar.tsx +0 -80
  122. package/src/components/studio/editor/StageContentRenderer.tsx +0 -134
  123. package/src/components/studio/editor/TrackPropertyEditors.tsx +0 -133
  124. package/src/components/studio/editor/TreeNodeItem.tsx +0 -91
  125. package/src/components/studio/editor/edgeStyles.ts +0 -43
  126. package/src/components/studio/editor/editorKeyHandler.ts +0 -95
  127. package/src/components/studio/editor/nodeTypeRegistry.ts +0 -137
  128. package/src/components/studio/editor/paletteCatalog.tsx +0 -84
  129. package/src/components/studio/nodes/shell/InteractionNodes.tsx +0 -82
  130. package/src/components/studio/nodes/shell/LayoutControlNodes.tsx +0 -69
  131. package/src/components/studio/nodes/shell/RegisterActionNode.tsx +0 -20
  132. package/src/components/studio/nodes/shell/RegisterButtonNode.tsx +0 -22
  133. package/src/components/studio/nodes/shell/RegisterPanelNode.tsx +0 -19
  134. package/src/components/studio/nodes/shell/RegisterSidebarNode.tsx +0 -19
  135. package/src/components/studio/nodes/shell/RegisterStatusBarNode.tsx +0 -22
  136. package/src/components/studio/nodes/shell/RegisterTabNode.tsx +0 -21
  137. package/src/components/studio/nodes/shell/RegisterTopBarNode.tsx +0 -22
  138. package/src/components/studio/nodes/shell/ShellConfigNode.tsx +0 -51
  139. package/src/components/studio/nodes/shell/ShellNodeBase.tsx +0 -100
  140. package/src/components/studio/nodes/shell/ThemeNodes.tsx +0 -51
  141. package/src/components/studio/nodes/shell/index.ts +0 -12
  142. package/src/components/widgets/BroadcastWidget.tsx +0 -93
  143. package/src/components/widgets/MarketplaceWidget.tsx +0 -298
  144. package/src/components/widgets/McpToolsWidget.tsx +0 -231
  145. package/src/components/widgets/OpsDashboard.tsx +0 -59
  146. package/src/components/widgets/QuickActionsWidget.tsx +0 -60
  147. package/src/components/widgets/UsageWidget.tsx +0 -112
  148. package/src/components/widgets/WidgetRenderer.tsx +0 -892
  149. package/src/components/widgets/WidgetSlotPanel.tsx +0 -213
  150. package/src/config/IconRegistry.ts +0 -126
  151. package/src/contexts/NetworkProvider.tsx +0 -162
  152. package/src/core/AIDirector.ts +0 -71
  153. package/src/core/EventBus.ts +0 -37
  154. package/src/core/PluginContext.tsx +0 -141
  155. package/src/hooks/listeners/useUIStateListener.ts +0 -59
  156. package/src/hooks/listeners/useWhatsAppListener.ts +0 -110
  157. package/src/hooks/morphBridge.ts +0 -82
  158. package/src/hooks/useAIModelSelector.ts +0 -144
  159. package/src/hooks/useAgentStream.ts +0 -220
  160. package/src/hooks/useAutoUpdater.ts +0 -89
  161. package/src/hooks/useBootSequence.ts +0 -20
  162. package/src/hooks/useExportDSD.ts +0 -53
  163. package/src/hooks/useFullscreen.ts +0 -35
  164. package/src/hooks/useGeminiStream.ts +0 -282
  165. package/src/hooks/useIntentLens.ts +0 -224
  166. package/src/hooks/useKeyboardShortcuts.ts +0 -69
  167. package/src/hooks/useLoggerBridge.ts +0 -32
  168. package/src/hooks/useMcpClient.ts +0 -112
  169. package/src/hooks/useNexusaiDeploy.ts +0 -118
  170. package/src/hooks/usePlaybackEngine.ts +0 -21
  171. package/src/hooks/usePlaygroundCommander.ts +0 -475
  172. package/src/hooks/usePluginEngine.ts +0 -165
  173. package/src/hooks/useScreenRecorder.ts +0 -73
  174. package/src/hooks/useShellKeyboard.ts +0 -40
  175. package/src/hooks/useShellShortcuts.ts +0 -118
  176. package/src/hooks/useSoundEffects.ts +0 -35
  177. package/src/hooks/useStudioConfig.ts +0 -72
  178. package/src/hooks/useSystemBoot.ts +0 -84
  179. package/src/hooks/useSystemTelemetry.ts +0 -62
  180. package/src/lib/debugLogger.ts +0 -80
  181. package/src/lib/networkInterceptor.ts +0 -100
  182. package/src/mocks/decido.tsx +0 -41
  183. package/src/plugins/pluginAPI.ts +0 -190
  184. package/src/store/McpStore.ts +0 -69
  185. package/src/store/UpdaterStore.ts +0 -60
  186. package/src/store/engine.ts +0 -392
  187. package/src/store/index.ts +0 -4
  188. package/src/store/layoutPresets.ts +0 -66
  189. package/src/store/playgroundTypes.ts +0 -98
  190. package/src/store/useActionTimelineStore.ts +0 -48
  191. package/src/store/useDebugPanelStore.ts +0 -98
  192. package/src/store/useDebugProfileStore.ts +0 -130
  193. package/src/store/useLayoutStore.ts +0 -205
  194. package/src/store/useMorphInstanceStore.ts +0 -289
  195. package/src/store/useMorphologyStore.ts +0 -103
  196. package/src/store/usePlaygroundStore.ts +0 -236
  197. package/src/store/useShellRegistry.ts +0 -123
  198. package/src/store/useSuggestionsStore.ts +0 -57
  199. package/src/store/useThemeStore.ts +0 -399
  200. package/src/store/useUIComponentStore.ts +0 -179
  201. package/src/types/DecidoStoryDefinition.ts +0 -43
  202. package/src/utils/ai/ai-architect.ts +0 -92
  203. package/src/utils/ai/ai-code.ts +0 -187
  204. package/src/utils/ai/ai-core.ts +0 -50
  205. package/src/utils/ai/ai-media.ts +0 -292
  206. package/src/utils/layoutGraph.ts +0 -67
  207. package/tsconfig.json +0 -17
  208. package/tsconfig.tsbuildinfo +0 -1
@@ -1,168 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- Target,
5
- Users,
6
- Eye,
7
- Car,
8
- FileText,
9
- CheckCircle2,
10
- TrendingDown,
11
- Activity,
12
- Smartphone,
13
- Globe,
14
- MapPin,
15
- HelpCircle,
16
- } from 'lucide-react';
17
-
18
- /* ═══════════════════════════════════════════════════════════════
19
- KIA EMBUDO OVERVIEW NODE
20
- Funnel visual animado con datos reales de Grecco Motors
21
- ═══════════════════════════════════════════════════════════════ */
22
-
23
- const FUNNEL_STAGES = [
24
- { key: 'oportunidades', label: 'Oportunidades', base: 437, icon: Users, color: '#6366f1' },
25
- { key: 'citas', label: 'Citas', base: 284, cumpl: 65, icon: Target, color: '#8b5cf6' },
26
- { key: 'showup', label: 'Show Up', base: 264, cumpl: 93, icon: Eye, color: '#3b82f6' },
27
- { key: 'testdrive', label: 'Test Drive', base: 79, cumpl: 129, icon: Car, color: '#0ea5e9' },
28
- { key: 'cotizacion', label: 'Cotización', base: 52, icon: FileText, color: '#22d3ee' },
29
- { key: 'pedidos', label: 'Pedidos', base: 15, icon: CheckCircle2, color: '#22c55e' },
30
- { key: 'entregas', label: 'Entregas / Matrículas', base: 30, icon: CheckCircle2, color: '#10b981' },
31
- ];
32
-
33
- const CANALES = [
34
- { name: 'Redes Sociales', pct: 54.7, icon: Smartphone, color: '#6366f1' },
35
- { name: 'Walk-in', pct: 26.3, icon: MapPin, color: '#22c55e' },
36
- { name: 'Google Ads', pct: 12.0, icon: Globe, color: '#f59e0b' },
37
- { name: 'Otros', pct: 7.0, icon: HelpCircle, color: '#64748b' },
38
- ];
39
-
40
- const jitter = (base: number, range: number) =>
41
- base + Math.round((Math.random() - 0.5) * range);
42
-
43
- export const KiaEmbudoOverviewNode = (props: any) => {
44
- const [tick, setTick] = useState(0);
45
- const [animateIn, setAnimateIn] = useState(false);
46
-
47
- /* Auto-refresh */
48
- useEffect(() => {
49
- setAnimateIn(true);
50
- const iv = setInterval(() => setTick(t => t + 1), 10000);
51
- return () => clearInterval(iv);
52
- }, []);
53
-
54
- /* Animated values */
55
- const stages = FUNNEL_STAGES.map(s => ({
56
- ...s,
57
- value: jitter(s.base, Math.round(s.base * 0.05)),
58
- }));
59
-
60
- const maxVal = stages[0].value;
61
-
62
- return (
63
- <BaseNode {...props} title="Embudo Comercial — Grecco Motors" width={520} height={600}>
64
- <div className="flex flex-col h-full bg-slate-900 text-white p-4 gap-3 overflow-hidden">
65
-
66
- {/* Header */}
67
- <div className="flex justify-between items-center">
68
- <div>
69
- <h2 className="text-sm font-bold tracking-wide">EMBUDO DE CONVERSIÓN</h2>
70
- <div className="flex items-center gap-2 mt-0.5">
71
- <span className="text-[10px] text-slate-400">Febrero 2026 · Grecco Motors</span>
72
- <span className="flex items-center gap-1 text-[10px] text-green-400 bg-green-500/10 px-1.5 rounded">
73
- <Activity size={8} className="animate-pulse" /> LIVE
74
- </span>
75
- </div>
76
- </div>
77
- <div className="flex items-center gap-2">
78
- <TrendingDown size={14} className="text-slate-500" />
79
- <span className="text-xs text-slate-400">Conversión: <span className="text-white font-bold">{((stages[5].value / stages[0].value) * 100).toFixed(1)}%</span></span>
80
- </div>
81
- </div>
82
-
83
- {/* Funnel Visual */}
84
- <div className="flex-1 flex flex-col gap-1.5 py-2" key={tick}>
85
- {stages.map((stage, i) => {
86
- const widthPct = Math.max(20, (stage.value / maxVal) * 100);
87
- const conversion = i > 0 ? ((stage.value / stages[i - 1].value) * 100).toFixed(0) : null;
88
- const Icon = stage.icon;
89
-
90
- return (
91
- <div key={stage.key} className="relative group">
92
- {/* Conversion Arrow */}
93
- {conversion && (
94
- <div className="text-[9px] text-slate-600 text-center mb-0.5">
95
- ↓ {conversion}%
96
- </div>
97
- )}
98
-
99
- {/* Bar */}
100
- <div className="flex items-center gap-2">
101
- <div className="w-6 flex-shrink-0 flex justify-center">
102
- <Icon size={13} style={{ color: stage.color }} />
103
- </div>
104
- <div className="flex-1 relative">
105
- <div
106
- className="rounded-md flex items-center justify-between px-3 py-2 transition-all duration-1000 ease-out cursor-pointer hover:brightness-125"
107
- style={{
108
- width: `${widthPct}%`,
109
- background: `linear-gradient(90deg, ${stage.color}dd, ${stage.color}88)`,
110
- boxShadow: `0 0 12px ${stage.color}22`,
111
- }}
112
- >
113
- <span className="text-[11px] font-medium text-white truncate">{stage.label}</span>
114
- <span className="text-sm font-bold text-white ml-2">{stage.value}</span>
115
- </div>
116
- </div>
117
- {stage.cumpl && (
118
- <span className={`text-[10px] font-mono w-10 text-right flex-shrink-0 ${stage.cumpl >= 100 ? 'text-green-400' : 'text-yellow-400'}`}>
119
- {stage.cumpl}%
120
- </span>
121
- )}
122
- </div>
123
- </div>
124
- );
125
- })}
126
- </div>
127
-
128
- {/* Canales de Origen */}
129
- <div className="bg-slate-800 p-3 rounded-xl border border-slate-700">
130
- <h3 className="text-[10px] uppercase text-slate-400 font-bold mb-2">Canales de Origen</h3>
131
- <div className="flex gap-1">
132
- {CANALES.map(c => (
133
- <div
134
- key={c.name}
135
- className="rounded transition-all hover:brightness-125 cursor-pointer flex flex-col items-center justify-center py-2"
136
- style={{
137
- flex: c.pct,
138
- background: `${c.color}22`,
139
- borderLeft: `2px solid ${c.color}`,
140
- }}
141
- >
142
- <c.icon size={12} style={{ color: c.color }} />
143
- <span className="text-[9px] font-bold mt-1" style={{ color: c.color }}>{c.pct}%</span>
144
- <span className="text-[8px] text-slate-500 mt-0.5">{c.name}</span>
145
- </div>
146
- ))}
147
- </div>
148
- </div>
149
-
150
- {/* Footer KPIs */}
151
- <div className="grid grid-cols-3 gap-2">
152
- <div className="bg-slate-800 px-3 py-2 rounded-lg border border-slate-700 text-center">
153
- <div className="text-lg font-bold text-green-400">95.3%</div>
154
- <div className="text-[9px] text-slate-500">NPS Comercial</div>
155
- </div>
156
- <div className="bg-slate-800 px-3 py-2 rounded-lg border border-slate-700 text-center">
157
- <div className="text-lg font-bold text-blue-400">13.3%</div>
158
- <div className="text-[9px] text-slate-500">Market Share</div>
159
- </div>
160
- <div className="bg-slate-800 px-3 py-2 rounded-lg border border-slate-700 text-center">
161
- <div className="text-lg font-bold text-yellow-400">S</div>
162
- <div className="text-[9px] text-slate-500">Partner Prog</div>
163
- </div>
164
- </div>
165
- </div>
166
- </BaseNode>
167
- );
168
- };
@@ -1,169 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- PieChart, TrendingUp, DollarSign, Users, BarChart3,
5
- Download, FileText, Calendar, ChevronUp, ChevronDown, Crown
6
- } from 'lucide-react';
7
-
8
- /* ═══════════════════════════════════════════════════════════════
9
- KIA EXECUTIVE NODE — Executive BI & Board Reports · Grecco
10
- Board deck, sparklines, macro KPIs, scheduled reports
11
- ═══════════════════════════════════════════════════════════════ */
12
-
13
- interface KPI {
14
- label: string;
15
- value: string;
16
- prev: string;
17
- trend: number;
18
- unit: string;
19
- sparkline: number[];
20
- }
21
-
22
- const KPIS: KPI[] = [
23
- { label: 'RUNT Matriculas', value: '95', prev: '146', trend: -34.9, unit: 'uds', sparkline: [120, 110, 145, 130, 165, 182, 146, 95, 0, 0, 0, 0] },
24
- { label: 'Vehículos', value: '156', prev: '142', trend: 9.9, unit: 'unid', sparkline: [40, 45, 42, 48, 55, 50, 58, 60, 65, 62, 70, 72] },
25
- { label: 'NPS', value: '95.3', prev: '91.2', trend: 4.5, unit: 'pts', sparkline: [78, 80, 82, 81, 85, 87, 88, 90, 91, 93, 94, 95] },
26
- { label: 'Market Share', value: '13.3%', prev: '12.1%', trend: 9.9, unit: '%', sparkline: [8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13] },
27
- { label: 'Partner Score', value: '91', prev: '87', trend: 4.6, unit: 'pts', sparkline: [72, 74, 76, 78, 80, 82, 84, 86, 87, 88, 89, 91] },
28
- { label: 'Posventa', value: '128', prev: '115', trend: 11.3, unit: 'OTs', sparkline: [80, 85, 90, 88, 95, 98, 100, 105, 110, 115, 120, 128] },
29
- ];
30
-
31
- const REPORTS = [
32
- { name: 'KIA Board Deck Q1', frequency: 'Trimestral', lastRun: 'Ene 31', pages: 24, format: 'PDF' },
33
- { name: 'Weekly Sales Report', frequency: 'Semanal', lastRun: 'Feb 14', pages: 8, format: 'PDF' },
34
- { name: 'Partner Program Update', frequency: 'Mensual', lastRun: 'Feb 1', pages: 12, format: 'PDF' },
35
- { name: 'Inventory Status', frequency: 'Diario', lastRun: 'Feb 17', pages: 4, format: 'Excel' },
36
- { name: 'CX Dashboard Export', frequency: 'Semanal', lastRun: 'Feb 14', pages: 6, format: 'PDF' },
37
- ];
38
-
39
- const TOP_MODELS = [
40
- { model: 'Picanto', units: 46, revenue: '$2.8B', share: 48.4 },
41
- { model: 'Sportage', units: 12, revenue: '$1.2B', share: 12.6 },
42
- { model: 'K3 Cross', units: 10, revenue: '$580M', share: 10.5 },
43
- { model: 'Stonic', units: 8, revenue: '$440M', share: 8.4 },
44
- { model: 'Sonet', units: 7, revenue: '$350M', share: 7.4 },
45
- ];
46
-
47
- export const KiaExecutiveNode = (props: any) => {
48
- const [tab, setTab] = useState<'kpis' | 'reports' | 'models'>('kpis');
49
-
50
- // Sparkline renderer
51
- const Spark = ({ data, color }: { data: number[]; color: string }) => {
52
- const max = Math.max(...data);
53
- const min = Math.min(...data);
54
- const range = max - min || 1;
55
- const w = 80;
56
- const h = 20;
57
- const points = data.map((v, i) => `${(i / (data.length - 1)) * w},${h - ((v - min) / range) * h}`).join(' ');
58
- return (
59
- <svg width={w} height={h} className="inline-block">
60
- <polyline points={points} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
61
- </svg>
62
- );
63
- };
64
-
65
- return (
66
- <BaseNode {...props} title="Kia Executive BI" width={500} height={620}>
67
- <div className="flex flex-col h-full bg-[#050810] text-white overflow-hidden">
68
-
69
- {/* Header */}
70
- <div className="flex items-center gap-3 p-3 bg-[#0a1020] border-b border-slate-800">
71
- <div className="w-10 h-10 rounded-full bg-linear-to-br from-yellow-500/20 to-amber-600/20 flex items-center justify-center border border-yellow-500/20">
72
- <Crown size={18} className="text-yellow-400" />
73
- </div>
74
- <div className="flex-1">
75
- <div className="text-xs font-bold tracking-wide flex items-center gap-2">
76
- EXECUTIVE BI
77
- <span className="text-[8px] px-1.5 py-0.5 bg-yellow-500/20 text-yellow-400 rounded font-normal">BOARD LEVEL</span>
78
- </div>
79
- <div className="text-[10px] text-slate-400">Grecco Motors · Febrero 2026 · Reporting Suite</div>
80
- </div>
81
- </div>
82
-
83
- {/* Tabs */}
84
- <div className="flex gap-1 p-2 bg-[#080e1a] border-b border-slate-800">
85
- {([
86
- { key: 'kpis' as const, label: '📊 KPIs Macro' },
87
- { key: 'reports' as const, label: '📄 Reportes' },
88
- { key: 'models' as const, label: '🚗 Top Modelos' },
89
- ]).map(t => (
90
- <button key={t.key} onClick={() => setTab(t.key)}
91
- className={`flex-1 py-1.5 rounded text-[9px] font-bold transition-all ${tab === t.key ? 'bg-yellow-600/20 text-yellow-400 border border-yellow-500/30' : 'text-slate-500'
92
- }`}>
93
- {t.label}
94
- </button>
95
- ))}
96
- </div>
97
-
98
- {/* Content */}
99
- <div className="flex-1 overflow-y-auto p-3 space-y-2">
100
-
101
- {tab === 'kpis' && KPIS.map(k => (
102
- <div key={k.label} className="bg-slate-900/50 rounded-lg p-3 border border-slate-800 flex items-center gap-3">
103
- <div className="flex-1">
104
- <div className="text-[9px] text-slate-500 uppercase font-bold">{k.label}</div>
105
- <div className="flex items-baseline gap-2">
106
- <span className="text-xl font-black">{k.value}</span>
107
- <span className={`text-[10px] flex items-center gap-0.5 font-bold ${k.trend > 0 ? 'text-green-400' : 'text-red-400'}`}>
108
- {k.trend > 0 ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
109
- {Math.abs(k.trend)}%
110
- </span>
111
- </div>
112
- <div className="text-[8px] text-slate-500">Prev: {k.prev}</div>
113
- </div>
114
- <Spark data={k.sparkline} color={k.trend > 0 ? '#22c55e' : '#ef4444'} />
115
- </div>
116
- ))}
117
-
118
- {tab === 'reports' && (
119
- <>
120
- <div className="text-[9px] text-slate-500 font-bold uppercase mb-1">Reportes Programados</div>
121
- {REPORTS.map(r => (
122
- <div key={r.name} className="bg-slate-900/50 rounded-lg p-2.5 border border-slate-800 flex items-center justify-between">
123
- <div>
124
- <div className="text-[11px] font-bold">{r.name}</div>
125
- <div className="text-[9px] text-slate-500 flex items-center gap-2">
126
- <span className="flex items-center gap-0.5"><Calendar size={8} />{r.frequency}</span>
127
- <span>{r.pages}p</span>
128
- <span className="text-slate-600">Último: {r.lastRun}</span>
129
- </div>
130
- </div>
131
- <button className="flex items-center gap-1 px-2 py-1 bg-yellow-500/10 border border-yellow-500/20 rounded text-[9px] font-bold text-yellow-400 hover:bg-yellow-500/20 transition-all">
132
- <Download size={9} /> {r.format}
133
- </button>
134
- </div>
135
- ))}
136
- </>
137
- )}
138
-
139
- {tab === 'models' && (
140
- <>
141
- <div className="text-[9px] text-slate-500 font-bold uppercase mb-1">Ranking Ventas por Modelo — Feb 2026</div>
142
- {TOP_MODELS.map((m, i) => (
143
- <div key={m.model} className="bg-slate-900/50 rounded-lg p-2.5 border border-slate-800">
144
- <div className="flex items-center justify-between mb-1">
145
- <div className="flex items-center gap-2">
146
- <span className={`text-[10px] font-black w-5 text-center ${i === 0 ? 'text-yellow-400' : i === 1 ? 'text-slate-300' : i === 2 ? 'text-orange-400' : 'text-slate-500'}`}>
147
- #{i + 1}
148
- </span>
149
- <span className="text-[11px] font-bold">{m.model}</span>
150
- </div>
151
- <span className="text-sm font-bold text-blue-400">{m.units}</span>
152
- </div>
153
- <div className="flex items-center gap-2">
154
- <div className="flex-1 h-2 bg-slate-800 rounded-full">
155
- <div className="h-full rounded-full bg-linear-to-r from-yellow-500 to-amber-500 transition-all"
156
- style={{ width: `${m.share * 3}%` }} />
157
- </div>
158
- <span className="text-[9px] text-yellow-400 font-bold">{m.share}%</span>
159
- <span className="text-[9px] text-slate-500">{m.revenue}</span>
160
- </div>
161
- </div>
162
- ))}
163
- </>
164
- )}
165
- </div>
166
- </div>
167
- </BaseNode>
168
- );
169
- };
@@ -1,229 +0,0 @@
1
- import React, { useState, useRef, useEffect } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- Trophy, Gift, PartyPopper, User, Phone, Mail,
5
- ArrowRight, RotateCcw, Users, Activity, BarChart3, Zap
6
- } from 'lucide-react';
7
-
8
- /* ═══════════════════════════════════════════════════════════════
9
- KIA GAMIFICATION NODE — Showroom Experience · Grecco Motors
10
- Lucky Drive: Ruleta lead-capture + KPIs de conversion
11
- ═══════════════════════════════════════════════════════════════ */
12
-
13
- const PRIZES = [
14
- { label: 'Mantenimiento Gratis', color: '#ef4444', value: '$850K' },
15
- { label: 'Bono $500k Accesorios', color: '#f59e0b', value: '$500K' },
16
- { label: 'Polarizado Nano-Cerámico', color: '#3b82f6', value: '$1.2M' },
17
- { label: 'Kit de Carretera Premium', color: '#22c55e', value: '$320K' },
18
- { label: '50% Dcto Alineación', color: '#a855f7', value: '$175K' },
19
- { label: 'Lavado Ecológico x3', color: '#06b6d4', value: '$90K' },
20
- ];
21
-
22
- export const KiaGamificationNode = (props: any) => {
23
- const [step, setStep] = useState<'form' | 'game' | 'result'>('form');
24
- const [lead, setLead] = useState({ name: '', phone: '', email: '', model: '' });
25
- const [spinning, setSpinning] = useState(false);
26
- const [prize, setPrize] = useState<(typeof PRIZES)[0] | null>(null);
27
- const [totalLeads, setTotalLeads] = useState(347);
28
- const [todayLeads, setTodayLeads] = useState(23);
29
- const wheelRef = useRef<HTMLDivElement>(null);
30
-
31
- /* Simulate growing leads */
32
- useEffect(() => {
33
- const iv = setInterval(() => {
34
- if (Math.random() > 0.6) setTotalLeads(t => t + 1);
35
- }, 12000);
36
- return () => clearInterval(iv);
37
- }, []);
38
-
39
- const handleSpin = () => {
40
- if (spinning) return;
41
- setSpinning(true);
42
-
43
- const randomDeg = 720 + Math.floor(Math.random() * 360);
44
- const selectedIdx = Math.floor(Math.random() * PRIZES.length);
45
-
46
- if (wheelRef.current) {
47
- wheelRef.current.style.transition = 'transform 3s cubic-bezier(0.2, 0.8, 0.2, 1)';
48
- wheelRef.current.style.transform = `rotate(${randomDeg}deg)`;
49
- }
50
-
51
- setTimeout(() => {
52
- setPrize(PRIZES[selectedIdx]);
53
- setStep('result');
54
- setSpinning(false);
55
- setTodayLeads(t => t + 1);
56
- setTotalLeads(t => t + 1);
57
- }, 3000);
58
- };
59
-
60
- const resetGame = () => {
61
- setStep('form');
62
- setPrize(null);
63
- setLead({ name: '', phone: '', email: '', model: '' });
64
- if (wheelRef.current) {
65
- wheelRef.current.style.transition = 'none';
66
- wheelRef.current.style.transform = 'rotate(0deg)';
67
- }
68
- };
69
-
70
- const segmentAngle = 360 / PRIZES.length;
71
-
72
- return (
73
- <BaseNode {...props} title="Kia Showroom Experience" width={420} height={640}>
74
- <div className="flex flex-col h-full bg-linear-to-b from-black to-slate-900 text-white relative overflow-hidden">
75
-
76
- {/* Animated bg */}
77
- <div className="absolute top-0 left-0 w-full h-full opacity-10 pointer-events-none">
78
- <div className="absolute top-[-20%] left-[-20%] w-[140%] h-[140%] bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-red-600 via-transparent to-transparent animate-pulse" />
79
- </div>
80
-
81
- {/* Header with Stats */}
82
- <div className="flex items-center p-3 bg-black/40 z-10 border-b border-slate-800">
83
- <div className="flex-1">
84
- <h2 className="text-sm font-bold tracking-[0.15em] uppercase">Lucky Drive</h2>
85
- <div className="text-[10px] text-slate-400">Grecco Motors · Lead Capture Gamificado</div>
86
- </div>
87
- <div className="flex gap-2">
88
- <div className="bg-slate-800 px-2 py-1 rounded text-center border border-slate-700">
89
- <div className="text-xs font-bold text-green-400">{todayLeads}</div>
90
- <div className="text-[8px] text-slate-500">Hoy</div>
91
- </div>
92
- <div className="bg-slate-800 px-2 py-1 rounded text-center border border-slate-700">
93
- <div className="text-xs font-bold text-blue-400">{totalLeads}</div>
94
- <div className="text-[8px] text-slate-500">Total</div>
95
- </div>
96
- </div>
97
- </div>
98
-
99
- {/* Content */}
100
- <div className="flex-1 flex flex-col items-center justify-center p-5 z-10">
101
-
102
- {step === 'form' && (
103
- <div className="w-full space-y-3">
104
- <div className="text-center mb-4">
105
- <Trophy className="mx-auto text-yellow-400 mb-2" size={44} />
106
- <h3 className="text-lg font-bold">¡Gana Premios para tu Kia!</h3>
107
- <p className="text-xs text-slate-400">Regístrate y gira la ruleta.</p>
108
- </div>
109
-
110
- <div className="space-y-2">
111
- <InputField icon={User} placeholder="Tu Nombre" value={lead.name} onChange={(v: string) => setLead({ ...lead, name: v })} />
112
- <InputField icon={Phone} placeholder="Celular" value={lead.phone} onChange={(v: string) => setLead({ ...lead, phone: v })} type="tel" />
113
- <InputField icon={Mail} placeholder="Email" value={lead.email} onChange={(v: string) => setLead({ ...lead, email: v })} type="email" />
114
- <select
115
- className="w-full bg-slate-800 border border-slate-700 rounded-lg py-2.5 px-3 text-sm text-white focus:outline-none focus:border-red-500"
116
- value={lead.model}
117
- onChange={e => setLead({ ...lead, model: e.target.value })}
118
- >
119
- <option value="">¿Qué modelo te interesa?</option>
120
- <option value="EV6">EV6</option>
121
- <option value="Sportage">Sportage</option>
122
- <option value="Seltos">Seltos</option>
123
- <option value="K3 Cross">K3 Cross</option>
124
- <option value="Picanto">Picanto</option>
125
- <option value="Stonic">Stonic</option>
126
- <option value="Sorento">Sorento</option>
127
- </select>
128
- </div>
129
-
130
- <button
131
- onClick={() => setStep('game')}
132
- disabled={!lead.name || !lead.phone}
133
- className="w-full bg-red-600 hover:bg-red-500 text-white font-bold py-3 rounded-lg flex items-center justify-center gap-2 mt-3 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
134
- >
135
- Jugar Ahora <ArrowRight size={16} />
136
- </button>
137
- <p className="text-[9px] text-center text-slate-600">*Aceptas términos, condiciones y política de datos.</p>
138
- </div>
139
- )}
140
-
141
- {step === 'game' && (
142
- <div className="flex flex-col items-center">
143
- <div className="text-[10px] text-slate-400 mb-3">
144
- ¡Hola <span className="text-white font-bold">{lead.name.split(' ')[0]}</span>! Gira la ruleta 👇
145
- </div>
146
- <div className="relative w-56 h-56 mb-6">
147
- <div className="absolute -top-3 left-1/2 -translate-x-1/2 z-20 text-red-500 text-xl filter drop-shadow-lg">▼</div>
148
- <div
149
- ref={wheelRef}
150
- className="w-full h-full rounded-full border-4 border-slate-700 shadow-2xl relative overflow-hidden"
151
- style={{
152
- background: `conic-gradient(${PRIZES.map((p, i) => `${p.color} ${i * segmentAngle}deg ${(i + 1) * segmentAngle}deg`).join(', ')})`
153
- }}
154
- >
155
- {PRIZES.map((p, i) => (
156
- <div
157
- key={i}
158
- className="absolute w-full h-full text-[8px] font-bold text-white flex justify-center pt-3"
159
- style={{ transform: `rotate(${i * segmentAngle + segmentAngle / 2}deg)` }}
160
- >
161
- <span className="bg-black/50 px-1 py-0.5 rounded backdrop-blur-sm max-w-[70px] text-center block" style={{ transform: 'translateY(16px)' }}>
162
- {p.label.split(' ').slice(0, 2).join(' ')}
163
- </span>
164
- </div>
165
- ))}
166
- </div>
167
- <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-12 h-12 bg-white rounded-full flex items-center justify-center shadow-lg z-10 border-4 border-slate-300">
168
- <span className="text-red-600 font-bold text-[8px] tracking-widest">KIA</span>
169
- </div>
170
- </div>
171
- <button
172
- onClick={handleSpin}
173
- disabled={spinning}
174
- className="px-8 py-3 bg-linear-to-r from-red-600 to-red-500 rounded-full text-white font-bold text-lg shadow-lg hover:shadow-red-500/20 hover:scale-105 active:scale-95 transition-all disabled:opacity-50"
175
- >
176
- {spinning ? '🎰 Girando...' : '¡GIRAR!'}
177
- </button>
178
- </div>
179
- )}
180
-
181
- {step === 'result' && prize && (
182
- <div className="flex flex-col items-center text-center">
183
- <div className="w-20 h-20 bg-yellow-400/20 rounded-full flex items-center justify-center mb-4 animate-bounce">
184
- <Trophy className="text-yellow-400" size={40} />
185
- </div>
186
- <h3 className="text-xl font-bold mb-1">¡Felicidades {lead.name.split(' ')[0]}!</h3>
187
- <p className="text-slate-400 text-sm mb-4">Ganaste:</p>
188
-
189
- <div className="bg-slate-800 border p-5 rounded-xl w-full max-w-xs mb-4 shadow-[0_0_30px_rgba(220,38,38,0.2)]" style={{ borderColor: `${prize.color}66` }}>
190
- <Gift className="mx-auto mb-2" size={28} style={{ color: prize.color }} />
191
- <div className="text-lg font-bold text-white">{prize.label}</div>
192
- <div className="text-xs mt-1" style={{ color: prize.color }}>Valor: {prize.value}</div>
193
- <div className="text-[10px] text-slate-500 mt-2">Código: KIA-GRC-{Math.floor(Math.random() * 10000)}</div>
194
- </div>
195
-
196
- <div className="bg-green-500/10 border border-green-500/20 rounded-lg p-2 text-[10px] text-green-300 w-full mb-4">
197
- ✅ Lead registrado en CRM · Asesor asignado automáticamente
198
- </div>
199
-
200
- <button onClick={resetGame} className="flex items-center gap-2 text-slate-400 hover:text-white transition-colors text-sm">
201
- <RotateCcw size={14} /> Siguiente Cliente
202
- </button>
203
- </div>
204
- )}
205
- </div>
206
-
207
- {/* Bottom Stats */}
208
- <div className="flex items-center justify-between text-[10px] text-slate-500 p-2 border-t border-slate-800 z-10">
209
- <span>Conv. Rate: <span className="text-green-400 font-bold">34.2%</span></span>
210
- <span>Avg Ticket: <span className="text-blue-400 font-bold">$420K</span></span>
211
- <span className="flex items-center gap-1"><Activity size={8} className="text-green-400 animate-pulse" /> Live</span>
212
- </div>
213
- </div>
214
- </BaseNode>
215
- );
216
- };
217
-
218
- const InputField = ({ icon: Icon, placeholder, value, onChange, type = 'text' }: any) => (
219
- <div className="relative">
220
- <Icon className="absolute left-3 top-3 text-slate-500" size={14} />
221
- <input
222
- type={type}
223
- placeholder={placeholder}
224
- className="w-full bg-slate-800 border border-slate-700 rounded-lg py-2.5 pl-9 text-sm focus:outline-none focus:border-red-500 transition-colors"
225
- value={value}
226
- onChange={e => onChange(e.target.value)}
227
- />
228
- </div>
229
- );