Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/app/auth/[path]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function AuthPage({
const { path } = await params;
const { redirect_url } = await searchParams;

// Default to /dashboard if no redirect_url is provided
// Default to /onboarding if no redirect_url is provided
// Otherwise use the redirect_url from query params (e.g., from share links)
const redirectTo = redirect_url || "/onboarding";

Expand Down
29 changes: 25 additions & 4 deletions src/app/dashboard/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
/**
* Dynamic route for workspace slugs: /dashboard/[slug]
* This imports and renders the same dashboard content as /dashboard
* Renders the dashboard shell for an active workspace.
*/
import DashboardPage from "../page";
import { SEO } from "@/components/seo/SEO";
import { seoConfig } from "@/lib/seo-config";
import { DashboardShell } from "../page";

export default function WorkspacePage() {
return <DashboardPage />;
interface WorkspacePageProps {
params: Promise<{ slug: string }>;
}

export default async function WorkspacePage({ params }: WorkspacePageProps) {
const { slug } = await params;
const workspaceUrl = `${seoConfig.siteUrl}/dashboard/${slug}`;

return (
<>
<SEO
title="Dashboard"
description="Manage your workspaces, create new projects, and organize knowledge effortlessly in your ThinkEx dashboard."
keywords="dashboard, workspace management, AI workspace, productivity tools"
url={workspaceUrl}
canonical={workspaceUrl}
noindex
/>
<DashboardShell />
</>
);
}

26 changes: 14 additions & 12 deletions src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Loader2 } from "lucide-react";
import { useRouter } from "next/navigation";
import { usePostHog } from 'posthog-js/react';
import { SEO } from "@/components/seo/SEO";
import type { AgentState } from "@/lib/workspace-state/types";
import { initialState } from "@/lib/workspace-state/state";
import { useScrollHeader } from "@/hooks/ui/use-scroll-header";
Expand Down Expand Up @@ -364,7 +363,7 @@ function DashboardContent({

// Main page component
// Main page component
function DashboardPage() {
export function DashboardPage() {
const router = useRouter();
// Get workspace context
const {
Expand Down Expand Up @@ -431,7 +430,7 @@ function DashboardPage() {
}

// Wrapper for sidebar provider
function SidebarCoordinator({ children }: { children: React.ReactNode }) {
export function SidebarCoordinator({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider defaultOpen={true}>
{children}
Expand All @@ -440,7 +439,7 @@ function SidebarCoordinator({ children }: { children: React.ReactNode }) {
}

// Component to handle anonymous users - redirect to guest-setup if no session
function AnonymousSessionHandler({ children }: { children: React.ReactNode }) {
export function AnonymousSessionHandler({ children }: { children: React.ReactNode }) {
const { data: session, isPending } = useSession();
const router = useRouter();

Expand Down Expand Up @@ -483,16 +482,9 @@ function AnonymousSessionHandler({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}

export default function Page() {
export function DashboardShell() {
return (
<>
<SEO
title="Dashboard"
description="Manage your workspaces, create new projects, and organize knowledge effortlessly in your ThinkEx dashboard."
keywords="dashboard, workspace management, AI workspace, productivity tools"
url="https://thinkex.app/dashboard"
canonical="https://thinkex.app/dashboard"
/>
<MobileWarning />
<AnonymousSessionHandler>
<WorkspaceProvider>
Expand All @@ -506,3 +498,13 @@ export default function Page() {
</>
);
}

export default function Page() {
const router = useRouter();

useEffect(() => {
router.replace("/home");
}, [router]);
Comment thread
urjitc marked this conversation as resolved.

return null;
}
4 changes: 2 additions & 2 deletions src/app/guest-setup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function GuestSetupPage() {
try {
// Step 1: Check if already authenticated (not anonymous)
if (session && !session.user.isAnonymous) {
router.replace("/dashboard");
router.replace("/home");
return;
}

Expand All @@ -55,7 +55,7 @@ export default function GuestSetupPage() {
if (data.slug) {
router.replace(`/dashboard/${data.slug}`);
} else {
router.replace("/dashboard");
router.replace("/home");
}
} catch (error) {
console.error("Guest setup error:", error);
Expand Down
17 changes: 17 additions & 0 deletions src/app/home/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { SEO } from "@/components/seo/SEO";
import { DashboardShell } from "../dashboard/page";

export default function HomePage() {
return (
<>
<SEO
title="Home"
description="Choose a workspace or create a new one to start organizing your knowledge in ThinkEx."
keywords="home, workspaces, dashboard, productivity tools"
url="https://thinkex.app/home"
canonical="https://thinkex.app/home"
/>
<DashboardShell />
</>
);
}
11 changes: 8 additions & 3 deletions src/app/onboarding/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,20 @@ export default function OnboardingPage() {

// If there's a redirect_url that's NOT a dashboard route (e.g., share links),
// prioritize that over the onboarding redirect
if (redirectUrl && !redirectUrl.startsWith("/dashboard") && !redirectUrl.startsWith("/onboarding")) {
if (
redirectUrl &&
!redirectUrl.startsWith("/dashboard") &&
!redirectUrl.startsWith("/onboarding") &&
!redirectUrl.startsWith("/home")
) {
sessionStorage.removeItem("auth_redirect_url");
router.replace(redirectUrl);
} else if (data.redirectTo) {
// Use the onboarding redirect (demo workspace)
router.replace(data.redirectTo);
} else {
// Existing user, go to dashboard
router.replace("/dashboard");
// Existing user, go to home
router.replace("/home");
}
} catch (error) {
if ((error as Error).name !== "AbortError") {
Expand Down
2 changes: 1 addition & 1 deletion src/app/share/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export default function SharePage() {
const handleModalClose = (open: boolean) => {
if (!open) {
// Redirect to dashboard when modal is closed without importing
router.push("/dashboard");
router.push("/home");
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/landing/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export function Navbar() {
variant="outline"
className="rounded-md font-medium transition-all hover:bg-foreground/5"
>
<Link href="/dashboard" prefetch>
<Link href="/home" prefetch>
Dashboard
</Link>
</Button>
Expand Down Expand Up @@ -235,7 +235,7 @@ export function Navbar() {
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link
href="/dashboard"
href="/home"
onClick={() => posthog.capture('navbar-dashboard-clicked', { location: 'mobile' })}
className="cursor-pointer"
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/workspace-canvas/WorkspaceSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function WorkspaceSidebar({
<h2 className="text-lg font-medium whitespace-nowrap -mb-0.5">ThinkEx</h2>
</Link>
<Link
href="/dashboard"
href="/home"
className={cn(
"inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors cursor-pointer group-data-[collapsible=icon]:hidden"
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/workspace/SharedWorkspaceModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export default function SharedWorkspaceModal({
if (!isCreating) {
onOpenChange(newOpen);
if (!newOpen) {
router.push("/dashboard");
router.push("/home");
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/contexts/WorkspaceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export function WorkspaceProvider({ children }: { children: React.ReactNode }) {
if (remainingWorkspaces.length > 0) {
switchWorkspace(remainingWorkspaces[0].slug || remainingWorkspaces[0].id);
} else {
router.push("/dashboard");
router.push("/home");
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ export async function proxy(request: NextRequest) {
const sessionCookie = getSessionCookie(request);
const { pathname } = request.nextUrl;

// Redirect authenticated users from root to dashboard
// Redirect authenticated users from root to home
if (sessionCookie && pathname === "/") {
return NextResponse.redirect(new URL("/dashboard", request.url));
return NextResponse.redirect(new URL("/home", request.url));
}

// Redirect authenticated users away from auth pages
if (sessionCookie && ["/sign-in", "/sign-up"].includes(pathname)) {
// Preserve redirect_url if present
const redirectUrl = request.nextUrl.searchParams.get('redirect_url') || '/dashboard';
const redirectUrl = request.nextUrl.searchParams.get('redirect_url') || '/home';
return NextResponse.redirect(new URL(redirectUrl, request.url));
}

// Allow anonymous users to access dashboard - they'll get an anonymous session created automatically
// NOTE: Dashboard page component handles creating anonymous sessions for unauthenticated users
// Allow anonymous users to access home - they'll get an anonymous session created automatically
// NOTE: Home page component handles creating anonymous sessions for unauthenticated users
// Actual auth validation happens in API routes, not in middleware

return NextResponse.next();
Expand Down