added Profile Page and Change password (also included breadcrumb

This commit is contained in:
2025-12-27 14:46:21 +07:00
parent bd71b27376
commit ba52869e8f
49 changed files with 11108 additions and 12778 deletions

View File

@@ -1,5 +1,18 @@
import { HugeiconsIcon } from '@hugeicons/react'
import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'
import { authClient } from '@/lib/auth-client';
import {
DotsThreeVerticalIcon,
KeyIcon,
SignInIcon,
SignOutIcon,
UserCircleIcon,
} from '@phosphor-icons/react';
import { useQueryClient } from '@tanstack/react-query';
import { createLink, useNavigate } from '@tanstack/react-router';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { useAuth } from '../auth/auth-provider';
import AvatarUser from '../AvatarUser';
import {
DropdownMenu,
DropdownMenuContent,
@@ -8,88 +21,75 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '../ui/dropdown-menu'
} from '../ui/dropdown-menu';
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from '../ui/sidebar'
import {
LoginSquare01Icon,
Logout01FreeIcons,
MoreVerticalIcon,
UserAccountIcon,
} from '@hugeicons/core-free-icons'
import { toast } from 'sonner'
import { Link, useNavigate } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { useAuth } from '../auth/auth-provider'
import { authClient } from '@/lib/auth-client'
import { useQueryClient } from '@tanstack/react-query'
} from '../ui/sidebar';
const SidebarMenuButtonLink = createLink(SidebarMenuButton);
const DropdownMenuItemLink = createLink(DropdownMenuItem);
const NavUser = () => {
const { t } = useTranslation()
const navigate = useNavigate()
const { isMobile } = useSidebar()
const queryClient = useQueryClient()
const { data: session, isLoading } = useAuth()
const { t } = useTranslation();
const navigate = useNavigate();
const { isMobile } = useSidebar();
const queryClient = useQueryClient();
const { data: session, isLoading } = useAuth();
const signout = async () => {
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
navigate({ to: '/' })
queryClient.invalidateQueries({ queryKey: ['session'] })
toast.success(t('loginPage.messages.logout_success'))
navigate({ to: '/' });
queryClient.invalidateQueries({ queryKey: ['session'] });
toast.success(t('loginPage.messages.logout_success'));
},
onError: (ctx) => {
toast.error(t(`backend.${ctx.error.code}` as any))
toast.error(t(`backend.${ctx.error.code}` as any));
},
},
})
}
});
};
if (isLoading) return null
if (isLoading) return null;
if (!session?.user)
return (
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton tooltip="Sign In">
<Link to="/sign-in" className="flex items-center gap-2 w-full">
<HugeiconsIcon icon={LoginSquare01Icon} />
{t('ui.login_btn')}
</Link>
</SidebarMenuButton>
<SidebarMenuButtonLink
to="/sign-in"
className="flex items-center gap-2 w-full"
tooltip="Sign In"
>
<SignInIcon size={28} />
{t('ui.login_btn')}
</SidebarMenuButtonLink>
</SidebarMenuItem>
</SidebarMenu>
)
);
return (
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger
render={
<SidebarMenuButton
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
/>
}
>
<Avatar className="h-8 w-8">
<AvatarImage src={session?.user?.image ?? undefined} />
<AvatarFallback className="bg-cyan-400 text-white">
S
</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">
{session?.user?.name}
</span>
<span className="truncate text-xs">{session?.user?.email}</span>
</div>
<HugeiconsIcon icon={MoreVerticalIcon} />
<DropdownMenuTrigger asChild>
<SidebarMenuButton
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground cursor-pointer"
tooltip={session?.user?.name}
>
<AvatarUser session={session} className="h-8 w-8" />
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">
{session?.user?.name}
</span>
<span className="truncate text-xs">{session?.user?.email}</span>
</div>
<DotsThreeVerticalIcon size={28} />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
@@ -98,37 +98,37 @@ const NavUser = () => {
sideOffset={4}
>
{/* Dropdown menu content */}
<DropdownMenuGroup>
<DropdownMenuLabel className="p-0 font-normal">
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<Avatar className="h-9 w-9">
<AvatarImage src={session?.user?.image ?? undefined} />
<AvatarFallback className="bg-cyan-400 text-white">
S
</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">
{session?.user?.name}
</span>
<span className="truncate text-xs">
{session?.user?.email}
</span>
</div>
<DropdownMenuLabel className="p-0 font-normal">
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<AvatarUser session={session} className="h-8 w-8" />
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">
{session?.user?.name}
</span>
<span className="truncate text-xs">
{session?.user?.email}
</span>
</div>
</DropdownMenuLabel>
</DropdownMenuGroup>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<HugeiconsIcon icon={UserAccountIcon} />
<DropdownMenuItemLink to="/profile" className="cursor-pointer">
<UserCircleIcon size={28} />
{t('nav.account')}
</DropdownMenuItem>
</DropdownMenuItemLink>
<DropdownMenuItemLink
to="/change-password"
className="cursor-pointer"
>
<KeyIcon size={28} />
{t('nav.change_password')}
</DropdownMenuItemLink>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem onClick={signout}>
<HugeiconsIcon icon={Logout01FreeIcons} />
<DropdownMenuItem onClick={signout} className="cursor-pointer">
<SignOutIcon size={28} />
{t('ui.logout_btn')}
</DropdownMenuItem>
</DropdownMenuGroup>
@@ -136,7 +136,7 @@ const NavUser = () => {
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
)
}
);
};
export default NavUser
export default NavUser;