@decido/shell 1.0.0 → 4.0.2

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 (209) hide show
  1. package/README.md +31 -0
  2. package/package.json +27 -18
  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/index.ts +0 -97
  181. package/src/lib/debugLogger.ts +0 -80
  182. package/src/lib/networkInterceptor.ts +0 -100
  183. package/src/mocks/decido.tsx +0 -41
  184. package/src/plugins/pluginAPI.ts +0 -190
  185. package/src/store/McpStore.ts +0 -69
  186. package/src/store/UpdaterStore.ts +0 -60
  187. package/src/store/engine.ts +0 -392
  188. package/src/store/index.ts +0 -4
  189. package/src/store/layoutPresets.ts +0 -66
  190. package/src/store/playgroundTypes.ts +0 -98
  191. package/src/store/useActionTimelineStore.ts +0 -48
  192. package/src/store/useDebugPanelStore.ts +0 -98
  193. package/src/store/useDebugProfileStore.ts +0 -130
  194. package/src/store/useLayoutStore.ts +0 -205
  195. package/src/store/useMorphInstanceStore.ts +0 -289
  196. package/src/store/useMorphologyStore.ts +0 -103
  197. package/src/store/usePlaygroundStore.ts +0 -236
  198. package/src/store/useShellRegistry.ts +0 -123
  199. package/src/store/useSuggestionsStore.ts +0 -57
  200. package/src/store/useThemeStore.ts +0 -399
  201. package/src/store/useUIComponentStore.ts +0 -179
  202. package/src/types/DecidoStoryDefinition.ts +0 -43
  203. package/src/utils/ai/ai-architect.ts +0 -92
  204. package/src/utils/ai/ai-code.ts +0 -187
  205. package/src/utils/ai/ai-core.ts +0 -50
  206. package/src/utils/ai/ai-media.ts +0 -292
  207. package/src/utils/layoutGraph.ts +0 -67
  208. package/tsconfig.json +0 -17
  209. package/tsconfig.tsbuildinfo +0 -1
