diff --git a/README.md b/README.md
index b5b171e..857672f 100644
--- a/README.md
+++ b/README.md
@@ -148,9 +148,6 @@ Or clone it for local development:
$ git clone https://github.com/yuntijs/dumi-theme-yunti.git
$ cd dumi-theme-yunti
$ pnpm install
-# run theme dev
-$ pnpm dev
-# run example dev
$ pnpm docs:dev
```
diff --git a/example/.dumirc.ts b/example/.dumirc.ts
index 8a31c76..e8d5f23 100644
--- a/example/.dumirc.ts
+++ b/example/.dumirc.ts
@@ -41,6 +41,14 @@ const themeConfig = defineThemeConfig({
socialLinks: {
github: homepage,
},
+ header: {
+ userActionButton: {
+ button: {
+ className: 'user-action-button',
+ type: 'primary',
+ },
+ },
+ },
title: 'Dumi Theme YuntiJS',
description: 'Yunti documentation site theme package designed for Dumi 2',
keywords: ['theme', 'antd', 'dumi', 'dumi-theme'],
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index c554710..3bc5210 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -1,3 +1,4 @@
{
+ "header.actions.user": "Login / Sign up",
"header.nav.home": "Home"
}
diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json
index fb4411f..aa2fd76 100644
--- a/src/locales/zh-CN.json
+++ b/src/locales/zh-CN.json
@@ -1,3 +1,4 @@
{
+ "header.actions.user": "登录/注册",
"header.nav.home": "首页"
}
diff --git a/src/slots/Header/UserActionButton.tsx b/src/slots/Header/UserActionButton.tsx
new file mode 100644
index 0000000..5de42ab
--- /dev/null
+++ b/src/slots/Header/UserActionButton.tsx
@@ -0,0 +1,84 @@
+import { Icon } from '@lobehub/ui';
+import { Avatar, Button, Dropdown } from 'antd';
+import { createStyles } from 'antd-style';
+import { useIntl } from 'dumi';
+import { LogOut, User2 } from 'lucide-react';
+import React, { memo, useCallback, useEffect, useState } from 'react';
+
+import { headerSel, useSiteStore } from '@/store';
+
+export const useStyles = createStyles(({ css }) => {
+ return {
+ avatar: css`
+ cursor: pointer;
+ `,
+ menu: css`
+ width: 180px;
+ `,
+ };
+});
+
+const LOGIN_USER_KEY = '__LOGIN_USER';
+
+export const HeaderUserActionButton: React.FC = memo(() => {
+ const { styles } = useStyles();
+ const headerConfig = useSiteStore(headerSel);
+ const loginUser = useSiteStore(s => s.loginUser);
+ const intl = useIntl();
+ const [userInfo, setUserInfo] = useState(loginUser);
+ useEffect(() => {
+ const loginUserStr = window.localStorage.getItem(LOGIN_USER_KEY);
+ if (loginUserStr) {
+ try {
+ const loginUser = JSON.parse(loginUserStr);
+ setUserInfo(loginUser);
+ useSiteStore.setState({ loginUser });
+ } catch (error) {
+ console.warn(`parse login user info from ${LOGIN_USER_KEY} failed`, error);
+ }
+ }
+ }, []);
+
+ const clearLoginUser = useCallback(() => {
+ window.localStorage.removeItem(LOGIN_USER_KEY);
+ }, []);
+
+ if (!headerConfig?.userActionButton?.button) {
+ return;
+ }
+ if (userInfo?.user) {
+ return (
+