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 NextAuth from "next-auth";
import { JWT } from "next-auth/jwt"; import Gitea from "@/lib/providers/gitea";
import Gitea, { GiteaProfile } from "@/lib/providers/gitea";
declare module "next-auth" {
interface User extends GiteaProfile {}
}
declare module "next-auth/jwt" {
interface JWT {
language?: string;
}
}
export const { handlers, signIn, signOut, auth } = NextAuth({ export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [ providers: [
@ -23,17 +12,5 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
}), }),
], ],
secret: process.env.AUTH_SECRET, 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", debug: process.env.NODE_ENV === "development",
}); });

View File

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