Skip to content

feat: Add global notification bell with dropdown panel across Navbar and dashboards #58

Description

@JamesVictor-O

Problem

The notification bell icon appears in 3 places but is completely non-functional everywhere:

Location File Line
Landing page Navbar `components/landing/Navbar.tsx` 50-52
Old dashboard topbar `components/dashboard/topbar.tsx` 35-40
Creator campaigns header `components/dashboard/creator/campaigns-page-header.tsx` 29-35

All are static `` elements with no `onClick` handler. Users expect a bell icon to be clickable — getting no response feels broken.


What to Build

1. Notification Context — `components/notifications/notification-context.tsx`

A lightweight context that holds mock notification data and an unread count.

```ts
type Notification = {
id: string;
title: string;
description: string;
time: string;
read: boolean;
type: "campaign" | "payout" | "system";
};

type NotificationContextValue = {
notifications: Notification[];
unreadCount: number;
markAsRead: (id: string) => void;
markAllRead: () => void;
};
```

  • Initialize with 3-5 mock notifications
  • Persist read state in `sessionStorage` so it survives navigation but resets on new sessions

2. Notification Bell — `components/notifications/notification-bell.tsx`

A reusable bell button with:

  • Unread badge: red dot or count badge when `unreadCount > 0`
  • On click: toggles a dropdown panel
  • Dropdown: positioned `absolute right-0 top-full`, shows notification list with title, description, time, read/unread state
  • "Mark all read" button in the dropdown header
  • Close on outside click and Escape key

Two visual variants:

  • Landing page: uses `text-on-surface-variant` tokens
  • Dashboard: uses `--dash-*` tokens

3. Wire into existing components

  • Replace the static bell in `Navbar.tsx` with ``
  • Replace the static bell in `campaigns-page-header.tsx` with ``
  • Add `NotificationProvider` to `app/layout.tsx`

Mock Notifications

```ts
[
{ id: "n1", title: "New applicant", description: "Alex Rivera applied to your Summer Launch campaign", time: "2 min ago", read: false, type: "campaign" },
{ id: "n2", title: "Proof submitted", description: "Creator submitted proof for Cyberpunk Rebrand Q4", time: "1 hour ago", read: false, type: "campaign" },
{ id: "n3", title: "Payout processed", description: "2,500 USDC released to your wallet", time: "3 hours ago", read: true, type: "payout" },
{ id: "n4", title: "Campaign ending soon", description: "Twitter Alpha Thread expires in 2 days", time: "Yesterday", read: true, type: "system" },
]
```


Acceptance Criteria

  • Bell icon in Navbar shows red unread badge when notifications exist
  • Clicking the bell opens a dropdown with notification list
  • Each notification shows title, description, and time
  • Unread notifications are visually distinct from read ones
  • "Mark all read" clears the unread badge
  • Clicking individual notification marks it as read
  • Dropdown closes on outside click and Escape key
  • Bell in creator campaigns page header also works
  • No hardcoded hex — uses appropriate token system per context
  • TypeScript compiles clean

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions