fix(i18n): wrap CookieConsentRoot with LanguageProvider

The CookieConsentBanner uses useLanguage() hook but was rendered
outside of LanguageProvider in RootLayout. Added LanguageProvider
wrapper to fix the runtime error.
This commit is contained in:
Antigravity
2026-05-23 09:27:29 +00:00
parent a20cee0f63
commit 77f69fc1d1
19 changed files with 748 additions and 6 deletions

View File

@@ -1,9 +1,11 @@
'use client'
import { useState } from 'react'
import { Download, Upload, Trash2, Loader2, RefreshCw, Sparkles, Database } from 'lucide-react'
import { Download, Upload, Trash2, Loader2, RefreshCw, Sparkles, Database, ShieldAlert } from 'lucide-react'
import { toast } from 'sonner'
import { useLanguage } from '@/lib/i18n'
import { useSession } from 'next-auth/react'
import { DeleteAccountDialog } from '@/components/legal/delete-account-dialog'
import { useRouter } from 'next/navigation'
import { motion } from 'motion/react'
import { cn } from '@/lib/utils'
@@ -11,6 +13,8 @@ import { cn } from '@/lib/utils'
export default function DataSettingsPage() {
const { t } = useLanguage()
const router = useRouter()
const { data: session } = useSession()
const [deleteOpen, setDeleteOpen] = useState(false)
const [isExporting, setIsExporting] = useState(false)
const [isImporting, setIsImporting] = useState(false)
const [isDeleting, setIsDeleting] = useState(false)
@@ -246,6 +250,42 @@ export default function DataSettingsPage() {
</button>
</div>
</div>
<div className="bg-rose-50/50 dark:bg-rose-500/5 rounded-2xl border border-rose-200/50 dark:border-rose-500/20 p-8 mt-6">
<div className="flex items-center gap-5 mb-8">
<div className="p-3 bg-rose-500/10 rounded-2xl text-rose-600 dark:text-rose-400 border border-rose-500/20">
<ShieldAlert size={20} />
</div>
<div>
<h4 className="text-sm font-bold text-rose-600 dark:text-rose-400">{t('account.deleteAccount.sectionTitle')}</h4>
<p className="text-[11px] text-concrete mt-0.5">{t('account.deleteAccount.sectionDescription')}</p>
</div>
</div>
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between p-6 bg-white/60 dark:bg-black/20 rounded-2xl border border-rose-200/30 dark:border-rose-500/10 gap-4">
<div className="space-y-1">
<p className="text-[13px] font-bold text-ink">{t('account.deleteAccount.dialogTitle')}</p>
<p className="text-[11px] text-concrete">{t('account.deleteAccount.sectionDescription')}</p>
</div>
<button
onClick={() => setDeleteOpen(true)}
className="shrink-0 px-6 py-3 rounded-2xl bg-rose-600 text-white text-[10px] font-bold uppercase tracking-[0.2em] shadow-xl shadow-rose-600/20 hover:scale-[1.02] active:scale-95 transition-all duration-300"
>
<div className="flex items-center justify-center gap-2">
<ShieldAlert className="h-4 w-4" />
{t('account.deleteAccount.buttonLabel')}
</div>
</button>
</div>
</div>
{session?.user?.email && (
<DeleteAccountDialog
userEmail={session.user.email}
open={deleteOpen}
onOpenChange={setDeleteOpen}
/>
)}
</motion.div>
)
}

View File

@@ -5,8 +5,9 @@ import { useLanguage } from '@/lib/i18n'
import { updateAISettings } from '@/app/actions/ai-settings'
import { toast } from 'sonner'
import { useRouter } from 'next/navigation'
import { Globe, Bell } from 'lucide-react'
import { Globe, Bell, Shield } from 'lucide-react'
import { motion } from 'motion/react'
import { openCookiePreferences } from '@/lib/consent/cookie-consent'
interface GeneralSettingsClientProps {
@@ -174,6 +175,27 @@ export function GeneralSettingsClient({ initialSettings }: GeneralSettingsClient
</div>
</div>
</div>
<div className="bg-white/40 dark:bg-white/5 border border-border rounded-xl p-8 space-y-6">
<div className="flex items-center gap-5">
<div className="p-3 bg-paper dark:bg-white/10 rounded-2xl text-concrete border border-border">
<Shield size={18} />
</div>
<div className="space-y-0.5">
<h4 className="text-base font-bold text-ink">{t('consent.preferences.title')}</h4>
<p className="text-[11px] text-concrete">{t('consent.preferences.description')}</p>
</div>
</div>
<div className="pt-2">
<button
onClick={() => openCookiePreferences()}
className="w-full px-5 py-3.5 bg-white dark:bg-white/10 border border-border rounded-xl text-xs font-bold uppercase tracking-[0.25em] text-ink dark:text-paper hover:scale-[1.01] active:scale-95 transition-all duration-300 shadow-sm"
>
{t('consent.banner.manage')}
</button>
</div>
</div>
</div>
</motion.div>
)

View File

@@ -8,6 +8,8 @@ import { ThemeInitializer } from "@/components/theme-initializer";
import { DirectionInitializer } from "@/components/direction-initializer";
import { ErrorReporter } from "@/components/error-reporter";
import { auth } from "@/auth";
import { CookieConsentRoot } from "@/components/legal/cookie-consent-root";
import { LanguageProvider } from "@/lib/i18n/LanguageProvider";
import Script from "next/script";
import { getThemeScript } from "@/lib/theme-script";
import { normalizeThemeId } from "@/lib/apply-document-theme";
@@ -123,6 +125,9 @@ export default async function RootLayout({
<DirectionInitializer />
<ThemeInitializer theme={userSettings.theme} fontSize={aiSettings.fontSize} fontFamily={aiSettings.fontFamily} accentColor={userSettings.accentColor} />
{children}
<LanguageProvider initialLanguage="en">
<CookieConsentRoot initialAnonymousAnalytics={aiSettings?.anonymousAnalytics} />
</LanguageProvider>
<Toaster />
</SessionProviderWrapper>
</body>