feat(admin): enhance login form with language switcher and update script handling
- Added AdminLanguageSwitcher to the login form for improved language selection. - Replaced inline script with next/script component for better performance and safety in layout.tsx. - Updated language initialization logic to ensure consistent SSR and client rendering.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
|
import Script from "next/script";
|
||||||
|
|
||||||
import { Providers } from "@/components/providers";
|
import { Providers } from "@/components/providers";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
@@ -37,7 +38,9 @@ export default function RootLayout({
|
|||||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<script dangerouslySetInnerHTML={{ __html: ADMIN_LOCALE_BOOTSTRAP }} />
|
<Script id="admin-locale-bootstrap" strategy="beforeInteractive">
|
||||||
|
{ADMIN_LOCALE_BOOTSTRAP}
|
||||||
|
</Script>
|
||||||
</head>
|
</head>
|
||||||
<body className="flex min-h-full flex-col">
|
<body className="flex min-h-full flex-col">
|
||||||
<Providers>{children}</Providers>
|
<Providers>{children}</Providers>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { toast } from "sonner";
|
|||||||
import { isAxiosError } from "axios";
|
import { isAxiosError } from "axios";
|
||||||
|
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||||
|
import { AdminLanguageSwitcher } from "@/components/admin/admin-language-switcher";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
@@ -121,6 +122,9 @@ export function LoginForm() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex min-h-full flex-1 flex-col items-center justify-center overflow-hidden px-4 py-14 sm:py-20">
|
<div className="relative flex min-h-full flex-1 flex-col items-center justify-center overflow-hidden px-4 py-14 sm:py-20">
|
||||||
|
<div className="absolute right-4 top-4 z-20 sm:right-6 sm:top-6">
|
||||||
|
<AdminLanguageSwitcher />
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
aria-hidden
|
||||||
className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_85%_50%_at_50%_-5%,rgb(59_130_246/0.09),transparent)] dark:bg-[radial-gradient(ellipse_85%_50%_at_50%_-5%,rgb(56_189_248/0.12),transparent)]"
|
className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_85%_50%_at_50%_-5%,rgb(59_130_246/0.09),transparent)] dark:bg-[radial-gradient(ellipse_85%_50%_at_50%_-5%,rgb(56_189_248/0.12),transparent)]"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { initReactI18next } from "react-i18next";
|
|||||||
import {
|
import {
|
||||||
adminHtmlLang,
|
adminHtmlLang,
|
||||||
applyAdminUiLocale,
|
applyAdminUiLocale,
|
||||||
getStoredAdminUiLocale,
|
|
||||||
hydrateAdminUiLocale,
|
hydrateAdminUiLocale,
|
||||||
type AdminApiLocale,
|
type AdminApiLocale,
|
||||||
} from "@/lib/admin-locale";
|
} from "@/lib/admin-locale";
|
||||||
@@ -124,16 +123,9 @@ export function normalizeAdminLanguage(lang: string | undefined): AdminLanguage
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getInitialAdminLanguage(): AdminLanguage {
|
function getInitialAdminLanguage(): AdminLanguage {
|
||||||
if (typeof window === "undefined") {
|
// Keep SSR and first client render aligned to avoid hydration mismatch.
|
||||||
|
// Stored locale is applied after mount in `Providers`.
|
||||||
return ADMIN_DEFAULT_LANGUAGE;
|
return ADMIN_DEFAULT_LANGUAGE;
|
||||||
}
|
|
||||||
|
|
||||||
const stored = getStoredAdminUiLocale();
|
|
||||||
if (stored) {
|
|
||||||
return stored;
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizeAdminLanguage(document.documentElement.lang);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncAdminLanguage(lang: AdminLanguage): void {
|
function syncAdminLanguage(lang: AdminLanguage): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user