Skip to content

Commit 70be50f

Browse files
shantanu patilclaude
authored andcommitted
Add Phase 4: Clerk auth, landing page redesign, feature gating, waitlist
- Clerk frontend integration: @clerk/nextjs, ClerkProvider in layout, middleware with public route matcher, AuthButtons component - Landing page overhaul: rebrand to GitUnderstand, curated wiki library grid replacing repo URL input, new Hero3D with children pattern, FooterCTA with waitlist CTA, updated ComparisonTable/CommunitySection - Feature gating: wiki generation requires Clerk auth, cached wikis remain public, AI chat gated behind sign-in, Clerk JWT passed to WebSocket connections via query param - WaitlistModal component: full pricing survey form posting to /api/waitlist, animated with Framer Motion - next.config.ts: new rewrites for /api/waitlist and /webhooks/clerk - useAuthentication hook: Clerk useAuth integration with backward compat - useWikiGeneration/useRepoStructure: accept clerkToken param Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e04aad6 commit 70be50f

17 files changed

Lines changed: 959 additions & 728 deletions

next.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ const nextConfig: NextConfig = {
6868
source: '/api/wiki_templates',
6969
destination: `${TARGET_SERVER_BASE_URL}/api/wiki_templates`,
7070
},
71+
{
72+
source: '/api/waitlist',
73+
destination: `${TARGET_SERVER_BASE_URL}/api/waitlist`,
74+
},
75+
{
76+
source: '/webhooks/clerk',
77+
destination: `${TARGET_SERVER_BASE_URL}/webhooks/clerk`,
78+
},
7179
];
7280
},
7381
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"test:e2e": "playwright test"
1212
},
1313
"dependencies": {
14+
"@clerk/nextjs": "^6.38.3",
1415
"@gsap/react": "^2.1.2",
1516
"@react-three/drei": "^10.7.7",
1617
"@react-three/fiber": "^9.5.0",

src/app/[owner]/[repo]/page.tsx

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import TableOfContents from '@/components/TableOfContents';
99
import RepoMetadata from '@/components/RepoMetadata';
1010
import WikiTreeView from '@/components/WikiTreeView';
1111
import ExportMenu from '@/components/ExportMenu';
12+
import WaitlistModal from '@/components/WaitlistModal';
1213
import { useLanguage } from '@/contexts/LanguageContext';
1314
import { RepoInfo } from '@/types/repoinfo';
1415
import Link from 'next/link';
1516
import { useParams, useSearchParams } from 'next/navigation';
1617
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1718
import { motion } from 'framer-motion';
18-
import { ArrowLeft, Book, BookOpen, List, MessageSquare, AlertTriangle, Home, Network, Search, RefreshCw, X } from 'lucide-react';
19+
import { ArrowLeft, Book, BookOpen, List, Lock, MessageSquare, AlertTriangle, Home, Network, Search, RefreshCw, X } from 'lucide-react';
1920
import DependencyGraph from '@/components/DependencyGraph';
2021
import WikiSidebarSkeleton from '@/components/skeletons/WikiSidebarSkeleton';
2122
import WikiContentSkeleton from '@/components/skeletons/WikiContentSkeleton';
@@ -28,6 +29,7 @@ import { useWikiCache } from '@/hooks/useWikiCache';
2829
import { useRepoStructure } from '@/hooks/useRepoStructure';
2930
import { useWikiExport } from '@/hooks/useWikiExport';
3031
import { wikiStyles } from '@/styles/wikiStyles';
32+
import { SignInButton } from '@clerk/nextjs';
3133

3234
export default function RepoWikiPage() {
3335
// Get route parameters and search params
@@ -153,7 +155,20 @@ export default function RepoWikiPage() {
153155
} | null>(null);
154156

155157
// Authentication (extracted hook)
156-
const { authRequired, authCode, setAuthCode, isAuthLoading } = useAuthentication();
158+
const { authRequired, authCode, setAuthCode, isAuthLoading, isAuthenticated, getToken } = useAuthentication();
159+
160+
// Clerk JWT token for WebSocket auth
161+
const [clerkToken, setClerkToken] = useState<string | null>(null);
162+
163+
// Waitlist modal state
164+
const [isWaitlistModalOpen, setIsWaitlistModalOpen] = useState(false);
165+
166+
// Fetch Clerk token when authenticated
167+
useEffect(() => {
168+
if (isAuthenticated) {
169+
getToken().then(setClerkToken);
170+
}
171+
}, [isAuthenticated, getToken]);
157172

158173
// Default branch state
159174
const [defaultBranch, setDefaultBranch] = useState<string>('main');
@@ -235,6 +250,7 @@ export default function RepoWikiPage() {
235250
modelIncludedFiles,
236251
isComprehensiveView,
237252
selectedTemplate,
253+
clerkToken,
238254
setIsLoading,
239255
setLoadingMessage,
240256
setError,
@@ -259,6 +275,7 @@ export default function RepoWikiPage() {
259275
modelExcludedFiles,
260276
authRequired,
261277
authCode,
278+
isClerkAuthenticated: isAuthenticated,
262279
setIsLoading,
263280
setLoadingMessage,
264281
setError,
@@ -532,6 +549,37 @@ export default function RepoWikiPage() {
532549
</div>
533550
</>
534551

552+
) : error === '__AUTH_REQUIRED__' ? (
553+
/* Auth gate: user needs to sign in to generate new wikis */
554+
<div className="max-w-md mx-auto mt-16 p-8 border border-border bg-card rounded-xl text-center">
555+
<div className="inline-flex items-center justify-center p-3 bg-primary/10 rounded-full mb-4">
556+
<Lock size={24} className="text-primary" />
557+
</div>
558+
<h3 className="text-xl font-semibold text-foreground mb-2">Sign in to Generate Wikis</h3>
559+
<p className="text-muted-foreground mb-6 text-sm">
560+
This repository doesn&apos;t have a cached wiki yet. Sign in to generate an AI-powered wiki for <strong>{owner}/{repo}</strong>.
561+
</p>
562+
<div className="flex flex-col gap-3 items-center">
563+
<SignInButton mode="modal">
564+
<button className="inline-flex items-center justify-center rounded-md text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-6 py-2 transition-colors">
565+
Sign In to Generate
566+
</button>
567+
</SignInButton>
568+
<button
569+
onClick={() => setIsWaitlistModalOpen(true)}
570+
className="text-sm text-muted-foreground hover:text-foreground transition-colors underline underline-offset-4"
571+
>
572+
Or join the waitlist
573+
</button>
574+
<Link
575+
href="/"
576+
className="mt-2 inline-flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
577+
>
578+
<Home size={14} className="mr-1.5" />
579+
Back to Home
580+
</Link>
581+
</div>
582+
</div>
535583
) : error ? (
536584
<div className="max-w-2xl mx-auto mt-12 p-6 border border-destructive/20 bg-destructive/5 rounded-xl text-center">
537585
<div className="inline-flex items-center justify-center p-3 bg-destructive/10 rounded-full mb-4">
@@ -902,16 +950,33 @@ export default function RepoWikiPage() {
902950
</div>
903951
{/* Drawer body */}
904952
<div className="flex-1 overflow-y-auto">
905-
{effectiveRepoInfo && (
906-
<Ask
907-
repoInfo={effectiveRepoInfo}
908-
provider={selectedProviderState}
909-
model={selectedModelState}
910-
isCustomModel={isCustomSelectedModelState}
911-
customModel={customSelectedModelState}
912-
language={language}
913-
onRef={(ref) => (askComponentRef.current = ref)}
914-
/>
953+
{isAuthenticated ? (
954+
effectiveRepoInfo && (
955+
<Ask
956+
repoInfo={effectiveRepoInfo}
957+
provider={selectedProviderState}
958+
model={selectedModelState}
959+
isCustomModel={isCustomSelectedModelState}
960+
customModel={customSelectedModelState}
961+
language={language}
962+
onRef={(ref) => (askComponentRef.current = ref)}
963+
/>
964+
)
965+
) : (
966+
<div className="flex flex-col items-center justify-center h-full px-8 text-center">
967+
<div className="inline-flex items-center justify-center p-3 bg-primary/10 rounded-full mb-4">
968+
<Lock size={24} className="text-primary" />
969+
</div>
970+
<h3 className="text-lg font-semibold text-foreground mb-2">Sign in to Chat</h3>
971+
<p className="text-sm text-muted-foreground mb-6">
972+
Sign in to ask questions and chat with this codebase using AI.
973+
</p>
974+
<SignInButton mode="modal">
975+
<button className="inline-flex items-center justify-center rounded-md text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-6 py-2 transition-colors">
976+
Sign In
977+
</button>
978+
</SignInButton>
979+
</div>
915980
)}
916981
</div>
917982
</motion.div>
@@ -983,6 +1048,12 @@ export default function RepoWikiPage() {
9831048
onClose={() => setShowGraph(false)}
9841049
/>
9851050

1051+
{/* Waitlist Modal */}
1052+
<WaitlistModal
1053+
isOpen={isWaitlistModalOpen}
1054+
onClose={() => setIsWaitlistModalOpen(false)}
1055+
/>
1056+
9861057
{/* Onboarding tooltips */}
9871058
{onboardingStep !== null && (
9881059
<div className="fixed inset-0 z-[60] pointer-events-none">

src/app/layout.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Metadata } from "next";
22
import { Inter, Noto_Serif_JP, Plus_Jakarta_Sans, JetBrains_Mono } from "next/font/google";
33
import "./globals.css";
4+
import { ClerkProvider } from "@clerk/nextjs";
45
import { ThemeProvider } from "next-themes";
56
import { LanguageProvider } from "@/contexts/LanguageContext";
67

@@ -35,8 +36,8 @@ const jetbrainsMono = JetBrains_Mono({
3536
});
3637

3738
export const metadata: Metadata = {
38-
title: "BetterCodeWiki | AI-Powered Code Documentation",
39-
description: "Automatically generate beautiful, interactive wikis for any GitHub, GitLab, or BitBucket repository",
39+
title: "GitUnderstand | AI-Powered Code Documentation",
40+
description: "Instantly understand any codebase with AI-generated wikis, diagrams, and interactive documentation",
4041
};
4142

4243
export default function RootLayout({
@@ -55,11 +56,13 @@ export default function RootLayout({
5556
>
5657
Skip to content
5758
</a>
58-
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
59-
<LanguageProvider>
60-
{children}
61-
</LanguageProvider>
62-
</ThemeProvider>
59+
<ClerkProvider>
60+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
61+
<LanguageProvider>
62+
{children}
63+
</LanguageProvider>
64+
</ThemeProvider>
65+
</ClerkProvider>
6366
</body>
6467
</html>
6568
);

0 commit comments

Comments
 (0)