Skip to content

Commit 78f4038

Browse files
committed
feat(ui): 添加学术平台社交图标及支持配置
- 新增 SocialIcon 组件,支持常见社交平台及学术平台图标展示 - 扩展配置示例文件,加入学术平台社交链接注释示例 - 依赖中新增 react-icons 库用于图标显示 - 修改 Footer 组件,替换纯文本为图标加名称展示社交链接 - 增加 Footer 样式,优化社交链接图标与文字布局及交互样式
1 parent e1e15c5 commit 78f4038

7 files changed

Lines changed: 157 additions & 18 deletions

File tree

config.example.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ profile:
2424
# ========================================
2525
# 社交链接
2626
# ========================================
27+
# 支持的图标类型:
28+
# 常见社交平台: github, twitter, linkedin, facebook, instagram, youtube, email,
29+
# website, medium, reddit, stackoverflow, wechat, weibo, zhihu
30+
# 学术平台: scholar/google-scholar (Google Scholar), orcid (ORCID),
31+
# researchgate/research-gate (ResearchGate)
2732
social:
2833
- name: "GitHub"
2934
icon: "github"
@@ -34,6 +39,16 @@ social:
3439
- name: "Twitter"
3540
icon: "twitter"
3641
url: "https://twitter.com/yourusername"
42+
# 学术平台示例:
43+
# - name: "Google Scholar"
44+
# icon: "scholar"
45+
# url: "https://scholar.google.com/citations?user=YOUR_ID"
46+
# - name: "ORCID"
47+
# icon: "orcid"
48+
# url: "https://orcid.org/YOUR-ORCID-ID"
49+
# - name: "ResearchGate"
50+
# icon: "researchgate"
51+
# url: "https://www.researchgate.net/profile/YOUR_PROFILE"
3752

3853
# ========================================
3954
# 导航菜单配置

