Skip to content

Commit 0c184d6

Browse files
kagura114RevySR
authored andcommitted
Add project lists
1 parent 61609bf commit 0c184d6

File tree

10 files changed

+238
-0
lines changed

10 files changed

+238
-0
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ sidebar_position: 1
3434

3535
对于文件夹,可以在文件夹中放置 `_category_.json` 手动设定其标题和所在位置,见[此处](docs/adaptation/_category_.json)
3636

37+
## 项目列表
38+
### 添加项目
39+
`src/pages/projects.tsx` 下面可以添加,具体每一项意义见 `src/components/InfoCard.tsx` `InfoCardProps`
40+
3741
## Links
3842
为了解决这个问题[facebook/docusaurus issues#3372](https://github.com/facebook/docusaurus/issues/3372),默认为所有链接后面加上了一个 `/`, 因此跳转到其他页面需要向上一级走一次
3943

docusaurus.config.ts

+5
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ const config: Config = {
6565
label: '提交问题与已知问题',
6666
position: 'left',
6767
},
68+
{
69+
href: '/projects',
70+
label: '项目列表',
71+
position: 'left',
72+
},
6873
{
6974
href: 'https://github.com/revyos',
7075
label: 'GitHub',

i18n/en/code.json

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
},
88
"开始使用": {
99
"message": "Get Started"
10+
},
11+
"RevyOS 项目列表": {
12+
"message": "RevyOS Projects"
1013
}
1114
}

