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) && } - +