Kraft102's picture
fix: sql.js Docker/Alpine compatibility layer for PatternMemory and FailureMemory
5a81b95
import { ReactNode, useState } from 'react';
import { Database } from 'lucide-react';
import { cn } from '@/lib/utils';
import SourceLink, { DataSource } from './SourceLink';
import { DataSourceSelector, DataSourceConfig, DataSourceTrigger } from './DataSourceSelector';
import { Button } from '@/components/ui/button';
interface CyberCardProps {
children: ReactNode;
className?: string;
variant?: 'default' | 'bordered' | 'glowing';
header?: string;
source?: DataSource;
/** Enable data source switching */
configurable?: boolean;
/** Initial data source config */
dataSource?: DataSourceConfig;
/** Called when data source changes */
onDataSourceChange?: (source: DataSourceConfig) => void;
}
const CyberCard = ({
children,
className,
variant = 'default',
header,
source,
configurable = false,
dataSource,
onDataSourceChange
}: CyberCardProps) => {
const [selectedSource, setSelectedSource] = useState<DataSourceConfig | undefined>(dataSource);
const [selectorOpen, setSelectorOpen] = useState(false);
const handleSourceChange = (newSource: DataSourceConfig) => {
setSelectedSource(newSource);
onDataSourceChange?.(newSource);
};
return (
<div
className={cn(
"relative bg-card/80 backdrop-blur-sm overflow-hidden",
variant === 'bordered' && "cyber-border",
variant === 'glowing' && "box-glow border border-primary/30",
variant === 'default' && "border border-border/50",
className
)}
>
{header && (
<div className="flex items-center gap-2 px-4 py-2 border-b border-border/50 bg-secondary/50">
<div className="w-2 h-2 rounded-full bg-primary animate-pulse" />
<span className="font-display text-xs uppercase tracking-wider text-primary">
{header}
</span>
<div className="flex-1" />
{configurable && (
<>
<DataSourceTrigger
selectedSource={selectedSource}
onClick={() => setSelectorOpen(true)}
/>
<DataSourceSelector
selectedSource={selectedSource}
onSourceChange={handleSourceChange}
open={selectorOpen}
onOpenChange={setSelectorOpen}
/>
</>
)}
{source && <SourceLink source={source} variant="badge" />}
<span className="font-mono text-xs text-muted-foreground">
{new Date().toLocaleTimeString('da-DK', { hour: '2-digit', minute: '2-digit', second: '2-digit' })}
</span>
</div>
)}
<div className="p-4 sm:p-6">
{children}
</div>
{/* Corner accents */}
<div className="absolute top-0 left-0 w-4 h-4 border-l-2 border-t-2 border-primary/50" />
<div className="absolute top-0 right-0 w-4 h-4 border-r-2 border-t-2 border-primary/50" />
<div className="absolute bottom-0 left-0 w-4 h-4 border-l-2 border-b-2 border-primary/50" />
<div className="absolute bottom-0 right-0 w-4 h-4 border-r-2 border-b-2 border-primary/50" />
</div>
);
};
export default CyberCard;