Skip to content

Commit

Permalink
refactor - new refactor layout group, master context start
Browse files Browse the repository at this point in the history
  • Loading branch information
manishiwa committed Jul 23, 2024
1 parent 654310f commit ed3586d
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 0 deletions.
71 changes: 71 additions & 0 deletions app/(refactor)/refactor/contexts/Master.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"use client";
import { MasterURL } from "@/lib/urls";
import { MasterResponse } from "@/types/api/MasterResponse";
import { createContext, useContext, useState } from "react";
import useSWR from "swr";

type MasterContextType = {
data: MasterResponse;
formatMetric: (value: number, unit: string, unitType?: string) => string;
};

const MasterContext = createContext<MasterContextType | null>({
data: {} as MasterResponse,
formatMetric: () => "MasterProvider: formatMetric not found",
});

export const MasterProvider = ({ children }: { children: React.ReactNode }) => {
const { data, isLoading, error } = useSWR<MasterResponse>(MasterURL);

const formatMetric = (value: number, metric: string, unitType: string = "value") => {

if (metric === "gas_fees_usd") {
metric = "fees";
unitType = "usd";
}

if (!data) {
return `MasterProvider: data not found`;
}

const metricInfo = data.metrics[metric];

if (!metricInfo) {
return `MasterProvider: metricInfo not found: ${metric}`;
}

const unit = metricInfo.units[unitType];

if (!unit) {
return `MasterProvider: unitType not found: ${unitType}`;
}

const { currency, prefix, suffix, decimals, decimals_tooltip, agg, agg_tooltip } = unit;

return `${prefix || ""}${value.toLocaleString("en-GB", {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
})}${suffix || ""}`;
}

if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>

return (
<MasterContext.Provider
value={{ data, formatMetric }}
>
{children}
</MasterContext.Provider>
);
};

export const useMaster = () => {
const ctx = useContext(MasterContext);

if (!ctx) {
throw new Error("useMaster must be used within a MasterProvider");
}

return ctx;
}
193 changes: 193 additions & 0 deletions app/(refactor)/refactor/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { Raleway, Inter, Roboto_Mono } from "next/font/google";
import { Metadata } from "next";
import { Graph } from "schema-dts";
import Head from "../../(layout)/head";
import "../../background.css";
import "../../globals.css";
import { Providers } from "./providers";
import { MasterProvider } from "./contexts/Master";


const jsonLd: Graph = {
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": `https://www.growthepie.xyz/#organization`,
name: "growthepie",
url: "https://www.growthepie.xyz",
logo: "https://www.growthepie.xyz/logo_full.png",
sameAs: [
"https://twitter.com/growthepie_eth",
"https://mirror.xyz/blog.growthepie.eth",
"https://github.com/growthepie",
],
},
{
"@type": "WebSite",
"@id": `https://www.growthepie.xyz/#website`,
url: `https://www.growthepie.xyz/`,
name: "growthepie",
description:
"At growthepie, our mission is to provide comprehensive and accurate analytics of layer 2 solutions for the Ethereum ecosystem, acting as a trusted data aggregator from reliable sources such as L2Beat and DefiLlama, while also developing our own metrics.",
publisher: {
"@type": "Organization",
name: "growthepie",
logo: {
"@type": "ImageObject",
url: `https://www.growthepie.xyz/logo_full.png`,
},
},
},
],
};

// const jsonLdWebSite: WithContext<WebSite> = {
// "@context": "https://schema.org",
// "@type": "WebSite",
// url: "https://www.growthepie.xyz",
// name: "growthepie",
// description:
// "At growthepie, our mission is to provide comprehensive and accurate analytics of layer 2 solutions for the Ethereum ecosystem, acting as a trusted data aggregator from reliable sources such as L2Beat and DefiLlama, while also developing our own metrics.",
// publisher: {
// "@type": "Organization",
// name: "growthepie",
// logo: {
// "@type": "ImageObject",
// url: "https://www.growthepie.xyz/logo_full.png",
// },
// },
// };

// const jsonLd = [jsonLdOrg, jsonLdWebSite];
export const viewport = {
width: "device-width",
initialScale: "1.0",
themeColor: "dark",
};

const gtpMain = {
title: {
absolute:
"Growing Ethereum’s Ecosystem Together - Layer 2 User Base - growthepie",
template: "%s - growthepie",
},
description:
"At growthepie, our mission is to provide comprehensive and accurate analytics of layer 2 solutions for the Ethereum ecosystem, acting as a trusted data aggregator from reliable sources such as L2Beat and DefiLlama, while also developing our own metrics.",
};

