Skip to content

Commit 36b4ea5

Browse files
committed
[TOOL-3556] Dashboard: Add Notifications, Revamp Team Overview page (#6368)
<!-- start pr-codex --> ## PR-Codex overview This PR focuses on enhancing the notification system in the dashboard by integrating changelog and inbox notifications, improving UI components, and updating dependencies. ### Detailed summary - Added `getChangelogNotifications`, `getInboxNotifications`, and `markNotificationAsRead` functions. - Integrated notifications in `AccountHeaderUI`, `TeamHeader`, and `SecondaryNav`. - Updated styles for various components. - Replaced `Changelog` component with a new layout in `TeamProjectsPage`. - Enhanced notification handling using `idb-keyval` for local storage. > The following files were skipped due to too many changes: `pnpm-lock.yaml` > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent e1f73c8 commit 36b4ea5

File tree

20 files changed

+939
-423
lines changed

20 files changed

+939
-423
lines changed

apps/dashboard/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"flat": "^6.0.1",
6464
"framer-motion": "12.4.7",
6565
"fuse.js": "7.1.0",
66+
"idb-keyval": "^6.2.1",
6667
"input-otp": "^1.4.1",
6768
"ioredis": "^5.5.0",
6869
"ipaddr.js": "^2.2.0",

apps/dashboard/src/@/components/ui/input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
1111
<input
1212
type={type}
1313
className={cn(
14-
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background selection:bg-foreground/10 file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
14+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background selection:bg-foreground/10 file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground placeholder:text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1515
className,
1616
)}
1717
ref={ref}

apps/dashboard/src/@/components/ui/tabs.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function TabLinks(props: {
7676

7777
export function TabButtons(props: {
7878
tabs: {
79-
name: string;
79+
name: React.ReactNode;
8080
onClick: () => void;
8181
isActive: boolean;
8282
isEnabled?: boolean;
@@ -108,10 +108,11 @@ export function TabButtons(props: {
108108
className={cn("flex", props.tabContainerClassName)}
109109
ref={containerRef}
110110
>
111-
{props.tabs.map((tab) => {
111+
{props.tabs.map((tab, index) => {
112112
return (
113113
<Button
114-
key={tab.name}
114+
// biome-ignore lint/suspicious/noArrayIndexKey: tabs don't change order, so index is stable
115+
key={index}
115116
variant="ghost"
116117
ref={tab.isActive ? activeTabRef : undefined}
117118
className={cn(

apps/dashboard/src/app/account/components/AccountHeader.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import { useCallback, useState } from "react";
1010
import { useActiveWallet, useDisconnect } from "thirdweb/react";
1111
import { LazyCreateProjectDialog } from "../../../components/settings/ApiKeys/Create/LazyCreateAPIKeyDialog";
1212
import { doLogout } from "../../login/auth-actions";
13+
import {
14+
getChangelogNotifications,
15+
getInboxNotifications,
16+
markNotificationAsRead,
17+
} from "../../team/components/NotificationButton/fetch-notifications";
1318
import {
1419
type AccountHeaderCompProps,
1520
AccountHeaderDesktopUI,
@@ -54,6 +59,9 @@ export function AccountHeader(props: {
5459
account: props.account,
5560
client,
5661
accountAddress: props.accountAddress,
62+
getChangelogNotifications: getChangelogNotifications,
63+
getInboxNotifications: getInboxNotifications,
64+
markNotificationAsRead: markNotificationAsRead,
5765
};
5866

5967
return (

apps/dashboard/src/app/account/components/AccountHeaderUI.stories.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ function Variants(props: {
6262
email: "foo@example.com",
6363
}}
6464
client={client}
65+
getChangelogNotifications={() => Promise.resolve([])}
66+
getInboxNotifications={() => Promise.resolve([])}
67+
markNotificationAsRead={() => Promise.resolve()}
6568
/>
6669
</div>
6770
</BadgeContainer>

apps/dashboard/src/app/account/components/AccountHeaderUI.tsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import type { ThirdwebClient } from "thirdweb";
88
import { SecondaryNav } from "../../components/Header/SecondaryNav/SecondaryNav";
99
import { MobileBurgerMenuButton } from "../../components/MobileBurgerMenuButton";
1010
import { ThirdwebMiniLogo } from "../../components/ThirdwebMiniLogo";
11+
import {
12+
NotificationButtonUI,
13+
type NotificationMetadata,
14+
} from "../../team/components/NotificationButton/NotificationButton";
1115
import { TeamAndProjectSelectorPopoverButton } from "../../team/components/TeamHeader/TeamAndProjectSelectorPopoverButton";
1216
import { TeamSelectorMobileMenuButton } from "../../team/components/TeamHeader/TeamSelectorMobileMenuButton";
1317

@@ -20,6 +24,9 @@ export type AccountHeaderCompProps = {
2024
account: Pick<Account, "email" | "id" | "image">;
2125
client: ThirdwebClient;
2226
accountAddress: string;
27+
getChangelogNotifications: () => Promise<NotificationMetadata[]>;
28+
getInboxNotifications: () => Promise<NotificationMetadata[]>;
29+
markNotificationAsRead: (id: string) => Promise<void>;
2330
};
2431

2532
export function AccountHeaderDesktopUI(props: AccountHeaderCompProps) {
@@ -70,6 +77,9 @@ export function AccountHeaderDesktopUI(props: AccountHeaderCompProps) {
7077
connectButton={props.connectButton}
7178
client={props.client}
7279
accountAddress={props.accountAddress}
80+
getChangelogs={props.getChangelogNotifications}
81+
getInboxNotifications={props.getInboxNotifications}
82+
markNotificationAsRead={props.markNotificationAsRead}
7383
/>
7484
</header>
7585
);
@@ -111,13 +121,21 @@ export function AccountHeaderMobileUI(props: AccountHeaderCompProps) {
111121
</div>
112122
</div>
113123

114-
<MobileBurgerMenuButton
115-
type="loggedIn"
116-
email={props.account?.email}
117-
logout={props.logout}
118-
connectButton={props.connectButton}
119-
accountAddress={props.accountAddress}
120-
/>
124+
<div className="flex items-center gap-3">
125+
<NotificationButtonUI
126+
getChangelogs={props.getChangelogNotifications}
127+
getInboxNotifications={props.getInboxNotifications}
128+
markNotificationAsRead={props.markNotificationAsRead}
129+
/>
130+
131+
<MobileBurgerMenuButton
132+
type="loggedIn"
133+
email={props.account?.email}
134+
logout={props.logout}
135+
connectButton={props.connectButton}
136+
accountAddress={props.accountAddress}
137+
/>
138+
</div>
121139
</header>
122140
);
123141
}

apps/dashboard/src/app/components/Header/SecondaryNav/SecondaryNav.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
22
import Link from "next/link";
33
import type React from "react";
44
import type { ThirdwebClient } from "thirdweb";
5+
import {
6+
NotificationButtonUI,
7+
type NotificationMetadata,
8+
} from "../../../team/components/NotificationButton/NotificationButton";
59
import { ResourcesDropdownButton } from "./ResourcesDropdownButton";
610
import { AccountButton } from "./account-button.client";
711

@@ -11,17 +15,27 @@ export function SecondaryNav(props: {
1115
connectButton: React.ReactNode;
1216
client: ThirdwebClient;
1317
accountAddress: string;
18+
getChangelogs: () => Promise<NotificationMetadata[]>;
19+
getInboxNotifications: () => Promise<NotificationMetadata[]>;
20+
markNotificationAsRead: (id: string) => Promise<void>;
1421
}) {
1522
return (
1623
<div className="flex items-center gap-6">
1724
<SecondaryNavLinks />
18-
<AccountButton
19-
logout={props.logout}
20-
connectButton={props.connectButton}
21-
account={props.account}
22-
client={props.client}
23-
accountAddress={props.accountAddress}
24-
/>
25+
<div className="flex items-center gap-3">
26+
<NotificationButtonUI
27+
getChangelogs={props.getChangelogs}
28+
getInboxNotifications={props.getInboxNotifications}
29+
markNotificationAsRead={props.markNotificationAsRead}
30+
/>
31+
<AccountButton
32+
logout={props.logout}
33+
connectButton={props.connectButton}
34+
account={props.account}
35+
client={props.client}
36+
accountAddress={props.accountAddress}
37+
/>
38+
</div>
2539
</div>
2640
);
2741
}

apps/dashboard/src/app/components/Header/SecondaryNav/account-button.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function AccountButton(props: {
3333
<Button
3434
size="icon"
3535
asChild
36-
className="size-10 cursor-pointer rounded-full hover:ring-2 hover:ring-offset-2"
36+
className="size-10 cursor-pointer rounded-full hover:ring-2 hover:ring-ring hover:ring-offset-1"
3737
variant="ghost"
3838
>
3939
{/* Don't remove the div */}

apps/dashboard/src/app/components/MobileBurgerMenuButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ export function MobileBurgerMenuButton(
5959
/> */}
6060
<Button
6161
variant="outline"
62-
className="!h-auto p-1"
62+
className="flex size-10 items-center justify-center rounded-full bg-background p-0"
6363
onClick={() => setIsMenuOpen(true)}
6464
>
65-
<MenuIcon className="size-6 text-muted-foreground" />
65+
<MenuIcon className="size-4 text-muted-foreground" />
6666
</Button>
6767

6868
{isMenuOpen && (

apps/dashboard/src/app/team/[team_slug]/(team)/page.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { getWalletConnections } from "@/api/analytics";
22
import { type Project, getProjects } from "@/api/projects";
33
import { getTeamBySlug } from "@/api/team";
4-
import { Changelog } from "components/dashboard/Changelog";
54
import { subDays } from "date-fns";
65
import { redirect } from "next/navigation";
76
import {
@@ -23,16 +22,17 @@ export default async function Page(props: {
2322
const projectsWithTotalWallets = await getProjectsWithAnalytics(projects);
2423

2524
return (
26-
<div className="container flex grow flex-col gap-12 py-8 lg:flex-row">
27-
<div className="flex grow flex-col">
28-
<h1 className="mb-4 font-semibold text-2xl tracking-tight">Projects</h1>
29-
<TeamProjectsPage projects={projectsWithTotalWallets} team={team} />
25+
<div className="flex grow flex-col">
26+
<div className="border-border border-b py-10">
27+
<div className="container">
28+
<h1 className="font-semibold text-3xl tracking-tight">
29+
Team Overview
30+
</h1>
31+
</div>
3032
</div>
31-
<div className="shrink-0 lg:w-[320px]">
32-
<h2 className="mb-4 font-semibold text-2xl tracking-tight">
33-
Changelog
34-
</h2>
35-
<Changelog />
33+
34+
<div className="container flex grow flex-col pt-8 pb-20">
35+
<TeamProjectsPage projects={projectsWithTotalWallets} team={team} />
3636
</div>
3737
</div>
3838
);

0 commit comments

Comments
 (0)