diff --git a/.env b/.env index 45a49705..fe95eddb 100644 --- a/.env +++ b/.env @@ -5,3 +5,6 @@ NEXT_PUBLIC_SUBGRAPH_URL=https://api.studio.thegraph.com/query/67235/mento-celo/ NEXT_PUBLIC_SUBGRAPH_URL_ALFAJORES=https://api.studio.thegraph.com/query/67235/mento-alfajores/version/latest NEXT_PUBLIC_WALLET_CONNECT_ID=f6fc31fb4c4e660595895d3cca81d304 + +NEXT_PUBLIC_SENTRY_DSN=https://b6c8f7b9cb466185a7a62fa432a9961d@o4504211835256832.ingest.us.sentry.io/4507407772352512 +SENTRY_DSN=https://b6c8f7b9cb466185a7a62fa432a9961d@o4504211835256832.ingest.us.sentry.io/4507407772352512 diff --git a/next.config.js b/next.config.js index ae6ad44c..221f9f13 100644 --- a/next.config.js +++ b/next.config.js @@ -22,45 +22,41 @@ const nextConfig = { module.exports = nextConfig; - // Injected content via Sentry wizard below const { withSentryConfig } = require("@sentry/nextjs"); -module.exports = withSentryConfig( - module.exports, - { - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options +module.exports = withSentryConfig(module.exports, { + // For all available options, see: + // https://github.com/getsentry/sentry-webpack-plugin#options - org: "mento-labs", - project: "governance-ui", + org: "mento-labs", + project: "governance-ui", - // Only print logs for uploading source maps in CI - silent: !process.env.CI, + // Only print logs for uploading source maps in CI + silent: !process.env.CI, - // For all available options, see: - // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ + // For all available options, see: + // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ - // Upload a larger set of source maps for prettier stack traces (increases build time) - widenClientFileUpload: true, + // Upload a larger set of source maps for prettier stack traces (increases build time) + widenClientFileUpload: true, - // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. - // This can increase your server load as well as your hosting bill. - // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- - // side errors will fail. - // tunnelRoute: "/monitoring", + // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. + // This can increase your server load as well as your hosting bill. + // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- + // side errors will fail. + tunnelRoute: "/monitoring", - // Hides source maps from generated client bundles - hideSourceMaps: true, + // Hides source maps from generated client bundles + hideSourceMaps: true, - // Automatically tree-shake Sentry logger statements to reduce bundle size - disableLogger: true, + // Automatically tree-shake Sentry logger statements to reduce bundle size + disableLogger: true, - // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) - // See the following for more information: - // https://docs.sentry.io/product/crons/ - // https://vercel.com/docs/cron-jobs - automaticVercelMonitors: true, - } -); + // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) + // See the following for more information: + // https://docs.sentry.io/product/crons/ + // https://vercel.com/docs/cron-jobs + automaticVercelMonitors: true, +}); diff --git a/sentry.client.config.ts b/sentry.client.config.ts index df4838b0..f87404c6 100644 --- a/sentry.client.config.ts +++ b/sentry.client.config.ts @@ -4,8 +4,10 @@ import * as Sentry from "@sentry/nextjs"; +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + Sentry.init({ - dsn: "https://b6c8f7b9cb466185a7a62fa432a9961d@o4504211835256832.ingest.us.sentry.io/4507407772352512", + dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, diff --git a/sentry.edge.config.ts b/sentry.edge.config.ts index 9ab7c256..0aeb4e07 100644 --- a/sentry.edge.config.ts +++ b/sentry.edge.config.ts @@ -5,8 +5,10 @@ import * as Sentry from "@sentry/nextjs"; +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + Sentry.init({ - dsn: "https://b6c8f7b9cb466185a7a62fa432a9961d@o4504211835256832.ingest.us.sentry.io/4507407772352512", + dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, diff --git a/sentry.server.config.ts b/sentry.server.config.ts index 8ac52e05..8fbe139b 100644 --- a/sentry.server.config.ts +++ b/sentry.server.config.ts @@ -4,8 +4,10 @@ import * as Sentry from "@sentry/nextjs"; +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + Sentry.init({ - dsn: "https://b6c8f7b9cb466185a7a62fa432a9961d@o4504211835256832.ingest.us.sentry.io/4507407772352512", + dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, @@ -15,5 +17,4 @@ Sentry.init({ // Uncomment the line below to enable Spotlight (https://spotlightjs.com) // spotlight: process.env.NODE_ENV === 'development', - }); diff --git a/src/app/(routes)/create-proposal/page.tsx b/src/app/create-proposal/page.tsx similarity index 100% rename from src/app/(routes)/create-proposal/page.tsx rename to src/app/create-proposal/page.tsx diff --git a/src/app/(routes)/layout.tsx b/src/app/layout.tsx similarity index 71% rename from src/app/(routes)/layout.tsx rename to src/app/layout.tsx index 757e59e0..34f2f39f 100644 --- a/src/app/(routes)/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,3 @@ -"use client"; import React, { ReactNode } from "react"; import { Analytics } from "@vercel/analytics/react"; import { Inter } from "next/font/google"; @@ -12,9 +11,9 @@ import { } from "@/components/_shared"; import "@rainbow-me/rainbowkit/styles.css"; import "@/styles/globals.scss"; -import { Providers } from "@/app/(routes)/providers"; -import { usePathname } from "next/navigation"; +import { Providers } from "@/app/providers"; import { cn } from "@/styles/helpers"; +import { Metadata } from "next"; const inter = Inter({ subsets: ["latin"], @@ -26,10 +25,30 @@ interface RootLayoutProps { children: ReactNode; } -export default function RootLayout({ children }: RootLayoutProps) { - const path = usePathname(); - const homePage = path === "/"; +export const metadata: Metadata = { + title: "Mento Governance", + description: "Mento governance platform.", + openGraph: { + url: "https://governance.mento.org", + type: "website", + title: "Mento Governance", + description: "Mento governance platform.", + }, + robots: { + index: false, + follow: true, + nocache: true, + googleBot: { + index: true, + follow: false, + noimageindex: true, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, +}; +export default function RootLayout({ children }: RootLayoutProps) { return (
- {!homePage && } + {children} diff --git a/src/app/(routes)/my-voting-power/page.tsx b/src/app/my-voting-power/page.tsx similarity index 100% rename from src/app/(routes)/my-voting-power/page.tsx rename to src/app/my-voting-power/page.tsx diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 00000000..470f9c0c --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,5 @@ +import { RedirectType, redirect } from "next/navigation"; + +export default function NotFoundPage() { + redirect("/", RedirectType.replace); +} diff --git a/src/app/opengraph-image.jpg b/src/app/opengraph-image.jpg new file mode 100644 index 00000000..a7b90aa1 Binary files /dev/null and b/src/app/opengraph-image.jpg differ diff --git a/src/app/(routes)/page.tsx b/src/app/page.tsx similarity index 76% rename from src/app/(routes)/page.tsx rename to src/app/page.tsx index 69733d02..d3a974fa 100644 --- a/src/app/(routes)/page.tsx +++ b/src/app/page.tsx @@ -1,22 +1,16 @@ "use client"; - import { Suspense } from "react"; import { useAccount } from "wagmi"; - -import { CeloLogoIcon, MentoIcon } from "@/components/_icons"; +import { MentoIcon } from "@/components/_icons"; import { - Badge, Button, ButtonProps, Card, Divider, Loader, } from "@/components/_shared"; -import useTokens from "@/lib/contracts/useTokens"; -import NumbersService from "@/lib/helpers/numbers.service"; -import { formatUnits } from "viem"; -import Head from "next/head"; import { + Badges, ContractParams, ProposalSummaryComponent, ProposalsListComponent, @@ -24,12 +18,9 @@ import { import Link from "next/link"; import { cn } from "@/styles/helpers"; -const Page = () => { +export default function Page() { return (
- - Mento Governance - <Subtitle /> <Card className="mt-8 md:mt-[55px]" block> @@ -53,7 +44,7 @@ const Page = () => { </Suspense> </main> ); -}; +} const MobileNavigationLinks = ({ className }: ButtonProps) => { const { address } = useAccount(); @@ -72,30 +63,6 @@ const MobileNavigationLinks = ({ className }: ButtonProps) => { </Link> ); }; - -const Badges = () => { - const { - mentoContractData: { totalSupply, decimals }, - } = useTokens(); - - const { chain } = useAccount(); - - return ( - <div className="flex flex-col gap-x3 md:flex-row"> - <Badge type="outline"> - <CeloLogoIcon /> -  {chain?.name || "Celo"}  - {chain?.testnet ? "Testnet" : "Mainnet"} - </Badge> - <Badge type="secondary"> - MENTO{" "} - {NumbersService.parseNumericValue(formatUnits(totalSupply, decimals))}{" "} - Supply - </Badge> - </div> - ); -}; - const DesktopTagline = () => ( <p className="mb-[20px] text-[18px] md:mb-[30px] md:text-[22px]"> Transparent Digital Asset Solutions @@ -141,5 +108,3 @@ const Subtitle = () => ( Participate in the governance process of Mento stablecoin platform </h2> ); - -export default Page; diff --git a/src/app/(routes)/proposals/[id]/_components/execution-code.component.tsx b/src/app/proposals/[id]/_components/execution-code.component.tsx similarity index 100% rename from src/app/(routes)/proposals/[id]/_components/execution-code.component.tsx rename to src/app/proposals/[id]/_components/execution-code.component.tsx diff --git a/src/app/(routes)/proposals/[id]/_components/participants.component.tsx b/src/app/proposals/[id]/_components/participants.component.tsx similarity index 100% rename from src/app/(routes)/proposals/[id]/_components/participants.component.tsx rename to src/app/proposals/[id]/_components/participants.component.tsx diff --git a/src/app/(routes)/proposals/[id]/_components/vote.component.tsx b/src/app/proposals/[id]/_components/vote.component.tsx similarity index 100% rename from src/app/(routes)/proposals/[id]/_components/vote.component.tsx rename to src/app/proposals/[id]/_components/vote.component.tsx diff --git a/src/app/(routes)/proposals/[id]/page.tsx b/src/app/proposals/[id]/page.tsx similarity index 95% rename from src/app/(routes)/proposals/[id]/page.tsx rename to src/app/proposals/[id]/page.tsx index 64eff913..c38ddd26 100644 --- a/src/app/(routes)/proposals/[id]/page.tsx +++ b/src/app/proposals/[id]/page.tsx @@ -14,9 +14,9 @@ import { Status, WalletAddressWithCopy, } from "@/components/_shared"; -import Vote from "@/app/(routes)/proposals/[id]/_components/vote.component"; -import ExecutionCode from "@/app/(routes)/proposals/[id]/_components/execution-code.component"; -import Participants from "@/app/(routes)/proposals/[id]/_components/participants.component"; +import Vote from "@/app/proposals/[id]/_components/vote.component"; +import ExecutionCode from "@/app/proposals/[id]/_components/execution-code.component"; +import Participants from "@/app/proposals/[id]/_components/participants.component"; import { Countdown, ProposalCurrentVotes } from "@/components/index"; const Page = ({ params: { id } }: { params: { id: string } }) => { diff --git a/src/app/(routes)/providers.tsx b/src/app/providers.tsx similarity index 98% rename from src/app/(routes)/providers.tsx rename to src/app/providers.tsx index 3caf77a1..e2cc8f7d 100644 --- a/src/app/(routes)/providers.tsx +++ b/src/app/providers.tsx @@ -1,3 +1,4 @@ +"use client"; import { ReactNode, useEffect, useState } from "react"; import { WagmiProvider } from "wagmi"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; diff --git a/src/app/twitter-image.jpg b/src/app/twitter-image.jpg new file mode 100644 index 00000000..a7b90aa1 Binary files /dev/null and b/src/app/twitter-image.jpg differ diff --git a/src/components/_shared/breadcrumbs/breadcrumbs.component.tsx b/src/components/_shared/breadcrumbs/breadcrumbs.component.tsx index 62e35719..71c6064d 100644 --- a/src/components/_shared/breadcrumbs/breadcrumbs.component.tsx +++ b/src/components/_shared/breadcrumbs/breadcrumbs.component.tsx @@ -33,13 +33,15 @@ const Crumb = ({ path, index, last }: CrumbProps) => { }; export const Breadcrumbs = () => { - const paths = usePathname().split("/"); + const path = usePathname(); + const homePage = path === "/"; + const paths = path.split("/"); const crumbsPath = useMemo( () => paths.filter((path) => routingMap.has(path)), [paths], ); - return ( + return !homePage ? ( <nav className="mt-10 w-full font-inter text-[18px]/[20px] font-medium" aria-label="Breadcrumb" @@ -55,6 +57,8 @@ export const Breadcrumbs = () => { ))} </ol> </nav> + ) : ( + <></> ); }; diff --git a/src/components/_shared/learn-more/learn-more.component.tsx b/src/components/_shared/learn-more/learn-more.component.tsx index fa9a2c7d..e4729208 100644 --- a/src/components/_shared/learn-more/learn-more.component.tsx +++ b/src/components/_shared/learn-more/learn-more.component.tsx @@ -1,3 +1,4 @@ +"use client"; import { usePathname } from "next/navigation"; import BaseComponentProps from "@/interfaces/base-component-props.interface"; import { ChevronIcon, DiscordIcon, LearnMoreIcon } from "@/components/_icons"; diff --git a/src/components/_shared/theme-switch/theme-switch.component.tsx b/src/components/_shared/theme-switch/theme-switch.component.tsx index 63c96309..d5aa2294 100644 --- a/src/components/_shared/theme-switch/theme-switch.component.tsx +++ b/src/components/_shared/theme-switch/theme-switch.component.tsx @@ -1,3 +1,4 @@ +"use client"; import { DarkModeIcon, LightModeIcon } from "@/components/_icons"; import { useTheme } from "next-themes"; import { cn } from "@/styles/helpers"; diff --git a/src/components/badges/badges.component.tsx b/src/components/badges/badges.component.tsx new file mode 100644 index 00000000..0ca32e84 --- /dev/null +++ b/src/components/badges/badges.component.tsx @@ -0,0 +1,30 @@ +"use client"; +import { CeloLogoIcon } from "@/components/_icons"; +import { Badge } from "@/components/_shared"; +import useTokens from "@/lib/contracts/useTokens"; +import NumbersService from "@/lib/helpers/numbers.service"; +import { formatUnits } from "viem"; +import { useAccount } from "wagmi"; + +export const Badges = () => { + const { + mentoContractData: { totalSupply, decimals }, + } = useTokens(); + + const { chain } = useAccount(); + + return ( + <div className="flex flex-col gap-x3 md:flex-row"> + <Badge type="outline"> + <CeloLogoIcon /> +  {chain?.name || "Celo"}  + {chain?.testnet ? "Testnet" : "Mainnet"} + </Badge> + <Badge type="secondary"> + MENTO{" "} + {NumbersService.parseNumericValue(formatUnits(totalSupply, decimals))}{" "} + Supply + </Badge> + </div> + ); +}; diff --git a/src/components/index.tsx b/src/components/index.tsx index 4b027976..050693b1 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -1,3 +1,4 @@ +export { Badges } from "./badges/badges.component"; export { ContractParams } from "./contract-params/contract-params.component"; export { Countdown } from "./countdown/countdown.component"; export { LocksList } from "./locks-list/locks-list.component"; diff --git a/src/lib/contracts/useTokens.ts b/src/lib/contracts/useTokens.ts index 80e503fc..2cc7f74f 100644 --- a/src/lib/contracts/useTokens.ts +++ b/src/lib/contracts/useTokens.ts @@ -1,3 +1,4 @@ +"use client"; import { useAccount, useBlockNumber, useReadContracts } from "wagmi"; import { useContracts } from "@/lib/contracts/useContracts"; import { useEffect, useMemo } from "react"; diff --git a/src/lib/hooks/useEnsureChain.ts b/src/lib/hooks/useEnsureChain.ts index 5c5a39ea..527ef3f9 100644 --- a/src/lib/hooks/useEnsureChain.ts +++ b/src/lib/hooks/useEnsureChain.ts @@ -1,3 +1,4 @@ +"use client"; import { Alfajores, Celo } from "@/config/chains"; import { useEffect } from "react"; import { useAccount, useSwitchChain } from "wagmi";