From 4c8333d4a30ed24fde142ca077a3a2d6ae57386a Mon Sep 17 00:00:00 2001 From: AmineAfia Date: Wed, 20 Nov 2024 10:51:08 +0000 Subject: [PATCH] [Dashboard] Feature: Add initial insight UI (#5435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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 17.12.16@2x.png](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}` Linear Ticket: https://linear.app/thirdweb/issue/BLOCK-436/implement-initial-insight-ui --- ## 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}` Linear Ticket: https://linear.app/thirdweb/issue/BLOCK-436/implement-initial-insight-ui --- ## 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}` --- .../insight/components/BlueprintsExplorer.tsx | 64 +++++++++++++++++++ .../insight/components/BlueprintsPage.tsx | 41 ++++++++++++ .../components/BlueprintsPageHeader.tsx | 25 ++++++++ .../[project_slug]/insight/page.tsx | 18 ++++++ .../[team_slug]/[project_slug]/layout.tsx | 4 ++ 5 files changed, 152 insertions(+) create mode 100644 apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsExplorer.tsx create mode 100644 apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPage.tsx create mode 100644 apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPageHeader.tsx create mode 100644 apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsExplorer.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsExplorer.tsx new file mode 100644 index 00000000000..1c4ff6582ef --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsExplorer.tsx @@ -0,0 +1,64 @@ +"use client"; + +import {} from "@/components/ui/dropdown-menu"; +import {} from "@/components/ui/select"; +import { Layers3 } from "lucide-react"; +import Link from "next/link"; + +export type Blueprint = { + id: string; + name: string; + slug: string; + description: string; +}; + +export function BlueprintsExplorer(props: { + blueprints: Blueprint[]; +}) { + const { blueprints } = props; + return ( +
+ {/* Blueprints */} + {blueprints.length === 0 ? ( +
+ No blueprints found +
+ ) : ( +
+ {blueprints.map((blueprint) => { + return ; + })} +
+ )} + +
+
+ ); +} + +function BlueprintCard(props: { + blueprint: Blueprint; +}) { + const { blueprint } = props; + return ( +
+ + +
+ +

{blueprint.name}

+ + +

+ {blueprint.description} +

+
+
+ ); +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPage.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPage.tsx new file mode 100644 index 00000000000..d20105c7738 --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPage.tsx @@ -0,0 +1,41 @@ +import { type Blueprint, BlueprintsExplorer } from "./BlueprintsExplorer"; +import { BlueprintsPageHeader } from "./BlueprintsPageHeader"; + +export function BlueprintsPage() { + return ( +
+ +
+ +
+ ); +} + +function getProjectBlueprints() { + return [ + { + id: "1", + name: "Transactions", + slug: "transactions-blueprint", + description: "Query transaction data", + }, + { + id: "2", + name: "Events", + slug: "events-blueprint", + description: "Query event data", + }, + { + id: "3", + name: "Tokens", + slug: "tokens-blueprint", + description: "Query ERC-20, ERC-721, and ERC-1155 tokens", + }, + ] as Blueprint[]; +} + +function BlueprintsPageContent() { + const blueprints = getProjectBlueprints(); + + return ; +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPageHeader.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPageHeader.tsx new file mode 100644 index 00000000000..ab68babe21b --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/components/BlueprintsPageHeader.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { PlusIcon } from "lucide-react"; + +export function BlueprintsPageHeader() { + return ( +
+
+
+

+ Insight +

+ +
+
+
+ ); +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx new file mode 100644 index 00000000000..4722c8cfab8 --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx @@ -0,0 +1,18 @@ +import { redirect } from "next/navigation"; +import { getAuthTokenWalletAddress } from "../../../../api/lib/getAuthToken"; +import { BlueprintsPage } from "./components/BlueprintsPage"; + +export default async function Page(props: { + params: Promise<{ team_slug: string; project_slug: string }>; +}) { + const accountAddress = await getAuthTokenWalletAddress(); + + if (!accountAddress) { + const { team_slug, project_slug } = await props.params; + return redirect( + `/login?next=${encodeURIComponent(`/team/${team_slug}/${project_slug}/insight`)}`, + ); + } + + return ; +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx index f7a25c64eb2..0b8994efc49 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx @@ -69,6 +69,10 @@ export default async function TeamLayout(props: { }, ] : []), + { + path: `/team/${params.team_slug}/${params.project_slug}/insight`, + name: "Insight", + }, { path: `/team/${params.team_slug}/${params.project_slug}/settings`, name: "Settings",