Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 99 additions & 98 deletions src/AppRouter.tsx
Original file line number Diff line number Diff line change
@@ -1,123 +1,124 @@
import { lazy, Suspense } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import Loading from './components/common/Loading';
import OwnerRoute from './components/OwnerRoute';

// Pages
import Manuals from './pages/products/Manuals';
import PlatformHub from './pages/PlatformHub'; // New Main Entry
import Echo from './pages/Echo';
import Platform from './pages/Platform';
import Agents from './pages/Agents';
import Start from './pages/Start';
import Analysis from './pages/Analysis';
import Checkout from './pages/Checkout';
import Manual from './pages/Manual';
import About from './pages/About';
import HowItWorks from './pages/HowItWorks';
import Privacy from './pages/Privacy';
import Terms from './pages/Terms';
import SignIn from './pages/SignIn';
import SignInVerify from './pages/SignInVerify';
// import Learn from './pages/Learn'; // If exists
import Relational from './pages/Relational'; // If exists
import Inversion from './pages/Inversion';
const Manuals = lazy(() => import(/* webpackChunkName: "Manuals" */ './pages/products/Manuals'));
const PlatformHub = lazy(() => import(/* webpackChunkName: "PlatformHub" */ './pages/PlatformHub'));
const Echo = lazy(() => import(/* webpackChunkName: "Echo" */ './pages/Echo'));
const Platform = lazy(() => import(/* webpackChunkName: "Platform" */ './pages/Platform'));
const Agents = lazy(() => import(/* webpackChunkName: "Agents" */ './pages/Agents'));
const Start = lazy(() => import(/* webpackChunkName: "Start" */ './pages/Start'));
const Analysis = lazy(() => import(/* webpackChunkName: "Analysis" */ './pages/Analysis'));
const Checkout = lazy(() => import(/* webpackChunkName: "Checkout" */ './pages/Checkout'));
const Manual = lazy(() => import(/* webpackChunkName: "Manual" */ './pages/Manual'));
const About = lazy(() => import(/* webpackChunkName: "About" */ './pages/About'));
const HowItWorks = lazy(() => import(/* webpackChunkName: "HowItWorks" */ './pages/HowItWorks'));
const Privacy = lazy(() => import(/* webpackChunkName: "Privacy" */ './pages/Privacy'));
const Terms = lazy(() => import(/* webpackChunkName: "Terms" */ './pages/Terms'));
const SignIn = lazy(() => import(/* webpackChunkName: "SignIn" */ './pages/SignIn'));
const SignInVerify = lazy(() => import(/* webpackChunkName: "SignInVerify" */ './pages/SignInVerify'));
const Relational = lazy(() => import(/* webpackChunkName: "Relational" */ './pages/Relational'));
const Inversion = lazy(() => import(/* webpackChunkName: "Inversion" */ './pages/Inversion'));

// Admin
import Admin from './pages/Admin';
import OwnerRoute from './components/OwnerRoute';
// import ProtectedRoute from './components/ProtectedRoute'; // Using DashboardLayout's internal auth check for new dashboard
const Admin = lazy(() => import(/* webpackChunkName: "Admin" */ './pages/Admin'));

// Dashboard (New)
import DashboardLayout from './pages/dashboard/Layout';
import Overview from './pages/dashboard/Overview';
import Keys from './pages/dashboard/Keys';
import Usage from './pages/dashboard/Usage';
const DashboardLayout = lazy(() => import(/* webpackChunkName: "DashboardLayout" */ './pages/dashboard/Layout'));
const Overview = lazy(() => import(/* webpackChunkName: "Overview" */ './pages/dashboard/Overview'));
const Keys = lazy(() => import(/* webpackChunkName: "Keys" */ './pages/dashboard/Keys'));
const Usage = lazy(() => import(/* webpackChunkName: "Usage" */ './pages/dashboard/Usage'));

