diff --git a/messages/en.json b/messages/en.json
index 1357ffc..d1c0755 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -7,7 +7,7 @@
"Dark": "Dark"
}
},
- "AvatarButton": {
+ "UserAvatar": {
"Settings": "Settings",
"LogIn": "LogIn",
"LogOut": "LogOut"
@@ -109,7 +109,8 @@
"description": "Enter your email below to sign in to your account",
"or": "Or",
"noAccount": "Don't have an account?",
- "signUp": "Sign up"
+ "signUp": "Sign up",
+ "oauth": "Sign in with {provider}"
},
"signInWithCredentials": {
"userNotFound": "User not found.",
@@ -215,4 +216,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/messages/zh.json b/messages/zh.json
index 82ed24a..9758d5b 100644
--- a/messages/zh.json
+++ b/messages/zh.json
@@ -7,7 +7,7 @@
"Dark": "深色"
}
},
- "AvatarButton": {
+ "UserAvatar": {
"Settings": "设置",
"LogIn": "登录",
"LogOut": "登出"
@@ -109,7 +109,8 @@
"description": "请输入你的邮箱以登录账户",
"or": "或者",
"noAccount": "还没有账户?",
- "signUp": "注册"
+ "signUp": "注册",
+ "oauth": "使用 {provider} 登录"
},
"signInWithCredentials": {
"userNotFound": "未找到用户。",
@@ -215,4 +216,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/components/avatar-button.tsx b/src/components/avatar-button.tsx
deleted file mode 100644
index ca9eb9c..0000000
--- a/src/components/avatar-button.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
-import { LogOutIcon } from "lucide-react";
-import { auth, signOut } from "@/lib/auth";
-import { getTranslations } from "next-intl/server";
-import { Skeleton } from "@/components/ui/skeleton";
-import LogInButton from "@/components/log-in-button";
-import { Avatar, AvatarImage } from "@/components/ui/avatar";
-import { SettingsButton } from "@/components/settings-button";
-
-const UserAvatar = ({ image, name }: { image: string; name: string }) => (
-
-
-
-
-);
-
-async function handleLogOut() {
- "use server";
- await signOut();
-}
-
-export async function AvatarButton() {
- const session = await auth();
- const t = await getTranslations("AvatarButton");
- const isLoggedIn = !!session?.user;
- const image = session?.user?.image ?? "/shadcn.jpg";
- const name = session?.user?.name ?? "unknown";
- const email = session?.user?.email ?? "unknwon@example.com";
-
- return (
-
-
-
-
-
- {!isLoggedIn ? (
-
-
-
-
- ) : (
- <>
-
-
-
-
- {name}
- {email}
-
-
-
-
-
-
-
-
- {t("LogOut")}
-
-
- >
- )}
-
-
- );
-}
diff --git a/src/components/log-in-button.tsx b/src/components/log-in-button.tsx
deleted file mode 100644
index e7438a1..0000000
--- a/src/components/log-in-button.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-"use client";
-
-import { LogIn } from "lucide-react";
-import { useTranslations } from "next-intl";
-import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
-import { usePathname, useRouter, useSearchParams } from "next/navigation";
-
-export default function LogInButton() {
- const router = useRouter();
- const pathname = usePathname();
- const searchParams = useSearchParams();
- const t = useTranslations("AvatarButton");
-
- const handleLogIn = () => {
- const params = new URLSearchParams(searchParams.toString());
- params.set("redirectTo", pathname);
- router.push(`/sign-in?${params.toString()}`);
- };
-
- return (
-
-
- {t("LogIn")}
-
- );
-}
diff --git a/src/components/settings-button.tsx b/src/components/settings-button.tsx
index 382fa6c..cb18ddc 100644
--- a/src/components/settings-button.tsx
+++ b/src/components/settings-button.tsx
@@ -6,7 +6,7 @@ import { useSettingsStore } from "@/stores/useSettingsStore";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
export function SettingsButton() {
- const t = useTranslations("AvatarButton");
+ const t = useTranslations("UserAvatar");
const { setDialogOpen } = useSettingsStore();
return (
diff --git a/src/components/user-avatar.tsx b/src/components/user-avatar.tsx
new file mode 100644
index 0000000..e6c97dd
--- /dev/null
+++ b/src/components/user-avatar.tsx
@@ -0,0 +1,108 @@
+import { cn } from "@/lib/utils";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu";
+import { LogIn, LogOutIcon } from "lucide-react";
+import { auth, signIn, signOut } from "@/lib/auth";
+import { getTranslations } from "next-intl/server";
+import { Skeleton } from "@/components/ui/skeleton";
+import { SettingsButton } from "@/components/settings-button";
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+
+const handleLogIn = async () => {
+ "use server";
+ await signIn();
+};
+
+const handleLogOut = async () => {
+ "use server";
+ await signOut();
+};
+
+interface UserAvatarIconProps {
+ image?: string | null;
+ name?: string | null;
+ className?: string;
+}
+
+const UserAvatarIcon = ({ image, name, className }: UserAvatarIconProps) => {
+ return (
+
+
+ {name?.charAt(0) ?? "U"}
+
+ );
+};
+
+interface UserProfileInfoProps {
+ name?: string | null;
+ email?: string | null;
+}
+
+const UserProfileInfo = ({ name, email }: UserProfileInfoProps) => {
+ return (
+
+ {name ?? "undefined"}
+ {email ?? "undefined"}
+
+ );
+};
+
+const UserAvatar = async () => {
+ const session = await auth();
+ const user = session?.user;
+ const isLoggedIn = !!user;
+ const t = await getTranslations("UserAvatar");
+
+ return (
+
+
+
+
+
+ {!isLoggedIn ? (
+
+
+
+
+ {t("LogIn")}
+
+
+ ) : (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ {t("LogOut")}
+
+
+ >
+ )}
+
+
+ );
+};
+
+const UserAvatarSkeleton = () => {
+ return ;
+};
+
+export { UserAvatar, UserAvatarSkeleton };