Skip to content

Commit 9128553

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 introduces a new `Insight` page to the dashboard, enhancing the team project features with insights into blueprints. It includes user authentication, a header component, and displays blueprints with relevant data. ### Detailed summary - Added `Insight` route in `layout.tsx`. - Created `Page` component in `page.tsx` for rendering insights. - Implemented user authentication redirect if not logged in. - Developed `BlueprintsPageHeader` for page title and button. - Added `BlueprintsPage` to display billing alerts and blueprints. - Defined `getProjectBlueprints` to fetch blueprint data. - Created `BlueprintsExplorer` to list blueprints with a card layout. - Implemented `BlueprintCard` for individual blueprint display. > ✨ 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` page for a project within a team dashboard, featuring a header and blueprint exploration components. It includes user authentication redirection and displays available blueprints with relevant information. ### Detailed summary - Added a new route for `Insight` in `layout.tsx`. - Created `BlueprintsPageHeader` component for the `Insight` page. - Implemented `Page` function to handle user authentication and redirection. - Developed `BlueprintsPage` to display blueprints and alerts. - Created `getProjectBlueprints` function to fetch blueprint data. - Added `BlueprintsExplorer` component to list blueprints. - Implemented `BlueprintCard` to display individual blueprint details. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
1 parent 2591c75 commit 9128553

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)