diff --git a/explorer-v2/envs/config.ts b/explorer-v2/envs/config.ts
new file mode 100644
index 0000000000..9b7df4287f
--- /dev/null
+++ b/explorer-v2/envs/config.ts
@@ -0,0 +1,88 @@
+import { type Environment } from "../src/providers/EnvironmentProvider";
+
+interface EnvConfig {
+ envName: Environment;
+ basePath: string;
+ apiUrl?: string;
+}
+
+function log(message?: any, ...optionalParams: any[]) {
+ if (
+ process.env.NODE_ENV === "development" ||
+ process.env.DEBUG_CONFIG_LOGS === "true"
+ ) {
+ console.log(message, ...optionalParams);
+ }
+}
+
+// export function getCurrentEnv(): Environment {
+// // Check for VERCEL_ENV from .env file
+// if (process.env.VERCEL_ENV === "sandbox") {
+// return "sandbox";
+// }
+// if (process.env.VERCEL_ENV === "production") {
+// return "mainnet";
+// }
+
+// // Check for environment-specific deployment branches
+// if (process.env.VERCEL_GIT_COMMIT_REF === "deploy/sandbox") {
+// return "sandbox";
+// }
+// if (process.env.VERCEL_GIT_COMMIT_REF === "deploy/mainnet") {
+// return "mainnet";
+// }
+
+// // Check for NODE_ENV
+// if (process.env.NODE_ENV === "production") {
+// return "mainnet";
+// }
+
+// // Default to mainnet for development
+// return "mainnet";
+// }
+
+function getMainnetEnv(): EnvConfig {
+ return {
+ envName: "mainnet",
+ basePath: "/explorer",
+ // apiUrl:
+ // process.env.NEXT_PUBLIC_MAINNET_API_URL || "https://nym.com/explorer",
+ };
+}
+
+function getSandboxEnv(): EnvConfig {
+ return {
+ envName: "sandbox",
+ basePath: "/sandbox-explorer",
+ // apiUrl:
+ // process.env.NEXT_PUBLIC_SANDBOX_API_URL ||
+ // "https://nym.com/sandbox-explorer",
+ };
+}
+
+export const getEnvByName = (name: Environment): EnvConfig => {
+ if (name === "sandbox") {
+ return getSandboxEnv();
+ }
+ if (name === "mainnet") {
+ return getMainnetEnv();
+ }
+
+ // Default to mainnet
+ log("🐼 using mainnet env vars");
+ return getMainnetEnv();
+};
+
+// export const getEnv = (): EnvConfig => {
+// const currentEnv = getCurrentEnv();
+// log(`currentEnv = "${currentEnv}"`);
+// return getEnvByName(currentEnv);
+// };
+
+export const getBasePathByEnv = (env: Environment): string => {
+ return getEnvByName(env).basePath;
+};
+
+// export const getApiUrlByEnv = (env: Environment): string => {
+// return getEnvByName(env).apiUrl;
+// };
diff --git a/explorer-v2/next.config.ts b/explorer-v2/next.config.ts
index 02e12b3e1c..a3f998889f 100644
--- a/explorer-v2/next.config.ts
+++ b/explorer-v2/next.config.ts
@@ -2,19 +2,29 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactStrictMode: true,
-
- basePath: "/explorer",
- assetPrefix: "/explorer",
trailingSlash: false,
- async redirects() {
+ async rewrites() {
return [
- // Change the basePath to /explorer
+ // Rewrite /sandbox-explorer to root
{
- source: "/",
- destination: "/explorer",
- basePath: false,
- permanent: true,
+ source: "/sandbox-explorer",
+ destination: "/",
+ },
+ // Rewrite /explorer to root
+ {
+ source: "/explorer",
+ destination: "/",
+ },
+ // Rewrite /sandbox-explorer/* to /*
+ {
+ source: "/sandbox-explorer/:path*",
+ destination: "/:path*",
+ },
+ // Rewrite /explorer/* to /*
+ {
+ source: "/explorer/:path*",
+ destination: "/:path*",
},
];
},
diff --git a/explorer-v2/src/app/(pages)/account/[address]/not-found/AccountNotFoundClient.tsx b/explorer-v2/src/app/(pages)/account/[address]/not-found/AccountNotFoundClient.tsx
new file mode 100644
index 0000000000..d4c2ccd022
--- /dev/null
+++ b/explorer-v2/src/app/(pages)/account/[address]/not-found/AccountNotFoundClient.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import ExplorerButtonGroup from "@/components/toggleButton/ToggleButton";
+import { useEnvironment } from "@/providers/EnvironmentProvider";
+import { getBasePathByEnv } from "../../../../../../envs/config";
+
+interface AccountNotFoundClientProps {
+ address: string;
+}
+
+export default function AccountNotFoundClient({
+ address,
+}: AccountNotFoundClientProps) {
+ const { environment } = useEnvironment();
+ const basePath = getBasePathByEnv(environment || "mainnet");
+
+ return (
+
+ );
+}
diff --git a/explorer-v2/src/app/(pages)/account/[address]/not-found/page.tsx b/explorer-v2/src/app/(pages)/account/[address]/not-found/page.tsx
index 2cbac6434d..23f582c7bd 100644
--- a/explorer-v2/src/app/(pages)/account/[address]/not-found/page.tsx
+++ b/explorer-v2/src/app/(pages)/account/[address]/not-found/page.tsx
@@ -1,62 +1,33 @@
-// import BlogArticlesCards from "@/components/blogs/BlogArticleCards";
import { ContentLayout } from "@/components/contentLayout/ContentLayout";
import SectionHeading from "@/components/headings/SectionHeading";
-import ExplorerButtonGroup from "@/components/toggleButton/ToggleButton";
import { Box, Typography } from "@mui/material";
import Grid from "@mui/material/Grid2";
import Markdown from "react-markdown";
+import AccountNotFoundClient from "./AccountNotFoundClient";
-export default async function Account({
+export default async function AccountNotFound({
params,
}: {
params: Promise<{ address: string }>;
}) {
- try {
- const address = (await params).address;
+ const { address } = await params;
- return (
-
-
-
-
-
-
-
-
+ return (
+
+
+
+
+
+
+
-
-
- This account does’t have a Nym node bonded. Is this your account?
- Start [setting up your node](https://nym.com/docs) today!
-
-
- {/*
-
-
-
-
- */}
-
- );
- } catch (error) {
- let errorMessage = "An error occurred";
- if (error instanceof Error) {
- errorMessage = error.message;
- }
- throw new Error(errorMessage);
- }
+
+
+
+ This account does't have a Nym node bonded. Is this your account?
+ Start [setting up your node](https://nym.com/docs) today!
+
+
+
+ );
}
diff --git a/explorer-v2/src/components/accountPageComponents/AccountBalancesCard.tsx b/explorer-v2/src/components/accountPageComponents/AccountBalancesCard.tsx
index 4782b4c2b0..ed3de0e967 100644
--- a/explorer-v2/src/components/accountPageComponents/AccountBalancesCard.tsx
+++ b/explorer-v2/src/components/accountPageComponents/AccountBalancesCard.tsx
@@ -81,17 +81,18 @@ export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
const {
data: nymPrice,
- isLoading: isLoadingPrice,
- error: priceError,
+ isLoading: isNymPriceLoading,
+ isError: isNymPriceError,
} = useQuery({
queryKey: ["nymPrice"],
queryFn: fetchNymPrice,
staleTime: 10 * 60 * 1000, // 10 minutes
refetchOnWindowFocus: false, // Prevents unnecessary refetching
refetchOnReconnect: false,
+ refetchOnMount: false,
});
- if (isLoading || isLoadingPrice) {
+ if (isLoading || isNymPriceLoading) {
return (
@@ -102,7 +103,7 @@ export const AccountBalancesCard = (props: IAccountBalancesCardProps) => {
);
}
- if (isError || priceError || !accountInfo || !nymPrice) {
+ if (isError || isNymPriceError || !accountInfo || !nymPrice) {
return (
+
+
+
);
}
diff --git a/explorer-v2/src/components/header/DesktopHeader.tsx b/explorer-v2/src/components/header/DesktopHeader.tsx
index 19433c1122..1eca8c8440 100644
--- a/explorer-v2/src/components/header/DesktopHeader.tsx
+++ b/explorer-v2/src/components/header/DesktopHeader.tsx
@@ -28,7 +28,7 @@ export const DesktopHeader = () => {
}}
>
{
const theme = useTheme();
const { environment, setEnvironment } = useEnvironment();
-
+ const router = useRouter();
+ const pathname = usePathname();
const explorerName = environment
? `${environment} Explorer`
@@ -16,10 +19,23 @@ export const Environment: React.FC = () => {
const switchNetworkText =
environment === "mainnet" ? "Switch to Testnet" : "Switch to Mainnet";
- const switchNetworkLink = environment === "mainnet" ? "/" : "/";
+ const getCurrentInternalPath = () => {
+ // Remove the base path from the current pathname to get the internal path
+ return pathname.replace(/^\/(explorer|sandbox-explorer)/, "") || "/";
+ };
const handleSwitchEnvironment = () => {
- setEnvironment(environment === "mainnet" ? "sandbox" : "mainnet");
+ const newEnvironment = environment === "mainnet" ? "sandbox" : "mainnet";
+ setEnvironment(newEnvironment);
+
+ // Get the current internal path and build the new path
+ const currentInternalPath = getCurrentInternalPath();
+ const newBasePath = getBasePathByEnv(newEnvironment);
+ const newPath =
+ currentInternalPath === "/"
+ ? newBasePath
+ : `${newBasePath}${currentInternalPath}`;
+ router.push(newPath);
};
return (
@@ -33,7 +49,7 @@ export const Environment: React.FC = () => {
}}
>
{
variant="outlined"
color="inherit"
onClick={handleSwitchEnvironment}
- href={switchNetworkLink}
sx={{
borderRadius: 2,
textTransform: "none",
diff --git a/explorer-v2/src/components/header/HeaderItem.tsx b/explorer-v2/src/components/header/HeaderItem.tsx
index 9f39b25792..992e8edece 100644
--- a/explorer-v2/src/components/header/HeaderItem.tsx
+++ b/explorer-v2/src/components/header/HeaderItem.tsx
@@ -4,6 +4,8 @@ import { Circle } from "@mui/icons-material";
import { Button, Stack } from "@mui/material";
import Link from "next/link";
import { usePathname } from "next/navigation";
+import { useEnvironment } from "../../providers/EnvironmentProvider";
+import { getBasePathByEnv } from "../../../envs/config";
import type { MenuItem } from "./menuItems";
type HeaderItemProps = {
@@ -12,10 +14,13 @@ type HeaderItemProps = {
const HeaderItem = ({ menu }: HeaderItemProps) => {
const pathname = usePathname();
+ const { environment } = useEnvironment();
+ const basePath = getBasePathByEnv(environment || "mainnet");
+
return (
{pathname.includes(menu.url) && }
-
+