// Documentation
import DocsIndex from './pages/docs/Index';
import DocLayout from './components/docs/DocLayout';
import GettingStarted from './pages/docs/GettingStarted';
import APIReference from './pages/docs/APIReference';
import Authentication from './pages/docs/Authentication';
import SDKs from './pages/docs/SDKs';
import CodeExamples from './pages/docs/CodeExamples';
const DocsIndex = lazy(() => import(/* webpackChunkName: "DocsIndex" */ './pages/docs/Index'));
const DocLayout = lazy(() => import(/* webpackChunkName: "DocLayout" */ './components/docs/DocLayout'));
const GettingStarted = lazy(() => import(/* webpackChunkName: "GettingStarted" */ './pages/docs/GettingStarted'));
const APIReference = lazy(() => import(/* webpackChunkName: "APIReference" */ './pages/docs/APIReference'));
const Authentication = lazy(() => import(/* webpackChunkName: "Authentication" */ './pages/docs/Authentication'));
const SDKs = lazy(() => import(/* webpackChunkName: "SDKs" */ './pages/docs/SDKs'));
const CodeExamples = lazy(() => import(/* webpackChunkName: "CodeExamples" */ './pages/docs/CodeExamples'));

// Developer Portal
import DeveloperLayout from './pages/developer/Layout';
import DeveloperIndex from './pages/developer/Index';
import DeveloperGuides from './pages/developer/Guides';
import DeveloperResources from './pages/developer/Resources';
import DeveloperCommunity from './pages/developer/Community';
import DeveloperRoadmap from './pages/developer/Roadmap';
const DeveloperLayout = lazy(() => import(/* webpackChunkName: "DeveloperLayout" */ './pages/developer/Layout'));
const DeveloperIndex = lazy(() => import(/* webpackChunkName: "DeveloperIndex" */ './pages/developer/Index'));
const DeveloperGuides = lazy(() => import(/* webpackChunkName: "DeveloperGuides" */ './pages/developer/Guides'));
const DeveloperResources = lazy(() => import(/* webpackChunkName: "DeveloperResources" */ './pages/developer/Resources'));
const DeveloperCommunity = lazy(() => import(/* webpackChunkName: "DeveloperCommunity" */ './pages/developer/Community'));
const DeveloperRoadmap = lazy(() => import(/* webpackChunkName: "DeveloperRoadmap" */ './pages/developer/Roadmap'));
Comment on lines +7 to +49
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The magic comments use Webpack syntax (webpackChunkName), but this project uses Vite as the build tool (confirmed in vite.config.ts and package.json). Vite doesn't recognize these comments. While Vite will automatically create chunks for lazy-loaded routes, these comments won't affect the chunk naming. Remove them or replace with Vite-compatible comments if you want custom chunk names (though Vite handles this automatically and these comments add no value).

Copilot uses AI. Check for mistakes.

export default function AppRouter() {
return (
<Routes>
{/* --- MAIN PLATFORM --- */}
{/* defrag.app root = Infrastructure Hub (ECHO/ORBIT/SIGNAL/API grid) */}
<Route path="/" element={<PlatformHub />} />
<Suspense fallback={<Loading />}>
<Routes>
{/* --- MAIN PLATFORM --- */}
{/* defrag.app root = Infrastructure Hub (ECHO/ORBIT/SIGNAL/API grid) */}
<Route path="/" element={<PlatformHub />} />

{/* Product-specific landings */}
{/* Product-specific landings */}
<Route path="/echo" element={<Echo />} />
<Route path="/api" element={<Platform />} /> {/* API-specific page (was at root, now at /api) */}
<Route path="/platform" element={<PlatformHub />} /> {/* Legacy support */}
<Route path="/agents" element={<Agents />} />
<Route path="/start" element={<Start />} />
<Route path="/analysis" element={<Analysis />} />
<Route path="/relational" element={<Relational />} />
<Route path="/inversion" element={<Inversion />} />
{/* Product-specific landings */}
<Route path="/echo" element={<Echo />} />
<Route path="/api" element={<Platform />} /> {/* API-specific page (was at root, now at /api) */}
<Route path="/platform" element={<PlatformHub />} /> {/* Legacy support */}
<Route path="/agents" element={<Agents />} />
<Route path="/start" element={<Start />} />
<Route path="/analysis" element={<Analysis />} />
<Route path="/relational" element={<Relational />} />
<Route path="/inversion" element={<Inversion />} />

{/* Product Pages */}
<Route path="/products/manuals" element={<Manuals />} /> {/* Original Sales Page */}
<Route path="/manual" element={<Navigate to="/defrag-manual" replace />} />
<Route path="/defrag-manual" element={<Manual />} /> {/* Legacy path support */}
{/* Product Pages */}
<Route path="/products/manuals" element={<Manuals />} /> {/* Original Sales Page */}
<Route path="/manual" element={<Navigate to="/defrag-manual" replace />} />
<Route path="/defrag-manual" element={<Manual />} /> {/* Legacy path support */}

{/* --- DASHBOARD --- */}
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<Overview />} />
<Route path="keys" element={<Keys />} />
<Route path="usage" element={<Usage />} />
</Route>
{/* --- DASHBOARD --- */}
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<Overview />} />
<Route path="keys" element={<Keys />} />
<Route path="usage" element={<Usage />} />
</Route>

