import React, { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { ChevronDown, Loader2 } from "lucide-react" import { toast } from "@/components/ui/use-toast" import TCPOverUDP from "./V0-tcp-over-udp" import SSTPOverUDP from "./V0 sstp-over-udp" type Protocol = "TCP" | "SSTP" type ConnectionStatus = "disconnected" | "connecting" | "connected" interface ConnectionDetails { protocol: Protocol address: string port: string } const ProtocolOption: React.FC<{ protocol: Protocol onSelect: (protocol: Protocol) => void isActive: boolean }> = ({ protocol, onSelect, isActive }) => ( onSelect(protocol)} className={`cursor-pointer ${ isActive ? "bg-accent text-accent-foreground" : "" } hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground`} role="menuitem" > {protocol} over UDP ) const ConnectionForm: React.FC<{ isEnabled: boolean connectionDetails: ConnectionDetails setConnectionDetails: React.Dispatch> connectionStatus: ConnectionStatus }> = ({ isEnabled, connectionDetails, setConnectionDetails, connectionStatus }) => ( Remote Address (IP) setConnectionDetails((prev) => ({ ...prev, address: e.target.value })) } placeholder="e.g., 192.168.1.1" disabled={!isEnabled || connectionStatus !== "disconnected"} /> Remote Port setConnectionDetails((prev) => ({ ...prev, port: e.target.value })) } placeholder="e.g., 51820" type="number" disabled={!isEnabled || connectionStatus !== "disconnected"} /> ) const ProtocolSelector: React.FC<{ isEnabled: boolean connectionDetails: ConnectionDetails setConnectionDetails: React.Dispatch> connectionStatus: ConnectionStatus onConnect: () => void }> = ({ isEnabled, connectionDetails, setConnectionDetails, connectionStatus, onConnect }) => { const isValidInput = connectionDetails.address.trim() !== "" && connectionDetails.port.trim() !== "" return ( {connectionDetails.protocol || "Select Protocol"} { setConnectionDetails((prev) => ({ ...prev, protocol })) onConnect() }} isActive={connectionDetails.protocol === "TCP"} /> { setConnectionDetails((prev) => ({ ...prev, protocol })) onConnect() }} isActive={connectionDetails.protocol === "SSTP"} /> ) } export default function WireGuardProtocolSelector() { const [isEnabled, setIsEnabled] = useState(false) const [connectionStatus, setConnectionStatus] = useState("disconnected") const [connectionDetails, setConnectionDetails] = useState({ protocol: "TCP", address: "", port: "", }) const [connection, setConnection] = useState(null) useEffect(() => { if (!isEnabled) { disconnectProtocol() } }, [isEnabled]) const toggleEnabled = () => { setIsEnabled((prev) => !prev) } const connectProtocol = async () => { if (connection) { await disconnectProtocol() } setConnectionStatus("connecting") let newConnection try { if (connectionDetails.protocol === "TCP") { newConnection = new TCPOverUDP(connectionDetails.address, parseInt(connectionDetails.port, 10)) } else { newConnection = new SSTPOverUDP(connectionDetails.address, parseInt(connectionDetails.port, 10)) } await newConnection.connect() setConnection(newConnection) setConnectionStatus("connected") toast({ title: "Connection Established", description: `Connected to ${connectionDetails.protocol} over UDP (${connectionDetails.address}:${connectionDetails.port})`, }) } catch (error) { console.error(`Failed to connect using ${connectionDetails.protocol}:`, error) toast({ title: "Connection Failed", description: `Failed to connect using ${connectionDetails.protocol}. Please try again.`, variant: "destructive", }) setConnectionStatus("disconnected") } } const disconnectProtocol = async () => { if (connection) { try { await connection.close() toast({ title: "Disconnected", description: "Protocol connection closed successfully.", }) } catch (error) { console.error("Error disconnecting:", error) toast({ title: "Disconnection Error", description: "Failed to disconnect properly. Please try again.", variant: "destructive", }) } } setConnection(null) setConnectionStatus("disconnected") setConnectionDetails((prev) => ({ ...prev, protocol: "TCP" })) } return ( {isEnabled ? "Disable" : "Enable"} WireGuard Protocols {isEnabled && ( )} {connectionStatus === "connected" && ( Disconnect )} {connectionStatus === "connecting" && ( Connecting... )} {isEnabled ? connectionStatus === "connected" ? `Connected: ${connectionDetails.protocol} over UDP (${connectionDetails.address}:${connectionDetails.port})` : connectionStatus === "connecting" ? "Establishing connection..." : "Please select a protocol" : "WireGuard protocols are disabled"} ) }