Skip to content

Commit

Permalink
add two api types to main branch
Browse files Browse the repository at this point in the history
  • Loading branch information
MatinDehghanian committed Nov 5, 2024
1 parent 7b3ea3b commit b016b3a
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 75 deletions.
66 changes: 44 additions & 22 deletions src/components/ClientTab/Configs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,45 @@ import {
extractNameFromConfigURL,
handleCopyToClipboard,
} from "../../utils/Helper.js";
import GetInfoRequest from "../../utils/GetInfoRequest.js";

const Configs = ({ data }) => {

const filteredLinks = useMemo(() => {
if (data?.links && data.links[data.links.length - 1] === "False") {
return data.links.slice(0, -1);
const [dataLinks, setDataLinks] = useState([]);

useEffect(() => {
if (data?.links) {
// Use links directly if available
const links =
data.links[data.links.length - 1] === "False"
? data.links.slice(0, -1)
: data.links;
setDataLinks(links);
} else {
// Fetch and decode links if not provided in data
GetInfoRequest.getConfigs().then((res) => {
const decodedLinks = decodeBase64(res.data.trim());
const configArray = decodedLinks ? decodedLinks.split("\n") : [];
setDataLinks(
configArray[configArray.length - 1] === "False"
? configArray.slice(0, -1)
: configArray
);
});
}
return data?.links || [];
}, [data?.links]);

const [icons, setIcons] = useState([]);
const [iconClasses, setIconClasses] = useState([]);

useEffect(() => {
if (filteredLinks) {
setIcons(filteredLinks.map(() => faClipboard));
setIconClasses(filteredLinks.map(() => "icon-copy"));
if (dataLinks) {
setIcons(dataLinks.map(() => faClipboard));
setIconClasses(dataLinks.map(() => "icon-copy"));
}
}, [filteredLinks]);
}, [dataLinks]);

const [show, setShow] = useState(false);
const [modalTitle, setModalTitle] = useState(false);
const [modalTitle, setModalTitle] = useState("");
const [link, setLink] = useState("");
const [index, setIndex] = useState(null);

Expand All @@ -52,7 +69,7 @@ const Configs = ({ data }) => {
<>
<ListGroup className="nav-links">
<ListGroup.Item
key={-1}
key={-2}
value={SubUrl}
onClick={() =>
handleCopyToClipboard(SubUrl, -2, setIcons, setIconClasses)
Expand All @@ -79,19 +96,14 @@ const Configs = ({ data }) => {
/>
</div>
</ListGroup.Item>
{filteredLinks?.map((link, index) => {
{dataLinks?.map((link, index) => {
const title = extractNameFromConfigURL(link);
return (
<ListGroup.Item
key={index}
value={filteredLinks?.[index]}
value={link}
onClick={() =>
handleCopyToClipboard(
filteredLinks?.[index],
index,
setIcons,
setIconClasses
)
handleCopyToClipboard(link, index, setIcons, setIconClasses)
}
>
<div className="title-a">{title}</div>
Expand All @@ -103,7 +115,7 @@ const Configs = ({ data }) => {
onClick={(e) => {
e.stopPropagation();
handleCopyToClipboard(
filteredLinks?.[index],
link,
index,
setIcons,
setIconClasses
Expand All @@ -115,7 +127,7 @@ const Configs = ({ data }) => {
icon={faQrcode}
onClick={(e) => {
e.stopPropagation();
handleShow(title, filteredLinks?.[index], index);
handleShow(title, link, index);
}}
/>
</div>
Expand All @@ -125,7 +137,7 @@ const Configs = ({ data }) => {
<Button
onClick={() =>
handleCopyToClipboard(
filteredLinks.join("\n"),
dataLinks.join("\n"),
-1,
setIcons,
setIconClasses
Expand Down Expand Up @@ -161,3 +173,13 @@ const Configs = ({ data }) => {
};

export default Configs;

function decodeBase64(encodedString) {
try {
const decodedString = atob(encodedString);
return decodedString;
} catch (error) {
console.error("Failed to decode base64:", error);
return "";
}
}
127 changes: 92 additions & 35 deletions src/components/ServiceInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,37 @@ const ServiceInfo = ({ data }) => {
remainingTraffic: "",
});

const statusMapping = {
// Determine API type
const isMarzban = data?.status !== undefined;

// Define status mapping for both API types
const statusMappingMarzbanApi = {
on_hold: { color: "yellow", detail: "در انتظار اتصال" },
expired: { color: "orange", detail: "منقضی شده" },
limited: { color: "brown", detail: "محدود شده" },
active: { color: "green", detail: "فعال" },
default: { color: "red", detail: "غیرفعال" },
};

const currentStatus = statusMapping[data?.status] || statusMapping.default;
const statusMappingMarzneshinApi = {
expired: { color: "orange", detail: "منقضی شده" },
data_limit_reached: { color: "brown", detail: "حجم تمام شده" },
inactive: { color: "red", detail: "غیرفعال" },
active: { color: "green", detail: "فعال" },
limited: { color: "yellow", detail: "محدود شده" },
default: { color: "gray", detail: "نامشخص" },
};

// Determine status and status detail based on API type
const currentStatus = isMarzban
? statusMappingMarzbanApi[data?.status] || statusMappingMarzbanApi.default
: data?.expired
? statusMappingMarzneshinApi.expired
: data?.data_limit_reached
? statusMappingMarzneshinApi.data_limit_reached
: data?.is_active
? statusMappingMarzneshinApi.active
: statusMappingMarzneshinApi.inactive; // Fallback to inactive or default

const statusColor = currentStatus.color;
const statusDetail = currentStatus.detail;
Expand All @@ -54,45 +76,80 @@ const ServiceInfo = ({ data }) => {

useEffect(() => {
if (data) {
const {
online_at: onlineAt,
created_at: createdAt,
expire,
used_traffic: usedTraffic,
data_limit: dataLimit,
} = data;

setServiceInfo({
formattedDate: onlineAt ? formatDate(onlineAt) : "نامشخص",
createdDate: createdAt ? formatDate(createdAt) : "نامشخص",
formattedExpireDate: expire ? formatExpireDate(expire) : "نامحدود",
remainingTime: expire ? (
calculateRemainingTime(expire)
) : (
<FontAwesomeIcon size="lg" icon={faInfinity} />
),
formattedTraffic:
usedTraffic !== 0 ? formatTraffic(usedTraffic) : "0 MB",
totalTraffic: dataLimit !== null ? formatTraffic(dataLimit) : "نامحدود",
remainingTraffic:
dataLimit !== null && dataLimit !== undefined ? (
dataLimit - (usedTraffic ?? 0) < 0 ? (
"منفی"
if (isMarzban) {
const {
online_at: onlineAt,
created_at: createdAt,
expire,
used_traffic: usedTraffic,
data_limit: dataLimit,
} = data;

setServiceInfo({
formattedDate: onlineAt ? formatDate(onlineAt) : "نامشخص",
createdDate: createdAt ? formatDate(createdAt) : "نامشخص",
formattedExpireDate: expire ? formatExpireDate(expire) : "نامحدود",
remainingTime: expire ? (
calculateRemainingTime(expire)
) : (
<FontAwesomeIcon size="lg" icon={faInfinity} />
),
formattedTraffic:
usedTraffic !== 0 ? formatTraffic(usedTraffic) : "0 MB",
totalTraffic:
dataLimit !== null ? formatTraffic(dataLimit) : "نامحدود",
remainingTraffic:
dataLimit !== null && dataLimit !== undefined ? (
dataLimit - (usedTraffic ?? 0) < 0 ? (
"منفی"
) : (
formatTraffic(dataLimit - (usedTraffic ?? 0))
)
) : (
formatTraffic(dataLimit - (usedTraffic ?? 0))
)
<FontAwesomeIcon size="lg" icon={faInfinity} />
),
});
} else {
const {
online_at: onlineAt,
created_at: createdAt,
expire_date: expire,
used_traffic: usedTraffic,
data_limit: dataLimit,
} = data;

setServiceInfo({
formattedDate: onlineAt ? formatDate(onlineAt) : "نامشخص",
createdDate: createdAt ? formatDate(createdAt) : "نامشخص",
formattedExpireDate: expire ? formatExpireDate(expire) : "نامحدود",
remainingTime: expire ? (
calculateRemainingTime(expire)
) : (
<FontAwesomeIcon size="lg" icon={faInfinity} />
),
});
formattedTraffic:
usedTraffic !== 0 ? formatTraffic(usedTraffic) : "0 MB",
totalTraffic:
dataLimit !== null ? formatTraffic(dataLimit) : "نامحدود",
remainingTraffic:
dataLimit !== null && dataLimit !== undefined ? (
dataLimit - (usedTraffic ?? 0) < 0 ? (
"منفی"
) : (
formatTraffic(dataLimit - (usedTraffic ?? 0))
)
) : (
<FontAwesomeIcon size="lg" icon={faInfinity} />
),
});
}
}
}, [data]);
}, [data, isMarzban]);

const [show, setShow] = useState(false);

const handleClose = () => setShow(false);
const handleShow = () => {
setShow(true);
};
const handleShow = () => setShow(true);

const {
formattedDate,
Expand Down Expand Up @@ -206,12 +263,12 @@ const ServiceInfo = ({ data }) => {
className="img-fluid"
value={SubUrl}
cursor={"pointer"}
onClick={() => handleCopyToClipboard(SubUrl)}
onClick={(e) => handleCopyToClipboard(SubUrl, e)}
/>
</Modal.Body>
</Modal>
</>
);
};

export default ServiceInfo;
export default ServiceInfo;
26 changes: 23 additions & 3 deletions src/utils/GetInfoRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,31 @@ export default class GetInfoRequest extends Request {
toastError: true,
}
);
return response; // Return the response if needed
return response;
} catch (error) {
// Handle any additional errors if needed
console.error("Error fetching info:", error);
throw error; // Re-throw to handle it further up if needed
throw error;
}
}

static async getConfigs() {
const pathname = `${
import.meta.env?.VITE_PANEL_DOMAIN || window.location.origin
}${window.location.pathname.split("#")[0]}`;

try {
const response = await GetInfoRequest.send(
`${pathname}`,
"GET",
{},
{
toastError: true,
}
);
return response;
} catch (error) {
console.error("Error fetching info:", error);
throw error;
}
}
}
Loading

0 comments on commit b016b3a

Please sign in to comment.