feat(ui): add pulse effect to connection indicator

This commit is contained in:
killianlarcher
2026-01-17 19:36:28 +01:00
parent 21b317e4f1
commit cddb0a7e05
4 changed files with 53 additions and 32 deletions
@@ -1,27 +0,0 @@
import {cn} from "@/lib/utils";
export type ConnectionCircleProps = {
date?: Date | null;
};
export const ConnectionCircle = ({date}: ConnectionCircleProps) => {
let style = "bg-gray-300 border-gray-400";
if (date instanceof Date && !isNaN(date.getTime())) {
const now = Date.now();
const timestamp = date.getTime();
const interval_seconds = (now - timestamp) / 1000;
if (interval_seconds < 55) {
style = "bg-green-400 border-green-600";
} else if (interval_seconds <= 60) {
style = "bg-orange-400 border-orange-600";
} else {
style = "bg-red-400 border-red-600";
}
} else {
console.warn("Invalid date passed to ConnectionCircle:", date);
}
return <div className={cn("w-5 h-5 rounded-full border-4", style)}/>;
};
@@ -0,0 +1,48 @@
import { cn } from "@/lib/utils";
export type ConnectionIndicatorProps = {
date?: Date | null;
};
export const ConnectionIndicator = ({ date }: ConnectionIndicatorProps) => {
let style = "bg-gray-300";
let active = false;
if (date instanceof Date && !isNaN(date.getTime())) {
const intervalSeconds = (Date.now() - date.getTime()) / 1000;
if (intervalSeconds < 55) {
style = "bg-green-500";
active = true;
} else if (intervalSeconds <= 60) {
style = "bg-orange-400";
} else {
style = "bg-red-500";
}
}
return (
<div className="relative w-4 h-4">
{active && (
<span
className={cn(
"absolute -inset-0.25 rounded-full opacity-60 animate-ping",
style
)}
style={{
animationDuration: "2s",
}}
/>
)}
<div
className={cn(
"relative w-4 h-4 rounded-full shadow-sm animate-pulse",
style
)}
style={{
animationDuration: "2s",
}}
/>
</div>
);
};
@@ -3,10 +3,10 @@
import {useState} from "react";
import Link from "next/link";
import {Card} from "@/components/ui/card";
import {ConnectionCircle} from "@/components/wrappers/common/connection-circle";
import {ConnectionIndicator} from "@/components/wrappers/common/connection-indicator";
import {formatDateLastContact} from "@/utils/date-formatting";
import {AgentWith} from "@/db/schema/08_agent";
import {Activity, ChevronRight, Copy, Check, Fingerprint, Server, Database, ShieldCheck} from "lucide-react";
import {Activity, ChevronRight, Copy, Check, Fingerprint, Server, Database} from "lucide-react";
import {Badge} from "@/components/ui/badge";
import {truncateWords} from "@/utils/text";
import {useIsMobile} from "@/hooks/use-mobile";
@@ -86,7 +86,7 @@ export const AgentCard = (props: agentCardProps) => {
</div>
<div className="scale-110">
<ConnectionCircle date={agent.lastContact}/>
<ConnectionIndicator date={agent.lastContact}/>
</div>
<ChevronRight className="w-5 h-5 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all" />
@@ -4,7 +4,7 @@ import Link from "next/link";
import Image from "next/image";
import {useState} from "react";
import {Card} from "@/components/ui/card";
import {ConnectionCircle} from "@/components/wrappers/common/connection-circle";
import {ConnectionIndicator} from "@/components/wrappers/common/connection-indicator";
import {formatDateLastContact} from "@/utils/date-formatting";
import {Database} from "@/db/schema/07_database";
import {ChevronRight, Activity, Fingerprint, Copy, Check} from "lucide-react";
@@ -60,7 +60,7 @@ export const DatabaseCard = (props: databaseCardProps) => {
</div>
<div className="flex flex-col items-end gap-3">
<div className="scale-100 origin-right">
<ConnectionCircle date={database.lastContact}/>
<ConnectionIndicator date={database.lastContact}/>
</div>
</div>
</div>