v1.1: Add CIDR subnet filtering and Agent filter in Devices page

This commit is contained in:
ypratama committed 2026-08-27 12:02:01 +07:00
commit 966058e2fe
422 files changed
+54656

No files matched your search

@@ -0,0 +1,77 @@
"use client";
import { Clock } from "lucide-react";
interface Props {
firstSeen?: string;
lastSeen?: string;
className?: string;
}
export function formatActiveDuration(firstSeen?: string, lastSeen?: string) {
if (!firstSeen || !lastSeen) return null;
const start = new Date(firstSeen).getTime();
const end = new Date(lastSeen).getTime();
const now = Date.now();
const dateObj = new Date(lastSeen);
const fullTimestamp = dateObj.toLocaleString("en-US", {
year: 'numeric', month: 'short', day: 'numeric',
hour: '2-digit', minute: '2-digit', second: '2-digit'
});
let diffSec = Math.floor((end - start) / 1000);
if (diffSec < 0) diffSec = 0;
const h = Math.floor(diffSec / 3600);
const m = Math.floor((diffSec % 3600) / 60);
const s = diffSec % 60;
let durationText = "Just now";
if (h > 0) durationText = `${h}h ${m}m ${s}s`;
else if (m > 0) durationText = `${m}m ${s}s`;
else if (s > 0) durationText = `${s}s`;
const timeSinceLastSeen = Math.floor((now - end) / 1000);
const isActive = timeSinceLastSeen <= 300;
let lastSeenText = "";
if (!isActive) {
const agoH = Math.floor(timeSinceLastSeen / 3600);
const agoM = Math.floor((timeSinceLastSeen % 3600) / 60);
if (agoH > 24) {
const agoD = Math.floor(agoH / 24);
lastSeenText = `${agoD}d ago`;
} else if (agoH > 0) {
lastSeenText = `${agoH}h ago`;
} else if (agoM > 0) {
lastSeenText = `${agoM}m ago`;
} else {
lastSeenText = "a few seconds ago";
}
}
return { isActive, durationText, fullTimestamp, lastSeenText };
}
export default function ActiveDurationDisplay({ firstSeen, lastSeen, className = "" }: Props) {
if (!firstSeen || !lastSeen) return null;
const dur = formatActiveDuration(firstSeen, lastSeen);
if (!dur) return null;
return (
<div className={`flex flex-col gap-1.5 bg-secondary/30 dark:bg-black/20 p-2.5 rounded-lg border border-border text-xs ${className}`}>
<div className="flex justify-between items-center">
<span className={`flex items-center gap-1.5 ${dur.isActive ? 'text-blue-600 dark:text-blue-400' : 'text-muted-foreground'}`}>
<Clock className="w-3.5 h-3.5" /> {dur.isActive ? "Active" : "Last seen"}
</span>
<span className="text-card-foreground font-medium">
{dur.isActive ? dur.durationText : dur.lastSeenText}
</span>
</div>
<div className="text-[10px] text-muted-foreground/60 text-right">
{dur.fullTimestamp}
</div>
</div>
);
}