package-lock.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"markdown-it-task-lists": "^2.1.1",
3434
"react": "^19.2.0",
3535
"react-dom": "^19.2.0",
36+
"react-icons": "^5.5.0",
3637
"react-router-dom": "^7.11.0"
3738
},
3839
"devDependencies": {

public/config.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ profile:
1616
location: "City, Country"
1717

1818
# 社交链接
19+
# 支持的图标类型:
20+
# 常见社交平台: github, twitter, linkedin, facebook, instagram, youtube, email,
21+
# website, medium, reddit, stackoverflow, wechat, weibo, zhihu
22+
# 学术平台: scholar/google-scholar (Google Scholar), orcid (ORCID),
23+
# researchgate/research-gate (ResearchGate)
1924
social:
2025
- name: "GitHub"
2126
icon: "github"
@@ -26,6 +31,13 @@ social:
2631
- name: "Twitter"
2732
icon: "twitter"
2833
url: "https://twitter.com/yourusername"
34+
# 学术平台示例(取消注释即可使用):
35+
# - name: "Google Scholar"
36+
# icon: "scholar"
37+
# url: "https://scholar.google.com/citations?user=YOUR_ID"
38+
# - name: "ORCID"
39+
# icon: "orcid"
40+
# url: "https://orcid.org/YOUR-ORCID-ID"
2941

3042
# 导航菜单
3143
# showInMobile: 控制在移动端是否默认显示(false则放入汉堡菜单)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from 'react'
2+
import {
3+
FaGithub,
4+
FaTwitter,
5+
FaLinkedin,
6+
FaFacebook,
7+
FaInstagram,
8+
FaYoutube,
9+
FaEnvelope,
10+
FaGlobe,
11+
FaMedium,
12+
FaReddit,
13+
FaStackOverflow,
14+
FaWeixin,
15+
FaWeibo,
16+
} from 'react-icons/fa'
17+
import {
18+
SiGooglescholar,
19+
SiOrcid,
20+
SiResearchgate,
21+
SiZhihu,
22+
} from 'react-icons/si'
23+
24+
/**
25+
* 社交媒体图标映射
26+
* 支持常见的社交平台和学术平台
27+
*/
28+
const iconMap = {
29+
// 常见社交平台
30+
github: FaGithub,
31+
twitter: FaTwitter,
32+
linkedin: FaLinkedin,
33+
facebook: FaFacebook,
34+
instagram: FaInstagram,
35+
youtube: FaYoutube,
36+
email: FaEnvelope,
37+
website: FaGlobe,
38+
medium: FaMedium,
39+
reddit: FaReddit,
40+
stackoverflow: FaStackOverflow,
41+
wechat: FaWeixin,
42+
weibo: FaWeibo,
43+
zhihu: SiZhihu,
44+
45+
// 学术平台
46+
scholar: SiGooglescholar,
47+
'google-scholar': SiGooglescholar,
48+
'google scholar': SiGooglescholar,
49+
orcid: SiOrcid,
50+
researchgate: SiResearchgate,
51+
'research-gate': SiResearchgate,
52+
}
53+
54+
/**
55+
* 社交媒体图标组件
56+
* @param {string} icon - 图标名称(小写)
57+
* @param {number} size - 图标大小(默认 20)
58+
* @param {object} props - 其他传递给图标的属性
59+
*/
60+
export function SocialIcon({ icon, size = 20, ...props }) {
61+
// 转换为小写并查找对应的图标组件
62+
const iconKey = icon?.toLowerCase() || ''
63+
const IconComponent = iconMap[iconKey]
64+
65+
// 如果找不到对应图标,返回默认的全局图标
66+
if (!IconComponent) {
67+
return <FaGlobe size={size} {...props} />
68+
}
69+
70+
return <IconComponent size={size} {...props} />
71+
}
72+
73+
/**
74+
* 获取所有支持的图标名称列表
75+
*/
76+
export function getSupportedIcons() {
77+
return Object.keys(iconMap)
78+
}
79+
80+
/**
81+
* 检查图标名称是否被支持
82+
*/
83+
export function isIconSupported(icon) {
84+
const iconKey = icon?.toLowerCase() || ''
85+
return iconKey in iconMap
86+
}

src/components/layout/Footer.jsx

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import React from 'react';
2-
import { useSiteConfig, useSocialConfig } from '../../config/ConfigContext';
3-
import { useI18n } from '../../i18n/I18nContext';
4-
import styles from './Footer.module.css';
1+
import React from 'react'
2+
import { useSiteConfig, useSocialConfig } from '../../config/ConfigContext'
3+
import { useI18n } from '../../i18n/I18nContext'
4+
import { SocialIcon } from '../common/SocialIcon'
5+
import styles from './Footer.module.css'
56

67
/**
78
* 页面底部组件
89
*/
910
export function Footer() {
10-
const siteConfig = useSiteConfig();
11-
const socialLinks = useSocialConfig();
12-
const { t } = useI18n();
13-
const currentYear = new Date().getFullYear();
11+
const siteConfig = useSiteConfig()
12+
const socialLinks = useSocialConfig()
13+
const { t } = useI18n()
14+
const currentYear = new Date().getFullYear()
1415

1516
return (
1617
<footer className={styles.footer}>
@@ -20,15 +21,17 @@ export function Footer() {
2021
{socialLinks && socialLinks.length > 0 && (
2122
<div className={styles.social}>
2223
{socialLinks.map((link, index) => (
23-
<a
24+
<a
2425
key={index}
2526
href={link.url}
2627
className={styles.socialLink}
2728
target="_blank"
2829
rel="noopener noreferrer"
2930
aria-label={link.name}
31+
title={link.name}
3032
>
31-
{link.name}
33+
<SocialIcon icon={link.icon} size={20} />
34+
<span className={styles.socialName}>{link.name}</span>
3235
</a>
3336
))}
3437
</div>
@@ -37,19 +40,21 @@ export function Footer() {
3740
{/* 版权信息 */}
3841
<div className={styles.copyright}>
3942
<p>
40-
© {currentYear} {siteConfig?.author || siteConfig?.title}.
41-
{' '}{t('footer.poweredBy')} <a
42-
href="https://github.com/mappedinfo/ppage"
43-
target="_blank"
43+
© {currentYear} {siteConfig?.author || siteConfig?.title}.{' '}
44+
{t('footer.poweredBy')}{' '}
45+
<a
46+
href="https://github.com/mappedinfo/ppage"
47+
target="_blank"
4448
rel="noopener noreferrer"
4549
className={styles.link}
4650
>
4751
{t('footer.poweredByLink')}
48-
</a>{t('footer.poweredBySuffix') && ` ${t('footer.poweredBySuffix')}`}
52+
</a>
53+
{t('footer.poweredBySuffix') && ` ${t('footer.poweredBySuffix')}`}
4954
</p>
5055
</div>
5156
</div>
5257
</div>
5358
</footer>
54-
);
59+
)
5560
}

src/components/layout/Footer.module.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,24 @@
2626
}
2727

2828
.socialLink {
29+
display: inline-flex;
30+
align-items: center;
31+
gap: 0.5rem;
2932
color: var(--text-secondary);
3033
text-decoration: none;
3134
font-size: var(--font-size-sm);
3235
transition: color var(--transition-base);
36+
padding: 0.25rem 0.5rem;
37+
border-radius: 4px;
3338
}
3439

3540
.socialLink:hover {
3641
color: var(--primary-color);
42+
background-color: var(--bg-primary);
43+
}
44+
45+
.socialName {
46+
font-size: var(--font-size-sm);
3747
}
3848

3949
.copyright {

0 commit comments

Comments
 (0)