@@ -1,194 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- Car, Palette, Calendar, Scale, ChevronRight,
5
- Star, Fuel, Gauge, Zap, Check, ArrowLeftRight
6
- } from 'lucide-react';
7
-
8
- /* ═══════════════════════════════════════════════════════════════
9
- KIA SHOWROOM DIGITAL NODE — Configurador · Grecco Motors
10
- Catálogo, configurador modelo+color+paquete, comparador, agenda
11
- ═══════════════════════════════════════════════════════════════ */
12
-
13
- interface Model {
14
- name: string;
15
- price: number;
16
- type: 'ICE' | 'HEV' | 'EV';
17
- hp: number;
18
- kmpl: number;
19
- colors: { name: string; hex: string }[];
20
- packages: { name: string; price: number }[];
21
- }
22
-
23
- const MODELS: Model[] = [
24
- { name: 'Sportage HEV', price: 159900000, type: 'HEV', hp: 230, kmpl: 18.2, colors: [{ name: 'Snow White', hex: '#f1f0eb' }, { name: 'Steel Grey', hex: '#71717a' }, { name: 'Black Cherry', hex: '#4a0e1b' }], packages: [{ name: 'Comfort', price: 0 }, { name: 'Premium', price: 8500000 }, { name: 'GT-Line', price: 14200000 }] },
25
- { name: 'Seltos', price: 109900000, type: 'ICE', hp: 160, kmpl: 14.5, colors: [{ name: 'Gravity Grey', hex: '#52525b' }, { name: 'Orange Fusion', hex: '#ea580c' }, { name: 'White Pearl', hex: '#f5f5f4' }], packages: [{ name: 'Zenith', price: 0 }, { name: 'Premium', price: 6200000 }] },
26
- { name: 'EV6 GT', price: 289900000, type: 'EV', hp: 585, kmpl: 0, colors: [{ name: 'Moonscape', hex: '#a8a29e' }, { name: 'Yacht Blue', hex: '#1e40af' }, { name: 'Snow White', hex: '#f1f0eb' }], packages: [{ name: 'Wind', price: 0 }, { name: 'GT-Line', price: 12000000 }, { name: 'GT', price: 28000000 }] },
27
- { name: 'Picanto', price: 59900000, type: 'ICE', hp: 84, kmpl: 19.8, colors: [{ name: 'Signal Red', hex: '#dc2626' }, { name: 'Lime Green', hex: '#65a30d' }, { name: 'Alice Blue', hex: '#60a5fa' }], packages: [{ name: 'Emotion', price: 0 }, { name: 'Emotion+', price: 3500000 }] },
28
- { name: 'EV9', price: 359900000, type: 'EV', hp: 384, kmpl: 0, colors: [{ name: 'Ocean Blue', hex: '#1d4ed8' }, { name: 'Pebble Grey', hex: '#a1a1aa' }, { name: 'Aurora Black', hex: '#18181b' }], packages: [{ name: 'Earth', price: 0 }, { name: 'GT-Line', price: 18000000 }] },
29
- ];
30
-
31
- const fmtPrice = (n: number) => `$${(n / 1000000).toFixed(0)}M`;
32
-
33
- const SLOTS = ['9:00 AM', '10:30 AM', '12:00 PM', '2:00 PM', '3:30 PM', '5:00 PM'];
34
-
35
- export const KiaShowroomNode = (props: any) => {
36
- const [tab, setTab] = useState<'config' | 'compare' | 'agenda'>('config');
37
- const [selected, setSelected] = useState(0);
38
- const [colorIdx, setColorIdx] = useState(0);
39
- const [pkgIdx, setPkgIdx] = useState(0);
40
- const [compareIdx, setCompareIdx] = useState(2);
41
-
42
- const model = MODELS[selected];
43
- const totalPrice = model.price + model.packages[pkgIdx].price;
44
-
45
- return (
46
- <BaseNode {...props} title="Kia Showroom Digital" width={500} height={620}>
47
- <div className="flex flex-col h-full bg-slate-950 text-white overflow-hidden">
48
-
49
- {/* Header */}
50
- <div className="flex items-center gap-3 p-3 bg-slate-900 border-b border-slate-800">
51
- <div className="w-9 h-9 rounded-full bg-indigo-600/20 flex items-center justify-center border border-indigo-500/30">
52
- <Car size={16} className="text-indigo-400" />
53
- </div>
54
- <div className="flex-1">
55
- <div className="text-xs font-bold tracking-wide">SHOWROOM DIGITAL</div>
56
- <div className="text-[10px] text-slate-400">Grecco Motors · {MODELS.length} modelos · Configurador 360°</div>
57
- </div>
58
- </div>
59
-
60
- {/* Tabs */}
61
- <div className="flex gap-1 p-2 bg-slate-900/50 border-b border-slate-800">
62
- {([
63
- { key: 'config' as const, label: '🎨 Configurador' },
64
- { key: 'compare' as const, label: '⚖️ Comparar' },
65
- { key: 'agenda' as const, label: '📅 Test Drive' },
66
- ]).map(t => (
67
- <button key={t.key} onClick={() => setTab(t.key)}
68
- className={`flex-1 py-1.5 rounded text-[9px] font-bold transition-all ${tab === t.key ? 'bg-indigo-600/20 text-indigo-400 border border-indigo-500/30' : 'text-slate-500'
69
- }`}>
70
- {t.label}
71
- </button>
72
- ))}
73
- </div>
74
-
75
- {/* Content */}
76
- <div className="flex-1 overflow-y-auto p-3 space-y-2">
77
-
78
- {tab === 'config' && (
79
- <>
80
- {/* Model selector */}
81
- <div className="flex gap-1 flex-wrap">
82
- {MODELS.map((m, i) => (
83
- <button key={m.name} onClick={() => { setSelected(i); setColorIdx(0); setPkgIdx(0); }}
84
- className={`px-2 py-1 rounded text-[9px] font-bold transition-all ${i === selected ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-500'
85
- }`}>{m.name}</button>
86
- ))}
87
- </div>
88
-
89
- {/* Color preview */}
90
- <div className="bg-slate-900/50 rounded-lg p-3 border border-slate-800">
91
- <div className="h-24 rounded-lg flex items-center justify-center mb-2"
92
- style={{ background: `linear-gradient(135deg, ${model.colors[colorIdx].hex}44 0%, ${model.colors[colorIdx].hex}22 100%)`, border: `1px solid ${model.colors[colorIdx].hex}44` }}>
93
- <Car size={48} style={{ color: model.colors[colorIdx].hex }} />
94
- </div>
95
- <div className="flex gap-2 justify-center">
96
- {model.colors.map((c, i) => (
97
- <button key={c.name} onClick={() => setColorIdx(i)}
98
- className={`w-6 h-6 rounded-full border-2 transition-all ${i === colorIdx ? 'border-white scale-110' : 'border-slate-700'}`}
99
- style={{ background: c.hex }} title={c.name} />
100
- ))}
101
- </div>
102
- <div className="text-[9px] text-center text-slate-400 mt-1">{model.colors[colorIdx].name}</div>
103
- </div>
104
-
105
- {/* Specs */}
106
- <div className="flex gap-2">
107
- <div className="flex-1 bg-slate-900/50 rounded p-2 border border-slate-800 text-center">
108
- <div className="text-sm font-bold text-blue-400">{model.hp} HP</div>
109
- <div className="text-[8px] text-slate-500">Potencia</div>
110
- </div>
111
- <div className="flex-1 bg-slate-900/50 rounded p-2 border border-slate-800 text-center">
112
- <div className="text-sm font-bold text-green-400">{model.type === 'EV' ? '500+ km' : `${model.kmpl} km/l`}</div>
113
- <div className="text-[8px] text-slate-500">{model.type === 'EV' ? 'Autonomía' : 'Rendimiento'}</div>
114
- </div>
115
- <div className="flex-1 bg-slate-900/50 rounded p-2 border border-slate-800 text-center">
116
- <div className={`text-sm font-bold ${model.type === 'EV' ? 'text-green-400' : model.type === 'HEV' ? 'text-cyan-400' : 'text-slate-400'}`}>{model.type}</div>
117
- <div className="text-[8px] text-slate-500">Motor</div>
118
- </div>
119
- </div>
120
-
121
- {/* Package */}
122
- <div className="bg-slate-900/50 rounded-lg p-2 border border-slate-800">
123
- <div className="text-[9px] text-slate-500 font-bold uppercase mb-1">Paquete</div>
124
- <div className="flex gap-1">
125
- {model.packages.map((p, i) => (
126
- <button key={p.name} onClick={() => setPkgIdx(i)}
127
- className={`flex-1 py-1.5 rounded text-[9px] font-bold ${i === pkgIdx ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-500'
128
- }`}>{p.name} {p.price > 0 ? `+${fmtPrice(p.price)}` : ''}</button>
129
- ))}
130
- </div>
131
- </div>
132
-
133
- {/* Total */}
134
- <div className="bg-indigo-500/10 rounded-lg p-3 border border-indigo-500/20 text-center">
135
- <div className="text-[9px] text-slate-400">PRECIO TOTAL</div>
136
- <div className="text-xl font-black text-indigo-400">{fmtPrice(totalPrice)}</div>
137
- <div className="text-[9px] text-slate-500">{model.name} · {model.colors[colorIdx].name} · {model.packages[pkgIdx].name}</div>
138
- </div>
139
- </>
140
- )}
141
-
142
- {tab === 'compare' && (
143
- <>
144
- <div className="flex gap-1 mb-2">
145
- {MODELS.map((m, i) => i !== selected && (
146
- <button key={m.name} onClick={() => setCompareIdx(i)}
147
- className={`px-2 py-1 rounded text-[9px] font-bold ${i === compareIdx ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-500'}`}>{m.name}</button>
148
- ))}
149
- </div>
150
- <div className="bg-slate-900/50 rounded-lg border border-slate-800 overflow-hidden">
151
- <div className="grid grid-cols-3 text-[9px] font-bold border-b border-slate-800 bg-slate-800/50">
152
- <div className="p-2 text-slate-400">Spec</div>
153
- <div className="p-2 text-indigo-400 text-center">{model.name}</div>
154
- <div className="p-2 text-purple-400 text-center">{MODELS[compareIdx].name}</div>
155
- </div>
156
- {[
157
- { label: 'Precio', a: fmtPrice(model.price), b: fmtPrice(MODELS[compareIdx].price) },
158
- { label: 'Motor', a: model.type, b: MODELS[compareIdx].type },
159
- { label: 'Potencia', a: `${model.hp} HP`, b: `${MODELS[compareIdx].hp} HP` },
160
- { label: 'Rendimiento', a: model.type === 'EV' ? '500+ km' : `${model.kmpl} km/l`, b: MODELS[compareIdx].type === 'EV' ? '500+ km' : `${MODELS[compareIdx].kmpl} km/l` },
161
- { label: 'Colores', a: model.colors.length.toString(), b: MODELS[compareIdx].colors.length.toString() },
162
- { label: 'Paquetes', a: model.packages.length.toString(), b: MODELS[compareIdx].packages.length.toString() },
163
- ].map(r => (
164
- <div key={r.label} className="grid grid-cols-3 text-[9px] border-b border-slate-800/50">
165
- <div className="p-1.5 text-slate-500">{r.label}</div>
166
- <div className="p-1.5 text-center font-semibold">{r.a}</div>
167
- <div className="p-1.5 text-center font-semibold">{r.b}</div>
168
- </div>
169
- ))}
170
- </div>
171
- </>
172
- )}
173
-
174
- {tab === 'agenda' && (
175
- <>
176
- <div className="text-[9px] text-slate-500 font-bold uppercase mb-1">📅 Agendar Test Drive — {model.name}</div>
177
- <div className="grid grid-cols-3 gap-1.5">
178
- {SLOTS.map(s => (
179
- <button key={s} className="bg-slate-900/50 border border-slate-800 rounded-lg p-2 text-center hover:bg-indigo-600/20 hover:border-indigo-500/30 transition-all">
180
- <div className="text-[10px] font-bold">{s}</div>
181
- <div className="text-[8px] text-green-400">Disponible</div>
182
- </button>
183
- ))}
184
- </div>
185
- <div className="bg-green-500/10 rounded-lg p-2.5 border border-green-500/20 text-[9px] text-green-400">
186
- ✅ Selecciona un slot y se enviará confirmación por WhatsApp al cliente.
187
- </div>
188
- </>
189
- )}
190
- </div>
191
- </div>
192
- </BaseNode>
193
- );
194
- };
@@ -1,215 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- ShoppingCart, Search, Star, Heart, Package, Truck,
5
- Plus, Minus, X, Sparkles, Tag, TrendingUp, BarChart3, Eye
6
- } from 'lucide-react';
7
-
8
- /* ═══════════════════════════════════════════════════════════════
9
- KIA STORE NODE — Accessories Store · Grecco Motors
10
- E-Commerce con recomendaciones IA y analytics de revenue
11
- ═══════════════════════════════════════════════════════════════ */
12
-
13
- const PRODUCTS = [
14
- { id: 1, name: 'Tapetes Originales Sportage', price: 280000, rating: 4.8, reviews: 142, category: 'Interior', image: '🏎️', badge: 'Más vendido', stock: 23 },
15
- { id: 2, name: 'Cámara de Reversa HD 4K', price: 450000, rating: 4.6, reviews: 89, category: 'Tecnología', image: '📷', badge: null, stock: 8 },
16
- { id: 3, name: 'Barras de Techo Seltos', price: 670000, rating: 4.9, reviews: 56, category: 'Exterior', image: '🔩', badge: 'Premium', stock: 12 },
17
- { id: 4, name: 'Kit Stickers Deportivos GT', price: 150000, rating: 4.3, reviews: 210, category: 'Exterior', image: '🎨', badge: null, stock: 45 },
18
- { id: 5, name: 'Cargador Inalámbrico QI 15W', price: 320000, rating: 4.7, reviews: 74, category: 'Tecnología', image: '🔋', badge: 'Nuevo', stock: 18 },
19
- { id: 6, name: 'Protector de Baúl EV6', price: 190000, rating: 4.5, reviews: 38, category: 'Interior', image: '🧳', badge: null, stock: 31 },
20
- { id: 7, name: 'Polarizado Nano-Cerámico 3M', price: 850000, rating: 4.9, reviews: 167, category: 'Servicio', image: '🪟', badge: 'Top Rated', stock: 99 },
21
- { id: 8, name: 'Dash Cam Inteligente IA', price: 520000, rating: 4.4, reviews: 43, category: 'Tecnología', image: '📹', badge: 'Nuevo', stock: 15 },
22
- ];
23
-
24
- const AI_RECOMMENDATIONS = [
25
- { text: 'Combo Sportage: Tapetes + Protector Baúl con 15% OFF', related: [1, 6], savings: '$70.500' },
26
- { text: 'Kit Tech: Cámara 4K + Cargador QI + Dash Cam = 12% OFF', related: [2, 5, 8], savings: '$154.800' },
27
- { text: 'Ideal para tu EV6: Barras de Techo + Kit GT', related: [3, 4], savings: '$82.000' },
28
- ];
29
-
30
- const jitter = (n: number, r: number) => n + Math.round((Math.random() - 0.5) * r);
31
-
32
- export const KiaStoreNode = (props: any) => {
33
- const [cart, setCart] = useState<Record<number, number>>({});
34
- const [search, setSearch] = useState('');
35
- const [favorites, setFavorites] = useState<Set<number>>(new Set([1, 3, 7]));
36
- const [showCart, setShowCart] = useState(false);
37
- const [showAI, setShowAI] = useState(false);
38
- const [monthRevenue] = useState(47800000);
39
- const [todayOrders] = useState(12);
40
-
41
- const cartCount = Object.values(cart).reduce((a, b) => a + b, 0);
42
- const cartTotal = Object.entries(cart).reduce((acc, [id, qty]) => {
43
- const product = PRODUCTS.find(p => p.id === Number(id));
44
- return acc + (product ? product.price * qty : 0);
45
- }, 0);
46
-
47
- const addToCart = (id: number) => setCart(prev => ({ ...prev, [id]: (prev[id] || 0) + 1 }));
48
- const removeFromCart = (id: number) => setCart(prev => {
49
- const next = { ...prev };
50
- if (next[id] > 1) next[id]--;
51
- else delete next[id];
52
- return next;
53
- });
54
- const toggleFav = (id: number) => setFavorites(prev => {
55
- const next = new Set(prev);
56
- next.has(id) ? next.delete(id) : next.add(id);
57
- return next;
58
- });
59
-
60
- const filtered = PRODUCTS.filter(p =>
61
- p.name.toLowerCase().includes(search.toLowerCase()) ||
62
- p.category.toLowerCase().includes(search.toLowerCase())
63
- );
64
-
65
- const formatCOP = (n: number) => `$${n.toLocaleString('es-CO')}`;
66
-
67
- return (
68
- <BaseNode {...props} title="Kia Accessories Store" width={480} height={660}>
69
- <div className="flex flex-col h-full bg-slate-950 text-white overflow-hidden">
70
-
71
- {/* Header */}
72
- <div className="flex items-center gap-3 p-3 bg-slate-900 border-b border-slate-800">
73
- <div className="w-9 h-9 rounded-full bg-red-600/20 flex items-center justify-center border border-red-500/30">
74
- <span className="text-red-500 font-bold text-[7px] tracking-widest">KIA</span>
75
- </div>
76
- <div className="flex-1">
77
- <div className="text-xs font-bold tracking-wide">ACCESSORIES STORE</div>
78
- <div className="text-[10px] text-slate-400">Grecco Motors · {PRODUCTS.length} productos</div>
79
- </div>
80
- <button
81
- onClick={() => { setShowAI(!showAI); setShowCart(false); }}
82
- className={`p-1.5 rounded-lg border transition-all ${showAI ? 'bg-violet-500/20 border-violet-500/40 text-violet-400' : 'bg-slate-800 border-slate-700 text-slate-400'}`}
83
- >
84
- <Sparkles size={14} />
85
- </button>
86
- <button
87
- onClick={() => { setShowCart(!showCart); setShowAI(false); }}
88
- className="relative p-1.5 rounded-lg bg-slate-800 border border-slate-700 text-slate-400 hover:text-white transition-all"
89
- >
90
- <ShoppingCart size={14} />
91
- {cartCount > 0 && (
92
- <span className="absolute -top-1 -right-1 w-4 h-4 bg-red-500 rounded-full text-[8px] font-bold flex items-center justify-center">{cartCount}</span>
93
- )}
94
- </button>
95
- </div>
96
-
97
- {/* Revenue Mini Stats */}
98
- <div className="flex items-center justify-between px-3 py-1.5 bg-slate-900/50 border-b border-slate-800 text-[10px]">
99
- <span className="text-slate-500">Revenue Mes: <span className="text-green-400 font-bold">{formatCOP(monthRevenue)}</span></span>
100
- <span className="text-slate-500">Pedidos Hoy: <span className="text-blue-400 font-bold">{todayOrders}</span></span>
101
- <span className="text-slate-500">Ticket Prom: <span className="text-purple-400 font-bold">{formatCOP(Math.round(monthRevenue / 128))}</span></span>
102
- </div>
103
-
104
- {/* Search */}
105
- <div className="p-2 border-b border-slate-800">
106
- <div className="relative">
107
- <Search size={12} className="absolute left-2.5 top-2.5 text-slate-500" />
108
- <input
109
- type="text" placeholder="Buscar accesorios..."
110
- value={search} onChange={e => setSearch(e.target.value)}
111
- className="w-full bg-slate-900 border border-slate-800 rounded-lg py-2 pl-8 pr-3 text-xs text-white focus:outline-none focus:border-red-500/50 transition-colors"
112
- />
113
- </div>
114
- </div>
115
-
116
- {/* AI Recommendations */}
117
- {showAI && (
118
- <div className="p-2 border-b border-slate-800 bg-violet-500/5">
119
- <div className="text-[9px] text-violet-400 font-bold uppercase mb-1.5 flex items-center gap-1"><Sparkles size={10} /> Combos IA — Ahorra más</div>
120
- <div className="space-y-1.5">
121
- {AI_RECOMMENDATIONS.map((r, i) => (
122
- <div key={i} className="bg-slate-900 border border-violet-500/20 rounded-lg p-2">
123
- <div className="text-[10px] text-slate-300 mb-1">{r.text}</div>
124
- <div className="flex items-center justify-between">
125
- <div className="flex gap-1">
126
- {r.related.map(id => (
127
- <button key={id} onClick={() => addToCart(id)} className="bg-violet-500/20 hover:bg-violet-500/30 text-violet-300 px-1.5 py-0.5 rounded text-[8px] transition-colors">
128
- + {PRODUCTS.find(p => p.id === id)?.name.split(' ').slice(0, 2).join(' ')}
129
- </button>
130
- ))}
131
- </div>
132
- <span className="text-[9px] text-green-400 font-bold">Ahorra {r.savings}</span>
133
- </div>
134
- </div>
135
- ))}
136
- </div>
137
- </div>
138
- )}
139
-
140
- {/* Cart Drawer */}
141
- {showCart && (
142
- <div className="p-2 border-b border-slate-800 bg-red-500/5">
143
- <div className="text-[9px] text-red-400 font-bold uppercase mb-1.5 flex items-center gap-1"><ShoppingCart size={10} /> Carrito ({cartCount})</div>
144
- {Object.keys(cart).length === 0 ? (
145
- <div className="text-[10px] text-slate-500 text-center py-3">Tu carrito está vacío</div>
146
- ) : (
147
- <>
148
- {Object.entries(cart).map(([id, qty]) => {
149
- const product = PRODUCTS.find(p => p.id === Number(id))!;
150
- return (
151
- <div key={id} className="flex items-center gap-2 py-1 text-[10px]">
152
- <span className="text-sm">{product.image}</span>
153
- <div className="flex-1 min-w-0 truncate text-slate-300">{product.name}</div>
154
- <div className="flex items-center gap-1">
155
- <button onClick={() => removeFromCart(Number(id))} className="p-0.5 bg-slate-800 rounded"><Minus size={8} /></button>
156
- <span className="w-4 text-center font-bold">{qty}</span>
157
- <button onClick={() => addToCart(Number(id))} className="p-0.5 bg-slate-800 rounded"><Plus size={8} /></button>
158
- </div>
159
- <span className="font-bold text-white">{formatCOP(product.price * qty)}</span>
160
- </div>
161
- );
162
- })}
163
- <div className="flex justify-between items-center pt-2 mt-1 border-t border-slate-800">
164
- <span className="text-xs font-bold">Total</span>
165
- <span className="text-sm font-bold text-red-400">{formatCOP(cartTotal)}</span>
166
- </div>
167
- <button className="w-full mt-2 bg-red-600 hover:bg-red-500 text-white text-xs font-bold py-2 rounded-lg flex items-center justify-center gap-2 transition-all">
168
- <Truck size={12} /> Agendar Instalación
169
- </button>
170
- </>
171
- )}
172
- </div>
173
- )}
174
-
175
- {/* Product Grid */}
176
- <div className="flex-1 overflow-y-auto p-2">
177
- <div className="grid grid-cols-2 gap-2">
178
- {filtered.map(p => (
179
- <div key={p.id} className="bg-slate-900 rounded-xl border border-slate-800 overflow-hidden hover:border-slate-700 transition-all group">
180
- <div className="relative h-16 bg-slate-800/50 flex items-center justify-center">
181
- <span className="text-3xl group-hover:scale-110 transition-transform">{p.image}</span>
182
- <button onClick={() => toggleFav(p.id)} className="absolute top-1.5 right-1.5">
183
- <Heart size={12} className={favorites.has(p.id) ? 'fill-red-500 text-red-500' : 'text-slate-500'} />
184
- </button>
185
- {p.badge && (
186
- <span className={`absolute top-1.5 left-1.5 text-[7px] font-bold px-1.5 py-0.5 rounded ${p.badge === 'Más vendido' ? 'bg-green-500' : p.badge === 'Premium' ? 'bg-blue-500' : p.badge === 'Top Rated' ? 'bg-yellow-500 text-black' : 'bg-red-500'}`}>
187
- {p.badge}
188
- </span>
189
- )}
190
- </div>
191
- <div className="p-2">
192
- <div className="text-[10px] font-semibold leading-tight mb-0.5">{p.name}</div>
193
- <div className="flex items-center gap-1 text-[9px] mb-1">
194
- <Star size={8} className="text-yellow-400 fill-yellow-400" />
195
- <span className="text-slate-400">{p.rating} ({p.reviews})</span>
196
- <span className="text-slate-600">·</span>
197
- <span className={`${p.stock < 10 ? 'text-red-400' : 'text-slate-500'}`}>
198
- {p.stock < 10 ? `¡${p.stock} left!` : `${p.stock} disp`}
199
- </span>
200
- </div>
201
- <div className="flex items-center justify-between">
202
- <span className="text-xs font-bold text-white">{formatCOP(p.price)}</span>
203
- <button onClick={() => addToCart(p.id)} className="p-1 bg-red-600 hover:bg-red-500 rounded text-white transition-colors">
204
- <Plus size={10} />
205
- </button>
206
- </div>
207
- </div>
208
- </div>
209
- ))}
210
- </div>
211
- </div>
212
- </div>
213
- </BaseNode>
214
- );
215
- };
@@ -1,173 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BaseNode } from '@decido/macia-core';
3
- import {
4
- Leaf, Zap, Droplets, Sun, TrendingUp,
5
- BarChart3, Award, Battery, Car, Factory
6
- } from 'lucide-react';
7
-
8
- /* ═══════════════════════════════════════════════════════════════
9
- KIA SUSTAINABILITY NODE — ESG & Green Dealer · Grecco Motors
10
- Huella CO₂, mix EV/ICE, ESG indicators, Green Dealer Score
11
- ═══════════════════════════════════════════════════════════════ */
12
-
13
- const CARBON = [
14
- { source: 'Showroom (electricidad)', co2: 12.4, unit: 'ton/mes', trend: -8, color: '#f59e0b' },
15
- { source: 'Taller (operación)', co2: 8.2, unit: 'ton/mes', trend: -5, color: '#ef4444' },
16
- { source: 'Flota Demo (combustible)', co2: 3.1, unit: 'ton/mes', trend: -22, color: '#3b82f6' },
17
- { source: 'V2G Grid Return', co2: -4.6, unit: 'ton/mes', trend: 15, color: '#22c55e' },
18
- { source: 'Paneles Solares', co2: -2.8, unit: 'ton/mes', trend: 12, color: '#10b981' },
19
- ];
20
-
21
- const EV_MIX = [
22
- { month: 'Sep', ev: 8, hev: 15, ice: 77 },
23
- { month: 'Oct', ev: 10, hev: 16, ice: 74 },
24
- { month: 'Nov', ev: 12, hev: 18, ice: 70 },
25
- { month: 'Dic', ev: 14, hev: 19, ice: 67 },
26
- { month: 'Ene', ev: 16, hev: 20, ice: 64 },
27
- { month: 'Feb', ev: 18, hev: 22, ice: 60 },
28
- ];
29
-
30
- const ESG_INDICATORS = [
31
- { category: '🌱 Ambiental', score: 82, items: ['Huella de carbono ↓18%', 'EV ratio 18%', 'Reciclaje 92%'] },
32
- { category: '👥 Social', score: 88, items: ['NPS 95.3', 'Capacitación 100%', 'Equity hiring ✓'] },
33
- { category: '🏛️ Gobernanza', score: 91, items: ['Compliance 98%', 'Auditoría Q4 ✓', 'Anti-corruption ✓'] },
34
- ];
35
-
36
- export const KiaSustainabilityNode = (props: any) => {
37
- const [tab, setTab] = useState<'carbon' | 'ev' | 'esg'>('carbon');
38
- const [carbon, setCarbon] = useState(CARBON.map(c => ({ ...c })));
39
-
40
- const netCarbon = carbon.reduce((s, c) => s + c.co2, 0).toFixed(1);
41
- const currentEV = EV_MIX[EV_MIX.length - 1];
42
- const greenScore = Math.round(ESG_INDICATORS.reduce((s, e) => s + e.score, 0) / ESG_INDICATORS.length);
43
-
44
- useEffect(() => {
45
- const interval = setInterval(() => {
46
- setCarbon(prev => prev.map(c => ({
47
- ...c,
48
- co2: parseFloat((c.co2 + (Math.random() - 0.52) * 0.2).toFixed(1)),
49
- })));
50
- }, 6000);
51
- return () => clearInterval(interval);
52
- }, []);
53
-
54
- return (
55
- <BaseNode {...props} title="Kia Sustainability" width={480} height={620}>
56
- <div className="flex flex-col h-full bg-[#040a06] text-white overflow-hidden">
57
-
58
- {/* Header */}
59
- <div className="flex items-center gap-3 p-3 bg-[#0a1a0e] border-b border-green-900/30">
60
- <div className="w-9 h-9 rounded-full bg-green-600/20 flex items-center justify-center border border-green-500/30">
61
- <Leaf size={16} className="text-green-400" />
62
- </div>
63
- <div className="flex-1">
64
- <div className="text-xs font-bold tracking-wide flex items-center gap-2">
65
- SUSTAINABILITY & ESG
66
- <span className="text-[8px] px-1.5 py-0.5 bg-green-500/20 text-green-400 rounded">{greenScore} GREEN SCORE</span>
67
- </div>
68
- <div className="text-[10px] text-slate-400">Grecco Motors · Net CO₂: {netCarbon} ton/mes · EV Mix {currentEV.ev}%</div>
69
- </div>
70
- </div>
71
-
72
- {/* Tabs */}
73
- <div className="flex gap-1 p-2 bg-[#060e08] border-b border-green-900/20">
74
- {([
75
- { key: 'carbon' as const, label: '🌍 Carbono' },
76
- { key: 'ev' as const, label: '⚡ EV Mix' },
77
- { key: 'esg' as const, label: '📊 ESG' },
78
- ]).map(t => (
79
- <button key={t.key} onClick={() => setTab(t.key)}
80
- className={`flex-1 py-1.5 rounded text-[9px] font-bold transition-all ${tab === t.key ? 'bg-green-600/20 text-green-400 border border-green-500/30' : 'text-slate-500'
81
- }`}>
82
- {t.label}
83
- </button>
84
- ))}
85
- </div>
86
-
87
- <div className="flex-1 overflow-y-auto p-3 space-y-2">
88
-
89
- {tab === 'carbon' && (
90
- <>
91
- <div className="bg-green-500/5 rounded-lg p-3 border border-green-500/20 text-center">
92
- <div className="text-[9px] text-slate-400 uppercase">Huella Neta Mensual</div>
93
- <div className={`text-2xl font-black ${parseFloat(netCarbon) > 0 ? 'text-yellow-400' : 'text-green-400'}`}>{netCarbon} ton CO₂</div>
94
- <div className="text-[9px] text-green-400">↓ 18% vs año anterior</div>
95
- </div>
96
- {carbon.map(c => (
97
- <div key={c.source} className="bg-slate-900/50 rounded-lg p-2.5 border border-slate-800"
98
- style={{ borderLeftWidth: '2px', borderLeftColor: c.color }}>
99
- <div className="flex items-center justify-between">
100
- <span className="text-[10px] font-semibold">{c.source}</span>
101
- <div className="flex items-center gap-2">
102
- <span className={`text-[8px] font-bold ${c.trend < 0 ? 'text-green-400' : 'text-red-400'}`}>
103
- {c.trend > 0 ? '↑' : '↓'}{Math.abs(c.trend)}%
104
- </span>
105
- <span className={`text-sm font-bold ${c.co2 < 0 ? 'text-green-400' : 'text-yellow-400'}`}>{c.co2}</span>
106
- </div>
107
- </div>
108
- </div>
109
- ))}
110
- </>
111
- )}
112
-
113
- {tab === 'ev' && (
114
- <>
115
- <div className="text-[9px] text-slate-500 font-bold uppercase mb-1">Mix Ventas EV / HEV / ICE — 6 meses</div>
116
- {EV_MIX.map(m => (
117
- <div key={m.month} className="bg-slate-900/50 rounded-lg p-2 border border-slate-800">
118
- <div className="text-[9px] text-slate-400 font-bold mb-1">{m.month}</div>
119
- <div className="flex h-3 rounded-full overflow-hidden">
120
- <div className="bg-green-500 transition-all" style={{ width: `${m.ev}%` }} title={`EV ${m.ev}%`} />
121
- <div className="bg-cyan-500 transition-all" style={{ width: `${m.hev}%` }} title={`HEV ${m.hev}%`} />
122
- <div className="bg-slate-700 transition-all" style={{ width: `${m.ice}%` }} title={`ICE ${m.ice}%`} />
123
- </div>
124
- <div className="flex justify-between text-[8px] text-slate-500 mt-0.5">
125
- <span className="text-green-400">EV {m.ev}%</span>
126
- <span className="text-cyan-400">HEV {m.hev}%</span>
127
- <span className="text-slate-500">ICE {m.ice}%</span>
128
- </div>
129
- </div>
130
- ))}
131
- <div className="bg-green-500/5 rounded-lg p-2.5 border border-green-500/20 text-[9px] text-green-400">
132
- 🎯 Meta KIA 2027: EV 35% · Actual: {currentEV.ev}% · Progreso: {((currentEV.ev / 35) * 100).toFixed(0)}%
133
- </div>
134
- </>
135
- )}
136
-
137
- {tab === 'esg' && (
138
- <>
139
- <div className="bg-green-500/5 rounded-lg p-3 border border-green-500/20 flex items-center justify-between">
140
- <div>
141
- <div className="text-[9px] text-slate-400">GREEN DEALER SCORE</div>
142
- <div className="text-2xl font-black text-green-400">{greenScore}</div>
143
- </div>
144
- <Award size={32} className="text-green-500/30" />
145
- </div>
146
- {ESG_INDICATORS.map(e => (
147
- <div key={e.category} className="bg-slate-900/50 rounded-lg p-3 border border-slate-800">
148
- <div className="flex items-center justify-between mb-1.5">
149
- <span className="text-[11px] font-bold">{e.category}</span>
150
- <span className="text-sm font-bold text-green-400">{e.score}/100</span>
151
- </div>
152
- <div className="flex items-center gap-2 mb-2">
153
- <div className="flex-1 h-2 bg-slate-800 rounded-full">
154
- <div className="h-full rounded-full bg-linear-to-r from-green-600 to-emerald-400"
155
- style={{ width: `${e.score}%` }} />
156
- </div>
157
- </div>
158
- <div className="space-y-0.5">
159
- {e.items.map(item => (
160
- <div key={item} className="text-[8px] text-slate-400 flex items-center gap-1">
161
- <span className="text-green-400">✓</span> {item}
162
- </div>
163
- ))}
164
- </div>
165
- </div>
166
- ))}
167
- </>
168
- )}
169
- </div>
170
- </div>
171
- </BaseNode>
172
- );
173
- };