b475c02707
Update all user-facing instances of 'Kandev' to 'KanDev' for consistent branding: - Page title and PWA manifest - Settings sidebar header - MCP config badge - Sprites settings description
91 lines
3.2 KiB
TypeScript
91 lines
3.2 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
|
import "./globals.css";
|
|
import { ThemeProvider } from "@/components/theme-provider";
|
|
import { StateProvider } from "@/components/state-provider";
|
|
import { WebSocketConnector } from "@/components/ws-connector";
|
|
import { ToastProvider } from "@/components/toast-provider";
|
|
import { TooltipProvider } from "@kandev/ui/tooltip";
|
|
import { CommandRegistryProvider } from "@/lib/commands/command-registry";
|
|
import { CommandPanel } from "@/components/command-panel";
|
|
import { GlobalCommands } from "@/components/global-commands";
|
|
import { DiffWorkerPoolProvider } from "@/components/diff-worker-pool-provider";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "KanDev - AI Kanban",
|
|
description: "AI-powered workflow management for developers",
|
|
};
|
|
|
|
export const viewport: Viewport = {
|
|
// Enable safe area insets for iOS devices (notch, home indicator)
|
|
viewportFit: "cover",
|
|
// Prevent iOS auto-zoom on input focus (for app-like experience)
|
|
maximumScale: 1,
|
|
userScalable: false,
|
|
};
|
|
|
|
/**
|
|
* Extract port from URL string (e.g., "http://localhost:8080" -> "8080")
|
|
*/
|
|
function extractPort(url: string): string | null {
|
|
try {
|
|
const parsed = new URL(url);
|
|
return parsed.port || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode;
|
|
}>) {
|
|
// Extract ports from server-side env vars
|
|
// We inject only ports, not full URLs, so client can build URLs from window.location.hostname
|
|
// This allows accessing the app from any device (iPhone, Tailscale, etc.)
|
|
const apiPort = extractPort(process.env.KANDEV_API_BASE_URL ?? "");
|
|
const mcpPort = extractPort(process.env.KANDEV_MCP_SERVER_URL ?? "");
|
|
const debugMode = process.env.NEXT_PUBLIC_KANDEV_DEBUG === "true";
|
|
|
|
return (
|
|
<html lang="en" suppressHydrationWarning>
|
|
<head>
|
|
<meta name="apple-mobile-web-app-title" content="KanDev" />
|
|
</head>
|
|
<body className="antialiased font-sans">
|
|
{apiPort || mcpPort || debugMode ? (
|
|
// Inject runtime config for production bundles where ports are chosen at launch.
|
|
// Client will build full URLs using window.location.hostname + port
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: [
|
|
apiPort ? `window.__KANDEV_API_PORT = ${JSON.stringify(apiPort)};` : "",
|
|
mcpPort ? `window.__KANDEV_MCP_PORT = ${JSON.stringify(mcpPort)};` : "",
|
|
debugMode ? `window.__KANDEV_DEBUG = true;` : "",
|
|
]
|
|
.filter(Boolean)
|
|
.join("\n"),
|
|
}}
|
|
/>
|
|
) : null}
|
|
<StateProvider>
|
|
<ThemeProvider>
|
|
<DiffWorkerPoolProvider>
|
|
<TooltipProvider>
|
|
<ToastProvider>
|
|
<CommandRegistryProvider>
|
|
<WebSocketConnector />
|
|
<GlobalCommands />
|
|
<CommandPanel />
|
|
{children}
|
|
</CommandRegistryProvider>
|
|
</ToastProvider>
|
|
</TooltipProvider>
|
|
</DiffWorkerPoolProvider>
|
|
</ThemeProvider>
|
|
</StateProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|