{/* --- DEVELOPER PORTAL --- */}
<Route path="/developer" element={<DeveloperLayout />}>
<Route index element={<DeveloperIndex />} />
<Route path="guides" element={<DeveloperGuides />} />
<Route path="resources" element={<DeveloperResources />} />
<Route path="community" element={<DeveloperCommunity />} />
<Route path="roadmap" element={<DeveloperRoadmap />} />
</Route>
{/* --- DEVELOPER PORTAL --- */}
<Route path="/developer" element={<DeveloperLayout />}>
<Route index element={<DeveloperIndex />} />
<Route path="guides" element={<DeveloperGuides />} />
<Route path="resources" element={<DeveloperResources />} />
<Route path="community" element={<DeveloperCommunity />} />
<Route path="roadmap" element={<DeveloperRoadmap />} />
</Route>
Comment on lines +75 to +88
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The single top-level Suspense boundary means all nested routes (Dashboard, Developer Portal, Docs) will show the same loading fallback when they're loading their layouts. This can cause the entire page to flash the Loading component when navigating between dashboard sub-routes. Consider adding nested Suspense boundaries around route groups that have layouts (DashboardLayout, DeveloperLayout, DocLayout) to provide more granular loading states and prevent full-page reloads when navigating within those sections.

Copilot uses AI. Check for mistakes.

{/* --- DOCUMENTATION --- */}
<Route path="/docs" element={<DocLayout><DocsIndex /></DocLayout>} />
<Route path="/docs/getting-started" element={<GettingStarted />} />
<Route path="/docs/api-reference" element={<APIReference />} />
<Route path="/docs/authentication" element={<Authentication />} />
<Route path="/docs/sdks" element={<SDKs />} />
<Route path="/docs/code-examples" element={<CodeExamples />} />
{/* --- DOCUMENTATION --- */}
<Route path="/docs" element={<DocLayout><DocsIndex /></DocLayout>} />
<Route path="/docs/getting-started" element={<GettingStarted />} />
<Route path="/docs/api-reference" element={<APIReference />} />
<Route path="/docs/authentication" element={<Authentication />} />
<Route path="/docs/sdks" element={<SDKs />} />
<Route path="/docs/code-examples" element={<CodeExamples />} />
Comment on lines +91 to +96

Choose a reason for hiding this comment

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

high

The current routing for documentation pages has an issue where only the /docs index page is rendered within DocLayout. Other pages like /docs/getting-started will not have the shared layout (sidebar, footer, etc.).

To ensure a consistent layout across all documentation pages and to use a more idiomatic react-router-dom v6 pattern (which is already used for the /dashboard routes), I suggest refactoring this to use nested routes.

Note that this change will also require updating DocLayout.tsx to render an <Outlet /> component instead of {children}.

