mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-19 08:28:10 +02:00
- AuthShell: dark two-column auth layout (brand/value panel with CSS-only waveform motif + proof points + Bland-style enterprise CTA block on the left, zinc-900 form card on the right; single-column on mobile). - AuthEnterpriseCTA: "Talk to our team" → dograh.com/contact?intent=enterprise. - stack-theme: dark StackTheme token overrides synced to globals.css. - page.tsx: wrap StackHandler (non-fullPage) in AuthShell + StackTheme; local-auth fallback preserved inside the shell. BackButton slimmed for the card. - Dark locked as default: <html className="dark">, next-themes ThemeProvider (defaultTheme="dark", enableSystem=false); inline no-FOUC script defaults dark. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
import "./globals.css";
|
|
|
|
import type { Metadata } from "next";
|
|
import { Geist, Geist_Mono } from "next/font/google";
|
|
import { Suspense } from "react";
|
|
|
|
import ChatwootWidget from "@/components/ChatwootWidget";
|
|
import AppLayout from "@/components/layout/AppLayout";
|
|
import PostHogIdentify from "@/components/PostHogIdentify";
|
|
import { SentryErrorBoundary } from "@/components/SentryErrorBoundary";
|
|
import SpinLoader from "@/components/SpinLoader";
|
|
import { ThemeProvider } from "@/components/ThemeProvider";
|
|
import { Toaster } from "@/components/ui/sonner";
|
|
import { AppConfigProvider } from "@/context/AppConfigContext";
|
|
import { OnboardingProvider } from "@/context/OnboardingContext";
|
|
import { TelephonyConfigWarningsProvider } from "@/context/TelephonyConfigWarningsContext";
|
|
import { UserConfigProvider } from "@/context/UserConfigContext";
|
|
import { AuthProvider } from "@/lib/auth";
|
|
|
|
|
|
const geistSans = Geist({
|
|
variable: "--font-geist-sans",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
const geistMono = Geist_Mono({
|
|
variable: "--font-geist-mono",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Dograh",
|
|
description: "Open Source Voice Assistant Workflow Builder",
|
|
};
|
|
|
|
export default function RootLayout({
|
|
children
|
|
}: {
|
|
children: React.ReactNode
|
|
}) {
|
|
|
|
return (
|
|
<html lang="en" className="dark" suppressHydrationWarning>
|
|
<head>
|
|
{/* Inline script to prevent flash of light theme - runs before React hydrates.
|
|
Dark is the locked default: only an explicit stored 'light' opts out. */}
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
(function() {
|
|
try {
|
|
var theme = localStorage.getItem('theme');
|
|
if (theme === 'light') {
|
|
document.documentElement.classList.remove('dark');
|
|
} else {
|
|
document.documentElement.classList.add('dark');
|
|
}
|
|
} catch (e) {
|
|
document.documentElement.classList.add('dark');
|
|
}
|
|
})();
|
|
`,
|
|
}}
|
|
/>
|
|
</head>
|
|
<body
|
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
|
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false} disableTransitionOnChange>
|
|
<SentryErrorBoundary>
|
|
<AuthProvider>
|
|
<AppConfigProvider>
|
|
<Suspense fallback={<SpinLoader />}>
|
|
<UserConfigProvider>
|
|
<TelephonyConfigWarningsProvider>
|
|
<OnboardingProvider>
|
|
<PostHogIdentify />
|
|
<AppLayout>
|
|
{children}
|
|
</AppLayout>
|
|
<Toaster />
|
|
<ChatwootWidget />
|
|
</OnboardingProvider>
|
|
</TelephonyConfigWarningsProvider>
|
|
</UserConfigProvider>
|
|
</Suspense>
|
|
</AppConfigProvider>
|
|
</AuthProvider>
|
|
</SentryErrorBoundary>
|
|
</ThemeProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|