const gtpLabels = {
title: {
absolute: "Ethereum Layer 2 Labels - growthepie",
template: "%s - growthepie",
},
description:
"Labels for Ethereum Layer 2 solutions - growthepie. A comprehensive list of labels for Ethereum Layer 2 solutions.",
};

const isLabels =
process.env.NEXT_PUBLIC_VERCEL_URL &&
process.env.NEXT_PUBLIC_VERCEL_URL.includes("labels.");

const host = isLabels ? "labels.growthepie.xyz" : "www.growthepie.xyz";

const title = isLabels ? gtpLabels.title : gtpMain.title;
const description = isLabels ? gtpLabels.description : gtpMain.description;

export const metadata: Metadata = {
metadataBase: new URL(`https://${host}`),
title,
description,
openGraph: {
title: "growthepie",
description: "Growing Ethereum’s Ecosystem Together",
url: `https://${host}`,
images: [
{
url: `https://${host}/gtp_og.png`,
width: 1200,
height: 627,
alt: "growthepie.xyz",
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "growthepie.xyz",
description: "Growing Ethereum’s Ecosystem Together",
site: "@growthepie_eth",
siteId: "1636391104689094656",
creator: "@growthepie_eth",
creatorId: "1636391104689094656",
images: [`https://${host}/gtp_og.png`],
},
robots: {
index: true,
follow: true,
nocache: true,
googleBot: {
index: true,
follow: true,
noimageindex: false,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
};

// If loading a variable font, you don't need to specify the font weight
const raleway = Raleway({
subsets: ["latin"],
variable: "--font-raleway",
display: "swap",
});

const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});

const robotoMono = Roboto_Mono({
subsets: ["latin"],
variable: "--font-roboto-mono",
display: "swap",
});

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html
lang="en"
className={`${raleway.variable} ${inter.variable} ${robotoMono.variable} scroll-smooth`}
suppressHydrationWarning
>
<Head />
<body className="bg-forest-50 dark:bg-[#1F2726] text-forest-900 dark:text-forest-500 font-raleway relative min-h-screen">
<div className="background-container !fixed">
<div className="background-gradient-group">
<div className="background-gradient-yellow"></div>
<div className="background-gradient-green"></div>
</div>
</div>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<main className="relative flex-1 w-full mx-auto min-h-screen select-none">
<Providers>
<MasterProvider>
{children}
</MasterProvider>
</Providers>
</main>
</body>
</html>
);
}
15 changes: 15 additions & 0 deletions app/(refactor)/refactor/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use client";
import { useMaster } from "./contexts/Master";

export default function Page() {
const { data, formatMetric } = useMaster();

console.log("page.tsx", data);

return (
<div>
<h1>Page</h1>
<div>123: {formatMetric(123, "fees", "usd")}</div>
</div>
);
}
59 changes: 59 additions & 0 deletions app/(refactor)/refactor/providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"use client";
import { ThemeProvider } from "next-themes";
import { SWRConfig } from "swr";
import { addCollection } from "@iconify/react";
import GTPIcons from "@/icons/gtp.json";
import { UIContextProvider } from "@/contexts/UIContext";
import { useLocalStorage } from "usehooks-ts";
import { IS_PRODUCTION } from "@/lib/helpers";
import { MasterProvider } from "@/contexts/Master";

// load icons
addCollection(GTPIcons);

type ProvidersProps = {
children: React.ReactNode;
forcedTheme?: string;
};

const devMiddleware = (useSWRNext) => {
return (key, fetcher, config) => {
return useSWRNext(
key,
(url) => {
if (url.includes("api.growthepie.xyz")) {
// replace /v1/ with /dev/ to get JSON files from the dev folder in S3
let newUrl = url.replace("/v1/", "/dev/");
return fetch(newUrl).then((r) => r.json());
} else {
return fetch(url).then((r) => r.json());
}
},
config,
);
};
};

export function Providers({ children, forcedTheme }: ProvidersProps) {
const [apiRoot, setApiRoot] = useLocalStorage("apiRoot", "v1");

return (
<ThemeProvider
attribute="class"
defaultTheme="dark"
forcedTheme={"dark"}
disableTransitionOnChange
>
<SWRConfig
value={{
fetcher: (url) => fetch(url).then((r) => r.json()),
use: apiRoot === "dev" && !IS_PRODUCTION ? [devMiddleware] : [],
}}
>
<UIContextProvider>
{children}
</UIContextProvider>
</SWRConfig>
</ThemeProvider>
);
}

0 comments on commit ed3586d

Please sign in to comment.