Refactor: Split UptimeBar.tsx into smaller components
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
|
||||
import React from 'react';
|
||||
import { X, RefreshCcw } from 'lucide-react';
|
||||
|
||||
interface UptimeErrorStateProps {
|
||||
uptime: number;
|
||||
onRetry: () => void;
|
||||
}
|
||||
|
||||
export const UptimeErrorState = ({ uptime, onRetry }: UptimeErrorStateProps) => {
|
||||
return (
|
||||
<div className="flex flex-col w-full gap-1">
|
||||
<div className="flex items-center space-x-0.5 w-full h-6">
|
||||
{Array(20).fill(0).map((_, index) => (
|
||||
<div
|
||||
key={`error-${index}`}
|
||||
className={`h-5 w-1.5 rounded-sm bg-gray-700 opacity-40`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground">{Math.round(uptime)}% uptime</span>
|
||||
<button
|
||||
onClick={onRetry}
|
||||
className="text-xs text-red-400 flex items-center gap-1 hover:text-red-300 transition-colors"
|
||||
>
|
||||
<X className="h-3 w-3" /> Connection error
|
||||
<RefreshCcw className="h-3 w-3 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export const UptimeLoadingState = () => {
|
||||
return (
|
||||
<div className="flex flex-col w-full gap-1">
|
||||
<div className="flex items-center space-x-0.5 w-full h-6">
|
||||
{Array(20).fill(0).map((_, index) => (
|
||||
<div
|
||||
key={`skeleton-${index}`}
|
||||
className={`h-5 w-1.5 rounded-sm bg-muted animate-pulse`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground w-16 h-4 bg-muted animate-pulse rounded"></span>
|
||||
<span className="text-muted-foreground w-24 h-4 bg-muted animate-pulse rounded"></span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import { UptimeData } from '@/types/service.types';
|
||||
import { useTheme } from '@/contexts/ThemeContext';
|
||||
|
||||
interface UptimeStatusItemProps {
|
||||
item: UptimeData;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export const UptimeStatusItem = ({ item, index }: UptimeStatusItemProps) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
// Get appropriate color classes for each status type
|
||||
const getStatusColor = (itemStatus: string) => {
|
||||
switch(itemStatus) {
|
||||
case "up":
|
||||
return theme === "dark" ? "bg-emerald-500" : "bg-emerald-500";
|
||||
case "down":
|
||||
return theme === "dark" ? "bg-red-500" : "bg-red-500";
|
||||
case "warning":
|
||||
return theme === "dark" ? "bg-yellow-500" : "bg-yellow-500";
|
||||
case "paused":
|
||||
default:
|
||||
return theme === "dark" ? "bg-gray-500" : "bg-gray-400";
|
||||
}
|
||||
};
|
||||
|
||||
// Get status label
|
||||
const getStatusLabel = (itemStatus: string): string => {
|
||||
switch(itemStatus) {
|
||||
case "up": return "Online";
|
||||
case "down": return "Offline";
|
||||
case "warning": return "Degraded";
|
||||
case "paused": return "Paused";
|
||||
default: return "Unknown";
|
||||
}
|
||||
};
|
||||
|
||||
// Format timestamp for display
|
||||
const formatTimestamp = (timestamp: string): string => {
|
||||
try {
|
||||
return new Date(timestamp).toLocaleString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
});
|
||||
} catch (e) {
|
||||
return timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
className={`h-5 w-1.5 rounded-sm ${getStatusColor(item.status)} cursor-pointer hover:opacity-80 transition-opacity`}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="top"
|
||||
className="bg-gray-900 text-white border-gray-800 px-3 py-2"
|
||||
>
|
||||
<div className="flex flex-col gap-1 text-xs">
|
||||
<div className="font-medium">{getStatusLabel(item.status)}</div>
|
||||
<div>
|
||||
{item.status !== "paused" && item.status !== "down" ?
|
||||
`${item.responseTime}ms` :
|
||||
"No response"}
|
||||
</div>
|
||||
<div className="text-gray-400">
|
||||
{formatTimestamp(item.timestamp)}
|
||||
</div>
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface UptimeSummaryProps {
|
||||
uptime: number;
|
||||
interval: number;
|
||||
}
|
||||
|
||||
export const UptimeSummary = ({ uptime, interval }: UptimeSummaryProps) => {
|
||||
return (
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground">
|
||||
{Math.round(uptime)}% uptime
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Last 20 checks ({interval}s interval)
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
export { UptimeStatusItem } from './UptimeStatusItem';
|
||||
export { UptimeSummary } from './UptimeSummary';
|
||||
export { UptimeLoadingState } from './UptimeLoadingState';
|
||||
export { UptimeErrorState } from './UptimeErrorState';
|
||||
Reference in New Issue
Block a user