Skip to content

Commit 4c6fbfd

Browse files
committed
feat(i18n): 剩余缺少的国际化
1 parent 59c9057 commit 4c6fbfd

20 files changed

Lines changed: 1167 additions & 499 deletions

web/src/components/ui/connections-chart.tsx

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
YAxis,
1010
Tooltip,
1111
} from "recharts";
12+
import { useTranslation } from "react-i18next";
1213

1314
import { type ChartConfig, ChartContainer } from "./chart";
1415
import { ConnectionsTooltip } from "./shared-chart-tooltip";
@@ -88,53 +89,71 @@ const formatTooltipTime = (timestamp: string): string => {
8889
const LoadingState: React.FC<{ height: number; className?: string }> = ({
8990
height,
9091
className,
91-
}) => (
92-
<div
93-
className={`flex items-center justify-center ${className}`}
94-
style={height ? { height } : {}}
95-
>
96-
<div className="space-y-1 text-center">
97-
<div className="flex justify-center">
98-
<div className="relative w-4 h-4">
99-
<div className="absolute inset-0 rounded-full border-2 border-default-200 border-t-primary animate-spin" />
92+
}) => {
93+
const { t } = useTranslation("tunnels");
94+
95+
return (
96+
<div
97+
className={`flex items-center justify-center ${className}`}
98+
style={height ? { height } : {}}
99+
>
100+
<div className="space-y-1 text-center">
101+
<div className="flex justify-center">
102+
<div className="relative w-4 h-4">
103+
<div className="absolute inset-0 rounded-full border-2 border-default-200 border-t-primary animate-spin" />
104+
</div>
100105
</div>
106+
<p className="text-default-500 animate-pulse text-xs">
107+
{t("details.chartStates.loading")}
108+
</p>
101109
</div>
102-
<p className="text-default-500 animate-pulse text-xs">加载中...</p>
103110
</div>
104-
</div>
105-
);
111+
);
112+
};
106113

107114
// 错误状态组件
108115
const ErrorState: React.FC<{
109116
error: string;
110117
height: number;
111118
className?: string;
112-
}> = ({ error, height, className }) => (
113-
<div
114-
className={`flex items-center justify-center ${className}`}
115-
style={height ? { height } : {}}
116-
>
117-
<div className="text-center">
118-
<p className="text-danger text-xs">加载失败</p>
119-
<p className="text-default-400 text-xs mt-0.5">{error}</p>
119+
}> = ({ error, height, className }) => {
120+
const { t } = useTranslation("tunnels");
121+
122+
return (
123+
<div
124+
className={`flex items-center justify-center ${className}`}
125+
style={height ? { height } : {}}
126+
>
127+
<div className="text-center">
128+
<p className="text-danger text-xs">
129+
{t("details.chartStates.loadFailed")}
130+
</p>
131+
<p className="text-default-400 text-xs mt-0.5">{error}</p>
132+
</div>
120133
</div>
121-
</div>
122-
);
134+
);
135+
};
123136

124137
// 空状态组件
125138
const EmptyState: React.FC<{ height: number; className?: string }> = ({
126139
height,
127140
className,
128-
}) => (
129-
<div
130-
className={`flex items-center justify-center ${className}`}
131-
style={height ? { height } : {}}
132-
>
133-
<div className="text-center">
134-
<p className="text-default-400 text-xs">暂无数据</p>
141+
}) => {
142+
const { t } = useTranslation("tunnels");
143+
144+
return (
145+
<div
146+
className={`flex items-center justify-center ${className}`}
147+
style={height ? { height } : {}}
148+
>
149+
<div className="text-center">
150+
<p className="text-default-400 text-xs">
151+
{t("details.chartStates.noData")}
152+
</p>
153+
</div>
135154
</div>
136-
</div>
137-
);
155+
);
156+
};
138157

