Skip to content

Commit 37b9b37

Browse files
author
AmineAfia
committed
[Dashboard] Feature: Add initial insight UI (#5435)
## Problem solved BLOCK-436 This PR adds an initial UI for insight to give visibility to insight in the platform. The first three blueprints are Data APIs available for all users. The next iteration will add the ability to create a new blueprint. ![CleanShot 2024-11-15 at [email protected]](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/dGj3ureqJk84bcvq1s10/8d0fb6d9-f80b-414a-925d-e6ed68aa6bfb.png) --- ## PR-Codex overview This PR introduces a new `Insight` page under the project structure, adding components for displaying blueprints, including a header and an explorer. It also implements authentication redirection and a loading state for better user experience. ### Detailed summary - Added a new route for `Insight` in `layout.tsx`. - Created `BlueprintsPageHeader` component for the `Insight` page. - Implemented `Page` component with authentication check and redirection logic. - Developed `BlueprintsPage` component to display blueprints with a loading state. - Created `getProjectBlueprints` function to fetch blueprint data. - Added `BlueprintsExplorer` component to list blueprints with a fallback message. - Implemented `BlueprintCard` for individual blueprint display. - Included loading spinner in `Loading` component. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> Linear Ticket: https://linear.app/thirdweb/issue/BLOCK-436/implement-initial-insight-ui <!-- start pr-codex --> --- ## PR-Codex overview This PR adds a new `Insight` page to the dashboard for a project, featuring a `BlueprintsPage` that displays blueprints and a header. It includes authentication checks and a redirect to the login page if the user is not authenticated. ### Detailed summary - Added a new route for `Insight` in `layout.tsx`. - Created `Page` component in `page.tsx` with authentication check. - Added `BlueprintsPageHeader` component for the `Insight` page. - Implemented `BlueprintsPage` to display billing alerts and blueprints. - Created `getProjectBlueprints` function to fetch blueprint data. - Developed `BlueprintsExplorer` component to list blueprints. - Added `BlueprintCard` component to display individual blueprints. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> Linear Ticket: https://linear.app/thirdweb/issue/BLOCK-436/implement-initial-insight-ui <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces a new `Insight` feature to the dashboard, which includes a dedicated page for insights with blueprints and a header component. It also implements authentication checks and displays billing alerts. ### Detailed summary - Added a new route for `Insight`. - Created `Page` component with authentication check and redirection. - Introduced `BlueprintsPage` component displaying billing alerts and blueprints. - Implemented `BlueprintsPageHeader` with a disabled button. - Added `BlueprintsExplorer` for listing blueprints. - Defined `BlueprintCard` for individual blueprint display. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
1 parent e95ddcd commit 37b9b37

File tree

5 files changed

+154
-0
lines changed

5 files changed

+154
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"use client";
2+
3+
import {} from "@/components/ui/dropdown-menu";
4+
import {} from "@/components/ui/select";
5+
import { Layers3 } from "lucide-react";
6+
import Link from "next/link";
7+
8+
export type Blueprint = {
9+
id: string;
10+
name: string;
11+
slug: string;
12+
description: string;
13+
};
14+
15+
export function BlueprintsExplorer(props: {
16+
blueprints: Blueprint[];
17+
}) {
18+
const { blueprints } = props;
19+
return (
20+
<div className="container">
21+
{/* Blueprints */}
22+
{blueprints.length === 0 ? (
23+
<div className="flex h-[450px] items-center justify-center rounded-lg border border-border ">
24+
No blueprints found
25+
</div>
26+
) : (
27+
<div className="grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3">
28+
{blueprints.map((blueprint) => {
29+
return <BlueprintCard key={blueprint.id} blueprint={blueprint} />;
30+
})}
31+
</div>
32+
)}
33+
34+
<div className="h-10" />
35+
</div>
36+
);
37+
}
38+
39+
function BlueprintCard(props: {
40+
blueprint: Blueprint;
41+
}) {
42+
const { blueprint } = props;
43+
return (
44+
<div
45+
key={blueprint.id}
46+
className="relative flex items-center gap-4 rounded-lg border border-border bg-muted/50 p-4 transition-colors hover:bg-muted/70"
47+
>
48+
<Layers3 className="size-10" />
49+
50+
<div>
51+
<Link
52+
className="group static before:absolute before:top-0 before:right-0 before:bottom-0 before:left-0 before:z-0"
53+
href={`https://portal.thirdweb.com/insight/blueprints#${blueprint.slug}`}
54+
>
55+
<h2 className="font-medium text-base">{blueprint.name}</h2>
56+
</Link>
57+
58+
<p className="my-1 text-muted-foreground/70 text-xs">
59+
{blueprint.description}
60+
</p>
61+
</div>
62+
</div>
63+
);
64+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { BillingAlerts } from "components/settings/Account/Billing/alerts/Alert";
2+
import { type Blueprint, BlueprintsExplorer } from "./BlueprintsExplorer";
3+
import { BlueprintsPageHeader } from "./BlueprintsPageHeader";
4+
5+
export function BlueprintsPage() {
6+
return (
7+
<div>
8+
<BillingAlerts />
9+
<BlueprintsPageHeader />
10+
<div className="h-6" />
11+
<BlueprintsPageContent />
12+
</div>
13+
);
14+
}
15+
16+
function getProjectBlueprints() {
17+
return [
18+
{
19+
id: "1",
20+
name: "Transactions",
21+
slug: "transactions-blueprint",
22+
description: "Query transaction data",
23+
},
24+
{
25+
id: "2",
26+
name: "Events",
27+
slug: "events-blueprint",
28+
description: "Query event data",
29+
},
30+
{
31+
id: "3",
32+
name: "Tokens",
33+
slug: "tokens-blueprint",
34+
description: "Query ERC-20, ERC-721, and ERC-1155 tokens",
35+
},
36+
] as Blueprint[];
37+
}
38+
39+
function BlueprintsPageContent() {
40+
const blueprints = getProjectBlueprints();
41+
42+
return <BlueprintsExplorer blueprints={blueprints} />;
43+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"use client";
2+
3+
import { Button } from "@/components/ui/button";
4+
import { PlusIcon } from "lucide-react";
5+
6+
export function BlueprintsPageHeader() {
7+
return (
8+
<div className="flex grow flex-col">
9+
<div className="border-border border-b py-10">
10+
<div className="container flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
11+
<h1 className="font-semibold text-2xl tracking-tight sm:text-3xl">
12+
Insight
13+
</h1>
14+
<Button
15+
className="w-full cursor-not-allowed gap-2 opacity-50 sm:w-auto"
16+
disabled
17+
>
18+
<PlusIcon className="size-4" />
19+
Create Blueprint (Coming Soon)
20+
</Button>
21+
</div>
22+
</div>
23+
</div>
24+
);
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { redirect } from "next/navigation";
2+
import { getAuthTokenWalletAddress } from "../../../../api/lib/getAuthToken";
3+
import { BlueprintsPage } from "./components/BlueprintsPage";
4+
5+
export default async function Page(props: {
6+
params: Promise<{ team_slug: string; project_slug: string }>;
7+
}) {
8+
const accountAddress = await getAuthTokenWalletAddress();
9+
10+
if (!accountAddress) {
11+
const { team_slug, project_slug } = await props.params;
12+
return redirect(
13+
`/login?next=${encodeURIComponent(`/team/${team_slug}/${project_slug}/insight`)}`,
14+
);
15+
}
16+
17+
return <BlueprintsPage />;
18+
}

apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ export default async function TeamLayout(props: {
6969
},
7070
]
7171
: []),
72+
{
73+
path: `/team/${params.team_slug}/${params.project_slug}/insight`,
74+
name: "Insight",
75+
},
7276
{
7377
path: `/team/${params.team_slug}/${params.project_slug}/settings`,
7478
name: "Settings",

0 commit comments

Comments
 (0)