refactory(i18n): Add internationalization support for the service statistics card
This commit is contained in:
@@ -4,6 +4,7 @@ import { Service, UptimeData } from "@/types/service.types";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { useMemo } from "react";
|
||||
import { formatDistanceStrict } from "date-fns";
|
||||
import {useLanguage} from "@/contexts/LanguageContext.tsx";
|
||||
|
||||
interface ServiceStatsCardsProps {
|
||||
service: Service;
|
||||
@@ -11,6 +12,8 @@ interface ServiceStatsCardsProps {
|
||||
}
|
||||
|
||||
export function ServiceStatsCards({ service, uptimeData }: ServiceStatsCardsProps) {
|
||||
|
||||
const { t } = useLanguage();
|
||||
// Calculate uptime percentage
|
||||
const calculateUptimePercentage = () => {
|
||||
if (uptimeData.length === 0) return 100;
|
||||
@@ -109,41 +112,46 @@ export function ServiceStatsCards({ service, uptimeData }: ServiceStatsCardsProp
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
||||
<Card className="border-blue-400 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/50 shadow-md">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-sm font-medium text-blue-800 dark:text-blue-100">Response Time</CardTitle>
|
||||
<CardTitle className="text-sm font-medium text-blue-800 dark:text-blue-100">{t('responseTime')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold text-blue-700 dark:text-white">
|
||||
{service.responseTime}ms
|
||||
</div>
|
||||
<p className="text-xs text-blue-600 dark:text-blue-200 mt-1">Last checked at {service.lastChecked}</p>
|
||||
<p className="text-xs text-blue-600 dark:text-blue-200 mt-1">{t('lastCheckedAt').replace('{datetime}', service.lastChecked)}</p>
|
||||
{avgResponseTime > 0 && avgResponseTime !== service.responseTime && (
|
||||
<p className="text-xs text-blue-600 dark:text-blue-200 mt-1">Avg: {avgResponseTime}ms (last {upChecks.length} up checks)</p>
|
||||
<p className="text-xs text-blue-600 dark:text-blue-200 mt-1">{t('avg')}: {avgResponseTime}ms ({t('lastUpChecksCount').replace('{count}', String(upChecks.length))})</p>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-green-400 dark:border-green-700 bg-green-50 dark:bg-green-900/50 shadow-md">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-sm font-medium text-green-800 dark:text-green-100">Uptime</CardTitle>
|
||||
<CardTitle className="text-sm font-medium text-green-800 dark:text-green-100">{t('uptime')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold text-green-700 dark:text-white">
|
||||
{uptimePercentage}%
|
||||
</div>
|
||||
<p className="text-xs text-green-600 dark:text-green-200 mt-1">Based on last {uptimeData.length} checks</p>
|
||||
<p className="text-xs text-green-600 dark:text-green-200 mt-1">{t('basedOnlastChecksCount').replace('{count}', String(uptimeData.length))}</p>
|
||||
<div className="flex flex-col space-y-1 mt-2">
|
||||
<div className="flex items-center text-xs text-green-600 dark:text-green-200">
|
||||
<ArrowUp className="h-3 w-3 mr-1 text-green-600 dark:text-green-400" />
|
||||
<span>Total uptime: {uptimeStats.totalUptimeFormatted}</span>
|
||||
<span>{t("totalUptime")}: {uptimeStats.totalUptimeFormatted}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-xs text-red-600 dark:text-red-200">
|
||||
<ArrowDown className="h-3 w-3 mr-1 text-red-600 dark:text-red-400" />
|
||||
<span>Total downtime: {uptimeStats.totalDowntimeFormatted}</span>
|
||||
<span>{t("totalDowntime")}: {uptimeStats.totalDowntimeFormatted}</span>
|
||||
</div>
|
||||
{service.status !== "paused" && (
|
||||
<div className="flex items-center text-xs font-medium mt-1">
|
||||
<span className={service.status === "up" ? "text-green-600 dark:text-green-400" : "text-red-600 dark:text-red-400"}>
|
||||
{service.status === "up" ? "Up" : "Down"} for {uptimeStats.currentStatusDuration}
|
||||
{
|
||||
service.status === "up" ?
|
||||
t('upStatusDuration').replace("{duration}", uptimeStats.currentStatusDuration)
|
||||
:
|
||||
t('downStatusDuration').replace("{duration}", uptimeStats.currentStatusDuration)
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -153,16 +161,16 @@ export function ServiceStatsCards({ service, uptimeData }: ServiceStatsCardsProp
|
||||
|
||||
<Card className="border-purple-400 dark:border-purple-700 bg-purple-50 dark:bg-purple-900/50 shadow-md">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-sm font-medium text-purple-800 dark:text-purple-100">Monitoring Settings</CardTitle>
|
||||
<CardTitle className="text-sm font-medium text-purple-800 dark:text-purple-100">{t('monitoringSettings')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center text-sm text-purple-700 dark:text-purple-200">
|
||||
<Clock className="h-4 w-4 mr-2 text-purple-600 dark:text-purple-400" />
|
||||
<span>Checked every {service.interval} seconds</span>
|
||||
<span>{t('monitoringSettingsInterval').replace('{interval}', String(service.interval))}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-sm text-purple-700 dark:text-purple-200 mt-1">
|
||||
<Server className="h-4 w-4 mr-2 text-purple-600 dark:text-purple-400" />
|
||||
<span>{service.type} monitoring</span>
|
||||
<span>{service.type} {t('monitoringSettingsType')}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { TooltipProvider } from '@/components/ui/tooltip';
|
||||
import { UptimeStatusItem } from './uptime/UptimeStatusItem';
|
||||
import { uptimeService } from '@/services/uptimeService';
|
||||
import { UptimeData } from '@/types/service.types';
|
||||
import {useLanguage} from "@/contexts/LanguageContext.tsx";
|
||||
|
||||
interface UptimeBarProps {
|
||||
uptime: number;
|
||||
@@ -15,6 +16,7 @@ interface UptimeBarProps {
|
||||
}
|
||||
|
||||
const UptimeBarComponent = ({ uptime, status, serviceId, interval, serviceType = "HTTP" }: UptimeBarProps) => {
|
||||
const { t } = useLanguage();
|
||||
// Calculate date range for last 20 checks with much more aggressive caching
|
||||
const endDate = useMemo(() => new Date(), []);
|
||||
const startDate = useMemo(() => {
|
||||
@@ -84,7 +86,7 @@ const UptimeBarComponent = ({ uptime, status, serviceId, interval, serviceType =
|
||||
</div>
|
||||
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Last 20 checks
|
||||
{t('last20Checks')}
|
||||
</span>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import {useLanguage} from "@/contexts/LanguageContext.tsx";
|
||||
|
||||
interface UptimeSummaryProps {
|
||||
uptime: number;
|
||||
@@ -7,13 +8,14 @@ interface UptimeSummaryProps {
|
||||
}
|
||||
|
||||
export const UptimeSummary = ({ uptime, interval }: UptimeSummaryProps) => {
|
||||
const { t } = useLanguage();
|
||||
return (
|
||||
<div className="flex items-center justify-between text-xs mt-1">
|
||||
<span className="text-muted-foreground">
|
||||
{Math.round(uptime)}% uptime
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Last 20 checks
|
||||
{t('last20Checks')}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -119,10 +119,21 @@ export const servicesTranslations: ServicesTranslations = {
|
||||
editService: "Edit Service",
|
||||
editServiceDesc: "Update the details of your monitored service.",
|
||||
|
||||
//ServiceStatsCards.tsx
|
||||
lastCheckedAt: "Last checked at {datetime}",
|
||||
avg: "Avg",
|
||||
lastUpChecksCount: "last {count} up checks",
|
||||
basedOnlastChecksCount: "Based on last {count} checks",
|
||||
totalUptime: "Total Uptime",
|
||||
totalDowntime: "Total Downtime",
|
||||
monitoringSettings: "Monitoring Settings",
|
||||
monitoringSettingsInterval: "Checked every {interval} seconds",
|
||||
monitoringSettingsType: "monitoring",
|
||||
upStatusDuration: "Up for {duration}",
|
||||
downStatusDuration: "Down for {duration}",
|
||||
|
||||
incidentHistory: "Incident History",
|
||||
processing: "Processing",
|
||||
back: "Back",
|
||||
|
||||
|
||||
last20Checks: "Last 20 checks",
|
||||
};
|
||||
@@ -117,7 +117,21 @@ export interface ServicesTranslations {
|
||||
editService: string;
|
||||
editServiceDesc: string;
|
||||
|
||||
//ServiceStatsCards.tsx
|
||||
lastCheckedAt: string;
|
||||
avg: string;
|
||||
lastUpChecksCount: string;
|
||||
basedOnlastChecksCount: string;
|
||||
totalUptime: string;
|
||||
totalDowntime: string;
|
||||
monitoringSettings: string;
|
||||
monitoringSettingsInterval: string;
|
||||
monitoringSettingsType: string;
|
||||
upStatusDuration: string;
|
||||
downStatusDuration: string;
|
||||
|
||||
incidentHistory: string;
|
||||
processing: string;
|
||||
back: string;
|
||||
last20Checks: string;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,21 @@ export const servicesTranslations: ServicesTranslations = {
|
||||
editService: "编辑服务",
|
||||
editServiceDesc: "更新您所监控服务的详细信息。",
|
||||
|
||||
//ServiceStatsCards.tsx
|
||||
lastCheckedAt: "最新检查时间 {datetime}",
|
||||
avg: "平均",
|
||||
lastUpChecksCount: "最近 {count} 次检查",
|
||||
basedOnlastChecksCount: "基于最近的 {count} 次检查",
|
||||
totalUptime: "总在线时间",
|
||||
totalDowntime: "总宕机时间",
|
||||
monitoringSettings: "监控设置",
|
||||
monitoringSettingsInterval: "每 {interval} 秒检查一次",
|
||||
monitoringSettingsType: "监控",
|
||||
upStatusDuration: "已在线 {duration}",
|
||||
downStatusDuration: "已宕机 {duration}",
|
||||
|
||||
incidentHistory: "事件历史",
|
||||
processing: "处理中",
|
||||
back: "返回",
|
||||
last20Checks: "最近 20 次检查",
|
||||
};
|
||||
Reference in New Issue
Block a user