139158
// 时间过滤函数 - 过滤出1小时内的数据
140159
const filterDataTo1Hour = (data: ConnectionDataPoint[]) => {
@@ -162,17 +181,19 @@ export const ConnectionsChart: React.FC<ConnectionsChartProps> = ({
162181
className = "",
163182
showFullData = false,
164183
}) => {
184+
const { t } = useTranslation("tunnels");
185+
165186
const chartConfig = {
166187
pool: {
167-
label: "池连接数",
188+
label: t("details.chartTooltips.pool"),
168189
color: "hsl(340 75% 55%)",
169190
},
170191
tcps: {
171-
label: "TCP连接数",
192+
label: t("details.chartTooltips.tcp"),
172193
color: "hsl(24 70% 50%)",
173194
},
174195
udps: {
175-
label: "UDP连接数",
196+
label: t("details.chartTooltips.udp"),
176197
color: "hsl(173 58% 39%)",
177198
},
178199
} satisfies ChartConfig;

web/src/components/ui/detailed-traffic-chart.tsx

Lines changed: 99 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
YAxis,
1010
Tooltip,
1111
} from "recharts";
12+
import { useTranslation } from "react-i18next";
1213

1314
import { type ChartConfig, ChartContainer } from "./chart";
1415
import { SharedChartTooltip } from "./shared-chart-tooltip";
@@ -61,101 +62,119 @@ const formatAxisTime = (timestamp: string): string => {
6162
};
6263

6364
// 自定义Tooltip组件
64-
const DetailedTrafficTooltip = ({ active, payload, label }: any) => (
65-
<SharedChartTooltip
66-
active={active}
67-
items={payload
68-
?.map((entry: any) => {
69-
let name = "";
70-
let color = "";
71-
72-
switch (entry.dataKey) {
73-
case "tcpIn":
74-
name = "TCP入站";
75-
color = "text-blue-600 dark:text-blue-400";
76-
break;
77-
case "tcpOut":
78-
name = "TCP出站";
79-
color = "text-green-600 dark:text-green-400";
80-
break;
81-
case "udpIn":
82-
name = "UDP入站";
83-
color = "text-purple-600 dark:text-purple-400";
84-
break;
85-
case "udpOut":
86-
name = "UDP出站";
87-
color = "text-orange-600 dark:text-orange-400";
88-
break;
89-
default:
90-
name = entry.name || entry.dataKey;
91-
color = "text-default-600";
92-
}
93-
94-
return {
95-
key: entry.dataKey,
96-
name,
97-
value: entry.value,
98-
color,
99-
unit: "traffic" as const,
100-
};
101-
})
102-
.filter((item: any) => item.value !== null && item.value !== undefined)}
103-
label={label}
104-
payload={payload}
105-
/>
106-
);
65+
const DetailedTrafficTooltip = ({ active, payload, label }: any) => {
66+
const { t } = useTranslation("tunnels");
67+
68+
return (
69+
<SharedChartTooltip
70+
active={active}
71+
items={payload
72+
?.map((entry: any) => {
73+
let name = "";
74+
let color = "";
75+
76+
switch (entry.dataKey) {
77+
case "tcpIn":
78+
name = t("details.chartTooltips.tcpInbound");
79+
color = "text-blue-600 dark:text-blue-400";
80+
break;
81+
case "tcpOut":
82+
name = t("details.chartTooltips.tcpOutbound");
83+
color = "text-green-600 dark:text-green-400";
84+
break;
85+
case "udpIn":
86+
name = t("details.chartTooltips.udpInbound");
87+
color = "text-purple-600 dark:text-purple-400";
88+
break;
89+
case "udpOut":
90+
name = t("details.chartTooltips.udpOutbound");
91+
color = "text-orange-600 dark:text-orange-400";
92+
break;
93+
default:
94+
name = entry.name || entry.dataKey;
95+
color = "text-default-600";
96+
}
97+
98+
return {
99+
key: entry.dataKey,
100+
name,
101+
value: entry.value,
102+
color,
103+
unit: "traffic" as const,
104+
};
105+
})
106+
.filter((item: any) => item.value !== null && item.value !== undefined)}
107+
label={label}
108+
payload={payload}
109+
/>
110+
);
111+
};
107112

108113
// 加载状态组件
109114
const LoadingState: React.FC<{ height: number; className?: string }> = ({
110115
height,
111116
className,
112-
}) => (
113-
<div
114-
className={`flex items-center justify-center ${className}`}
115-
style={height ? { height } : {}}
116-
>
117-
<div className="space-y-1 text-center">
118-
<div className="flex justify-center">
119-
<div className="relative w-4 h-4">
120-
<div className="absolute inset-0 rounded-full border-2 border-default-200 border-t-primary animate-spin" />
117+
}) => {
118+
const { t } = useTranslation("tunnels");
119+
120+
return (
121+
<div
122+
className={`flex items-center justify-center ${className}`}
123+
style={height ? { height } : {}}
124+
>
125+
<div className="space-y-1 text-center">
126+
<div className="flex justify-center">
127+
<div className="relative w-4 h-4">
128+
<div className="absolute inset-0 rounded-full border-2 border-default-200 border-t-primary animate-spin" />
129+
</div>
121130
</div>
131+
<p className="text-default-500 animate-pulse text-xs">
132+
{t("details.chartStates.loading")}
133+
</p>
122134
</div>
123-
<p className="text-default-500 animate-pulse text-xs">加载中...</p>
124135
</div>
125-
</div>
126-
);
136+
);
137+
};
127138