i18n/en/docusaurus-theme-classic/navbar.json

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"message": "Docs",
1212
"description": "Navbar item with label 文档"
1313
},
14+
"item.label.项目列表": {
15+
"message": "Projects"
16+
},
1417
"item.label.提交问题与已知问题": {
1518
"message": "Issues",
1619
"description": "Navbar item with label 提交问题与已知问题"

src/components/InfoCard.module.css

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* 适配深色模式 */
2+
:root {
3+
--background-color: #f9f9f9;
4+
--text-color: #333;
5+
--card-background: #fff;
6+
--card-shadow: rgba(0, 0, 0, 0.1);
7+
}
8+
9+
[data-theme='dark'] {
10+
--background-color: #1a1a1a;
11+
--text-color: #fff;
12+
--card-background: #2a2a2a;
13+
--card-shadow: rgba(0, 0, 0, 0.3);
14+
}
15+
16+
/* 标题样式 */
17+
.title {
18+
text-align: center;
19+
font-size: 1.75rem;
20+
font-weight: bold;
21+
margin-bottom: 20px;
22+
color: var(--text-color);
23+
}
24+
25+
/* 副标题样式 */
26+
.subTitle {
27+
text-align: start;
28+
font-size: 1rem;
29+
margin-bottom: 10px;
30+
color: var(--text-color);
31+
}
32+
33+
/* 单个卡片样式 */
34+
.card {
35+
background: var(--card-background);
36+
border-radius: 12px;
37+
box-shadow: 0 4px 10px var(--card-shadow);
38+
padding: 20px;
39+
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
40+
cursor: pointer;
41+
display: inline-block;
42+
}
43+
44+
.card:hover {
45+
transform: translateY(-5px);
46+
box-shadow: 0 8px 20px var(--card-shadow);
47+
}

src/components/InfoCard.tsx

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { useColorMode } from '@docusaurus/theme-common';
3+
import Link from '@docusaurus/Link';
4+
import styles from './InfoCard.module.css'
5+
import useBaseUrl from '@docusaurus/useBaseUrl';
6+
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
7+
8+
export type InfoCardProps = {
9+
title: string; // 标题,中文
10+
title_en?: string; // 标题,英文
11+
logo?: string; // logo, xx.xx -> xx.dark.xx for night mode
12+
subtitle?: string;
13+
subtitle_en?: string;
14+
description?: string;
15+
description_en?: string;
16+
link: string; // Link
17+
};
18+
19+
export const InfoCard: React.FC<InfoCardProps> = ({ title, title_en, logo, subtitle, subtitle_en, description, description_en, link }) => {
20+
const [dark, setDark] = useState(false);
21+
const { colorMode } = useColorMode();
22+
useEffect(() => {
23+
setDark(colorMode === 'dark');
24+
}, [[]])
25+
const [name, ext] = logo.split(/\.(?=[^.]+$)/);
26+
const {
27+
i18n: { currentLocale },
28+
} = useDocusaurusContext();
29+
const isEn = currentLocale === 'en';
30+
31+
return (
32+
<div className={styles.card} onClick={() => window.open(link, '_blank')}>
33+
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
34+
{logo &&
35+
dark ?
36+
<img src={useBaseUrl(`${name}.dark.${ext}`)} alt={title} style={{ width: 40, height: 40, borderRadius: '50%' }} onError={(e) => (e.currentTarget.src = useBaseUrl(logo))} />
37+
:
38+
<img src={useBaseUrl(logo)} alt={title} style={{ width: 40, height: 40, borderRadius: '50%' }} />
39+
}
40+
<div>
41+
<h3 style={{ margin: 0, fontSize: '1.1em' }}>
42+
<Link to={link} className={styles.title} style={{ textDecoration: 'none', color: 'inherit' }}>
43+
{isEn ? (title_en != null ? title_en : title) : title}
44+
</Link>
45+
</h3>
46+
<p className={styles.subTitle} style={{ margin: 0 }}>
47+
{isEn ? (subtitle_en != null ? subtitle_en : subtitle) : subtitle}
48+
</p>
49+
</div>
50+
</div>
51+
<p style={{ margin: '10px 0 0', fontSize: '0.85em', color: dark ? '#aaa' : '#555' }}>
52+
{isEn ? (description_en != null ? description_en : description) : description}
53+
</p>
54+
</div>
55+
);
56+
};
57+
58+
59+
const InfoCardList: React.FC<{ items: InfoCardProps[] }> = ({ items }) => {
60+
return (
61+
<div style={{ display: 'grid', gap: '16px' }}>
62+
{items.map((item, index) => (
63+
<InfoCard key={index} {...item} />
64+
))}
65+
</div>
66+
);
67+
};
68+
69+
export default InfoCardList;

src/pages/projects.module.css

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* 全局容器样式(就是整个里面的东西) */
2+
.container {
3+
background-color: var(--background-color);
4+
color: var(--text-color);
5+
padding: 4rem 0;
6+
display: flex;
7+
flex-direction: column;
8+
align-items: center;
9+
justify-content: start;
10+
overflow: hidden;
11+
flex-grow: 1;
12+
position: relative;
13+
}
14+
15+
/* 适配深色模式 */
16+
:root {
17+
--background-color: #f9f9f9;
18+
--text-color: #333;
19+
--card-background: #fff;
20+
--card-shadow: rgba(0, 0, 0, 0.1);
21+
}
22+
23+
[data-theme='dark'] {
24+
--background-color: #1a1a1a;
25+
--text-color: #fff;
26+
--card-background: #2a2a2a;
27+
--card-shadow: rgba(0, 0, 0, 0.3);
28+
}
29+
30+
/* 卡片列表容器 */
31+
.cardListContainer {
32+
display: grid;
33+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
34+
padding-top: 20px;
35+
gap: 25px;
36+
width: 80%;
37+
max-width: 1200px;
38+
}

src/pages/projects.tsx

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { useColorMode } from '@docusaurus/theme-common';
3+
import Translate, { translate } from '@docusaurus/Translate';
4+
import Layout from '@theme/Layout';
5+
import styles from './projects.module.css';
6+
import InfoCardList, { InfoCardProps } from '../components/InfoCard';
7+
8+
const projects: InfoCardProps[] = [
9+
{
10+
title: 'th1520-linux-kernel',
11+
title_en: 'th1520-linux-kernel',
12+
logo: '/img/github-mark.svg',
13+
subtitle: 'th1520-linux-kernel',
14+
subtitle_en: 'th1520-linux-kernel',
15+
description: 'TH1520 的 Linux kernel',
16+
description_en: 'Linux kernel for TH1520',
17+
link: 'https://github.com/revyos/th1520-linux-kernel'
18+
},
19+
{
20+
title: 'th1520-boot-firmware',
21+
title_en: 'th1520-boot-firmware',
22+
logo: '/img/github-mark.svg',
23+
subtitle: 'th1520-boot-firmware',
24+
subtitle_en: 'th1520-boot-firmware',
25+
description: 'TH1520 的 boot firmware',
26+
description_en: 'Boot firmware kernel for TH1520',
27+
link: 'https://github.com/revyos/th1520-boot-firmware'
28+
},
29+
];
30+
31+
const ProjectsInner: React.FC = () => {
32+
const [dark, setDark] = useState(false);
33+
const { colorMode } = useColorMode();
34+
useEffect(() => {
35+
setDark(colorMode === 'dark');
36+
}, [[]])
37+
38+
return (
39+
<div
40+
className={styles.container}
41+
style={{
42+
backgroundColor: dark ? '#1a1a1a' : '#f9f9f9',
43+
color: dark ? '#fff' : '#333',
44+
padding: '40px 20px',
45+
}}
46+
>
47+
<h1 style={{ textAlign: 'center', fontSize: '3rem', marginBottom: 'px' }}>
48+
<Translate>RevyOS 项目列表</Translate>
49+
</h1>
50+
<div className={styles.cardListContainer}>
51+
<InfoCardList items={projects} />
52+
</div>
53+
</div>
54+
)
55+
}
56+
57+
const ProjectsPage: React.FC = () => {
58+
return (
59+
<Layout
60+
title={translate({ message: 'RevyOS 项目列表' })}
61+
>
62+
<ProjectsInner />
63+
</Layout>
64+
);
65+
};
66+
67+
export default ProjectsPage;

static/img/github-mark.dark.svg

+1
Loading

static/img/github-mark.svg

+1
Loading

0 commit comments

Comments
 (0)