Skip to content

Commit

Permalink
feat(insights): initial app shell & index pages
Browse files Browse the repository at this point in the history
  • Loading branch information
cprussin committed Nov 13, 2024
1 parent 7f9ab33 commit 4a60587
Show file tree
Hide file tree
Showing 89 changed files with 4,051 additions and 762 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.17.0
v20.18.0
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
nodejs 20.17.0
pnpm 9.12.1
nodejs 20.18.0
pnpm 9.12.3
rust 1.78.0
python 3.12.4
4 changes: 2 additions & 2 deletions Dockerfile.node
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20.17.0-slim@sha256:2394e403d45a644e41ac2a15b6f843a7d4a99ad24be48c27982c5fdc61a1ef17 as builder-base
FROM node:20.18.0-slim@sha256:ec35a66c9a0a275b027debde05247c081f8b2f0c43d7399d3a6ad5660cee2f6a as builder-base
WORKDIR /usr/src/pyth
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
Expand All @@ -7,7 +7,7 @@ COPY ./ .
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile


FROM node:20.17.0-alpine@sha256:2d07db07a2df6830718ae2a47db6fedce6745f5bcd174c398f2acdda90a11c03 as runner-base
FROM node:20.18.0-alpine3.20@sha256:c13b26e7e602ef2f1074aef304ce6e9b7dd284c419b35d89fcf3cc8e44a8def9 as runner-base
WORKDIR /srv
ENV NODE_ENV production
RUN addgroup --system --gid 1001 pyth && adduser --system --uid 1001 pyth -g pyth && chown pyth:pyth .
Expand Down
16 changes: 15 additions & 1 deletion apps/insights/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,35 @@
"build": "next build",
"fix:format": "prettier --write .",
"fix:lint": "eslint --fix .",
"pull:env": "[ $CI ] || VERCEL_ORG_ID=team_BKQrg3JJFLxZyTqpuYtIY0rj VERCEL_PROJECT_ID=prj_TBkf9EyQjQF37gs4Vk0sQKJj97kE vercel env pull",
"start:dev": "next dev --port 3003",
"start:prod": "next start --port 3003",
"test:format": "prettier --check .",
"test:lint": "jest --selectProjects lint",
"test:types": "tsc"
},
"dependencies": {
"@clickhouse/client": "catalog:",
"@phosphor-icons/react": "catalog:",
"@pythnetwork/app-logger": "workspace:*",
"@pythnetwork/client": "catalog:",
"@pythnetwork/component-library": "workspace:*",
"@pythnetwork/fonts": "workspace:*",
"@pythnetwork/known-publishers": "workspace:*",
"@pythnetwork/next-root": "workspace:*",
"@react-hookz/web": "catalog:",
"@solana/web3.js": "catalog:",
"clsx": "catalog:",
"cryptocurrency-icons": "catalog:",
"framer-motion": "catalog:",
"next": "catalog:",
"next-themes": "catalog:",
"nuqs": "catalog:",
"react": "catalog:",
"react-dom": "catalog:"
"react-aria": "catalog:",
"react-aria-components": "catalog:",
"react-dom": "catalog:",
"zod": "catalog:"
},
"devDependencies": {
"@cprussin/eslint-config": "catalog:",
Expand Down
1 change: 1 addition & 0 deletions apps/insights/src/app/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Loading as default } from "../components/Loading";
2 changes: 1 addition & 1 deletion apps/insights/src/app/page.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Home as default } from "../components/Home";
export { Overview as default } from "../components/Overview";
1 change: 1 addition & 0 deletions apps/insights/src/app/price-feeds/layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PriceFeedsLayout as default } from "../../components/PriceFeeds/layout";
1 change: 1 addition & 0 deletions apps/insights/src/app/price-feeds/loading.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PriceFeedsLoading as default } from "../../components/PriceFeeds/loading";
1 change: 1 addition & 0 deletions apps/insights/src/app/price-feeds/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PriceFeeds as default } from "../../components/PriceFeeds";
1 change: 1 addition & 0 deletions apps/insights/src/app/publishers/layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PublishersLayout as default } from "../../components/Publishers/layout";
1 change: 1 addition & 0 deletions apps/insights/src/app/publishers/loading.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PublishersLoading as default } from "../../components/Publishers/loading";
1 change: 1 addition & 0 deletions apps/insights/src/app/publishers/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Publishers as default } from "../../components/Publishers";
5 changes: 5 additions & 0 deletions apps/insights/src/clickhouse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createClient } from "@clickhouse/client";

import { CLICKHOUSE } from "./config/server";

export const client = createClient(CLICKHOUSE);
78 changes: 78 additions & 0 deletions apps/insights/src/components/CopyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"use client";

