import { useState } from "react"; import toast from "react-hot-toast"; import { IoCopyOutline, IoWifiOutline } from "react-icons/io5"; import { MdOutlineDns } from "react-icons/md"; import { FaBolt } from "react-icons/fa6"; import { BsShieldExclamation } from "react-icons/bs"; import { useMutation } from "@tanstack/react-query"; import { AxiosError } from "axios"; import MuiModal from "../../../../common/modal"; import Button from "../../../../components/button"; import Input from "../../../../components/input"; import Alert from "../../../../components/alert/Alert"; import { ModalDnsConfigProps } from "../../../../types/props"; import useAxios from "../../../../hooks/useAxios"; import { queryClient } from "../../../../main"; const IP_ADDRESS_REGEX = /^(((\d{1,3}\.){3}\d{1,3})|([0-9a-fA-F:]+:+[0-9a-fA-F:]+))$/; const CLIENT_IP_ENDPOINTS = [ { url: "https://api64.ipify.org?format=json", parse: async (res: Response) => (await res.json())?.ip, }, { url: "https://api.ipify.org?format=json", parse: async (res: Response) => (await res.json())?.ip, }, { url: "https://icanhazip.com", parse: async (res: Response) => (await res.text()).trim(), }, ]; const getErrorMessage = (err: AxiosError) => { const responseData = err.response?.data; if ( responseData && typeof responseData === "object" && "alert" in responseData ) { return (responseData as { alert: string }).alert; } return "یک خطای غیرمنتظره رخ داد"; }; const ModalDnsConfig = ({ isOpen, setIsOpen, nameConfig, orderId, primaryIpv4, secondaryIpv4, primaryIpv6, secondaryIpv6, dnsIpPending, dnsRegistrationExpired, }: ModalDnsConfigProps) => { const axios = useAxios(); const [ip, setIp] = useState(""); const [isDetecting, setIsDetecting] = useState(false); const copyToClipboard = async (label: string, textToCopy?: string | null) => { if (!textToCopy) return; try { await navigator.clipboard.writeText(textToCopy); toast.success(`${label} کپی شد!`); } catch (err) { toast.error(`کپی انجام نشد: ${err}`); } }; const registerIpMutation = useMutation({ mutationKey: ["registerDnsIp", orderId], mutationFn: (ipToRegister: string) => { return axios.post(`/profile/dns/${orderId}/register-ip`, { ip: ipToRegister, }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["profile"] }); }, }); const registerIp = async (ipToRegister: string) => { const normalizedIp = ipToRegister.trim(); if (!orderId) { toast.error("شناسه سفارش نامعتبر است"); return; } if (!IP_ADDRESS_REGEX.test(normalizedIp)) { toast.error("آی‌پی وارد شده معتبر نیست"); return; } setIp(normalizedIp); try { await toast.promise(registerIpMutation.mutateAsync(normalizedIp), { loading: "درحال ذخیره آی‌پی...", success: (res) => res?.data?.alert || "آی‌پی با موفقیت ذخیره شد", error: (err: AxiosError) => getErrorMessage(err), }); } catch { return; } }; const handleAutoDetectIp = async () => { setIsDetecting(true); try { for (const endpoint of CLIENT_IP_ENDPOINTS) { try { const res = await fetch(endpoint.url, { cache: "no-store" }); if (!res.ok) continue; const detectedIp = await endpoint.parse(res); if (detectedIp && IP_ADDRESS_REGEX.test(detectedIp)) { setIp(detectedIp); toast.success("آی‌پی کاربر دریافت شد"); return; } } catch { continue; } } toast.error("دریافت آی‌پی خودکار ممکن نشد"); } catch (err) { toast.error(`دریافت آی‌پی خودکار با خطا مواجه شد: ${err}`); } finally { setIsDetecting(false); } }; const ipRows: { label: string; badge: string; value?: string | null }[] = [ { label: "DNS نسل 4", badge: "v4", value: primaryIpv4 }, { label: "DNS نسل 4", badge: "v4", value: secondaryIpv4 }, { label: "DNS نسل 6", badge: "v6", value: primaryIpv6 }, { label: "DNS نسل 6", badge: "v6", value: secondaryIpv6 }, ].filter((row) => row.value); return (
{dnsRegistrationExpired && ( مهلت ثبت آی‌پی برای این سرویس به پایان رسیده است )} {dnsIpPending && !dnsRegistrationExpired && ( ثبت آی‌پی این سرویس در انتظار تایید است )} {ipRows.length > 0 && (
آدرس‌های DNS
{ipRows.map((row, index) => (
{row.badge} {row.label}
{row.value}
))}
)}
در صورت روشن بودن فیلترشکن (VPN)، برای ثبت صحیح آی‌پی، لطفا ابتدا آن را خاموش کنید.
ثبت آی‌پی
setIp(e.target.value)} extra="!text-start" />
); }; export default ModalDnsConfig;