mirror of
https://github.com/csehviktor/status-monitor.git
synced 2025-08-08 18:06:14 +02:00
fix responsive issues
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { UptimeMessage } from "@/services/types";
|
import { UptimeMessage } from "@/services/types";
|
||||||
import { formatRelativeTime, isAgentOnline } from "@/services/utils";
|
import { formatRelativeTime, isAgentOnline } from "@/services/utils";
|
||||||
import { DottedProgressBar } from "./Progressbar";
|
import { Progressbar } from "./Progressbar";
|
||||||
|
|
||||||
export type AgentOverviewCardProps = {
|
export type AgentOverviewCardProps = {
|
||||||
count: number;
|
count: number;
|
||||||
@@ -69,24 +69,23 @@ export function AgentCard({ props }: { props: AgentCardProps }) {
|
|||||||
onClick={() => props.onClick?.()}
|
onClick={() => props.onClick?.()}
|
||||||
className="bg-[#111111] border border-[#262626] rounded-lg p-6 hover:bg-[#151515] transition-all cursor-pointer group"
|
className="bg-[#111111] border border-[#262626] rounded-lg p-6 hover:bg-[#151515] transition-all cursor-pointer group"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between space-x-10">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div
|
<div
|
||||||
className={`px-2 py-1 rounded-md text-xs font-medium ${status.bgColor} ${status.textColor} border ${status.borderColor}`}
|
className={`px-2 py-1 rounded-md text-xs font-medium ${status.bgColor} ${status.textColor} border ${status.borderColor}`}
|
||||||
>
|
>
|
||||||
{status.name.toUpperCase()}
|
{status.name.toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg font-semibold text-white transition-colors">
|
<h3 className="text-sm md:text-md lg:text-lg font-semibold text-white transition-colors">
|
||||||
{props.data.agent}
|
{props.data.agent}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center space-x-3 flex-1 justify-end">
|
<div className="flex items-center space-x-3 flex-1 justify-end">
|
||||||
<div className="flex flex-col max-w-lg gap-y-2">
|
<div className="flex flex-col max-w-lg gap-y-2">
|
||||||
<DottedProgressBar
|
<Progressbar
|
||||||
color={status.color}
|
color={status.color}
|
||||||
percentage={props.data.uptime}
|
percentage={props.data.uptime}
|
||||||
totalDots={20}
|
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-between items-center text-xs">
|
<div className="flex justify-between items-center text-xs">
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export type HeaderProps = {
|
|||||||
|
|
||||||
export function Header({ props }: { props: HeaderProps }) {
|
export function Header({ props }: { props: HeaderProps }) {
|
||||||
return (
|
return (
|
||||||
<header className="bg-[#111111] border-b border-[#111111]">
|
<header className="bg-[#0d0d0d] border-b border-[#191919]">
|
||||||
<div className="max-w-7xl mx-auto py-4 flex justify-between items-center">
|
<div className="max-w-7xl mx-auto py-4 flex justify-between items-center">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="w-11 h-11 text-yellow-500 flex items-center justify-center">
|
<div className="w-11 h-11 text-yellow-500 flex items-center justify-center">
|
||||||
|
|||||||
@@ -1,20 +1,54 @@
|
|||||||
export function DottedProgressBar({
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
export function Progressbar({
|
||||||
color,
|
color,
|
||||||
percentage,
|
percentage,
|
||||||
totalDots = 10,
|
|
||||||
}: {
|
}: {
|
||||||
color: string;
|
color: string;
|
||||||
percentage: number;
|
percentage: number;
|
||||||
totalDots?: number;
|
|
||||||
}) {
|
}) {
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [totalDots, setTotalDots] = useState<number>(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const calculateDots = () => {
|
||||||
|
if (!containerRef.current) return;
|
||||||
|
|
||||||
|
const parent =
|
||||||
|
containerRef.current.parentElement?.parentElement
|
||||||
|
?.parentElement;
|
||||||
|
|
||||||
|
if (!parent) return;
|
||||||
|
|
||||||
|
const availableWidth = parent.clientWidth;
|
||||||
|
const dotCount = Math.floor(availableWidth / 48);
|
||||||
|
|
||||||
|
setTotalDots(Math.max(5, Math.min(20, dotCount)));
|
||||||
|
};
|
||||||
|
|
||||||
|
calculateDots();
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(calculateDots);
|
||||||
|
if (containerRef.current) {
|
||||||
|
resizeObserver.observe(containerRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => resizeObserver.disconnect();
|
||||||
|
});
|
||||||
|
|
||||||
const filledDots = Math.round((percentage / 100) * totalDots);
|
const filledDots = Math.round((percentage / 100) * totalDots);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center space-x-2">
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className="flex items-center justify-center space-x-2"
|
||||||
|
>
|
||||||
{Array.from({ length: totalDots }).map((_, index) => (
|
{Array.from({ length: totalDots }).map((_, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`w-[14px] h-[14px] rounded-full transition-all duration-300 ${
|
className={`w-3 h-3 lg:w-4 lg:h-4 rounded-full transition-all duration-300 ${
|
||||||
index < filledDots ? color : "bg-[#232323]"
|
index < filledDots ? color : "bg-[#232323]"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -32,55 +32,60 @@ export function HomePage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<main className="max-w-7xl mx-auto py-8">
|
<main className="max-w-7xl mx-auto py-8">
|
||||||
<h2 className="text-xl font-semibold mb-4">Overview</h2>
|
<div className="mx-2">
|
||||||
|
<h2 className="text-xl font-semibold mb-4">Overview</h2>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||||
<AgentOverviewCard
|
<AgentOverviewCard
|
||||||
props={{
|
props={{
|
||||||
count: totalAgents,
|
count: totalAgents,
|
||||||
title: "total agents",
|
title: "total agents",
|
||||||
icon: {
|
icon: {
|
||||||
ref: <Box />,
|
ref: <Box />,
|
||||||
color: "rgb(96, 165, 250)",
|
color: "rgb(96, 165, 250)",
|
||||||
bgColor: "rgba(59, 130, 246, 0.2)",
|
bgColor: "rgba(59, 130, 246, 0.2)",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgentOverviewCard
|
<AgentOverviewCard
|
||||||
props={{
|
props={{
|
||||||
count: onlineAgents,
|
count: onlineAgents,
|
||||||
title: "online",
|
title: "online",
|
||||||
icon: {
|
icon: {
|
||||||
ref: (
|
ref: (
|
||||||
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse-slow" />
|
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse-slow" />
|
||||||
),
|
),
|
||||||
color: "rgb(34, 197, 94)",
|
color: "rgb(34, 197, 94)",
|
||||||
bgColor: "rgba(34, 197, 94, 0.2)",
|
bgColor: "rgba(34, 197, 94, 0.2)",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgentOverviewCard
|
<AgentOverviewCard
|
||||||
props={{
|
props={{
|
||||||
count: offlineAgents,
|
count: offlineAgents,
|
||||||
title: "offline",
|
title: "offline",
|
||||||
icon: {
|
icon: {
|
||||||
ref: (
|
ref: (
|
||||||
<div className="w-3 h-3 bg-red-500 rounded-full animate-pulse-slow" />
|
<div className="w-3 h-3 bg-red-500 rounded-full animate-pulse-slow" />
|
||||||
),
|
),
|
||||||
color: "rgb(239, 68, 68)",
|
color: "rgb(239, 68, 68)",
|
||||||
bgColor: "rgba(239, 68, 68, 0.2)",
|
bgColor: "rgba(239, 68, 68, 0.2)",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h2 className="text-xl font-semibold mb-4">Agents</h2>
|
<h2 className="text-xl font-semibold mb-4">Agents</h2>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{agents.map((agent, index) => (
|
{agents.map((agent, index) => (
|
||||||
<AgentCard key={index} props={{ data: agent }} />
|
<AgentCard
|
||||||
))}
|
key={index}
|
||||||
|
props={{ data: agent }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user