Skip to content

Conversation

@joaquim-verges
Copy link
Member

@joaquim-verges joaquim-verges commented Sep 23, 2025

[Dashboard] Feature: Add AI usage billing banner to Nebula chat empty state

Notes for the reviewer

This PR introduces a new AIUsageBanner component to EmptyStateChatPageContent.tsx. The banner informs users about thirdweb AI usage billing and links to the pricing page. It is styled to be consistent with existing info/alert banners in the dashboard, floating at the top of the component.

How to test

  1. Navigate to the Nebula AI chat page (e.g., /nebula).
  2. Ensure no active chat is selected, so the empty state content is displayed.
  3. Verify that the "thirdweb AI usage is billable..." banner is visible at the top of the content.
  4. Check that the "pricing page" link correctly navigates to https://thirdweb.com/pricing.
  5. Test in both light and dark modes, and verify responsiveness.

Slack Thread

Open in Cursor Open in Web


PR-Codex overview

This PR focuses on code modifications across multiple files, including changes to UI components and the addition of a new banner for AI usage information.

Detailed summary

  • In EmptyStateChatPageContent.tsx, added <AIUsageBanner /> to display information about AI usage billing.
  • Modified AnnouncementBanner.tsx to return null instead of rendering the announcement UI.
  • Updated the div class in EmptyStateChatPageContent.tsx to relative for proper positioning.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features
    • Added an AI usage banner to the AI chat empty state with info and a link to pricing.
  • Style
    • Removed the announcement banner from the dashboard (no banner now shown).
    • Minor layout tweak to the empty state chat container for improved positioning.
  • Documentation
    • Updated payments (x402) examples by removing an outdated middleware import.
  • Chores
    • Cleaned up unused imports in the payments example app.

Co-authored-by: joaquim.verges <joaquim.verges@gmail.com>
@cursor
Copy link

cursor bot commented Sep 23, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@vercel
Copy link

vercel bot commented Sep 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Ready Preview Comment Sep 23, 2025 1:45am
nebula Ready Ready Preview Comment Sep 23, 2025 1:45am
thirdweb_playground Ready Ready Preview Comment Sep 23, 2025 1:45am
thirdweb-www Ready Ready Preview Comment Sep 23, 2025 1:45am
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
wallet-ui Skipped Skipped Sep 23, 2025 1:45am

@changeset-bot
Copy link

changeset-bot bot commented Sep 23, 2025

⚠️ No Changeset found

Latest commit: fd3cb3c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "[Dashboard] Add ai usage billing banner to dashboard" directly and concisely describes the main change (adding an AI usage billing banner to the dashboard empty state) and matches the modifications in EmptyStateChatPageContent.tsx and related files.
Description Check ✅ Passed The PR description follows the repository template by providing a clear summary, a "Notes for the reviewer" section, and a detailed "How to test" section with steps and links, which together document the change and verification steps; it also includes contextual links (Slack) and a PR-Codex summary for reviewers. The template's optional request for an issue/Linear tag was not provided.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/add-ai-usage-billing-banner-to-dashboard-f4fb

Comment @coderabbitai help to get the list of available commands and usage tips.

@graphite-app
Copy link
Contributor

graphite-app bot commented Sep 23, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@codecov
Copy link

