Country Select to API

This commit is contained in:
2026-06-29 18:38:56 +07:00
parent a878461264
commit 16760c16ea
14 changed files with 287 additions and 34 deletions
+29 -20
View File
@@ -1,4 +1,3 @@
import { useState } from "react";
import {
Select,
SelectContent,
@@ -6,34 +5,43 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Globe } from "lucide-react";
import { useTranslation } from "react-i18next";
import ReactCountryFlag from "react-country-flag";
import { cn } from "@/lib/utils";
const countries = [
{ code: "us", name: "United States" },
{ code: "de", name: "Germany" },
{ code: "jp", name: "Japan" },
];
import { useNodesStore } from "@/store/useNodesStore";
import { useVpnStore } from "@/store/useVpnStore";
export function CountrySelect() {
const { t } = useTranslation();
const [selectedCode, setSelectedCode] = useState<string>("");
const { nodes, selectedId, selectNode, loading } = useNodesStore();
const { status } = useVpnStore();
const selectedCountry = countries.find((c) => c.code === selectedCode);
const selectedNode = nodes.find((n) => n.id === selectedId);
// Запрещаем смену сервера во время активного подключения.
const disabled = loading || status !== "idle";
return (
<Select onValueChange={setSelectedCode} value={selectedCode}>
<SelectTrigger className="w-[280px] h-12 bg-white/5 backdrop-blur-lg border-white/10 hover:bg-white/10 transition-all rounded-xl shadow-lg ring-offset-0 focus:ring-0">
<Select
onValueChange={selectNode}
value={selectedId ?? ""}
disabled={disabled}
>
<SelectTrigger className="w-[280px] h-12 bg-white/5 backdrop-blur-lg border-white/10 hover:bg-white/10 transition-all rounded-xl shadow-lg ring-offset-0 focus:ring-0 disabled:opacity-60">
<div
className={cn(
"flex items-center gap-2 w-full px-3",
selectedCountry ? "justify-start" : "justify-center",
selectedNode ? "justify-start" : "justify-center",
)}
>
<span className="truncate flex-1 text-left">
<SelectValue placeholder={t("select_location_placeholder")} />
<SelectValue
placeholder={
loading
? t("loading_servers")
: t("select_location_placeholder")
}
/>
</span>
</div>
</SelectTrigger>
@@ -42,20 +50,21 @@ export function CountrySelect() {
className="bg-white/10 backdrop-blur-2xl border-white/10 rounded-xl overflow-hidden"
style={{ width: "var(--radix-select-trigger-width)" }}
>
{countries.map((country) => (
{nodes.map((node) => (
<SelectItem
key={country.code}
value={country.code}
key={node.id}
value={node.id}
className="cursor-pointer hover:bg-white/10 focus:bg-white/20 transition-colors"
>
<div className="flex items-center gap-3">
<ReactCountryFlag
countryCode={country.code.toUpperCase()}
countryCode={node.countryCode.toUpperCase()}
svg
className="size-5 rounded-sm"
/>
<span className="font-medium text-foreground">
{country.name}
<span className="font-medium text-foreground">{node.name}</span>
<span className="ml-auto text-xs text-muted-foreground">
{node.currentLoad}%
</span>
</div>
</SelectItem>
+10 -5
View File
@@ -9,11 +9,13 @@ import { listen } from "@tauri-apps/api/event";
import VpnControlButton from "@/components/shared/VpnControlButton";
import { useTheme } from "@/ThemeProvider";
import { useSettingsStore } from "@/store/useSettingsStore";
import { useNodesStore } from "@/store/useNodesStore";
export function VpnControl() {
const { status, setStatus } = useVpnStore();
const { t } = useTranslation();
const { killSwitch, excludedApps, excludedDomains } = useSettingsStore();
const { getSelectedNode } = useNodesStore();
// Подключаем тему
const { isDark } = useTheme();
@@ -24,16 +26,19 @@ export function VpnControl() {
if (status === "idle") {
setStatus("connecting");
// Параметры подключения берём из выбранного на бэкенде узла.
const node = getSelectedNode();
const config: TunnelConfig = {
address: "10.0.0.1",
prefix: 24,
dns: "10.0.0.2",
mtu: 1450,
address: node.tunnelAddress,
prefix: node.tunnelPrefix,
dns: node.tunnelDns,
mtu: node.tunnelMtu,
killswitchEnabled: killSwitch,
excludedApps: excludedApps,
excludedDomains: excludedDomains,
};
await startVpn(config, "147.45.43.70", 443);
await startVpn(config, node.ipAddress, node.port);
} else {
await stopVpn();
}