feat: fleet intelligence dashboard -- health score, XMR price, contribution map, analytics
This commit is contained in:
@@ -26,11 +26,18 @@ function LaserPulse({ start, end, color }: { start: [number, number, number], en
|
||||
);
|
||||
}
|
||||
|
||||
const STALE_THRESHOLD_MS = 5 * 60 * 1000;
|
||||
|
||||
function AgentNode({ agent, position, serverPos }: { agent: Agent, position: [number, number, number], serverPos: [number, number, number] }) {
|
||||
const isOnline = agent.status === 'online';
|
||||
const isHashing = agent.hashrate_15m > 0;
|
||||
const color = isOnline ? (isHashing ? '#00f5ff' : '#00aa55') : '#ff4444';
|
||||
const pulseRef = useRef<THREE.Mesh>(null);
|
||||
const ringRef = useRef<THREE.Mesh>(null);
|
||||
|
||||
// Stale = online status but last_seen older than 5 min (silently dead)
|
||||
const isStale = isOnline && !!agent.last_seen &&
|
||||
(Date.now() - new Date(agent.last_seen).getTime()) > STALE_THRESHOLD_MS;
|
||||
|
||||
useFrame((state) => {
|
||||
if (isOnline && pulseRef.current) {
|
||||
@@ -41,6 +48,11 @@ function AgentNode({ agent, position, serverPos }: { agent: Agent, position: [nu
|
||||
pulseRef.current.rotation.x += 0.05;
|
||||
}
|
||||
}
|
||||
// Slowly spin the staleness warning ring
|
||||
if (isStale && ringRef.current) {
|
||||
ringRef.current.rotation.z += 0.01;
|
||||
ringRef.current.rotation.x = Math.sin(state.clock.elapsedTime * 0.5) * 0.3;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -48,11 +60,20 @@ function AgentNode({ agent, position, serverPos }: { agent: Agent, position: [nu
|
||||
<Sphere ref={pulseRef} args={[0.3, 16, 16]}>
|
||||
<meshStandardMaterial color={color} emissive={color} emissiveIntensity={isOnline ? (isHashing ? 2 : 1) : 0.2} wireframe />
|
||||
</Sphere>
|
||||
|
||||
{/* Staleness warning ring — amber halo for online-but-silent nodes */}
|
||||
{isStale && (
|
||||
<mesh ref={ringRef}>
|
||||
<torusGeometry args={[0.55, 0.04, 8, 40]} />
|
||||
<meshBasicMaterial color="#ffb020" opacity={0.85} transparent />
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
{/* Connection Line */}
|
||||
<Line points={[[0,0,0], [serverPos[0] - position[0], serverPos[1] - position[1], serverPos[2] - position[2]]]} color={isOnline ? '#004455' : '#330000'} lineWidth={1} transparent opacity={0.4} />
|
||||
<Line points={[[0,0,0], [serverPos[0] - position[0], serverPos[1] - position[1], serverPos[2] - position[2]]]} color={isStale ? '#665500' : isOnline ? '#004455' : '#330000'} lineWidth={1} transparent opacity={0.4} />
|
||||
|
||||
{/* Laser Pulse simulating hashing packets */}
|
||||
{isOnline && isHashing && (
|
||||
{isOnline && isHashing && !isStale && (
|
||||
<LaserPulse start={[0,0,0]} end={[serverPos[0] - position[0], serverPos[1] - position[1], serverPos[2] - position[2]]} color="#00ffff" />
|
||||
)}
|
||||
</group>
|
||||
|
||||
Reference in New Issue
Block a user