feat(i18n): add localized sidebar and breadcrumb labels

This commit is contained in:
cfngc4594 2026-05-19 16:49:03 +08:00
parent 2cbe91d487
commit 318249d20e
6 changed files with 89 additions and 23 deletions

View File

@ -12,6 +12,34 @@
"LogIn": "LogIn",
"LogOut": "LogOut"
},
"Sidebar": {
"platform": "Platform",
"appTagline": "Programming Learning",
"teachingTagline": "Teaching Platform"
},
"Breadcrumb": {
"home": "Home",
"dashboard": "Dashboard",
"management": "Management",
"profile": "Profile",
"changePassword": "Change Password",
"problems": "Problems",
"problem": "Problem",
"problemset": "Problemset",
"admin": "Admin",
"teacher": "Teacher",
"student": "Student",
"usermanagement": "Account Management",
"courses": "Courses",
"assignments": "Assignments",
"userdashboard": "User Dashboard",
"protected": "Protected",
"app": "App",
"auth": "Auth",
"signIn": "Sign In",
"signUp": "Sign Up",
"detail": "Detail"
},
"Banner": {
"Text": "Star this project if you like it."
},

View File

@ -12,6 +12,34 @@
"LogIn": "登录",
"LogOut": "登出"
},
"Sidebar": {
"platform": "平台",
"appTagline": "编程学习平台",
"teachingTagline": "教学平台"
},
"Breadcrumb": {
"home": "首页",
"dashboard": "仪表板",
"management": "管理面板",
"profile": "用户信息",
"changePassword": "修改密码",
"problems": "题目",
"problem": "题目",
"problemset": "题目集",
"admin": "管理后台",
"teacher": "教师平台",
"student": "学生平台",
"usermanagement": "账号管理",
"courses": "课程",
"assignments": "作业",
"userdashboard": "用户仪表板",
"protected": "受保护",
"app": "应用",
"auth": "认证",
"signIn": "登录",
"signUp": "注册",
"detail": "详情"
},
"Banner": {
"Text": "如果喜欢该项目不妨收藏一下"
},

View File

@ -9,6 +9,7 @@ import {
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { usePathname } from "next/navigation";
import { useTranslations } from "next-intl";
interface BreadcrumbItem {
label: string;
@ -17,13 +18,14 @@ interface BreadcrumbItem {
export function DynamicBreadcrumb() {
const pathname = usePathname();
const t = useTranslations("Breadcrumb");
const generateBreadcrumbs = (): BreadcrumbItem[] => {
const segments = pathname.split("/").filter(Boolean);
const breadcrumbs: BreadcrumbItem[] = [];
// 添加首页
breadcrumbs.push({ label: "首页", href: "/" });
breadcrumbs.push({ label: t("home"), href: "/" });
let currentPath = "";
@ -35,29 +37,30 @@ export function DynamicBreadcrumb() {
// 路径映射
const pathMap: Record<string, string> = {
dashboard: "仪表板",
management: "管理面板",
profile: "用户信息",
"change-password": "修改密码",
problems: "题目",
problemset: "题目集",
admin: "管理后台",
teacher: "教师平台",
student: "学生平台",
usermanagement: "账号管理",
courses: "课程",
assignments: "作业",
userdashboard: "用户仪表板",
protected: "受保护",
app: "应用",
auth: "认证",
"sign-in": "登录",
"sign-up": "注册",
dashboard: t("dashboard"),
management: t("management"),
profile: t("profile"),
"change-password": t("changePassword"),
problems: t("problems"),
problem: t("problem"),
problemset: t("problemset"),
admin: t("admin"),
teacher: t("teacher"),
student: t("student"),
usermanagement: t("usermanagement"),
courses: t("courses"),
assignments: t("assignments"),
userdashboard: t("userdashboard"),
protected: t("protected"),
app: t("app"),
auth: t("auth"),
"sign-in": t("signIn"),
"sign-up": t("signUp"),
};
// 如果是数字可能是题目ID显示为"题目详情"
if (/^\d+$/.test(segment)) {
label = "详情";
label = t("detail");
} else if (pathMap[segment]) {
label = pathMap[segment];
} else {

View File

@ -17,6 +17,7 @@ import {
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { ChevronRight, type LucideIcon } from "lucide-react";
import { useTranslations } from "next-intl";
export function NavMain({
items,
@ -32,9 +33,11 @@ export function NavMain({
}[];
}[];
}) {
const t = useTranslations("Sidebar");
return (
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarGroupLabel>{t("platform")}</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => (
<Collapsible key={item.title} asChild defaultOpen={item.isActive}>

View File

@ -17,6 +17,7 @@ import { NavUser } from "@/components/nav-user";
import { NavProjects } from "@/components/nav-projects";
import { NavSecondary } from "@/components/nav-secondary";
import { Command, LifeBuoy, Send, Shield } from "lucide-react";
import { useTranslations } from "next-intl";
const data = {
navMain: [
@ -100,6 +101,7 @@ interface AppSidebarProps {
}
export function AppSidebar({ user, wrongProblems, ...props }: AppSidebarProps) {
const t = useTranslations("Sidebar");
const userInfo = {
name: user.name ?? "",
email: user.email ?? "",
@ -118,7 +120,7 @@ export function AppSidebar({ user, wrongProblems, ...props }: AppSidebarProps) {
</div>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">Judge4c</span>
<span className="truncate text-xs">Programming Learning</span>
<span className="truncate text-xs">{t("appTagline")}</span>
</div>
</a>
</SidebarMenuButton>

View File

@ -16,6 +16,7 @@ import { siteConfig } from "@/config/site";
import { NavMain } from "@/components/nav-main";
import { NavUser } from "@/components/nav-user";
import { NavSecondary } from "@/components/nav-secondary";
import { useTranslations } from "next-intl";
const data = {
navMain: [
@ -66,6 +67,7 @@ export function TeacherSidebar({
user,
...props
}: TeacherSidebarProps & React.ComponentProps<typeof Sidebar>) {
const t = useTranslations("Sidebar");
const userInfo = {
name: user.name ?? "",
email: user.email ?? "",
@ -84,7 +86,7 @@ export function TeacherSidebar({
</div>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">Judge4c </span>
<span className="truncate text-xs">Teaching Platform</span>
<span className="truncate text-xs">{t("teachingTagline")}</span>
</div>
</a>
</SidebarMenuButton>