feat(i18n): refactor authentication to use user locale from cookies and implement language switching

This commit is contained in:
ngc2207 2024-12-12 20:16:41 +08:00
parent e5b8848b8f
commit cd842b3bdd
5 changed files with 35 additions and 32 deletions

View File

@ -1,16 +1,5 @@
import NextAuth from "next-auth";
import { JWT } from "next-auth/jwt";
import Gitea, { GiteaProfile } from "@/lib/providers/gitea";
declare module "next-auth" {
interface User extends GiteaProfile {}
}
declare module "next-auth/jwt" {
interface JWT {
language?: string;
}
}
import Gitea from "@/lib/providers/gitea";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
@ -23,17 +12,5 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
}),
],
secret: process.env.AUTH_SECRET,
callbacks: {
jwt({ token, user }) {
if (user) {
token.language = user.language;
}
return token;
},
session({ session, token }) {
session.user.language = token.language;
return session;
},
},
debug: process.env.NODE_ENV === "development",
});

View File

@ -1,4 +1,5 @@
import { auth } from "@/auth";
"use client";
import {
Select,
SelectContent,
@ -6,19 +7,26 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useLocale } from "next-intl";
import { Locale } from "@/i18n/config";
import { setUserLocale } from "@/services/locale";
const languages = [
{ value: "en-US", label: "English (United States)", flag: "🇺🇸" },
{ value: "zh-CN", label: "简体中文", flag: "🇨🇳" },
];
export default async function LanguageSwitcher() {
const session = await auth();
const defaultLanguage = session?.user?.language || "en-US";
export default function LanguageSwitcher() {
const locale = useLocale();
function onChange(value: string) {
const locale = value as Locale;
setUserLocale(locale);
}
return (
<div className="space-y-2">
<Select defaultValue={defaultLanguage}>
<Select defaultValue={locale} onValueChange={onChange}>
<SelectTrigger className="[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0 [&>span_svg]:text-muted-foreground/80">
<SelectValue placeholder="Select language" />
</SelectTrigger>

5
src/i18n/config.ts Normal file
View File

@ -0,0 +1,5 @@
export type Locale = (typeof locales)[number];
export const locales = ["en-US", "zh-CN"] as const;
export const defaultLocale: Locale = "en-US";

View File

@ -1,9 +1,8 @@
import { auth } from "@/auth";
import { getUserLocale } from "@/services/locale";
import { getRequestConfig } from "next-intl/server";
export default getRequestConfig(async () => {
const session = await auth();
const locale = session?.user?.language || "en-US";
const locale = await getUserLocale();
return {
locale,

14
src/services/locale.ts Normal file
View File

@ -0,0 +1,14 @@
"use server";
import { cookies } from "next/headers";
import { defaultLocale, Locale } from "@/i18n/config";
const LOBE_LOCALE_COOKIE = "JUDGE4C_LOCALE";
export async function getUserLocale() {
return (await cookies()).get(LOBE_LOCALE_COOKIE)?.value || defaultLocale;
}
export async function setUserLocale(locale: Locale) {
(await cookies()).set(LOBE_LOCALE_COOKIE, locale);
}