widgettdc-api / apps /widget-board /widgets /IntegrationExample.tsx
Kraft102's picture
fix: esbuild Docker build + email:new EventType for HuggingFace deployment
6f8b03d
/**
* 🚀 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;