diff --git a/src/pages/admin/AdminPage.tsx b/src/pages/admin/AdminPage.tsx index ebf2d787..ac7b56bb 100644 --- a/src/pages/admin/AdminPage.tsx +++ b/src/pages/admin/AdminPage.tsx @@ -1,5 +1,8 @@ +import { ReactNode, useEffect, useState } from "react"; + import { ThinContainer } from "@/components/layout/ThinContainer"; -import { Heading1, Paragraph } from "@/components/utils/Text"; +import { Divider } from "@/components/utils/Divider"; +import { Heading1, Heading2, Paragraph } from "@/components/utils/Text"; import { SubPageLayout } from "@/pages/layouts/SubPageLayout"; import { ConfigValuesPart } from "@/pages/parts/admin/ConfigValuesPart"; import { TMDBTestPart } from "@/pages/parts/admin/TMDBTestPart"; @@ -7,7 +10,69 @@ import { WorkerTestPart } from "@/pages/parts/admin/WorkerTestPart"; import { BackendTestPart } from "../parts/admin/BackendTestPart"; +function ConfigValue(props: { name: string; children?: ReactNode }) { + return ( + <> +
+

{props.name}

+

{props.children}

+
+ + + ); +} + +async function getRecentPlayedItems() { + const response = await fetch("https://backend.sudo-flix.lol/metrics"); + const text = await response.text(); + + const regex = + /mw_media_watch_count{tmdb_full_id="([^"]+)",provider_id="([^"]+)",title="([^"]+)",success="([^"]+)"} (\d+)/g; + let match; + const loop = true; + const items = []; + + while (loop) { + match = regex.exec(text); + if (match === null) break; + + const [_, tmdbFullId, providerId, title, success, count] = match; + items.push({ + tmdbFullId, + providerId, + title, + success: success === "true", + count: parseInt(count, 10), + }); + } + + if (items.length > 0) { + return items; + } + throw new Error("RECENT_PLAYED_ITEMS not found"); +} + export function AdminPage() { + const [recentPlayedItems, setRecentPlayedItems] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + getRecentPlayedItems() + .then((items) => { + setRecentPlayedItems(items); + }) + .catch((error) => { + console.error("Error fetching recent played items:", error); + }) + .finally(() => { + setLoading(false); + }); + }, []); + + if (loading) { + return

Loading...

; + } + return ( @@ -18,6 +83,20 @@ export function AdminPage() { +
+ Recently Played List +

+ This data is fetched from the current backend deployment. +

+ {recentPlayedItems.map((item) => { + const successText = item.success ? "Yes" : "No"; // Convert bool to "Yes" or "No" + return ( + + {`${item.providerId} - Provided: ${successText}, Views: ${item.count}`} + + ); + })} +
); diff --git a/src/pages/parts/admin/ConfigValuesPart.tsx b/src/pages/parts/admin/ConfigValuesPart.tsx index 15b748ec..dce783b2 100644 --- a/src/pages/parts/admin/ConfigValuesPart.tsx +++ b/src/pages/parts/admin/ConfigValuesPart.tsx @@ -8,23 +8,41 @@ async function getAccountNumber() { const response = await fetch("https://backend.sudo-flix.lol/metrics"); const text = await response.text(); - const regex1 = - /mw_provider_hostname_count{hostname="https:\/\/sudo-flix.lol"} (\d+)/; - const match1 = text.match(regex1); - const regex2 = /mw_user_count{namespace="movie-web"} (\d+)/; - const match2 = text.match(regex2); + // Adjusted regex to match any hostname + const regex = + /mw_provider_hostname_count{hostname="https?:\/\/[^"}]+"} (\d+)/g; + let total = 0; + let match = regex.exec(text); // Initial assignment outside the loop - if (match1 && match2) { - return match1[1] + match2[1]; + while (match !== null) { + total += parseInt(match[1], 10); + match = regex.exec(text); // Update the assignment at the end of the loop body + } + + if (total > 0) { + return total.toString(); } throw new Error("ACCOUNT_NUMBER not found"); } +async function getAllAccounts() { + const response = await fetch("https://backend.sudo-flix.lol/metrics"); + const text = await response.text(); + + const regex = /mw_user_count{namespace="movie-web"} (\d+)/; + const match = text.match(regex); + + if (match) { + return match[1]; + } + throw new Error("USER_COUNT not found"); +} + function ConfigValue(props: { name: string; children?: ReactNode }) { return ( <>
-

{props.name}

+

{props.name}

{props.children}

@@ -34,7 +52,7 @@ function ConfigValue(props: { name: string; children?: ReactNode }) { export function ConfigValuesPart() { const [accountNumber, setAccountNumber] = useState(null); - const [loading, setLoading] = useState(true); + const [allAccounts, setAllAccounts] = useState(null); const normalRouter = conf().NORMAL_ROUTER; const appVersion = conf().APP_VERSION; const backendUrl = conf().BACKEND_URL; @@ -43,18 +61,20 @@ export function ConfigValuesPart() { getAccountNumber() .then((number) => { setAccountNumber(number); - setLoading(false); }) .catch((error) => { console.error("Error fetching account number:", error); - setLoading(false); + }); + + getAllAccounts() + .then((accounts) => { + setAllAccounts(accounts); + }) + .catch((error) => { + console.error("Error fetching all accounts:", error); }); }, []); - if (loading) { - return

Loading...

; - } - return ( <> Site Constants @@ -62,7 +82,8 @@ export function ConfigValuesPart() { {normalRouter ? "Normal routing" : "Hash based routing"} v{appVersion} - {accountNumber} + {accountNumber} + {allAccounts} {backendUrl} );