Skip to content

refactor: Deduplicate DashboardHeader, DashboardChrome, and MobileNavContext between creator and business #76

Description

@JamesVictor-O

Problem

Three core dashboard infrastructure components are copy-pasted identically between the creator and business directories:

Component Creator Business Difference
`DashboardHeader` `creator/dashboard-header.tsx` `business/dashboard-header.tsx` None — byte-identical
`MobileNavContext` `creator/mobile-nav-context.tsx` `business/mobile-nav-context.tsx` None — byte-identical
`DashboardChrome` `creator/dashboard-chrome.tsx` `business/dashboard-chrome.tsx` Only the theme class (`creator-dashboard-theme` vs `business-dashboard-theme`) and import paths

This means every bug fix or improvement (like the recurring "missing DashboardHeader" issue) must be applied twice. The DashboardFooter is already shared (business imports from creator), proving the pattern works.


Proposed Solution

Move the shared components to `components/dashboard/shared/`:

```
components/dashboard/shared/
├── dashboard-header.tsx ← shared (already identical)
├── mobile-nav-context.tsx ← shared (already identical)
└── dashboard-chrome.tsx ← shared, accepts themeClass prop
```

`DashboardChrome` changes

Add a `themeClass` prop:

```tsx
export function DashboardChrome({
children,
themeClass
}: {
children: ReactNode;
themeClass: "creator-dashboard-theme" | "business-dashboard-theme";
}) {
return (

<div className={`${themeClass} min-h-screen overflow-x-hidden bg-[var(--dash-bg)] text-[var(--dash-body)]`}>
...


);
}
```

Each layout calls it with the appropriate class:

```tsx
// app/dashboard/creator/layout.tsx
<DashboardChrome themeClass="creator-dashboard-theme">
{children}

// app/dashboard/business/layout.tsx
<DashboardChrome themeClass="business-dashboard-theme">
{children}

```

`SidebarNav` stays separate

The sidebar content differs between creator and business (different nav items, different branding text), so `SidebarNav` correctly lives in each dashboard's directory. Pass it as a prop or use a render slot.


Acceptance Criteria

  • `DashboardHeader` exists once in `shared/`, imported by both layouts
  • `MobileNavContext` exists once in `shared/`, imported by both layouts
  • `DashboardChrome` exists once in `shared/`, accepts `themeClass` prop
  • Old duplicated files in `creator/` and `business/` are deleted
  • Both dashboards render identically to before (no visual change)
  • TypeScript compiles clean

Metadata

Metadata

Assignees

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