128139
// 错误状态组件
129140
const ErrorState: React.FC<{
130141
error: string;
131142
height: number;
132143
className?: string;
133-
}> = ({ error, height, className }) => (
134-
<div
135-
className={`flex items-center justify-center ${className}`}
136-
style={height ? { height } : {}}
137-
>
138-
<div className="text-center">
139-
<p className="text-danger text-xs">加载失败</p>
140-
<p className="text-default-400 text-xs mt-0.5">{error}</p>
144+
}> = ({ error, height, className }) => {
145+
const { t } = useTranslation("tunnels");
146+
147+
return (
148+
<div
149+
className={`flex items-center justify-center ${className}`}
150+
style={height ? { height } : {}}
151+
>
152+
<div className="text-center">
153+
<p className="text-danger text-xs">{t("details.chartStates.loadFailed")}</p>
154+
<p className="text-default-400 text-xs mt-0.5">{error}</p>
155+
</div>
141156
</div>
142-
</div>
143-
);
157+
);
158+
};
144159

145160
// 空状态组件
146161
const EmptyState: React.FC<{ height: number; className?: string }> = ({
147162
height,
148163
className,
149-
}) => (
150-
<div
151-
className={`flex items-center justify-center ${className}`}
152-
style={height ? { height } : {}}
153-
>
154-
<div className="text-center">
155-
<p className="text-default-400 text-xs">暂无数据</p>
164+
}) => {
165+
const { t } = useTranslation("tunnels");
166+
167+
return (
168+
<div
169+
className={`flex items-center justify-center ${className}`}
170+
style={height ? { height } : {}}
171+
>
172+
<div className="text-center">
173+
<p className="text-default-400 text-xs">{t("details.chartStates.noData")}</p>
174+
</div>
156175
</div>
157-
</div>
158-
);
176+
);
177+
};
159178

160179
// 时间过滤函数 - 过滤出1小时内的数据
161180
const filterDataTo1Hour = (data: DetailedTrafficDataPoint[]) => {
@@ -183,21 +202,23 @@ export const DetailedTrafficChart: React.FC<DetailedTrafficChartProps> = ({
183202
className = "",
184203
showFullData = false,
185204
}) => {
205+
const { t } = useTranslation("tunnels");
206+
186207
const chartConfig = {
187208
tcpIn: {
188-
label: "TCP入站",
209+
label: t("details.chartTooltips.tcpInbound"),
189210
color: "hsl(217 91% 60%)",
190211
},
191212
tcpOut: {
192-
label: "TCP出站",
213+
label: t("details.chartTooltips.tcpOutbound"),
193214
color: "hsl(142 76% 36%)",
194215
},
195216
udpIn: {
196-
label: "UDP入站",
217+
label: t("details.chartTooltips.udpInbound"),
197218
color: "hsl(262 83% 58%)",
198219
},
199220
udpOut: {
200-
label: "UDP出站",
221+
label: t("details.chartTooltips.udpOutbound"),
201222
color: "hsl(25 95% 53%)",
202223
},
203224
} satisfies ChartConfig;

0 commit comments

Comments
 (0)