Spaces:
Paused
Paused
| /** | |
| * 🚀 QUICK START INTEGRATION EXAMPLE | |
| * Sådan integrerer du Neural Ascension + Data & Indsigter widgets | |
| */ | |
| import React, { useState } from 'react'; | |
| import { Rocket, Database, Menu, X } from 'lucide-react'; | |
| // Import Neural Ascension Widgets | |
| import { | |
| MasterControl, | |
| SEGA, | |
| THG, | |
| SCE, | |
| NSQI, | |
| PTAM, | |
| CDMM, | |
| APD, | |
| MSH, | |
| QEK, | |
| CCA, | |
| NeuralAscensionWidgets | |
| } from './widgets/NeuralAscension'; | |
| // Import Data & Indsigter | |
| import DataInsightsHub from './widgets/DataInsightsHub'; | |
| // Widget Registry - Kombiner alle widgets | |
| export const COMPLETE_WIDGET_REGISTRY = [ | |
| ...NeuralAscensionWidgets, | |
| { | |
| id: 'DataInsightsHub', | |
| name: 'Data & Indsigter Central', | |
| category: 'data', | |
| path: './widgets/DataInsightsHub', | |
| icon: 'Database', | |
| defaultSize: { w: 12, h: 6 }, | |
| description: 'Omfattende adgang til alle data, arkiver og biblioteker' | |
| } | |
| ]; | |
| // Menu Struktur | |
| export const MENU_CATEGORIES = [ | |
| { | |
| id: 'neural-ascension', | |
| name: 'Neural Ascension', | |
| icon: Rocket, | |
| description: '10 Transformation Points - Cosmic Cognitive Singularity', | |
| widgets: NeuralAscensionWidgets | |
| }, | |
| { | |
| id: 'data-insights', | |
| name: 'Data & Indsigter', | |
| icon: Database, | |
| description: 'Omfattende data management og AI-powered insights', | |
| widgets: [COMPLETE_WIDGET_REGISTRY.find(w => w.id === 'DataInsightsHub')] | |
| } | |
| ]; | |
| // Widget Component Map | |
| export const WIDGET_COMPONENTS = { | |
| // Neural Ascension | |
| MasterControl, | |
| SEGA, | |
| THG, | |
| SCE, | |
| NSQI, | |
| PTAM, | |
| CDMM, | |
| APD, | |
| MSH, | |
| QEK, | |
| CCA, | |
| // Data & Indsigter | |
| DataInsightsHub | |
| }; | |
| // Example Implementation: Widget Selector Modal | |
| export function WidgetSelectorModal({ isOpen, onClose, onSelectWidget }) { | |
| const [selectedCategory, setSelectedCategory] = useState('neural-ascension'); | |
| if (!isOpen) return null; | |
| const currentCategory = MENU_CATEGORIES.find(c => c.id === selectedCategory); | |
| return ( | |
| <div className="fixed inset-0 bg-black/80 flex items-center justify-center z-50"> | |
| <div className="bg-gray-900 rounded-lg w-[90vw] max-w-6xl h-[80vh] flex flex-col"> | |
| {/* Header */} | |
| <div className="p-6 border-b border-gray-700 flex items-center justify-between"> | |
| <h2 className="text-2xl font-bold text-white">Select Widget</h2> | |
| <button onClick={onClose} className="text-gray-400 hover:text-white"> | |
| <X /> | |
| </button> | |
| </div> | |
| <div className="flex flex-1 overflow-hidden"> | |
| {/* Sidebar - Categories */} | |
| <div className="w-64 bg-gray-800/50 p-4 overflow-y-auto"> | |
| <h3 className="text-sm font-semibold text-gray-400 mb-3">CATEGORIES</h3> | |
| {MENU_CATEGORIES.map(category => ( | |
| <button | |
| key={category.id} | |
| onClick={() => setSelectedCategory(category.id)} | |
| className={`w-full text-left p-3 rounded-lg mb-2 transition-all ${ | |
| selectedCategory === category.id | |
| ? 'bg-blue-600 text-white' | |
| : 'bg-gray-700/50 text-gray-300 hover:bg-gray-700' | |
| }`} | |
| > | |
| <div className="flex items-center gap-2 mb-1"> | |
| <category.icon className="w-4 h-4" /> | |
| <span className="font-semibold">{category.name}</span> | |
| </div> | |
| <p className="text-xs text-gray-400">{category.description}</p> | |
| </button> | |
| ))} | |
| </div> | |
| {/* Main Area - Widgets */} | |
| <div className="flex-1 p-6 overflow-y-auto"> | |
| <h3 className="text-xl font-bold text-white mb-4">{currentCategory?.name}</h3> | |
| <div className="grid grid-cols-3 gap-4"> | |
| {currentCategory?.widgets.map(widget => ( | |
| <button | |
| key={widget.id} | |
| onClick={() => { | |
| onSelectWidget(widget); | |
| onClose(); | |
| }} | |
| className="bg-gray-800 hover:bg-gray-700 p-4 rounded-lg border border-gray-700 hover:border-blue-500 transition-all text-left" | |
| > | |
| <h4 className="font-semibold text-white mb-2">{widget.name}</h4> | |
| <p className="text-sm text-gray-400">{widget.description}</p> | |
| <div className="mt-3 text-xs text-blue-400"> | |
| {widget.defaultSize.w}x{widget.defaultSize.h} grid | |
| </div> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| // Example Implementation: Widget Renderer | |
| export function WidgetRenderer({ widgetId, ...props }) { | |
| const WidgetComponent = WIDGET_COMPONENTS[widgetId]; | |
| if (!WidgetComponent) { | |
| return ( | |
| <div className="h-full bg-red-900/20 border border-red-500 rounded-lg p-4 flex items-center justify-center"> | |
| <p className="text-red-400">Widget '{widgetId}' not found</p> | |
| </div> | |
| ); | |
| } | |
| return <WidgetComponent {...props} />; | |
| } | |
| // Example Usage in App | |
| export function ExampleApp() { | |
| const [isModalOpen, setIsModalOpen] = useState(false); | |
| const [activeWidgets, setActiveWidgets] = useState([]); | |
| const handleSelectWidget = (widget) => { | |
| setActiveWidgets(prev => [...prev, { | |
| id: widget.id + '-' + Date.now(), | |
| widgetType: widget.id, | |
| ...widget.defaultSize | |
| }]); | |
| }; | |
| return ( | |
| <div className="h-screen bg-black text-white"> | |
| {/* Top Bar */} | |
| <div className="h-16 bg-gray-900 border-b border-gray-800 flex items-center px-6 justify-between"> | |
| <h1 className="text-xl font-bold">WidgeTDC Neural Platform</h1> | |
| <button | |
| onClick={() => setIsModalOpen(true)} | |
| className="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg flex items-center gap-2" | |
| > | |
| <Menu className="w-4 h-4" /> | |
| Add Widget | |
| </button> | |
| </div> | |
| {/* Widget Grid */} | |
| <div className="p-6 grid grid-cols-12 gap-4"> | |
| {activeWidgets.map(widget => ( | |
| <div | |
| key={widget.id} | |
| className={`col-span-${widget.w} row-span-${widget.h} h-96`} | |
| > | |
| <WidgetRenderer widgetId={widget.widgetType} /> | |
| </div> | |
| ))} | |
| </div> | |
| {/* Widget Selector Modal */} | |
| <WidgetSelectorModal | |
| isOpen={isModalOpen} | |
| onClose={() => setIsModalOpen(false)} | |
| onSelectWidget={handleSelectWidget} | |
| /> | |
| </div> | |
| ); | |
| } | |
| export default ExampleApp; | |