feat: fix bugs in avatar-button.tsx and settings-dialog.tsx because of wrong translation coding

This commit is contained in:
fly6516 2025-04-14 10:05:11 +08:00
parent 3bd2b5f075
commit 06b6032436
2 changed files with 157 additions and 157 deletions

View File

@ -1,106 +1,107 @@
//avatar-button //avatar-button
import { import {
BadgeCheck, BadgeCheck,
Bell, Bell,
LogIn, LogIn,
LogOut, LogOut,
} from "lucide-react"; } from "lucide-react";
import { import {
Avatar, Avatar,
AvatarImage, AvatarImage,
} from "@/components/ui/avatar"; } from "@/components/ui/avatar";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
DropdownMenuGroup, DropdownMenuGroup,
DropdownMenuItem, DropdownMenuItem,
DropdownMenuLabel, DropdownMenuLabel,
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { auth, signOut } from "@/lib/auth"; import { auth, signOut } from "@/lib/auth";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { SettingsButton } from "@/components/settings-button"; import { SettingsButton } from "@/components/settings-button";
import { useTranslations } from 'next-intl'; //import { useTranslations } from 'next-intl';
import { getTranslations } from "next-intl/server";
const UserAvatar = ({ image, name }: { image: string; name: string }) => ( const UserAvatar = ({ image, name }: { image: string; name: string }) => (
<Avatar className="h-8 w-8 rounded-lg"> <Avatar className="h-8 w-8 rounded-lg">
<AvatarImage src={image} alt={name} /> <AvatarImage src={image} alt={name} />
<Skeleton className="h-full w-full" /> <Skeleton className="h-full w-full" />
</Avatar> </Avatar>
); );
async function handleSignIn() { async function handleSignIn() {
"use server"; "use server";
redirect("/sign-in"); redirect("/sign-in");
} }
async function handleSignOut() { async function handleSignOut() {
"use server"; "use server";
await signOut(); await signOut();
} }
export async function AvatarButton() { export async function AvatarButton() {
const session = await auth(); const session = await auth();
const isLoggedIn = !!session?.user; const isLoggedIn = !!session?.user;
const image = session?.user?.image ?? "https://github.com/shadcn.png"; const image = session?.user?.image ?? "https://github.com/shadcn.png";
const name = session?.user?.name ?? "unknown"; const name = session?.user?.name ?? "unknown";
const email = session?.user?.email ?? "unknwon@example.com"; const email = session?.user?.email ?? "unknwon@example.com";
const t = useTranslations('avatar-button'); const t = await getTranslations('avatar-button');
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<UserAvatar image={image} name={name} />
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
align="end"
sideOffset={8}
>
{!isLoggedIn ? (
<DropdownMenuGroup>
<SettingsButton />
<DropdownMenuItem onClick={handleSignIn}>
<LogIn />
{t('log-in')}
</DropdownMenuItem>
</DropdownMenuGroup>
) : (
<>
<DropdownMenuLabel className="p-0 font-normal">
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<UserAvatar image={image} name={name} /> <UserAvatar image={image} name={name} />
<div className="grid flex-1 text-left text-sm leading-tight"> </DropdownMenuTrigger>
<span className="truncate font-semibold">{name}</span> <DropdownMenuContent
<span className="truncate text-xs">{email}</span> className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
</div> align="end"
</div> sideOffset={8}
</DropdownMenuLabel> >
<DropdownMenuSeparator /> {!isLoggedIn ? (
<DropdownMenuGroup> <DropdownMenuGroup>
<DropdownMenuItem> <SettingsButton />
<BadgeCheck /> <DropdownMenuItem onClick={handleSignIn}>
{t('account')} <LogIn />
</DropdownMenuItem> {t('log-in')}
<DropdownMenuItem> </DropdownMenuItem>
<Bell /> </DropdownMenuGroup>
Notifications ) : (
</DropdownMenuItem> <>
</DropdownMenuGroup> <DropdownMenuLabel className="p-0 font-normal">
<DropdownMenuSeparator /> <div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<DropdownMenuGroup> <UserAvatar image={image} name={name} />
<SettingsButton /> <div className="grid flex-1 text-left text-sm leading-tight">
</DropdownMenuGroup> <span className="truncate font-semibold">{name}</span>
<DropdownMenuSeparator /> <span className="truncate text-xs">{email}</span>
<DropdownMenuItem onClick={handleSignOut}> </div>
<LogOut /> </div>
{t('log-out')} </DropdownMenuLabel>
</DropdownMenuItem> <DropdownMenuSeparator />
</> <DropdownMenuGroup>
)} <DropdownMenuItem>
</DropdownMenuContent> <BadgeCheck />
</DropdownMenu> {t('account')}
); </DropdownMenuItem>
<DropdownMenuItem>
<Bell />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<SettingsButton />
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleSignOut}>
<LogOut />
{t('log-out')}
</DropdownMenuItem>
</>
)}
</DropdownMenuContent>
</DropdownMenu>
);
} }

