Files
persian-ping-frontend/src/pages/profile/section/components/ModalConfigDetails.tsx
soheil khaledabadi 8b6c0b07de fix: remove expired status from profile filter, show order code
- 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
2026-09-04 17:34:52 +03:30

233 lines
8.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;