mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-26 02:56:22 +00:00
All checks were successful
Push to Helm Chart Repository / build (push) Successful in 13s
- Removed the old reset password form component and replaced it with a new implementation. - Updated routing paths for login, registration, and reset password to be under a common auth path. - Added new login and registration pages with corresponding forms. - Introduced a common auth header component for consistent branding across auth pages. - Implemented a current logged-in user display component. - Enhanced the register form to include email verification and captcha. - Updated translations for new and modified components. - Refactored the navigation bar to include user avatar dropdown and improved menu structure.
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
"use client"
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu"
|
|
import { userLogout } from "@/api/user";
|
|
import Link from "next/link";
|
|
import { toast } from "sonner";
|
|
import { useToLogin } from "@/hooks/use-route";
|
|
import { CircleUser } from "lucide-react";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { getGravatarFromUser } from "@/utils/common/gravatar";
|
|
import { formatDisplayName, getFallbackAvatarFromUsername } from "@/utils/common/username";
|
|
import { useAuth } from "@/contexts/auth-context";
|
|
|
|
export function AvatarWithDropdownMenu() {
|
|
const { user } = useAuth();
|
|
const toLogin = useToLogin();
|
|
|
|
const handleLogout = () => {
|
|
userLogout().then(() => {
|
|
toast.success("Logged out successfully");
|
|
window.location.reload();
|
|
})
|
|
}
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
|
|
<DropdownMenuTrigger asChild>
|
|
<button className="rounded-full overflow-hidden">
|
|
{user ? <Avatar className="h-8 w-8 rounded-full">
|
|
<AvatarImage src={getGravatarFromUser({ user })} alt={user.username} />
|
|
<AvatarFallback className="rounded-full">{getFallbackAvatarFromUsername(user.nickname || user.username)}</AvatarFallback>
|
|
</Avatar> : <CircleUser className="h-8 w-8" />}
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
|
|
<DropdownMenuContent className="w-auto" align="start">
|
|
{user && <DropdownMenuLabel>
|
|
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
|
<span className="truncate font-medium">{formatDisplayName(user)}</span>
|
|
<span className="text-muted-foreground truncate text-xs">
|
|
{user.email}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</DropdownMenuLabel>}
|
|
|
|
{user &&
|
|
<>
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem asChild>
|
|
<Link href={`/u/${user?.username}`}>Profile</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/console">Console</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
</>
|
|
}
|
|
|
|
<DropdownMenuItem onClick={user ? handleLogout : toLogin}>
|
|
{user ? "Logout" : "Login"}
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
} |