View File

@ -31,84 +31,83 @@ import { useSettingsStore } from "@/stores/useSettingsStore";
import { CodeXml, Globe, Paintbrush, Settings } from "lucide-react"; import { CodeXml, Globe, Paintbrush, Settings } from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
const t = useTranslations('settings');
const data = {
nav: [
{ name: t('appearance'), icon: Paintbrush },
{ name: t('language-and-region'), icon: Globe },
{ name: t('code-editor'), icon: CodeXml },
{ name: t('advanced'), icon: Settings },
],
};
export function SettingsDialog() { export function SettingsDialog() {
const { isDialogOpen, activeSetting, setDialogOpen, setActiveSetting } = useSettingsStore(); const { isDialogOpen, activeSetting, setDialogOpen, setActiveSetting } =
useSettingsStore();
const t = useTranslations("settings");
const navItems = [
{ name: t("appearance"), icon: Paintbrush },
{ name: t("language-and-region"), icon: Globe },
{ name: t("code-editor"), icon: CodeXml },
{ name: t("advanced"), icon: Settings },
];
return ( return (
<Dialog open={isDialogOpen} onOpenChange={setDialogOpen}> <Dialog open={isDialogOpen} onOpenChange={setDialogOpen}>
<DialogContent className="overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]"> <DialogContent className="overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]">
<DialogTitle className="sr-only">{t('settings')}</DialogTitle> <DialogTitle className="sr-only">{t("settings")}</DialogTitle>
<DialogDescription className="sr-only"> <DialogDescription className="sr-only">
{t('customize-your-settings-here')} {t("customize-your-settings-here")}
</DialogDescription> </DialogDescription>
<SidebarProvider className="items-start"> <SidebarProvider className="items-start">
<Sidebar collapsible="none" className="hidden md:flex"> <Sidebar collapsible="none" className="hidden md:flex">
<SidebarContent> <SidebarContent>
<SidebarGroup> <SidebarGroup>
<SidebarGroupContent> <SidebarGroupContent>
<SidebarMenu className="pt-2"> <SidebarMenu className="pt-2">
{data.nav.map((item) => ( {navItems.map((item) => (
<SidebarMenuItem key={item.name}> <SidebarMenuItem key={item.name}>
<SidebarMenuButton <SidebarMenuButton
asChild asChild
isActive={item.name === activeSetting} isActive={item.name === activeSetting}
onClick={() => setActiveSetting(item.name)} onClick={() => setActiveSetting(item.name)}
> >
<a href="#"> <a href="#">
<item.icon /> <item.icon />
<span>{item.name}</span> <span>{item.name}</span>
</a> </a>
</SidebarMenuButton> </SidebarMenuButton>
</SidebarMenuItem> </SidebarMenuItem>
))} ))}
</SidebarMenu> </SidebarMenu>
</SidebarGroupContent> </SidebarGroupContent>
</SidebarGroup> </SidebarGroup>
</SidebarContent> </SidebarContent>
</Sidebar> </Sidebar>
<main className="flex h-[480px] flex-1 flex-col overflow-hidden"> <main className="flex h-[480px] flex-1 flex-col overflow-hidden">
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12"> <header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
<div className="flex items-center gap-2 px-4"> <div className="flex items-center gap-2 px-4">
<Breadcrumb> <Breadcrumb>
<BreadcrumbList> <BreadcrumbList>
<BreadcrumbItem className="hidden md:block"> <BreadcrumbItem className="hidden md:block">
<BreadcrumbLink href="#">{t('settings')}</BreadcrumbLink> <BreadcrumbLink href="#">{t("settings")}</BreadcrumbLink>
</BreadcrumbItem> </BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" /> <BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem> <BreadcrumbItem>
<BreadcrumbPage>{activeSetting}</BreadcrumbPage> <BreadcrumbPage>{activeSetting}</BreadcrumbPage>
</BreadcrumbItem> </BreadcrumbItem>
</BreadcrumbList> </BreadcrumbList>
</Breadcrumb> </Breadcrumb>
</div> </div>
</header> </header>
<ScrollArea className="flex-1 overflow-y-auto p-4 pt-0"> <ScrollArea className="flex-1 overflow-y-auto p-4 pt-0">
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
{activeSetting === t('appearance') ? ( {activeSetting === t("appearance") ? (
<AppearanceSettings /> <AppearanceSettings />
) : ( ) : (
Array.from({ length: 10 }).map((_, i) => ( Array.from({ length: 10 }).map((_, i) => (
<div <div
key={i} key={i}
className="aspect-video max-w-3xl rounded-xl bg-muted/50" className="aspect-video max-w-3xl rounded-xl bg-muted/50"
/> />
)) ))
)} )}
</div> </div>
</ScrollArea> </ScrollArea>
</main> </main>
</SidebarProvider> </SidebarProvider>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );
} }