Skip to content

Conversation

@SirjanSingh
Copy link

@SirjanSingh SirjanSingh commented Dec 14, 2025

Summary

  • Extracted the duplicated dashboard header/navbar into a shared component: Frontend/src/components/dashboard-header.tsx.
  • Replaced repeated header markup across dashboard pages to reduce duplication and keep behavior consistent.

Files updated

  • Added: Frontend/src/components/dashboard-header.tsx
  • Updated:
    • Frontend/src/pages/DashboardPage.tsx
    • Frontend/src/pages/Sponsorships.tsx
    • Frontend/src/pages/Collaborations.tsx
    • Frontend/src/pages/Messages.tsx
    • Frontend/src/pages/CollaborationDetails.tsx

Behavior

  • UI/UX remains the same across all dashboard views.
  • Quick logout button remains only on DashboardPage via props (showQuickLogout, onLogout).

Testing

  • Ran the frontend locally and verified navigation/header renders on:
    /dashboard, /dashboard/sponsorships, /dashboard/collaborations, /dashboard/messages, and collaboration details page.

Team Name - EtherX

  • Ritigya Gupta
  • Sirjan Singh
  • Heeral Mandolia

Summary by CodeRabbit

  • Refactor

    • Consolidated header implementations across dashboard pages (Collaborations, Messages, Sponsorships, CollaborationDetails, and DashboardPage) using a new unified DashboardHeader component with integrated navigation, search, theme toggle, and logout functionality.
  • Chores

    • Removed environment variable example entries from configuration file.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

Walkthrough

This change introduces a new reusable DashboardHeader component and refactors five existing pages to use it instead of inline header markup. An environment example file is updated with the removal of three environment variable entries.

Changes

Cohort / File(s) Summary
New Component
Frontend/src/components/dashboard-header.tsx
New DashboardHeader component with responsive layout, navigation items, optional search bar, mode toggle, optional logout button, and user navigation menu. Accepts props for search visibility, logout button visibility, and logout callback.
Page Refactoring
Frontend/src/pages/CollaborationDetails.tsx, Frontend/src/pages/Collaborations.tsx, Frontend/src/pages/DashboardPage.tsx, Frontend/src/pages/Messages.tsx, Frontend/src/pages/Sponsorships.tsx
Each page replaces inline header markup with a single DashboardHeader component import and invocation. Removes duplicated header-related imports and UI controls (Link, ModeToggle, UserNav, navigation icons). Page structure and content logic remain unchanged.
Configuration
Frontend/env-example
Removed three environment variable example lines: VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY, and VITE_YOUTUBE_API_KEY.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~20 minutes

  • DashboardHeader component: Review prop interface, conditional rendering logic for search (md+ screens), logout button, and navigation structure
  • Page updates: Verify imports are correctly added and inline header markup is cleanly removed across all five pages
  • Env file: Confirm environment variable removal is intentional and documented

Poem

🐰 Headers once scattered, now unified and neat,
Five pages hop along with a component so sweet!
One DashboardHeader to rule them all,
Responsive and tidy—a refactor to call!

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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references issue #224 and indicates a refactor to extract a shared header component, which aligns with the core changeset of consolidating duplicated dashboard headers into a reusable DashboardHeader component.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Frontend/src/pages/Messages.tsx (1)

160-322: Remove dead code.

Lines 160-322 contain old code marked as "Old Code" and hidden with className="hidden". Dead code should be removed entirely rather than hidden, as it increases maintenance burden and codebase size.

Apply this diff to remove the dead code:

       <DashboardHeader />
-      {/* Old Code */}
-      <main className="flex-1 hidden">
-        {/* Sidebar */}
-        <div className="w-full md:w-175 border-r flex flex-col bg-white dark:bg-gray-900">
-          {/* Search Input */}
-          <div className="p-4 border-b">
-            <div className="relative">
-              <Search className="absolute left-3 top-3 h-4 w-4 text-gray-500" />
-              <Input
-                type="search"
-                placeholder="Search messages..."
-                className="pl-10 py-2 w-full bg-gray-100 dark:bg-gray-800 border rounded-md focus:ring focus:ring-blue-300"
-              />
-            </div>
-          </div>
-
-          {/* Tabs Section */}
-          <Tabs
-            defaultValue="all"
-            className="flex-1 flex flex-col"
-            onValueChange={setActiveTab}
-          >
-            <div className="px-4 py-2">
-              <TabsList className="grid w-full grid-cols-3 bg-gray-100">
-                <TabsTrigger value="all" className="text-gray-900">
-                  All
-                </TabsTrigger>
-                <TabsTrigger value="brand" className="text-gray-900">
-                  Brands
-                </TabsTrigger>
-                <TabsTrigger value="creator" className="text-gray-900">
-                  Creators
-                </TabsTrigger>
-              </TabsList>
-            </div>
-
-            {/* Contacts List */}
-            <ScrollArea className="flex-1">
-              <div className="p-3 space-y-2">
-                {filteredContacts.map((contact) => (
-                  <div key={contact.id}>
-                    <Button
-                      variant="ghost"
-                      className={`w-full justify-start px-2 py-3 rounded-md transition duration-200 ${
-                        activeContact.id === contact.id
-                          ? "bg-gray-200 dark:bg-gray-800"
-                          : "hover:bg-gray-100 dark:hover:bg-gray-700"
-                      }`}
-                      onClick={() => setActiveContact(contact)}
-                    >
-                      <div className="flex items-center w-full">
-                        <Avatar className="h-9 w-9 mr-3">
-                          <AvatarImage
-                            src={contact.avatar}
-                            alt={contact.name}
-                          />
-                          <AvatarFallback>{contact.initials}</AvatarFallback>
-                        </Avatar>
-                        <div className="flex-1 overflow-hidden">
-                          <div className="flex justify-between">
-                            <span className="font-medium truncate">
-                              {contact.name}
-                            </span>
-                            <span className="text-xs text-gray-500">
-                              {contact.time}
-                            </span>
-                          </div>
-                          <p className="text-sm text-gray-500 truncate">
-                            {contact.lastMessage}
-                          </p>
-                        </div>
-                        {contact.unread && (
-                          <Badge className="ml-2 h-2 w-2 rounded-full bg-red-500 p-0" />
-                        )}
-                      </div>
-                    </Button>
-                    <Separator className="my-2" />
-                  </div>
-                ))}
-              </div>
-            </ScrollArea>
-          </Tabs>
-        </div>
-
-        {/* Chat Section */}
-        <div className="flex-1 flex flex-col bg-gray-50 dark:bg-gray-900">
-          {/* Chat Header */}
-          <div className="p-4 border-b flex items-center justify-between bg-white dark:bg-gray-800">
-            <div className="flex items-center">
-              <Avatar className="h-10 w-10 mr-3">
-                <AvatarImage
-                  src={activeContact.avatar}
-                  alt={activeContact.name}
-                />
-                <AvatarFallback>{activeContact.initials}</AvatarFallback>
-              </Avatar>
-              <div>
-                <h2 className="font-medium">{activeContact.name}</h2>
-                <p className="text-xs text-gray-500">
-                  {activeContact.type === "brand" ? "Brand Partner" : "Creator"}
-                </p>
-              </div>
-            </div>
-            <div className="flex items-center gap-2">
-              <Button variant="outline" size="sm">
-                View Profile
-              </Button>
-              <Button variant="outline" size="sm">
-                Create Contract
-              </Button>
-            </div>
-          </div>
-
-          {/* Messages Area */}
-          <ScrollArea className="flex-5 p-8">
-            <div className="space-y-8">
-              {activeMessages.map((message) => (
-                <div
-                  key={message.id}
-                  className={`flex ${
-                    message.sender === "user" ? "justify-end" : "justify-start"
-                  }`}
-                >
-                  <div
-                    className={`max-w-[75%] p-3 rounded-lg shadow-md ${
-                      message.sender === "user"
-                        ? "bg-purple-700 text-white"
-                        : "bg-gray-200 dark:bg-gray-800 text-black dark:text-white"
-                    }`}
-                  >
-                    <p>{message.content}</p>
-                    <p className="text-xs mt-1 opacity-70">{message.time}</p>
-                  </div>
-                </div>
-              ))}
-            </div>
-          </ScrollArea>
-
-          {/* Message Input */}
-          <div className="p-4 border-t bg-white dark:bg-gray-800">
-            <div className="flex items-center gap-2">
-              <Input
-                placeholder="Type your message..."
-                value={messageInput}
-                onChange={(e) => setMessageInput(e.target.value)}
-                onKeyDown={(e) => {
-                  if (e.key === "Enter") {
-                    handleSendMessage();
-                  }
-                }}
-                className="w-full p-2 border rounded-md bg-gray-100 dark:bg-gray-700 focus:ring focus:ring-purple-300"
-              />
-              <Button
-                size="sm"
-                onClick={handleSendMessage}
-                className="bg-purple-700 hover:bg-purple-600 text-white"
-              >
-                <Send className="h-5 w-5" />
-              </Button>
-            </div>
-          </div>
-        </div>
-      </main>
       <Chat />
🧹 Nitpick comments (2)
Frontend/src/components/dashboard-header.tsx (2)

1-1: Remove unnecessary React import.

With React 19 and the modern JSX transform enabled (as indicated in the PR), explicit React imports are no longer required for JSX files.

Apply this diff:

-import React from "react";
 import { Link } from "react-router-dom";

56-69: Consider adding active route highlighting.

The navigation buttons don't indicate which page is currently active. Users benefit from visual feedback showing their current location in the navigation.

You can use react-router-dom's useLocation hook to highlight the active route:

+import { Link, useLocation } from "react-router-dom";

 export default function DashboardHeader({
   showSearch = true,
   showQuickLogout = false,
   onLogout,
 }: DashboardHeaderProps) {
+  const location = useLocation();
+
   return (
     <header className="sticky top-0 z-50 w-full border-b border-gray-200 bg-white/95 backdrop-blur supports-[backdrop-filter]:bg-white/60">
       <div className="container flex h-16 items-center">
         <Link to="/" className="flex items-center space-x-2 mr-6 ml-6">
           <Rocket className="h-6 w-6 text-[hsl(262.1,83.3%,57.8%)]" />
           <span className="font-bold text-xl hidden md:inline-block">Inpact</span>
         </Link>

         <div className="flex items-center space-x-4">
           {DASHBOARD_NAV_ITEMS.map(({ to, icon: Icon, label }) => (
             <Button
               key={to}
               variant="ghost"
               size="sm"
-              className="w-9 px-0 hover:bg-[hsl(210,40%,96.1%)] hover:text-[hsl(222.2,47.4%,11.2%)]"
+              className={`w-9 px-0 hover:bg-[hsl(210,40%,96.1%)] hover:text-[hsl(222.2,47.4%,11.2%)] ${
+                location.pathname === to ? 'bg-[hsl(210,40%,96.1%)] text-[hsl(222.2,47.4%,11.2%)]' : ''
+              }`}
               asChild
             >
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3be437 and 92f5f67.

📒 Files selected for processing (7)
  • Frontend/env-example (0 hunks)
  • Frontend/src/components/dashboard-header.tsx (1 hunks)
  • Frontend/src/pages/CollaborationDetails.tsx (3 hunks)
  • Frontend/src/pages/Collaborations.tsx (2 hunks)
  • Frontend/src/pages/DashboardPage.tsx (2 hunks)
  • Frontend/src/pages/Messages.tsx (2 hunks)
  • Frontend/src/pages/Sponsorships.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • Frontend/env-example
🧰 Additional context used
🧬 Code graph analysis (6)
Frontend/src/pages/Collaborations.tsx (1)
Frontend/src/components/dashboard-header.tsx (1)
  • DashboardHeader (42-97)
Frontend/src/pages/CollaborationDetails.tsx (1)
Frontend/src/components/dashboard-header.tsx (1)
  • DashboardHeader (42-97)
Frontend/src/components/dashboard-header.tsx (2)
Frontend/src/components/mode-toggle.tsx (1)
  • ModeToggle (11-36)
Frontend/src/components/user-nav.tsx (1)
  • UserNav (17-74)
Frontend/src/pages/Messages.tsx (1)
Frontend/src/components/dashboard-header.tsx (1)
  • DashboardHeader (42-97)
Frontend/src/pages/DashboardPage.tsx (1)
Frontend/src/components/dashboard-header.tsx (1)
  • DashboardHeader (42-97)
Frontend/src/pages/Sponsorships.tsx (1)
Frontend/src/components/dashboard-header.tsx (1)
  • DashboardHeader (42-97)
🔇 Additional comments (6)
Frontend/src/pages/DashboardPage.tsx (1)

4-4: LGTM! Clean refactor to shared header component.

The DashboardPage correctly imports and uses the new DashboardHeader component with appropriate props. The showQuickLogout and onLogout props are passed correctly, maintaining the quick logout functionality that should only appear on the main dashboard.

Also applies to: 22-22

Frontend/src/pages/Sponsorships.tsx (1)

3-3: LGTM! Consistent header implementation.

The Sponsorships page correctly uses the DashboardHeader with default props. The refactor eliminates duplicate header markup while maintaining the same UI/UX.

Also applies to: 18-18

Frontend/src/pages/Collaborations.tsx (1)

3-3: LGTM! Proper conditional rendering.

The Collaborations page correctly implements conditional header rendering using the showHeader prop. This allows the component to be embedded in other views (like the dashboard tabs) without duplicate headers.

Also applies to: 44-44

Frontend/src/pages/Messages.tsx (1)

4-5: LGTM! Clean header refactor.

The Messages page correctly imports and uses the DashboardHeader component with streamlined icon imports.

Also applies to: 159-159

Frontend/src/pages/CollaborationDetails.tsx (1)

2-2: LGTM! Successful header consolidation.

The CollaborationDetails page correctly imports and uses the DashboardHeader component, with appropriate import cleanup for react-router-dom.

Also applies to: 11-11, 312-312

Frontend/src/components/dashboard-header.tsx (1)

42-96: LGTM! Well-structured reusable component.

The DashboardHeader component successfully consolidates header logic from multiple pages into a single, maintainable component. The implementation includes:

  • Clean prop-based customization (showSearch, showQuickLogout, onLogout)
  • Good accessibility with sr-only labels for icon buttons
  • Proper type safety with exported DashboardHeaderProps
  • Responsive design with conditional rendering

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant