File size: 3,162 Bytes
5a81b95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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;