import { Copy, Check } from "@phosphor-icons/react/dist/ssr";
import { useLogger } from "@pythnetwork/app-logger";
import { UnstyledButton } from "@pythnetwork/component-library/UnstyledButton";
import clsx from "clsx";
import { type ComponentProps, useCallback, useEffect, useState } from "react";

type CopyButtonProps = ComponentProps<typeof UnstyledButton> & {
text: string;
};

export const CopyButton = ({
text,
children,
className,
...props
}: CopyButtonProps) => {
const [isCopied, setIsCopied] = useState(false);
const logger = useLogger();
const copy = useCallback(() => {
// eslint-disable-next-line n/no-unsupported-features/node-builtins
navigator.clipboard
.writeText(text)
.then(() => {
setIsCopied(true);
})
.catch((error: unknown) => {
/* TODO do something here? */
logger.error(error);
});
}, [text, logger]);

useEffect(() => {
setIsCopied(false);
}, [text]);

useEffect(() => {
if (isCopied) {
const timeout = setTimeout(() => {
setIsCopied(false);
}, 2000);
return () => {
clearTimeout(timeout);
};
} else {
return;
}
}, [isCopied]);

return (
<UnstyledButton
onPress={copy}
isDisabled={isCopied}
className={clsx(
"group/copy-button mx-[-0.5em] -mt-0.5 inline-block whitespace-nowrap rounded-md px-[0.5em] py-0.5 outline-none outline-0 outline-steel-600 transition data-[hovered]:bg-black/5 data-[focus-visible]:outline-2 dark:outline-steel-300 dark:data-[hovered]:bg-white/10",
className,
)}
{...(isCopied && { "data-is-copied": true })}
{...props}
>
{(...args) => (
<>
<span>
{typeof children === "function" ? children(...args) : children}
</span>
<span className="relative top-[0.125em] ml-1 inline-block">
<span className="opacity-50 transition-opacity duration-100 group-data-[is-copied]/copy-button:opacity-0">
<Copy className="size-[1em]" />
<div className="sr-only">Copy to clipboard</div>
</span>
<Check className="absolute inset-0 text-green-600 opacity-0 transition-opacity duration-100 group-data-[is-copied]/copy-button:opacity-100" />
</span>
</>
)}
</UnstyledButton>
);
};
6 changes: 4 additions & 2 deletions apps/insights/src/components/Error/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useLogger } from "@pythnetwork/app-logger";
import { Button } from "@pythnetwork/component-library/Button";
import { useEffect } from "react";

import { MaxWidth } from "../MaxWidth";

type Props = {
error: Error & { digest?: string };
reset?: () => void;
Expand All @@ -15,13 +17,13 @@ export const Error = ({ error, reset }: Props) => {
}, [error, logger]);

return (
<main>
<MaxWidth>
<h1>Uh oh!</h1>
<h2>Something went wrong</h2>
<p>
Error Details: <strong>{error.digest ?? error.message}</strong>
</p>
{reset && <Button onPress={reset}>Reset</Button>}
</main>
</MaxWidth>
);
};
8 changes: 8 additions & 0 deletions apps/insights/src/components/H1/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import clsx from "clsx";
import type { ComponentProps } from "react";

export const H1 = ({ className, children, ...props }: ComponentProps<"h1">) => (
<h1 className={clsx(className, "text-2xl font-medium")} {...props}>
{children}
</h1>
);
5 changes: 0 additions & 5 deletions apps/insights/src/components/Home/index.tsx

This file was deleted.

12 changes: 12 additions & 0 deletions apps/insights/src/components/Loading/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Skeleton } from "@pythnetwork/component-library/Skeleton";

import { H1 } from "../H1";
import { MaxWidth } from "../MaxWidth";

export const Loading = () => (
<MaxWidth>
<H1>
<Skeleton className="w-60" />
</H1>
</MaxWidth>
);
9 changes: 9 additions & 0 deletions apps/insights/src/components/MaxWidth/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import clsx from "clsx";
import type { ComponentProps } from "react";

export const MaxWidth = ({ className, ...props }: ComponentProps<"div">) => (
<div
className={clsx("mx-auto box-content max-w-screen-2xl px-6", className)}
{...props}
/>
);
6 changes: 4 additions & 2 deletions apps/insights/src/components/NotFound/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { ButtonLink } from "@pythnetwork/component-library/Button";

import { MaxWidth } from "../MaxWidth";

export const NotFound = () => (
<main>
<MaxWidth>
<h1>Not Found</h1>
<p>{"The page you're looking for isn't here"}</p>
<ButtonLink href="/">Go Home</ButtonLink>
</main>
</MaxWidth>
);
8 changes: 8 additions & 0 deletions apps/insights/src/components/Overview/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { H1 } from "../H1";
import { MaxWidth } from "../MaxWidth";

export const Overview = () => (
<MaxWidth>
<H1>Overview</H1>
</MaxWidth>
);
Loading

0 comments on commit 4a60587

Please sign in to comment.