mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 20:51:49 +00:00
init
This commit is contained in:
28
thirdeye/dashboard/app/intelligence/IntelFooter.tsx
Normal file
28
thirdeye/dashboard/app/intelligence/IntelFooter.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
const stats = [
|
||||
{ label: "Inference Latency", value: "14 MS" },
|
||||
{ label: "Neural Encryption", value: "THIRDEYE-X9" },
|
||||
{ label: "Active Connectors", value: "14 / 16" },
|
||||
];
|
||||
|
||||
export default function IntelFooter() {
|
||||
return (
|
||||
<footer
|
||||
className="mt-20 pt-8 flex flex-wrap justify-between items-center gap-8"
|
||||
style={{ borderTop: "1px solid rgba(167,139,250,0.1)" }}
|
||||
>
|
||||
<div className="flex items-center space-x-12">
|
||||
{stats.map((s) => (
|
||||
<div key={s.label}>
|
||||
<div className="text-[10px] font-mono-data uppercase tracking-widest mb-1" style={{ color: "rgba(249,245,248,0.4)" }}>
|
||||
{s.label}
|
||||
</div>
|
||||
<div className="text-lg font-bold text-white font-mono-data">{s.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-[10px] font-mono-data tracking-tighter" style={{ color: "rgba(167,139,250,0.6)" }}>
|
||||
© 2024 THIRDEYE_INTELLIGENCE // PRIVACY_FIRST_MONITORING
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
318
thirdeye/dashboard/app/intelligence/IntelligenceCards.tsx
Normal file
318
thirdeye/dashboard/app/intelligence/IntelligenceCards.tsx
Normal file
@@ -0,0 +1,318 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { fetchAllPatterns, fetchAllSignals, Pattern, Signal } from "../lib/api";
|
||||
|
||||
type CardMetric = {
|
||||
type: string;
|
||||
label: string;
|
||||
value: string;
|
||||
width?: string;
|
||||
valueDim?: boolean;
|
||||
};
|
||||
|
||||
type CardData = {
|
||||
icon: string;
|
||||
iconBg: string;
|
||||
iconBorder: string;
|
||||
iconColor: string;
|
||||
title: string;
|
||||
pulse?: boolean;
|
||||
time: string;
|
||||
description: string;
|
||||
metrics?: CardMetric[];
|
||||
recommendation?: string;
|
||||
footerLabel: string;
|
||||
footerIcon: string;
|
||||
footerDim: boolean;
|
||||
};
|
||||
|
||||
const STATIC_CARDS = [
|
||||
{
|
||||
icon: "subject",
|
||||
iconBg: "rgba(167,139,250,0.1)",
|
||||
iconBorder: "rgba(167,139,250,0.2)",
|
||||
iconColor: "#A78BFA",
|
||||
title: "SEMANTIC_PROCESSOR",
|
||||
},
|
||||
{
|
||||
icon: "mood",
|
||||
iconBg: "rgba(167,139,250,0.1)",
|
||||
iconBorder: "rgba(167,139,250,0.2)",
|
||||
iconColor: "#A78BFA",
|
||||
title: "SENTIMENT_MINER",
|
||||
},
|
||||
{
|
||||
icon: "schema",
|
||||
iconBg: "rgba(249,245,248,0.05)",
|
||||
iconBorder: "rgba(255,255,255,0.1)",
|
||||
iconColor: "rgba(249,245,248,0.4)",
|
||||
title: "PATTERN_DETECTOR",
|
||||
},
|
||||
];
|
||||
|
||||
export default function IntelligenceCards() {
|
||||
const [patterns, setPatterns] = useState<Pattern[]>([]);
|
||||
const [signals, setSignals] = useState<Signal[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
try {
|
||||
const [ptns, allGroups] = await Promise.all([
|
||||
fetchAllPatterns(),
|
||||
fetchAllSignals(),
|
||||
]);
|
||||
setPatterns(ptns);
|
||||
setSignals(allGroups.flatMap((g) => g.signals));
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
load();
|
||||
}, []);
|
||||
|
||||
const totalSignals = signals.length;
|
||||
const sentimentSignals = signals.filter(
|
||||
(s) =>
|
||||
s.metadata.type.includes("sentiment") ||
|
||||
s.metadata.sentiment !== "neutral"
|
||||
);
|
||||
const avgSentiment =
|
||||
sentimentSignals.length > 0
|
||||
? `${Math.round((sentimentSignals.length / Math.max(totalSignals, 1)) * 100)}%`
|
||||
: "—";
|
||||
|
||||
const activePatterns = patterns.filter((p) => p.is_active);
|
||||
const criticalPatterns = patterns.filter((p) => p.severity === "critical");
|
||||
|
||||
const cardData: CardData[] = [
|
||||
{
|
||||
...STATIC_CARDS[0],
|
||||
time: loading ? "LOADING..." : `${totalSignals} SIGNALS`,
|
||||
description: loading
|
||||
? "Loading signal data..."
|
||||
: `Processing deep contextual inference across ${totalSignals} signals. Semantic alignment analysis running across all active node clusters.`,
|
||||
metrics: [
|
||||
{
|
||||
type: "bar",
|
||||
label: "Coverage",
|
||||
value: totalSignals > 0 ? "active" : "0%",
|
||||
width: totalSignals > 0 ? "88%" : "0%",
|
||||
},
|
||||
{
|
||||
type: "row",
|
||||
label: "Signals Indexed",
|
||||
value: String(totalSignals),
|
||||
},
|
||||
],
|
||||
footerLabel: "Inference Details",
|
||||
footerIcon: "arrow_forward",
|
||||
footerDim: false,
|
||||
},
|
||||
{
|
||||
...STATIC_CARDS[1],
|
||||
pulse: true,
|
||||
time: loading ? "LOADING..." : `${sentimentSignals.length} SAMPLES`,
|
||||
description: loading
|
||||
? "Loading sentiment data..."
|
||||
: `Identifying emotional flux patterns within communications. Analyzed ${sentimentSignals.length} sentiment-bearing signals out of ${totalSignals} total.`,
|
||||
recommendation:
|
||||
sentimentSignals.length > 0
|
||||
? `${avgSentiment} of signals carry sentiment signals. Monitor channels with high emotional flux.`
|
||||
: undefined,
|
||||
footerLabel: "Refine Analysis",
|
||||
footerIcon: "arrow_forward",
|
||||
footerDim: false,
|
||||
},
|
||||
{
|
||||
...STATIC_CARDS[2],
|
||||
time: loading ? "LOADING..." : `${activePatterns.length} ACTIVE`,
|
||||
description: loading
|
||||
? "Loading pattern data..."
|
||||
: activePatterns.length > 0
|
||||
? `${activePatterns.length} active patterns detected across all groups. ${criticalPatterns.length} require immediate attention.`
|
||||
: "No patterns detected yet. Patterns emerge as more signals are processed.",
|
||||
metrics:
|
||||
activePatterns.length > 0
|
||||
? [
|
||||
{
|
||||
type: "row",
|
||||
label: "Active Patterns",
|
||||
value: String(activePatterns.length),
|
||||
valueDim: false,
|
||||
},
|
||||
{
|
||||
type: "row",
|
||||
label: "Critical",
|
||||
value: criticalPatterns.length > 0 ? `${criticalPatterns.length} CRITICAL` : "NONE",
|
||||
valueDim: criticalPatterns.length > 0,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
type: "row",
|
||||
label: "Status",
|
||||
value: "Accumulating data",
|
||||
valueDim: true,
|
||||
},
|
||||
],
|
||||
footerLabel: activePatterns.length > 0 ? "View Patterns" : "System Initializing",
|
||||
footerIcon: activePatterns.length > 0 ? "arrow_forward" : "hourglass_empty",
|
||||
footerDim: activePatterns.length === 0,
|
||||
},
|
||||
];
|
||||
|
||||
type CardMetric = {
|
||||
type: string;
|
||||
label: string;
|
||||
value: string;
|
||||
width?: string;
|
||||
valueDim?: boolean;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{cardData.map((card, idx) => (
|
||||
<div
|
||||
key={card.title}
|
||||
className="glass p-6 rounded-2xl border neon-border flex flex-col relative overflow-hidden group card-interactive animate-fade-in-up"
|
||||
style={{ animationDelay: `${idx * 100}ms` }}
|
||||
>
|
||||
{/* Background Glow */}
|
||||
<div className="absolute inset-0 rounded-2xl -z-10 bg-gradient-to-br from-violet-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||
|
||||
{/* Card Header */}
|
||||
<div className="flex justify-between items-start">
|
||||
<div
|
||||
className="p-2.5 rounded-xl"
|
||||
style={{ backgroundColor: card.iconBg, border: `1px solid ${card.iconBorder}` }}
|
||||
>
|
||||
<span
|
||||
className={`material-symbols-outlined${card.pulse ? " active-pulse" : ""}`}
|
||||
style={{ color: card.iconColor, fontSize: "24px" }}
|
||||
>
|
||||
{card.icon}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className="text-[10px] font-mono-data uppercase tracking-widest"
|
||||
style={{ color: "rgba(249,245,248,0.4)" }}
|
||||
>
|
||||
{card.time}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Card Body */}
|
||||
<div className="flex-1 mt-4">
|
||||
<h3 className="text-lg font-bold tracking-tight text-white mb-2 uppercase">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed mb-6" style={{ color: "rgba(249,245,248,0.7)" }}>
|
||||
{card.description}
|
||||
</p>
|
||||
|
||||
{card.recommendation && (
|
||||
<div
|
||||
className="p-4 rounded-xl mb-6"
|
||||
style={{
|
||||
backgroundColor: "rgba(167,139,250,0.05)",
|
||||
border: "1px solid rgba(167,139,250,0.1)",
|
||||
}}
|
||||
>
|
||||
<div className="text-[10px] uppercase font-bold mb-1" style={{ color: "#A78BFA" }}>
|
||||
Recommended Action
|
||||
</div>
|
||||
<p className="text-[11px] leading-relaxed" style={{ color: "rgba(249,245,248,0.8)" }}>
|
||||
{card.recommendation}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{card.metrics && (
|
||||
<div className="space-y-4 mb-6">
|
||||
{(card.metrics as CardMetric[]).map((m) =>
|
||||
m.type === "bar" ? (
|
||||
<div key={m.label} className="flex flex-col">
|
||||
<div className="flex justify-between items-end mb-1.5">
|
||||
<span
|
||||
className="text-[10px] uppercase tracking-widest"
|
||||
style={{ color: "rgba(249,245,248,0.4)" }}
|
||||
>
|
||||
{m.label}
|
||||
</span>
|
||||
<span
|
||||
className="text-[10px] font-mono-data"
|
||||
style={{ color: "#A78BFA" }}
|
||||
>
|
||||
{m.value}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-full h-1 rounded-full overflow-hidden"
|
||||
style={{ backgroundColor: "rgba(255,255,255,0.05)" }}
|
||||
>
|
||||
<div
|
||||
className="h-full"
|
||||
style={{
|
||||
width: m.width,
|
||||
background: "linear-gradient(to right, #A78BFA, #b79fff)",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
key={m.label}
|
||||
className="flex justify-between items-center py-2"
|
||||
style={{ borderBottom: "1px solid rgba(255,255,255,0.05)" }}
|
||||
>
|
||||
<span
|
||||
className="text-[10px] uppercase"
|
||||
style={{ color: "rgba(249,245,248,0.4)" }}
|
||||
>
|
||||
{m.label}
|
||||
</span>
|
||||
<span
|
||||
className="text-xs font-mono-data"
|
||||
style={{
|
||||
color: m.valueDim ? "#A78BFA" : "rgba(249,245,248,1)",
|
||||
}}
|
||||
>
|
||||
{m.value}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Card Footer */}
|
||||
<div
|
||||
className="px-6 py-4 flex justify-between items-center cursor-pointer group/footer btn-interactive"
|
||||
style={{ borderTop: "1px solid rgba(255,255,255,0.05)" }}
|
||||
>
|
||||
<span
|
||||
className="text-[10px] font-bold uppercase tracking-[0.2em] group-hover/footer:translate-x-1 transition-transform"
|
||||
style={{ color: card.footerDim ? "rgba(249,245,248,0.4)" : "#A78BFA" }}
|
||||
>
|
||||
{card.footerLabel}
|
||||
</span>
|
||||
<span
|
||||
className="material-symbols-outlined text-sm group-hover/footer:translate-x-1 transition-transform"
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
color: card.footerDim ? "rgba(249,245,248,0.4)" : "#A78BFA",
|
||||
}}
|
||||
>
|
||||
{card.footerIcon}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
87
thirdeye/dashboard/app/intelligence/KnowledgeMesh.tsx
Normal file
87
thirdeye/dashboard/app/intelligence/KnowledgeMesh.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
export default function KnowledgeMesh() {
|
||||
return (
|
||||
<div className="xl:col-span-2 glass-card p-6 rounded-2xl relative overflow-hidden">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h3 className="text-sm font-bold tracking-tight text-white uppercase">
|
||||
Global Knowledge Mesh
|
||||
</h3>
|
||||
<p className="text-[10px] font-mono-data mt-1 uppercase" style={{ color: "rgba(249,245,248,0.4)" }}>
|
||||
Cross-Source Entity Integration / Real-time Feed
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
className="px-2 py-1 rounded text-[10px] font-mono-data"
|
||||
style={{
|
||||
backgroundColor: "#131315",
|
||||
border: "1px solid rgba(167,139,250,0.2)",
|
||||
color: "#A78BFA",
|
||||
}}
|
||||
>
|
||||
KNOWLEDGE_GRAPH
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Visualization area */}
|
||||
<div
|
||||
className="h-64 w-full rounded-xl flex items-center justify-center relative overflow-hidden"
|
||||
style={{
|
||||
backgroundColor: "rgba(0,0,0,0.3)",
|
||||
border: "1px solid rgba(255,255,255,0.05)",
|
||||
}}
|
||||
>
|
||||
{/* Dot grid background */}
|
||||
<div className="absolute inset-0 opacity-20 pointer-events-none">
|
||||
<div className="absolute inset-0 dot-grid" />
|
||||
</div>
|
||||
|
||||
{/* Animated SVG node network */}
|
||||
<svg
|
||||
className="absolute inset-0 w-full h-full opacity-20"
|
||||
viewBox="0 0 600 256"
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
>
|
||||
{/* Connection lines */}
|
||||
<line x1="300" y1="128" x2="180" y2="80" stroke="#A78BFA" strokeWidth="0.5" />
|
||||
<line x1="300" y1="128" x2="420" y2="80" stroke="#A78BFA" strokeWidth="0.5" />
|
||||
<line x1="300" y1="128" x2="180" y2="176" stroke="#A78BFA" strokeWidth="0.5" />
|
||||
<line x1="300" y1="128" x2="420" y2="176" stroke="#A78BFA" strokeWidth="0.5" />
|
||||
<line x1="180" y1="80" x2="90" y2="50" stroke="#A78BFA" strokeWidth="0.3" />
|
||||
<line x1="420" y1="80" x2="510" y2="50" stroke="#A78BFA" strokeWidth="0.3" />
|
||||
<line x1="180" y1="176" x2="90" y2="206" stroke="#A78BFA" strokeWidth="0.3" />
|
||||
<line x1="420" y1="176" x2="510" y2="206" stroke="#A78BFA" strokeWidth="0.3" />
|
||||
{/* Secondary nodes */}
|
||||
<circle cx="180" cy="80" r="3" fill="#A78BFA" opacity="0.6" />
|
||||
<circle cx="420" cy="80" r="3" fill="#A78BFA" opacity="0.6" />
|
||||
<circle cx="180" cy="176" r="3" fill="#A78BFA" opacity="0.6" />
|
||||
<circle cx="420" cy="176" r="3" fill="#A78BFA" opacity="0.6" />
|
||||
<circle cx="90" cy="50" r="2" fill="#A78BFA" opacity="0.4" />
|
||||
<circle cx="510" cy="50" r="2" fill="#A78BFA" opacity="0.4" />
|
||||
<circle cx="90" cy="206" r="2" fill="#A78BFA" opacity="0.4" />
|
||||
<circle cx="510" cy="206" r="2" fill="#A78BFA" opacity="0.4" />
|
||||
</svg>
|
||||
|
||||
{/* Central pulsing node */}
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="relative">
|
||||
<div
|
||||
className="w-4 h-4 rounded-full active-pulse"
|
||||
style={{ backgroundColor: "#A78BFA" }}
|
||||
/>
|
||||
<div
|
||||
className="absolute top-6 -left-12 backdrop-blur-md px-3 py-1 rounded text-[10px] font-mono-data text-white whitespace-nowrap"
|
||||
style={{
|
||||
backgroundColor: "rgba(19,19,21,0.8)",
|
||||
border: "1px solid rgba(167,139,250,0.2)",
|
||||
}}
|
||||
>
|
||||
ENTITY_CLUSTER_09
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
86
thirdeye/dashboard/app/intelligence/ThoughtStreams.tsx
Normal file
86
thirdeye/dashboard/app/intelligence/ThoughtStreams.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { fetchAllSignals, Signal, formatRelativeTime, getSeverityColor } from "../lib/api";
|
||||
|
||||
export default function ThoughtStreams() {
|
||||
const [signals, setSignals] = useState<Signal[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
try {
|
||||
const all = await fetchAllSignals();
|
||||
const flat = all
|
||||
.flatMap((g) => g.signals)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
new Date(b.metadata.timestamp).getTime() -
|
||||
new Date(a.metadata.timestamp).getTime()
|
||||
)
|
||||
.slice(0, 10);
|
||||
setSignals(flat);
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
load();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="glass-card p-6 rounded-2xl flex flex-col">
|
||||
<h3 className="text-sm font-bold tracking-tight text-white uppercase mb-6">
|
||||
Thought Streams
|
||||
</h3>
|
||||
|
||||
<div
|
||||
className="space-y-4 flex-1 overflow-y-auto pr-2 custom-scrollbar"
|
||||
style={{ maxHeight: "16rem" }}
|
||||
>
|
||||
{loading && (
|
||||
<div className="flex items-center gap-2 text-zinc-600 text-[10px] font-mono-data">
|
||||
<span className="material-symbols-outlined animate-spin text-sm">autorenew</span>
|
||||
Loading streams...
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!loading && signals.length === 0 && (
|
||||
<p className="text-[10px] text-zinc-600 font-mono-data">
|
||||
No signals yet. Streams will appear here as groups send messages.
|
||||
</p>
|
||||
)}
|
||||
|
||||
{signals.map((sig, i) => (
|
||||
<div key={i} className="flex items-start space-x-3 text-[10px]">
|
||||
<span className="font-mono-data shrink-0" style={{ color: "#A78BFA" }}>
|
||||
{formatRelativeTime(sig.metadata.timestamp)}
|
||||
</span>
|
||||
<p
|
||||
className="font-mono-data leading-relaxed"
|
||||
style={{ color: "rgba(249,245,248,0.6)" }}
|
||||
>
|
||||
<span style={{ color: getSeverityColor(sig.metadata.severity) }}>
|
||||
{sig.metadata.type.toUpperCase()}:
|
||||
</span>{" "}
|
||||
{sig.document.slice(0, 80)}
|
||||
{sig.document.length > 80 ? "…" : ""}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="mt-6 w-full py-3 rounded-xl text-[10px] font-mono-data uppercase tracking-widest transition-all hover:opacity-80"
|
||||
style={{
|
||||
backgroundColor: "rgba(167,139,250,0.05)",
|
||||
border: "1px solid rgba(167,139,250,0.2)",
|
||||
color: "#A78BFA",
|
||||
}}
|
||||
>
|
||||
Export Intelligence Data
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
49
thirdeye/dashboard/app/intelligence/intelligence.css
Normal file
49
thirdeye/dashboard/app/intelligence/intelligence.css
Normal file
@@ -0,0 +1,49 @@
|
||||
/* Intelligence cards — glass style from Stitch */
|
||||
.glass-card {
|
||||
background: linear-gradient(180deg, rgba(28, 20, 45, 0.7) 0%, rgba(18, 14, 28, 0.9) 100%);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(167, 139, 250, 0.12);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.glass-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 20%;
|
||||
height: 60%;
|
||||
width: 2px;
|
||||
background: linear-gradient(to bottom, transparent, #A78BFA, transparent);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.glass-card:hover {
|
||||
border-color: rgba(167, 139, 250, 0.3);
|
||||
box-shadow: 0 0 30px rgba(167, 139, 250, 0.1);
|
||||
}
|
||||
|
||||
.neon-glow-violet {
|
||||
box-shadow: 0 0 20px rgba(167, 139, 250, 0.15);
|
||||
}
|
||||
|
||||
.active-pulse {
|
||||
box-shadow: 0 0 15px rgba(167, 139, 250, 0.4);
|
||||
animation: intel-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes intel-pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.7; transform: scale(1.1); }
|
||||
}
|
||||
|
||||
.font-mono-data {
|
||||
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
||||
}
|
||||
|
||||
/* dot-grid background for knowledge mesh */
|
||||
.dot-grid {
|
||||
background-image: radial-gradient(circle at 2px 2px, #A78BFA 1px, transparent 0);
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
107
thirdeye/dashboard/app/intelligence/page.tsx
Normal file
107
thirdeye/dashboard/app/intelligence/page.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
|
||||
import Sidebar from "../components/Sidebar";
|
||||
import TopBar from "../components/TopBar";
|
||||
import IntelligenceCards from "./IntelligenceCards";
|
||||
import KnowledgeMesh from "./KnowledgeMesh";
|
||||
import ThoughtStreams from "./ThoughtStreams";
|
||||
import IntelFooter from "./IntelFooter";
|
||||
import { useEffect, useState } from "react";
|
||||
import { fetchGroups, fetchAllSignals, fetchAllPatterns } from "../lib/api";
|
||||
|
||||
export default function IntelligencePage() {
|
||||
const [signalCount, setSignalCount] = useState<number | null>(null);
|
||||
const [patternCount, setPatternCount] = useState<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
try {
|
||||
const [allGroups, patterns] = await Promise.all([
|
||||
fetchAllSignals(),
|
||||
fetchAllPatterns(),
|
||||
]);
|
||||
setSignalCount(allGroups.flatMap((g) => g.signals).length);
|
||||
setPatternCount(patterns.filter((p) => p.is_active).length);
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
}
|
||||
load();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex h-screen overflow-hidden bg-[#09090B] text-white"
|
||||
style={{ fontFamily: "'Poppins', sans-serif" }}
|
||||
>
|
||||
<Sidebar />
|
||||
<main className="flex-1 ml-[240px] flex flex-col h-screen overflow-hidden">
|
||||
<TopBar />
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar px-10 pb-12 pt-10">
|
||||
{/* Page Header */}
|
||||
<header className="mb-12">
|
||||
<div className="flex items-end justify-between">
|
||||
<div>
|
||||
<h1
|
||||
className="text-4xl font-bold tracking-tight text-white"
|
||||
style={{ fontFamily: "'Poppins', sans-serif" }}
|
||||
>
|
||||
Intelligence Control
|
||||
</h1>
|
||||
<p
|
||||
className="text-xs mt-2 tracking-widest uppercase font-mono-data"
|
||||
style={{ color: "#A78BFA" }}
|
||||
>
|
||||
ACTIVE_INSIGHTS:{" "}
|
||||
{signalCount !== null ? signalCount.toLocaleString() : "—"} //
|
||||
PATTERNS_ACTIVE:{" "}
|
||||
{patternCount !== null ? patternCount : "—"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Status pill */}
|
||||
<div className="flex items-center space-x-4">
|
||||
<div
|
||||
className="px-4 py-2 rounded-xl flex items-center space-x-3"
|
||||
style={{ backgroundColor: "#131315" }}
|
||||
>
|
||||
<span
|
||||
className="w-2 h-2 rounded-full active-pulse"
|
||||
style={{ backgroundColor: "#A78BFA", display: "inline-block" }}
|
||||
/>
|
||||
<span
|
||||
className="text-[10px] font-mono-data uppercase"
|
||||
style={{ color: "rgba(249,245,248,0.6)" }}
|
||||
>
|
||||
Inference Engine: Optimal
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Main card grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* Top row: 3 intelligence engine cards */}
|
||||
<div className="lg:col-span-3">
|
||||
<IntelligenceCards />
|
||||
</div>
|
||||
|
||||
{/* Bottom row: Knowledge mesh (2 cols) + Thought Streams (1 col) */}
|
||||
<div className="lg:col-span-2">
|
||||
<KnowledgeMesh />
|
||||
</div>
|
||||
<div className="lg:col-span-1">
|
||||
<ThoughtStreams />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer stats bar */}
|
||||
<IntelFooter />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user