Suggested change
<Route path="/docs" element={<DocLayout><DocsIndex /></DocLayout>} />
<Route path="/docs/getting-started" element={<GettingStarted />} />
<Route path="/docs/api-reference" element={<APIReference />} />
<Route path="/docs/authentication" element={<Authentication />} />
<Route path="/docs/sdks" element={<SDKs />} />
<Route path="/docs/code-examples" element={<CodeExamples />} />
<Route path="/docs" element={<DocLayout />}>
<Route index element={<DocsIndex />} />
<Route path="getting-started" element={<GettingStarted />} />
<Route path="api-reference" element={<APIReference />} />
<Route path="authentication" element={<Authentication />} />
<Route path="sdks" element={<SDKs />} />
<Route path="code-examples" element={<CodeExamples />} />
</Route>

Comment on lines +91 to +96
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The documentation routes have an inconsistent structure compared to Dashboard and Developer Portal. The /docs route wraps DocsIndex in DocLayout inline, but child routes like /docs/getting-started don't use DocLayout, meaning they won't have the sidebar navigation. This appears to be a pre-existing issue, but with lazy loading, each of these child routes will now load independently without the layout wrapper. Consider restructuring to use nested routes with DocLayout as a parent, similar to the Dashboard and Developer Portal patterns.

Suggested change
<Route path="/docs" element={<DocLayout><DocsIndex /></DocLayout>} />
<Route path="/docs/getting-started" element={<GettingStarted />} />
<Route path="/docs/api-reference" element={<APIReference />} />
<Route path="/docs/authentication" element={<Authentication />} />
<Route path="/docs/sdks" element={<SDKs />} />
<Route path="/docs/code-examples" element={<CodeExamples />} />
<Route path="/docs" element={<DocLayout />}>
<Route index element={<DocsIndex />} />
<Route path="getting-started" element={<GettingStarted />} />
<Route path="api-reference" element={<APIReference />} />
<Route path="authentication" element={<Authentication />} />
<Route path="sdks" element={<SDKs />} />
<Route path="code-examples" element={<CodeExamples />} />
</Route>

Copilot uses AI. Check for mistakes.

{/* --- AUTH & UTILS --- */}
<Route path="/checkout" element={<Checkout />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/signin/verify" element={<SignInVerify />} />
{/* --- AUTH & UTILS --- */}
<Route path="/checkout" element={<Checkout />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/signin/verify" element={<SignInVerify />} />

{/* --- LEGAL & INFO --- */}
<Route path="/about" element={<About />} />
<Route path="/how-it-works" element={<HowItWorks />} />
<Route path="/privacy" element={<Privacy />} />
<Route path="/terms" element={<Terms />} />
{/* --- LEGAL & INFO --- */}
<Route path="/about" element={<About />} />
<Route path="/how-it-works" element={<HowItWorks />} />
<Route path="/privacy" element={<Privacy />} />
<Route path="/terms" element={<Terms />} />

{/* --- ADMIN --- */}
<Route
path="/admin"
element={
<OwnerRoute>
<Admin />
</OwnerRoute>
}
/>
{/* --- ADMIN --- */}
<Route
path="/admin"
element={
<OwnerRoute>
<Admin />
</OwnerRoute>
}
/>

{/* Fallback */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
{/* Fallback */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
);
}
9 changes: 9 additions & 0 deletions src/components/common/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Loader2 } from 'lucide-react';

export default function Loading() {
return (
<div className="flex min-h-[50vh] w-full items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin text-zinc-500" />
Comment on lines +5 to +6
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The Loading component uses Loader2 from lucide-react with text-zinc-500, but the rest of the codebase consistently uses custom circular spinners with orange accents (e.g., border-orange-500/30 border-t-orange-500 in OwnerRoute.tsx:22 and ProtectedRoute.tsx:17). For visual consistency across loading states, consider using the established pattern: a circular div with border-2 border-white/30 border-t-orange-500 rounded-full animate-spin.

Copilot uses AI. Check for mistakes.
</div>
);
}
Loading