codecov bot commented Sep 23, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.32%. Comparing base (b366d56) to head (fd3cb3c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8104   +/-   ##
=======================================
  Coverage   56.32%   56.32%           
=======================================
  Files         906      906           
  Lines       59197    59197           
  Branches     4176     4176           
=======================================
  Hits        33345    33345           
  Misses      25746    25746           
  Partials      106      106           
Flag Coverage Δ
packages 56.32% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@joaquim-verges joaquim-verges changed the title Add ai usage billing banner to dashboard [Dashboard] Add ai usage billing banner to dashboard Sep 23, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Sep 23, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.07 KB (0%) 1.3 s (0%) 241 ms (+199.37% 🔺) 1.6 s
thirdweb (cjs) 361.6 KB (0%) 7.3 s (0%) 883 ms (+24.76% 🔺) 8.2 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 97 ms (+676.01% 🔺) 211 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 76 ms (+3306.73% 🔺) 87 ms
thirdweb/react (minimal + tree-shaking) 19.14 KB (0%) 383 ms (0%) 87 ms (+1713.16% 🔺) 470 ms

@joaquim-verges joaquim-verges marked this pull request as ready for review September 23, 2025 01:29
@joaquim-verges joaquim-verges requested review from a team as code owners September 23, 2025 01:29
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 23, 2025 01:30 Inactive
@github-actions github-actions bot added Dashboard Involves changes to the Dashboard. Playground Changes involving the Playground codebase. Portal Involves changes to the Portal (docs) codebase. labels Sep 23, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
apps/nebula/src/app/(app)/components/EmptyStateChatPageContent.tsx (1)

26-26: Adding relative changes the containing block for absolutely‑positioned children (Aurora). Verify no visual shift.

This makes the outer wrapper the positioning context; Aurora (absolute) may render differently versus before. If the intent was only to anchor an AI banner, consider adding the banner here as well or confirm no regression across breakpoints/dark mode.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx (3)

170-171: Add explicit return type and a className prop; merge with cn().

Meets TS/tsx guidelines and allows local overrides.

-function AIUsageBanner() {
+function AIUsageBanner({ className = "" }: { className?: string }): JSX.Element {
   return (
-    <div className="absolute top-0 left-0 right-0 z-10 flex justify-center px-4 pt-4">
+    <div className={cn("absolute top-0 left-0 right-0 z-10 flex justify-center px-4 pt-4", className)}>

174-189: Use design tokens instead of raw blue colors.

Dashboard code should rely on tokens (bg-card, border-border, text-muted-foreground, text-primary) for theme consistency.

-        <div className="relative overflow-hidden rounded-lg border border-blue-200 bg-gradient-to-r from-blue-50 to-blue-50/50 p-3 shadow-sm dark:border-blue-800 dark:from-blue-950/50 dark:to-blue-950/20">
+        <div className="relative overflow-hidden rounded-lg border border-border bg-card p-3 shadow-sm">
           <div className="relative flex items-center gap-3 px-2">
-            <div className="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
-              <InfoIcon className="size-3.5 text-blue-600 dark:text-blue-400" />
+            <div className="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted">
+              <InfoIcon className="size-3.5 text-muted-foreground" />
             </div>
 
             <div className="flex-1 text-sm">
-              <p className="text-blue-800 dark:text-blue-200">
+              <p className="text-muted-foreground">
                 thirdweb AI usage is billed based on number of tokens used. See
                 the{" "}
                 <a
                   href="https://thirdweb.com/pricing"
                   target="_blank"
                   rel="noopener noreferrer"
-                  className="font-medium text-blue-700 underline decoration-blue-300 underline-offset-2 transition-colors hover:text-blue-800 hover:decoration-blue-500 dark:text-blue-300 dark:decoration-blue-600 dark:hover:text-blue-200 dark:hover:decoration-blue-400"
+                  className="font-medium text-primary underline underline-offset-2 transition-colors hover:text-primary/90"
                 >
                   pricing page
                 </a>
                 .
               </p>

182-193: Microcopy tweak for clarity.

Consider “based on the number of tokens used” (add “the”) for correctness.

-                thirdweb AI usage is billed based on number of tokens used. See
+                thirdweb AI usage is billed based on the number of tokens used. See
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b366d56 and fd3cb3c.

📒 Files selected for processing (5)
  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx (3 hunks)
  • apps/nebula/src/app/(app)/components/EmptyStateChatPageContent.tsx (1 hunks)
  • apps/playground-web/src/app/payments/x402/page.tsx (0 hunks)
  • apps/portal/src/app/payments/x402/page.mdx (0 hunks)
💤 Files with no reviewable changes (2)
  • apps/portal/src/app/payments/x402/page.mdx
  • apps/playground-web/src/app/payments/x402/page.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size

Files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
  • apps/nebula/src/app/(app)/components/EmptyStateChatPageContent.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
  • apps/nebula/src/app/(app)/components/EmptyStateChatPageContent.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/_ (e.g., Button, Input, Tabs, Card)
Use NavLink for internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names with cn() from @/lib/utils for conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start with import "server-only"; use next/headers, server‑only env, heavy data fetching, and redirect() where appropriate
Client Components must start with 'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: call getAuthToken() from cookies, send Authorization: Bearer <token> header, and return typed results (avoid any)
Client-side data fetching: wrap calls in React Query with descriptive, stable queryKeys and set sensible staleTime/cacheTime (≥ 60s default); keep tokens secret via internal routes or server actions
Do not import posthog-js in server components (client-side only)

Files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
apps/{dashboard,playground}/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Expose a className prop on the root element of every component

Files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
🧠 Learnings (8)
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.

Applied to files:

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx
📚 Learning: 2025-07-07T21:21:47.488Z
Learnt from: saminacodes
PR: thirdweb-dev/js#7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-07-31T16:17:42.753Z
Learnt from: MananTank
PR: thirdweb-dev/js#7768
File: apps/playground-web/src/app/navLinks.ts:1-1
Timestamp: 2025-07-31T16:17:42.753Z
Learning: Configuration files that import and reference React components (like icon components from lucide-react) need the "use client" directive, even if they primarily export static data, because the referenced components need to be executed in a client context when used by other client components.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with `'use client';` before imports.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from `lucide-react` or the project-specific `…/icons` exports – never embed raw SVG.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Size
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx (1)

3-3: Lucide import naming LGTM.

InfoIcon follows the repo’s “Icon”-suffix convention.

Comment on lines +47 to +54
// return (
// <AnnouncementBannerUI
// href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
// label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
// trackingLabel="product-rebrand"
// />
// );
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Don’t silently disable AnnouncementBanner; gate or delete to avoid regressions.

Commenting out the render and returning null removes all global announcements and conflicts with our guidance to use AnnouncementBanner for notices. Either gate via a flag or delete the feature entirely (and its UI) to avoid dead code.

Apply one of these:

-  // return (
-  //   <AnnouncementBannerUI
-  //     href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
-  //     label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
-  //     trackingLabel="product-rebrand"
-  //   />
-  // );
-  return null;
+  const SHOW_ANNOUNCEMENT = false; // flip to true to (re)enable when needed
+  return SHOW_ANNOUNCEMENT ? (
+    <AnnouncementBannerUI
+      href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
+      label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
+      trackingLabel="product-rebrand"
+    />
+  ) : null;

Quick check to ensure no pages depend on this banner:


🏁 Script executed:

#!/bin/bash
# Find imports/usages of AnnouncementBanner
rg -nP --type=tsx -C2 '<AnnouncementBanner\b|import\s+{[^}]*AnnouncementBanner[^}]*}\s+from'

Length of output: 27


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "rg version:"
rg --version || true
echo

echo "Finding AnnouncementBanner.tsx files (case-insensitive)..."
# Prefer find if fd isn't available
if command -v fd >/dev/null 2>&1; then
  fd -HI -e tsx -g "*AnnouncementBanner.tsx" || true
else
  find . -type f -iname "AnnouncementBanner.tsx" -print || true
fi
echo

echo "Searching repo for 'AnnouncementBanner' (imports/usages)..."
rg -nS "AnnouncementBanner" || true
echo

echo "Searching repo for JSX usage '<AnnouncementBanner'..."
rg -nS "<AnnouncementBanner\b" || true
echo

echo "Searching repo for 'AnnouncementBannerUI'..."
rg -nS "AnnouncementBannerUI" || true
echo

TARGET="apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx"
if [ -f "$TARGET" ]; then
  echo "== Showing $TARGET with line numbers =="
  nl -ba "$TARGET" | sed -n '1,240p'
else
  echo "File not found at $TARGET"
fi

Length of output: 2070


Don't silently disable AnnouncementBanner — gate it or remove the feature.

AnnouncementBanner currently returns null but is imported and rendered in multiple layouts, which removes global announcements (regression).

  • apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx — export at line 46; UI is commented out (~lines 48–54).
  • apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx — import at line 9; at line 82.
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx — import at line 7; at line 66.
  • apps/dashboard/src/app/(app)/account/layout.tsx — import at line 8; at line 67.

Apply one of: gate behind a feature flag or delete the component and its usages. Suggested minimal change:

-  // return (
-  //   <AnnouncementBannerUI
-  //     href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
-  //     label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
-  //     trackingLabel="product-rebrand"
-  //   />
-  // );
-  return null;
+  const SHOW_ANNOUNCEMENT = false; // flip to true to (re)enable when needed
+  return SHOW_ANNOUNCEMENT ? (
+    <AnnouncementBannerUI
+      href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
+      label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
+      trackingLabel="product-rebrand"
+    />
+  ) : null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// return (
// <AnnouncementBannerUI
// href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
// label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
// trackingLabel="product-rebrand"
// />
// );
return null;
const SHOW_ANNOUNCEMENT = false; // flip to true to (re)enable when needed
return SHOW_ANNOUNCEMENT ? (
<AnnouncementBannerUI
href="https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
label="We have re-branded our Engine, Payments, and Connect products. Please read the full blog post for details on changes"
trackingLabel="product-rebrand"
/>
) : null;
🤖 Prompt for AI Agents
In apps/dashboard/src/@/components/misc/AnnouncementBanner.tsx around lines
47–54 the component is returning null and its UI is commented out, removing
global announcements; either gate it behind a feature flag or delete it and its
usages. To gate: restore the commented return (use AnnouncementBannerUI with the
same href/label/trackingLabel props), read a feature flag (e.g.,
isFeatureEnabled('announcementBanner') or
process.env.FEATURE_ANNOUNCEMENT_BANNER) and render the UI only when the flag is
true (default false), export the component unchanged; to remove: delete this
file or export null and then remove the AnnouncementBanner import and
<AnnouncementBanner /> occurrences from the three layout files listed (team
layout line ~82, project sidebar layout line ~66, account layout line ~67) and
run a build to ensure no unused-import errors.

}) {
return (
<div className="overflow-hidden py-10 lg:py-16">
<AIUsageBanner />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Make the banner’s positioning deterministic by making the container relative.

AIUsageBanner is absolute top-0. The nearest positioned ancestor is currently not the page section, so placement can drift. Align with the Nebula change and set the outer wrapper to relative.

Apply:

-    <div className="overflow-hidden py-10 lg:py-16">
+    <div className="relative overflow-hidden py-10 lg:py-16">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<AIUsageBanner />
<div className="relative overflow-hidden py-10 lg:py-16">
<AIUsageBanner />
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/ai/components/EmptyStateChatPageContent.tsx
around line 27, the AIUsageBanner is positioned absolute (top-0) but its nearest
positioned ancestor is not the page section which makes placement drift; wrap
the <AIUsageBanner /> in the outer container that should be the positioned
ancestor and add relative positioning to that wrapper (e.g., give the outer
div/className a "relative" class) so the banner’s absolute positioning is
deterministic and anchored to the intended container.

@joaquim-verges joaquim-verges merged commit a81899d into main Sep 23, 2025
24 checks passed
@joaquim-verges joaquim-verges deleted the cursor/add-ai-usage-billing-banner-to-dashboard-f4fb branch September 23, 2025 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Dashboard Involves changes to the Dashboard. Playground Changes involving the Playground codebase. Portal Involves changes to the Portal (docs) codebase.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants