mirror of
https://github.com/massbug/judge4c.git
synced 2026-05-20 13:18:52 +00:00
feat(i18n): add localized sidebar and breadcrumb labels
This commit is contained in:
parent
2cbe91d487
commit
318249d20e
@ -12,6 +12,34 @@
|
|||||||
"LogIn": "LogIn",
|
"LogIn": "LogIn",
|
||||||
"LogOut": "LogOut"
|
"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": {
|
"Banner": {
|
||||||
"Text": "Star this project if you like it."
|
"Text": "Star this project if you like it."
|
||||||
},
|
},
|
||||||
|
|||||||
@ -12,6 +12,34 @@
|
|||||||
"LogIn": "登录",
|
"LogIn": "登录",
|
||||||
"LogOut": "登出"
|
"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": {
|
"Banner": {
|
||||||
"Text": "如果喜欢该项目不妨收藏一下"
|
"Text": "如果喜欢该项目不妨收藏一下"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from "@/components/ui/breadcrumb";
|
} from "@/components/ui/breadcrumb";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
interface BreadcrumbItem {
|
interface BreadcrumbItem {
|
||||||
label: string;
|
label: string;
|
||||||
@ -17,13 +18,14 @@ interface BreadcrumbItem {
|
|||||||
|
|
||||||
export function DynamicBreadcrumb() {
|
export function DynamicBreadcrumb() {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
const t = useTranslations("Breadcrumb");
|
||||||
|
|
||||||
const generateBreadcrumbs = (): BreadcrumbItem[] => {
|
const generateBreadcrumbs = (): BreadcrumbItem[] => {
|
||||||
const segments = pathname.split("/").filter(Boolean);
|
const segments = pathname.split("/").filter(Boolean);
|
||||||
const breadcrumbs: BreadcrumbItem[] = [];
|
const breadcrumbs: BreadcrumbItem[] = [];
|
||||||
|
|
||||||
// 添加首页
|
// 添加首页
|
||||||
breadcrumbs.push({ label: "首页", href: "/" });
|
breadcrumbs.push({ label: t("home"), href: "/" });
|
||||||
|
|
||||||
let currentPath = "";
|
let currentPath = "";
|
||||||
|
|
||||||
@ -35,29 +37,30 @@ export function DynamicBreadcrumb() {
|
|||||||
|
|
||||||
// 路径映射
|
// 路径映射
|
||||||
const pathMap: Record<string, string> = {
|
const pathMap: Record<string, string> = {
|
||||||
dashboard: "仪表板",
|
dashboard: t("dashboard"),
|
||||||
management: "管理面板",
|
management: t("management"),
|
||||||
profile: "用户信息",
|
profile: t("profile"),
|
||||||
"change-password": "修改密码",
|
"change-password": t("changePassword"),
|
||||||
problems: "题目",
|
problems: t("problems"),
|
||||||
problemset: "题目集",
|
problem: t("problem"),
|
||||||
admin: "管理后台",
|
problemset: t("problemset"),
|
||||||
teacher: "教师平台",
|
admin: t("admin"),
|
||||||
student: "学生平台",
|
teacher: t("teacher"),
|
||||||
usermanagement: "账号管理",
|
student: t("student"),
|
||||||
courses: "课程",
|
usermanagement: t("usermanagement"),
|
||||||
assignments: "作业",
|
courses: t("courses"),
|
||||||
userdashboard: "用户仪表板",
|
assignments: t("assignments"),
|
||||||
protected: "受保护",
|
userdashboard: t("userdashboard"),
|
||||||
app: "应用",
|
protected: t("protected"),
|
||||||
auth: "认证",
|
app: t("app"),
|
||||||
"sign-in": "登录",
|
auth: t("auth"),
|
||||||
"sign-up": "注册",
|
"sign-in": t("signIn"),
|
||||||
|
"sign-up": t("signUp"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果是数字,可能是题目ID,显示为"题目详情"
|
// 如果是数字,可能是题目ID,显示为"题目详情"
|
||||||
if (/^\d+$/.test(segment)) {
|
if (/^\d+$/.test(segment)) {
|
||||||
label = "详情";
|
label = t("detail");
|
||||||
} else if (pathMap[segment]) {
|
} else if (pathMap[segment]) {
|
||||||
label = pathMap[segment];
|
label = pathMap[segment];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import {
|
|||||||
CollapsibleTrigger,
|
CollapsibleTrigger,
|
||||||
} from "@/components/ui/collapsible";
|
} from "@/components/ui/collapsible";
|
||||||
import { ChevronRight, type LucideIcon } from "lucide-react";
|
import { ChevronRight, type LucideIcon } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function NavMain({
|
export function NavMain({
|
||||||
items,
|
items,
|
||||||
@ -32,9 +33,11 @@ export function NavMain({
|
|||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
}) {
|
}) {
|
||||||
|
const t = useTranslations("Sidebar");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>Platform</SidebarGroupLabel>
|
<SidebarGroupLabel>{t("platform")}</SidebarGroupLabel>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
{items.map((item) => (
|
{items.map((item) => (
|
||||||
<Collapsible key={item.title} asChild defaultOpen={item.isActive}>
|
<Collapsible key={item.title} asChild defaultOpen={item.isActive}>
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { NavUser } from "@/components/nav-user";
|
|||||||
import { NavProjects } from "@/components/nav-projects";
|
import { NavProjects } from "@/components/nav-projects";
|
||||||
import { NavSecondary } from "@/components/nav-secondary";
|
import { NavSecondary } from "@/components/nav-secondary";
|
||||||
import { Command, LifeBuoy, Send, Shield } from "lucide-react";
|
import { Command, LifeBuoy, Send, Shield } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
navMain: [
|
navMain: [
|
||||||
@ -100,6 +101,7 @@ interface AppSidebarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function AppSidebar({ user, wrongProblems, ...props }: AppSidebarProps) {
|
export function AppSidebar({ user, wrongProblems, ...props }: AppSidebarProps) {
|
||||||
|
const t = useTranslations("Sidebar");
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
name: user.name ?? "",
|
name: user.name ?? "",
|
||||||
email: user.email ?? "",
|
email: user.email ?? "",
|
||||||
@ -118,7 +120,7 @@ export function AppSidebar({ user, wrongProblems, ...props }: AppSidebarProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span className="truncate font-semibold">Judge4c</span>
|
<span className="truncate font-semibold">Judge4c</span>
|
||||||
<span className="truncate text-xs">Programming Learning</span>
|
<span className="truncate text-xs">{t("appTagline")}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { siteConfig } from "@/config/site";
|
|||||||
import { NavMain } from "@/components/nav-main";
|
import { NavMain } from "@/components/nav-main";
|
||||||
import { NavUser } from "@/components/nav-user";
|
import { NavUser } from "@/components/nav-user";
|
||||||
import { NavSecondary } from "@/components/nav-secondary";
|
import { NavSecondary } from "@/components/nav-secondary";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
navMain: [
|
navMain: [
|
||||||
@ -66,6 +67,7 @@ export function TeacherSidebar({
|
|||||||
user,
|
user,
|
||||||
...props
|
...props
|
||||||
}: TeacherSidebarProps & React.ComponentProps<typeof Sidebar>) {
|
}: TeacherSidebarProps & React.ComponentProps<typeof Sidebar>) {
|
||||||
|
const t = useTranslations("Sidebar");
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
name: user.name ?? "",
|
name: user.name ?? "",
|
||||||
email: user.email ?? "",
|
email: user.email ?? "",
|
||||||
@ -84,7 +86,7 @@ export function TeacherSidebar({
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span className="truncate font-semibold">Judge4c 教师端</span>
|
<span className="truncate font-semibold">Judge4c 教师端</span>
|
||||||
<span className="truncate text-xs">Teaching Platform</span>
|
<span className="truncate text-xs">{t("teachingTagline")}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user