Skip to content

Commit

Permalink
feat: add UserActionButton for header
Browse files Browse the repository at this point in the history
  • Loading branch information
Carrotzpc committed Aug 14, 2024
1 parent eb9cd60 commit 4089d3d
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 8 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down
8 changes: 8 additions & 0 deletions example/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down
1 change: 1 addition & 0 deletions src/locales/en-US.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"header.actions.user": "Login / Sign up",
"header.nav.home": "Home"
}
1 change: 1 addition & 0 deletions src/locales/zh-CN.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"header.actions.user": "登录/注册",
"header.nav.home": "首页"
}
84 changes: 84 additions & 0 deletions src/slots/Header/UserActionButton.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Dropdown
menu={{
className: styles.menu,
items: headerConfig.userActionButton.menuItems || [
{
icon: <Icon icon={User2} />,
label: <a href="https://console.botnow.cn/oidc/management/account">账户中心</a>,
key: 'account',
},
{ type: 'divider' },
{
icon: <Icon icon={LogOut} />,
label: (
<a href="https://console.botnow.cn/oidc/logout" onClick={clearLoginUser}>
退出登录
</a>
),
key: 'logout',
},
],
}}
>
<Avatar className={styles.avatar} size="small" src={userInfo.avatar}>
{userInfo.user.charAt(0).toUpperCase()}
</Avatar>
</Dropdown>
);
}
return (
<Button {...headerConfig.userActionButton.button}>
{intl.formatMessage({ id: 'header.actions.user' })}
</Button>
);
});
13 changes: 8 additions & 5 deletions src/slots/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Header as Head } from '@lobehub/ui';
import { Flex } from 'antd';
import { useResponsive } from 'antd-style';
import { memo } from 'react';

Expand All @@ -12,6 +13,7 @@ import DiscordButton from './DiscordButton';
import GithubButton from './GithubButton';
import LangSwitch from './LangSwitch';
import ThemeSwitch from './ThemeSwitch';
import { HeaderUserActionButton } from './UserActionButton';

const Header = memo(() => {
const hasHeader = useSiteStore(s => Boolean(s.routeMeta.frontmatter));
Expand All @@ -23,17 +25,18 @@ const Header = memo(() => {
<Head
actions={
mobile ? (
<>
<Flex align="center" gap="small">
<ThemeSwitch />
<div id="header-actions-extra"></div>
</>
<HeaderUserActionButton />
</Flex>
) : (
<>
<SearchBar /> <LangSwitch />
<SearchBar />
<LangSwitch />
<GithubButton />
<DiscordButton />
<ThemeSwitch />
<div id="header-actions-extra"></div>
<HeaderUserActionButton />
</>
)
}
Expand Down
6 changes: 6 additions & 0 deletions src/store/initialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export interface ISiteData {
themeConfig: AllSiteThemeConfig;
}

export interface ILoginUser {
user: string;
avatar?: string;
}

export interface SiteStore {
locale: ILocale;
location: Location;
Expand All @@ -52,6 +57,7 @@ export interface SiteStore {
sidebar?: ISidebarGroup[];
siteData: ISiteData;
tabMeta?: NonNullable<IRouteMeta['tabs']>[0]['meta'];
loginUser?: ILoginUser;
}

export const initialState: SiteStore = {
Expand Down
4 changes: 4 additions & 0 deletions src/store/selectors/siteBasicInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ export const githubSel = (s: SiteStore) => s.siteData.themeConfig.socialLinks?.g
export const discordSel = (s: SiteStore) => s.siteData.themeConfig.socialLinks?.discord || '';

export const giscusSel = (s: SiteStore) => s.siteData.themeConfig.giscus;

export const headerSel = (s: SiteStore) => {
return s.siteData.themeConfig.header;
};
8 changes: 8 additions & 0 deletions src/types/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { FeaturesProps, FooterProps, HeroProps } from '@lobehub/ui';
import { ButtonProps, MenuProps } from 'antd';
import type { IThemeConfig, SocialTypes } from 'dumi/dist/client/theme-api/types';
import { FooterColumn } from 'rc-footer/es/column';

Expand Down Expand Up @@ -92,6 +93,13 @@ export interface SiteThemeConfig {
socialLinks?: {
[key in SocialTypes | 'discord']?: string;
};
header?: {
/** 用户信息,默认会从 __LOGIN_USER 本地存储中获取 user 和 avatar,不存在的话展示 登录按钮 */
userActionButton?: {
button?: Omit<ButtonProps, 'children'>;
menuItems?: MenuProps['items'];
};
};
title?: string;
/** 默认描述,未设置描述的页面,该值会用于生成 <meta> 标签 */
description?: string;
Expand Down

0 comments on commit 4089d3d

Please sign in to comment.