- Drop the now-unused "expired" filter option/status (the API never returns expired services anymore). - Show the order code next to each service in the config card and in the service details modal. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMLvfLviDB12t4U9UijE4k
233 lines
8.5 KiB
TypeScript
233 lines
8.5 KiB
TypeScript
import { Dispatch, SetStateAction, useState } from "react";
|
||
import MuiModal from "../../../../common/modal";
|
||
import Button from "../../../../components/button";
|
||
import { IoCopy, IoDownload } from "react-icons/io5";
|
||
import Alert from "../../../../components/alert/Alert";
|
||
import ProgressSpace from "../../../../components/progressSpace";
|
||
import toast from "react-hot-toast";
|
||
import { useNavigate } from "react-router-dom";
|
||
import { useDispatch } from "react-redux";
|
||
import { setCategoryId } from "../../../../redux/slices/categoryId";
|
||
import Input from "../../../../components/input";
|
||
import LoaderSpaceConfig from "./LoaderSpaceConfig";
|
||
import { AxiosError } from "axios";
|
||
import { downloadWireGuardConfig } from "../../utils/wireguardConfig";
|
||
|
||
const ModalConfigDetails = ({
|
||
isOpen,
|
||
setIsOpen,
|
||
isDisabled,
|
||
dateBuy,
|
||
orderId,
|
||
nameConfig,
|
||
isShowTraffic,
|
||
textCopy,
|
||
maxTraffic,
|
||
traffic,
|
||
type,
|
||
username,
|
||
password,
|
||
wireguardUsername,
|
||
categoryId,
|
||
isLoadSpaceConfig,
|
||
error,
|
||
useMaxTraffic,
|
||
}: {
|
||
isOpen: boolean;
|
||
setIsOpen: Dispatch<SetStateAction<boolean>>;
|
||
isDisabled: boolean;
|
||
dateBuy: string;
|
||
orderId?: number;
|
||
nameConfig: string;
|
||
isShowTraffic: boolean;
|
||
textCopy: string;
|
||
maxTraffic: number | "unlimited";
|
||
traffic: number;
|
||
type: string | null;
|
||
username: string;
|
||
password: string;
|
||
wireguardUsername?: string | null;
|
||
categoryId: number;
|
||
isLoadSpaceConfig: boolean;
|
||
error: AxiosError | Error | null;
|
||
useMaxTraffic: boolean;
|
||
}) => {
|
||
const navigate = useNavigate();
|
||
const dispatch = useDispatch();
|
||
const [isCopyError, setIsCopyError] = useState(false);
|
||
const configType = type ?? "";
|
||
const isWireGuard = configType.toLowerCase() === "wireguard";
|
||
|
||
const copyToClipboard = async (textToCopy: string) => {
|
||
try {
|
||
await navigator.clipboard.writeText(textToCopy);
|
||
|
||
toast.success("متن با موفقیت کپی شد!");
|
||
} catch (err) {
|
||
setIsCopyError(true);
|
||
toast.error(`Failed to copy: , ${err}`);
|
||
}
|
||
};
|
||
const downloadWireGuardFile = () => {
|
||
if (!textCopy) {
|
||
toast.error("کانفیگ وایرگارد موجود نیست");
|
||
return;
|
||
}
|
||
|
||
downloadWireGuardConfig(textCopy, wireguardUsername);
|
||
toast.success("فایل کانفیگ دانلود شد");
|
||
};
|
||
|
||
return (
|
||
<MuiModal
|
||
isOpenModal={isOpen}
|
||
setIsOpenModal={setIsOpen}
|
||
nameService={nameConfig}
|
||
>
|
||
{isDisabled && <Alert type="warning"> {nameConfig} غیر فعال است </Alert>}
|
||
<div className="w-full h-full flex flex-col p-3 gap-4 border-2 border-gray-800 rounded-md max-sm:text-xs max-md:text-sm text-base">
|
||
<h1 className="w-full h-full text-center rounded-md p-1 md:p-2 bg-gray-800">
|
||
تاریخ خرید : {dateBuy}
|
||
{orderId && (
|
||
<span className="block text-xs opacity-70 mt-1">
|
||
کد سفارش : #{orderId}
|
||
</span>
|
||
)}
|
||
</h1>
|
||
<div className="w-full h-full flex flex-row-reverse gap-2 flex-wrap justify-center items-center">
|
||
{isDisabled || useMaxTraffic ? (
|
||
<div className="w-full h-full flex flex-wrap justify-center items-center">
|
||
{/* <Button extra="!m-0 !px-2 !py-1 shadow-md flex-1 shadow-secondTheme !bg-secondTheme font-bold hover:!bg-gray-800 hover:!shadow-gray-800 ">
|
||
تمدید
|
||
</Button> */}
|
||
<div className="w-full h-full text-xs sm:text-sm md:text-base">
|
||
{useMaxTraffic ? (
|
||
<h1>مشترک گرامی کانفیگ شما به دلیل اتمام حجم غیر فعال است</h1>
|
||
) : isDisabled && (
|
||
<h1>مشترک گرامی کانفیگ شما به دلیل پایان اعتبار غیر فعال است</h1>
|
||
)}
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<>
|
||
{configType === "gaming" ? (
|
||
<>
|
||
{isCopyError ? (
|
||
<div className="w-full h-full flex flex-col gap-2">
|
||
<h1 className="bg-red-600 rounded-md p-1">
|
||
کاربر گرامی کپی خودکار موفقیت آمیز نبود لطفا به صورت
|
||
دستی از زیر انتخاب کرده و کپی کنید
|
||
</h1>
|
||
<Input
|
||
type="text"
|
||
value={`نام کاربری : ${username}`}
|
||
disabled={true}
|
||
/>
|
||
<Input
|
||
type="text"
|
||
value={`رمز عبور : ${password}`}
|
||
disabled={true}
|
||
/>
|
||
</div>
|
||
) : (
|
||
<>
|
||
<Button
|
||
onClick={() => {
|
||
copyToClipboard(password);
|
||
}}
|
||
extra="!m-0 !px-2 !py-1.5 flex flex-row-reverse justify-center items-center gap-1 shadow-md shadow-white"
|
||
>
|
||
کپی پسورد
|
||
<IoCopy />
|
||
</Button>
|
||
<Button
|
||
onClick={() => {
|
||
copyToClipboard(username);
|
||
}}
|
||
extra="!m-0 !px-2 !py-1.5 flex flex-row-reverse justify-center items-center gap-1 shadow-md shadow-white"
|
||
>
|
||
کپی یوزرنیم
|
||
<IoCopy />
|
||
</Button>
|
||
</>
|
||
)}
|
||
</>
|
||
) : (
|
||
<>
|
||
{isCopyError ? (
|
||
<>
|
||
<div className="w-full h-full flex flex-col gap-2">
|
||
<h1 className="bg-red-600 rounded-md p-1">
|
||
کاربر گرامی کپی خودکار موفقیت آمیز نبود لطفا به صورت
|
||
دستی از زیر انتخاب کرده و کپی کنید
|
||
</h1>
|
||
<textarea
|
||
value={textCopy}
|
||
className="outline-none border-none sm:text-sm rounded-lg block w-full p-2.5 md:p-3 bg-gray-700 border-gray-600 placeholder-gray-400 text-white"
|
||
disabled={true}
|
||
rows={8}
|
||
></textarea>
|
||
</div>
|
||
</>
|
||
) : (
|
||
<>
|
||
{isWireGuard ? (
|
||
<Button
|
||
onClick={downloadWireGuardFile}
|
||
extra="!m-0 !px-2 !py-1.5 flex flex-row-reverse justify-center items-center gap-1 shadow-md shadow-white"
|
||
>
|
||
دانلود فایل
|
||
<IoDownload />
|
||
</Button>
|
||
) : (
|
||
<Button
|
||
onClick={() => {
|
||
copyToClipboard(textCopy);
|
||
}}
|
||
extra="!m-0 !px-2 !py-1.5 flex flex-row-reverse justify-center items-center gap-1 shadow-md shadow-white"
|
||
>
|
||
کپی
|
||
<IoCopy />
|
||
</Button>
|
||
)}
|
||
</>
|
||
)}
|
||
</>
|
||
)}
|
||
<Button
|
||
onClick={() => {
|
||
if (categoryId) {
|
||
dispatch(setCategoryId(categoryId));
|
||
navigate("/tutorial");
|
||
}
|
||
}}
|
||
extra="!m-0 !px-2 !py-1.5 shadow-md shadow-white"
|
||
>
|
||
آموزش
|
||
</Button>
|
||
</>
|
||
)}
|
||
</div>
|
||
{!isDisabled && isShowTraffic && (
|
||
<div className="w-full h-full">
|
||
{isLoadSpaceConfig ? (
|
||
<div className="flex w-full h-full justify-center items-center">
|
||
<LoaderSpaceConfig />
|
||
</div>
|
||
) : error ? (
|
||
<div className="w-full h-full text-center">
|
||
{" "}
|
||
خطایی رخ داد : {error?.message}
|
||
</div>
|
||
) : (
|
||
<ProgressSpace startSpace={traffic} endSpace={maxTraffic} />
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</MuiModal>
|
||
);
|
||
};
|
||
|
||
export default ModalConfigDetails;
|