Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m7s
Replaced ~100+ hardcoded French and English text strings across 30+ components with proper i18n t() calls. Added 57 new translation keys to all 15 locale files (ar, de, en, es, fa, fr, hi, it, ja, ko, nl, pl, pt, ru, zh). Key changes: - contextual-ai-chat.tsx: 30 French strings → t() (actions, toasts, labels, placeholders) - ai-chat.tsx: 15 French/English strings → t() (header, tabs, welcome, insights, history) - note-inline-editor.tsx: 20 French fallbacks removed (toolbar, save status, checklist) - lab-skeleton.tsx: French loading text → t() - admin-header.tsx, header.tsx, editor-connections-section.tsx: French fallbacks removed - New AI chat component, agent cards, sidebar, settings panel i18n cleanup Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
|
import "./globals.css";
|
|
import { Toaster } from "@/components/ui/toast";
|
|
import { SessionProviderWrapper } from "@/components/session-provider-wrapper";
|
|
import { getAISettings } from "@/app/actions/ai-settings";
|
|
import { getUserSettings } from "@/app/actions/user-settings";
|
|
import { ThemeInitializer } from "@/components/theme-initializer";
|
|
import { DirectionInitializer } from "@/components/direction-initializer";
|
|
import { ErrorReporter } from "@/components/error-reporter";
|
|
import { auth } from "@/auth";
|
|
import Script from "next/script";
|
|
|
|
import { Inter, Manrope } from "next/font/google";
|
|
|
|
const inter = Inter({
|
|
subsets: ["latin"],
|
|
variable: "--font-inter",
|
|
});
|
|
|
|
const manrope = Manrope({
|
|
subsets: ["latin"],
|
|
variable: "--font-manrope",
|
|
});
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Memento - Your Digital Notepad",
|
|
description: "A beautiful note-taking app built with Next.js 16",
|
|
manifest: "/manifest.json",
|
|
icons: {
|
|
icon: "/icons/icon-512.svg",
|
|
apple: "/icons/icon-512.svg",
|
|
},
|
|
appleWebApp: {
|
|
capable: true,
|
|
statusBarStyle: "default",
|
|
title: "Memento",
|
|
},
|
|
};
|
|
|
|
export const viewport: Viewport = {
|
|
themeColor: "#3A7CA5",
|
|
};
|
|
|
|
function getHtmlClass(theme?: string): string {
|
|
if (theme === 'dark') return 'dark';
|
|
if (theme === 'midnight') return 'dark';
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Inline script that runs BEFORE React hydrates.
|
|
* Reads the user's saved language from localStorage and sets
|
|
* `dir` on <html> immediately — prevents RTL/LTR flash.
|
|
*/
|
|
const directionScript = `
|
|
(function(){
|
|
try {
|
|
var lang = localStorage.getItem('user-language');
|
|
if (lang === 'fa' || lang === 'ar') {
|
|
document.documentElement.dir = 'rtl';
|
|
document.documentElement.lang = lang;
|
|
}
|
|
} catch(e) {}
|
|
})();
|
|
`;
|
|
|
|
export default async function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode;
|
|
}>) {
|
|
const session = await auth();
|
|
const userId = session?.user?.id;
|
|
|
|
const [aiSettings, userSettings] = await Promise.all([
|
|
getAISettings(userId),
|
|
getUserSettings(userId),
|
|
])
|
|
|
|
return (
|
|
<html suppressHydrationWarning className={getHtmlClass(userSettings.theme)}>
|
|
<head />
|
|
<body className={`${inter.className} ${inter.variable} ${manrope.variable}`}>
|
|
<Script
|
|
id="sw-cleanup"
|
|
strategy="afterInteractive"
|
|
dangerouslySetInnerHTML={{ __html: `if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then(function(rs){rs.forEach(function(r){r.unregister()})})}` }}
|
|
/>
|
|
<SessionProviderWrapper>
|
|
<ErrorReporter />
|
|
<DirectionInitializer />
|
|
<ThemeInitializer theme={userSettings.theme} fontSize={aiSettings.fontSize} />
|
|
{children}
|
|
<Toaster />
|
|
</SessionProviderWrapper>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|