Routing¶
Carbon Connect uses the Next.js App Router with file-system based routing. All routes are defined in the src/app/ directory.
Route Table¶
Public Routes¶
| Route | Directory | Description | Auth |
|---|---|---|---|
/ | app/page.tsx | Landing page with marketing content | No |
/login | app/login/ | Login form (OAuth2 password flow) | No |
/register | app/register/ | Registration with tenant creation | No |
/verify-email | app/verify-email/ | Email verification callback | No |
Authenticated Routes¶
| Route | Directory | Description |
|---|---|---|
/dashboard | app/dashboard/page.tsx | Dashboard home with stats and activity |
/dashboard/grants | app/dashboard/grants/ | Grant search, filter, and browse |
/dashboard/grants/[id] | app/dashboard/grants/[id]/ | Grant detail view |
/dashboard/companies | app/dashboard/companies/ | Company list and management |
/dashboard/companies/[id] | app/dashboard/companies/[id]/ | Company detail/edit |
/dashboard/matches | app/dashboard/matches/ | Match results with score breakdowns |
/dashboard/applications | app/dashboard/applications/ | Application tracking (Kanban) |
/dashboard/applications/[id] | app/dashboard/applications/[id]/ | Application detail/edit |
/dashboard/carbon-profile | app/dashboard/carbon-profile/ | Carbon profile form (Scope ½/3) |
/dashboard/settings | app/dashboard/settings/ | User and tenant settings |
/dashboard/vcri | app/dashboard/vcri/ | VCRI project management |
Layout Structure¶
Root Layout (app/layout.tsx)¶
Wraps the entire application:
- HTML structure with fonts and metadata
- Theme provider (light/dark mode)
- React Query provider
- Toast notification container
Dashboard Layout (app/dashboard/layout.tsx)¶
Wraps all authenticated pages:
- Sidebar navigation with route highlighting
- Top header bar with user menu and notifications
- Authentication guard (redirects to
/loginif unauthenticated) - Breadcrumb navigation
flowchart TB
subgraph RootLayout["Root Layout"]
direction TB
Providers[QueryClient + Theme]
subgraph PublicPages["Public Pages"]
Landing["/"]
Login["/login"]
Register["/register"]
end
subgraph DashLayout["Dashboard Layout"]
direction TB
Sidebar[Sidebar Nav]
Header[Header Bar]
subgraph Content["Page Content"]
Dashboard["/dashboard"]
Grants["/dashboard/grants"]
Companies["/dashboard/companies"]
Matches["/dashboard/matches"]
Apps["/dashboard/applications"]
Carbon["/dashboard/carbon-profile"]
Settings["/dashboard/settings"]
VCRI["/dashboard/vcri"]
end
end
end Authentication Guards¶
The dashboard layout checks for authentication status before rendering:
// app/dashboard/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
const { data: user, isLoading } = useCurrentUser();
// Redirect to login if not authenticated
if (!isLoading && !user) {
redirect("/login");
}
return (
<div className="flex h-screen">
<Sidebar />
<div className="flex-1 flex flex-col">
<Header user={user} />
<main className="flex-1 overflow-auto p-6">
{children}
</main>
</div>
</div>
);
}
Token-Based Auth Flow¶
sequenceDiagram
participant B as Browser
participant N as Next.js App
participant A as API
B->>N: Navigate to /dashboard
N->>N: Check localStorage for token
alt Token exists
N->>A: GET /api/v1/auth/me
alt Token valid
A-->>N: User profile
N-->>B: Render dashboard
else Token expired
A-->>N: 401 Unauthorized
N->>A: POST /api/v1/auth/refresh
alt Refresh succeeds
A-->>N: New tokens
N->>A: Retry GET /api/v1/auth/me
A-->>N: User profile
N-->>B: Render dashboard
else Refresh fails
N-->>B: Redirect to /login
end
end
else No token
N-->>B: Redirect to /login
end Navigation¶
Sidebar Links¶
The sidebar provides navigation for all dashboard sections:
| Icon | Label | Route | Description |
|---|---|---|---|
| Home | Dashboard | /dashboard | Overview statistics |
| Search | Grants | /dashboard/grants | Search and browse grants |
| Building | Companies | /dashboard/companies | Manage company profiles |
| Target | Matches | /dashboard/matches | View grant matches |
| FileText | Applications | /dashboard/applications | Track applications |
| Leaf | Carbon Profile | /dashboard/carbon-profile | Emission inputs |
| Settings | Settings | /dashboard/settings | Account settings |
Breadcrumbs¶
Breadcrumb navigation is generated from the URL path segments:
Dynamic Routes¶
Grant Detail¶
Uses Next.js dynamic segments to render individual grant pages. The [id] parameter is a UUID that maps to a grant in the database.
Company Detail¶
Application Detail¶
API Route Mapping¶
Frontend routes map to backend API endpoints:
| Frontend Route | API Endpoint | Hook |
|---|---|---|
/dashboard | GET /api/v1/dashboard/stats | useDashboardStats |
/dashboard/grants | GET /api/v1/grants/search | useGrantSearch |
/dashboard/grants/[id] | GET /api/v1/grants/{id} | useGrant |
/dashboard/companies | GET /api/v1/companies | useCompanies |
/dashboard/matches | GET /api/v1/matches | useMatches |
/dashboard/applications | GET /api/v1/applications | useApplications |
/dashboard/carbon-profile | GET /api/v1/companies/{id}/carbon-profile | useCarbonProfile |