Country Select to API
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user