Files
codeboard/apps/web/src/app/layout.tsx
Vectry 64ce70daa4 feat: add subscription service — user auth, Stripe billing, API keys, dashboard
- NextAuth v5 with email+password credentials, JWT sessions
- Registration, login, email verification, password reset flows
- Stripe integration: Free (15/day), Starter ($5/1k/mo), Pro ($20/100k/mo)
- API key management (cb_ prefix) with hash-based validation
- Dashboard with generations history, settings, billing management
- Rate limiting: Redis daily counter (free), DB monthly (paid)
- Generate route auth: Bearer API key + session, anonymous allowed
- Worker userId propagation for generation history
- Pricing section on landing page, auth-aware navbar
- Middleware with route protection, CORS for codeboard.vectry.tech
- Docker env vars for auth, Stripe, email (smtp.migadu.com)
2026-02-10 20:08:13 +00:00

103 lines
3.4 KiB
TypeScript

import type { Metadata } from "next";
import { Inter, JetBrains_Mono } from "next/font/google";
import "./globals.css";
import { Navbar } from "@/components/navbar";
import { Footer } from "@/components/footer";
import { Providers } from "@/components/providers";
const inter = Inter({
subsets: ["latin"],
variable: "--font-sans",
display: "swap",
});
const jetbrainsMono = JetBrains_Mono({
subsets: ["latin"],
variable: "--font-mono",
display: "swap",
});
export const metadata: Metadata = {
metadataBase: new URL("https://codeboard.vectry.tech"),
title: "CodeBoard — Understand any codebase in 5 minutes",
description:
"Paste a GitHub URL and get interactive onboarding documentation with architecture diagrams, module breakdowns, and getting started guides. Built by Vectry AI consultancy.",
keywords: ["code analysis", "documentation", "github", "codebase", "AI", "developer tools"],
authors: [{ name: "Vectry" }],
creator: "Vectry",
icons: {
icon: [
{ url: "/favicon.ico", sizes: "any" },
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
],
apple: [{ url: "/apple-touch-icon.png", sizes: "180x180" }],
},
openGraph: {
title: "CodeBoard — Understand any codebase in 5 minutes",
description:
"Paste a GitHub URL and get interactive onboarding documentation with architecture diagrams, module breakdowns, and getting started guides.",
type: "website",
url: "https://codeboard.vectry.tech",
siteName: "CodeBoard",
locale: "en_US",
images: [
{
url: "/og-image.png",
width: 1200,
height: 630,
alt: "CodeBoard — Understand any codebase in 5 minutes",
},
],
},
twitter: {
card: "summary_large_image",
title: "CodeBoard — Understand any codebase in 5 minutes",
description:
"Paste a GitHub URL and get interactive onboarding documentation with architecture diagrams, module breakdowns, and getting started guides.",
images: ["/og-image.png"],
},
alternates: {
canonical: "https://codeboard.vectry.tech",
},
robots: {
index: true,
follow: true,
},
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className="dark">
<body
className={`${inter.variable} ${jetbrainsMono.variable} font-sans antialiased bg-[#0a0a0a] text-white min-h-screen`}
>
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-[200] focus:px-4 focus:py-2 focus:rounded-lg focus:bg-[var(--accent-blue)] focus:text-white focus:text-sm focus:font-medium focus:outline-none focus:ring-2 focus:ring-white/50"
>
Skip to content
</a>
<Providers>
<div className="relative min-h-screen flex flex-col">
<div className="fixed inset-0 bg-gradient-radial pointer-events-none" aria-hidden="true" />
<div className="fixed inset-0 bg-grid pointer-events-none opacity-50" aria-hidden="true" />
<Navbar />
<main id="main-content" className="flex-1 relative">
{children}
</main>
<Footer />
</div>
</Providers>
</body>
</html>
);
}