From 89e10633cff891d3f6c737b93bc1271b60d62a00 Mon Sep 17 00:00:00 2001
From: dethan3
Date: Mon, 17 Mar 2025 14:57:56 +0000
Subject: [PATCH 1/8] feat(home): add "view all" buttons for events, blogs, and
partners
---
.env | 2 +-
components/Home/CommunityStats.tsx | 27 +++++++++
components/Home/LatestBlogs.tsx | 40 +++++++++++++
components/Home/Sponsors.tsx | 34 +++++++++++
components/Home/UpcomingEvents.tsx | 42 +++++++++++++
components/Layout/Footer.tsx | 0
components/Navigator/MainNavigator.tsx | 13 +---
pages/about.tsx | 33 ++++++++++
pages/activity.tsx | 0
pages/community.tsx | 0
pages/index.tsx | 83 ++++++++++----------------
styles/About.module.less | 15 +++++
styles/Home.module.less | 12 ++++
styles/globals.less | 10 ++++
translation/en-US.ts | 7 +++
translation/zh-CN.ts | 9 ++-
translation/zh-TW.ts | 7 +++
17 files changed, 269 insertions(+), 65 deletions(-)
create mode 100644 components/Home/CommunityStats.tsx
create mode 100644 components/Home/LatestBlogs.tsx
create mode 100644 components/Home/Sponsors.tsx
create mode 100644 components/Home/UpcomingEvents.tsx
create mode 100644 components/Layout/Footer.tsx
create mode 100644 pages/about.tsx
create mode 100644 pages/activity.tsx
create mode 100644 pages/community.tsx
create mode 100644 styles/About.module.less
diff --git a/.env b/.env
index b69254bc2..14a3ba6c3 100644
--- a/.env
+++ b/.env
@@ -1,4 +1,4 @@
-NEXT_PUBLIC_SITE_NAME=freecodecamp-chengdu.github.io
+NEXT_PUBLIC_SITE_NAME=fCC-ChengDu
NEXT_PUBLIC_SITE_SUMMARY=Lark project scaffold based on TypeScript, React, Next.js, Bootstrap & Workbox.
NEXT_PUBLIC_SENTRY_DSN =
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
new file mode 100644
index 000000000..2985e7ac2
--- /dev/null
+++ b/components/Home/CommunityStats.tsx
@@ -0,0 +1,27 @@
+import { Card,Col, Container, Row } from 'react-bootstrap';
+
+export const CommunityStats = () => (
+
+
+ 社区数据
+ {/*
*/}
+
+
+ {[
+ { number: '1000+', label: '社区成员' },
+ { number: '50+', label: '举办活动' },
+ { number: '200+', label: '技术文章' },
+ { number: '30+', label: '开源项目' },
+ ].map((stat, index) => (
+
+
+
+ {stat.number}
+ {stat.label}
+
+
+
+ ))}
+
+
+);
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
new file mode 100644
index 000000000..f3b16e653
--- /dev/null
+++ b/components/Home/LatestBlogs.tsx
@@ -0,0 +1,40 @@
+import Link from 'next/link';
+import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+
+export const LatestBlogs = () => (
+
+ 最新博客文章
+
+
+
+
+ 如何学习 TypeScript?
+ 发布日期: 2025年3月10日
+
+ 阅读文章
+
+
+
+
+
+
+
+ React 18 新特性
+ 发布日期: 2025年2月25日
+
+ 阅读文章
+
+
+
+
+
+
+
+
+
+
+
+
+);
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
new file mode 100644
index 000000000..7b5b7aaaf
--- /dev/null
+++ b/components/Home/Sponsors.tsx
@@ -0,0 +1,34 @@
+import Link from 'next/link';
+import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+
+export const Sponsors = () => (
+
+ 赞助商与合作伙伴
+
+
+
+
+ 企业 A
+ 领先的技术公司,支持开源社区。
+
+
+
+
+
+
+ 企业 B
+ 专注于智能具身领域的创新公司。
+
+
+
+
+
+
+
+
+
+
+
+);
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
new file mode 100644
index 000000000..aa53a9cab
--- /dev/null
+++ b/components/Home/UpcomingEvents.tsx
@@ -0,0 +1,42 @@
+import Link from 'next/link';
+import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+
+export const UpcomingEvents = () => (
+
+ 即将举行的活动
+
+
+
+
+ 活动标题 1
+ 时间: 2025年3月20日
+ 地点: 成都某咖啡馆
+
+ 查看详情
+
+
+
+
+
+
+
+ 活动标题 2
+ 时间: 2025年4月5日
+ 地点: 线上直播
+
+ 查看详情
+
+
+
+
+
+
+
+
+
+
+
+
+);
diff --git a/components/Layout/Footer.tsx b/components/Layout/Footer.tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/components/Navigator/MainNavigator.tsx b/components/Navigator/MainNavigator.tsx
index c72b1b32b..b83c1ae17 100644
--- a/components/Navigator/MainNavigator.tsx
+++ b/components/Navigator/MainNavigator.tsx
@@ -20,18 +20,11 @@ export const MainNavigator: FC = observer(() => (
diff --git a/pages/about.tsx b/pages/about.tsx
new file mode 100644
index 000000000..173492f8c
--- /dev/null
+++ b/pages/about.tsx
@@ -0,0 +1,33 @@
+import { observer } from 'mobx-react';
+import { compose, translator } from 'next-ssr-middleware';
+import { Container } from 'react-bootstrap';
+
+import { PageHead } from '../components/Layout/PageHead';
+import { i18n, t } from '../models/Translation';
+import styles from '../styles/About.module.less';
+
+export const getServerSideProps = compose(translator(i18n));
+
+const AboutPage = observer(() => (
+
+
+
+ {t('about_us')}
+
+ FCC 成都社区, 成立于 2016 年 6
+ 月,是一个非营利性的公益性技术社区,是由一群热血有志青年爱好者,利用个人业余休息时间组建而成的技术社区,目的是为了搭建一个友好的交流、学习、互助的社区,帮助成都市众多的开发者,技术爱好者提升个人技术能力。社区致力于做西南地区首个有温度与情怀的技术社区,鼓励人人皆可编程实现个人梦想。
+
+
+
+ {t('our_mission')}
+ 让更多人享受编程的乐趣,并改变自己的生活。
+
+
+
+ {t('our_team')}
+ 。。。
+
+
+));
+
+export default AboutPage;
diff --git a/pages/activity.tsx b/pages/activity.tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/pages/community.tsx b/pages/community.tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/pages/index.tsx b/pages/index.tsx
index a6e0e1b25..4eec01e8b 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,71 +1,48 @@
import { observer } from 'mobx-react';
import { compose, translator } from 'next-ssr-middleware';
-import { Card, Col, Container, Row } from 'react-bootstrap';
+import { Button,Card, Col, Container, Row } from 'react-bootstrap';
-import { GitCard } from '../components/Git/Card';
+import { CommunityStats } from '../components/Home/CommunityStats';
+import { LatestBlogs } from '../components/Home/LatestBlogs';
+import { Sponsors } from '../components/Home/Sponsors';
+import { UpcomingEvents } from '../components/Home/UpcomingEvents';
import { PageHead } from '../components/Layout/PageHead';
import { i18n, t } from '../models/Translation';
import styles from '../styles/Home.module.less';
-import { framework, mainNav } from './api/home';
export const getServerSideProps = compose(translator(i18n));
const HomePage = observer(() => (
-
+
+
+
+
+ freeCodeCamp 成都社区
+
+
+ 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
+
+
+
+
+
+
+
+ {/* */}
+
-
+
-
- {t('get_started_by_editing')}
-
- pages/index.tsx
-
-
+
-
- {mainNav().map(({ link, title, summary }) => (
-
-
-
-
-
- {title} →
-
-
- {summary}
-
-
-
- ))}
-
+
- {t('upstream_projects')}
-
- {framework.map(
- ({ title, languages, tags, summary, link, repository }) => (
-
-
-
- ),
- )}
-
+
));
diff --git a/styles/About.module.less b/styles/About.module.less
new file mode 100644
index 000000000..3a811e0c6
--- /dev/null
+++ b/styles/About.module.less
@@ -0,0 +1,15 @@
+.main {
+ margin: auto;
+ padding: 2rem;
+ max-width: 800px;
+}
+
+.main h1,
+.main h2 {
+ color: #0070f3;
+ text-align: center;
+}
+
+.main p {
+ line-height: 1.6;
+}
diff --git a/styles/Home.module.less b/styles/Home.module.less
index 6e9bf39b6..43e89d03f 100644
--- a/styles/Home.module.less
+++ b/styles/Home.module.less
@@ -3,6 +3,18 @@
min-height: 100vh;
}
+.imagePlaceholder {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
+ border-radius: 16px;
+ background: #f0f0f0;
+ width: 80%;
+ max-width: 400px;
+ height: 300px;
+}
+
.title {
font-size: 4rem;
line-height: 1.15;
diff --git a/styles/globals.less b/styles/globals.less
index 7b2851f5b..123889418 100644
--- a/styles/globals.less
+++ b/styles/globals.less
@@ -1,6 +1,11 @@
html,
body {
margin: 0;
+ background-image: linear-gradient(
+ 150deg,
+ #028dfa 60%,
+ #0ee6e6 100%
+ ) !important;
padding: 0;
font-family:
-apple-system,
@@ -42,3 +47,8 @@ div:has(.next-error-h1) {
width: auto !important;
}
}
+
+:root {
+ --bs-primary: #000000;
+ --bs-primary-rgb: 2, 141, 250;
+}
diff --git a/translation/en-US.ts b/translation/en-US.ts
index 2d682c8c5..36bac0a5b 100644
--- a/translation/en-US.ts
+++ b/translation/en-US.ts
@@ -1,6 +1,13 @@
import { IDType } from 'mobx-restful';
export default {
+ about: 'About',
+ about_us: 'About US',
+ our_team: 'Our Team',
+ our_mission: 'Our Mission',
+ activity: 'Activity',
+ community_description: 'Let more people enjoy the fun of programming',
+ community: 'Community',
welcome_to: 'Welcome to',
get_started_by_editing: 'Get started by editing',
upstream_projects: 'Upstream projects',
diff --git a/translation/zh-CN.ts b/translation/zh-CN.ts
index 65a569823..19958ce58 100644
--- a/translation/zh-CN.ts
+++ b/translation/zh-CN.ts
@@ -1,7 +1,14 @@
import { IDType } from 'mobx-restful';
export default {
- welcome_to: '欢迎使用',
+ about: '关于',
+ about_us: '关于我们',
+ our_mission: '我们的使命',
+ our_team: '我们的团队',
+ activity: '活动',
+ community_description: '让更多人享受编程的乐趣',
+ community: '社区',
+ welcome_to: '欢迎来到',
get_started_by_editing: '开始你的项目吧,编辑',
upstream_projects: '上游项目',
home_page: '主页',
diff --git a/translation/zh-TW.ts b/translation/zh-TW.ts
index 1eca7cdd9..00c620ca1 100644
--- a/translation/zh-TW.ts
+++ b/translation/zh-TW.ts
@@ -1,6 +1,13 @@
import { IDType } from 'mobx-restful';
export default {
+ about: '關於',
+ about_us: '關於我們',
+ our_mission: '我們的使命',
+ our_team: '我們的團隊',
+ activity: '活動',
+ community_description: '讓更多人享受程式設計的樂趣',
+ community: '社群',
welcome_to: '歡迎使用',
get_started_by_editing: '開始你的專案吧,編輯',
upstream_projects: '上游專案',
From de0fe92ed41feaa5ee789432dd7612f5527e0345 Mon Sep 17 00:00:00 2001
From: dethan3
Date: Fri, 9 May 2025 00:53:02 +0800
Subject: [PATCH 2/8] refactor: convert About page to use Bootstrap utility
classes and add comprehensive community content
---
.env | 4 +-
components/Home/CommunityStats.tsx | 9 +-
components/Home/LatestBlogs.tsx | 54 +++++----
components/Home/Sponsors.tsx | 44 ++++----
components/Home/UpcomingEvents.tsx | 58 +++++-----
components/Layout/Footer.tsx | 0
components/Navigator/MainNavigator.tsx | 4 +
package.json | 7 ++
pages/about.tsx | 146 +++++++++++++++++++++++--
pages/activity.tsx | 0
pages/api/core.ts | 67 ++++++------
pages/index.tsx | 97 ++++++++++++++--
styles/About.module.less | 15 ---
13 files changed, 348 insertions(+), 157 deletions(-)
delete mode 100644 components/Layout/Footer.tsx
delete mode 100644 pages/activity.tsx
delete mode 100644 styles/About.module.less
diff --git a/.env b/.env
index 68969b27b..8763eff34 100644
--- a/.env
+++ b/.env
@@ -1,5 +1,5 @@
-NEXT_PUBLIC_SITE_NAME=fCC-ChengDu
-NEXT_PUBLIC_SITE_SUMMARY=Lark project scaffold based on TypeScript, React, Next.js, Bootstrap & Workbox.
+NEXT_PUBLIC_SITE_NAME=fCC 成都社区
+NEXT_PUBLIC_SITE_SUMMARY=fCC 成都社区
NEXT_PUBLIC_LOGO = https://github.com/FreeCodeCamp-Chengdu.png
NEXT_PUBLIC_SENTRY_DSN =
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
index 2985e7ac2..8bef15924 100644
--- a/components/Home/CommunityStats.tsx
+++ b/components/Home/CommunityStats.tsx
@@ -4,7 +4,6 @@ export const CommunityStats = () => (
社区数据
- {/*
*/}
{[
@@ -12,12 +11,12 @@ export const CommunityStats = () => (
{ number: '50+', label: '举办活动' },
{ number: '200+', label: '技术文章' },
{ number: '30+', label: '开源项目' },
- ].map((stat, index) => (
-
+ ].map(({ number, label }) => (
+
- {stat.number}
- {stat.label}
+ {number}
+ {label}
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
index f3b16e653..30e092bcb 100644
--- a/components/Home/LatestBlogs.tsx
+++ b/components/Home/LatestBlogs.tsx
@@ -1,40 +1,36 @@
import Link from 'next/link';
-import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+import { ArticleMeta } from '../../pages/api/core';
-export const LatestBlogs = () => (
+interface LatestBlogsProps {
+ articles: ArticleMeta[];
+}
+
+export const LatestBlogs: React.FC = ({ articles }) => (
最新博客文章
-
-
-
- 如何学习 TypeScript?
- 发布日期: 2025年3月10日
-
- 阅读文章
-
-
-
-
-
-
-
- React 18 新特性
- 发布日期: 2025年2月25日
-
- 阅读文章
-
-
-
-
+ {articles.map((article) => (
+
+
+
+ {article.name}
+
+ 发布日期: {article.meta?.date || '未知日期'}
+
+
+ 阅读文章
+
+
+
+
+ ))}
-
-
-
+
);
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
index 7b5b7aaaf..5754f9401 100644
--- a/components/Home/Sponsors.tsx
+++ b/components/Home/Sponsors.tsx
@@ -1,34 +1,30 @@
-import Link from 'next/link';
-import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+import { ArticleMeta } from '../../pages/api/core';
-export const Sponsors = () => (
+interface SponsorsProps {
+ sponsors: ArticleMeta[];
+}
+
+export const Sponsors: React.FC = ({ sponsors }) => (
赞助商与合作伙伴
-
-
-
- 企业 A
- 领先的技术公司,支持开源社区。
-
-
-
-
-
-
- 企业 B
- 专注于智能具身领域的创新公司。
-
-
-
+ {sponsors.map((sponsor) => (
+
+
+
+ {sponsor.name}
+ {sponsor.meta?.description || '暂无描述'}
+
+
+
+ ))}
-
-
-
+
);
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
index aa53a9cab..e8b48f76a 100644
--- a/components/Home/UpcomingEvents.tsx
+++ b/components/Home/UpcomingEvents.tsx
@@ -1,42 +1,36 @@
import Link from 'next/link';
-import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+import { ArticleMeta } from '../../pages/api/core';
-export const UpcomingEvents = () => (
+interface UpcomingEventsProps {
+ events: ArticleMeta[];
+}
+
+export const UpcomingEvents: React.FC = ({ events }) => (
- 即将举行的活动
+ 往期活动
-
-
-
- 活动标题 1
- 时间: 2025年3月20日
- 地点: 成都某咖啡馆
-
- 查看详情
-
-
-
-
-
-
-
- 活动标题 2
- 时间: 2025年4月5日
- 地点: 线上直播
-
- 查看详情
-
-
-
-
+ {events.map((event) => (
+
+
+
+ {event.meta?.title}
+ 时间: {event.meta?.start || 'void 0'}
+ 地点: {event.meta?.address || 'void 0'}
+ {/* TODO: 无 Path 不渲染 */}
+
+ 查看详情
+
+
+
+
+ ))}
-
-
-
+
);
diff --git a/components/Layout/Footer.tsx b/components/Layout/Footer.tsx
deleted file mode 100644
index e69de29bb..000000000
diff --git a/components/Navigator/MainNavigator.tsx b/components/Navigator/MainNavigator.tsx
index b83c1ae17..02ca0bb51 100644
--- a/components/Navigator/MainNavigator.tsx
+++ b/components/Navigator/MainNavigator.tsx
@@ -25,6 +25,10 @@ export const MainNavigator: FC = observer(() => (
{t('community')}
{t('about')}
+
+
+ {t('source_code')}
+
diff --git a/package.json b/package.json
index 3168eadf7..bf2f2edb8 100644
--- a/package.json
+++ b/package.json
@@ -97,5 +97,12 @@
"test": "lint-staged && npm run lint",
"pack-image": "docker build -t freecodecamp-chengdu/freecodecamp-chengdu.github.io:latest .",
"container": "docker rm -f freecodecamp-chengdu.github.io && docker run --name freecodecamp-chengdu.github.io -p 3000:3000 -d freecodecamp-chengdu/freecodecamp-chengdu.github.io:latest"
+ },
+ "pnpm": {
+ "ignoredBuiltDependencies": [
+ "@sentry/cli",
+ "core-js",
+ "sharp"
+ ]
}
}
diff --git a/pages/about.tsx b/pages/about.tsx
index 173492f8c..b11d5e751 100644
--- a/pages/about.tsx
+++ b/pages/about.tsx
@@ -1,31 +1,157 @@
import { observer } from 'mobx-react';
import { compose, translator } from 'next-ssr-middleware';
-import { Container } from 'react-bootstrap';
-
+import { Container, Table } from 'react-bootstrap';
import { PageHead } from '../components/Layout/PageHead';
import { i18n, t } from '../models/Translation';
-import styles from '../styles/About.module.less';
export const getServerSideProps = compose(translator(i18n));
const AboutPage = observer(() => (
-
+
{t('about_us')}
- FCC 成都社区, 成立于 2016 年 6
- 月,是一个非营利性的公益性技术社区,是由一群热血有志青年爱好者,利用个人业余休息时间组建而成的技术社区,目的是为了搭建一个友好的交流、学习、互助的社区,帮助成都市众多的开发者,技术爱好者提升个人技术能力。社区致力于做西南地区首个有温度与情怀的技术社区,鼓励人人皆可编程实现个人梦想。
+ FCC 成都社区, 成立于 2016 年 6 月,是一个非营利性的公益性技术社区,是由一群热血有志青年爱好者,利用个人业余休息时间组建而成的技术社区,目的是为了搭建一个友好的交流、学习、互助的社区,帮助成都市众多的开发者,技术爱好者提升个人技术能力。社区致力于做西南地区首个有温度与情怀的技术社区,鼓励人人皆可编程实现个人梦想。
- {t('our_mission')}
- 让更多人享受编程的乐趣,并改变自己的生活。
+ 什么是 FCC
+
+ freeCodeCamp(简称 FCC)是由美国人 Quincy Larson 发起的开源项目,截止 2018-02-03,在 Github 上获得 29+万 Star(教育类排名第一)。有长达 1600 小时的课程, 并且是基于浏览器、课程免费、证书免费、结合了游戏化闯关的乐趣。FCC 是一个在 160 多个国家和 2000 多个城市的拥有与 1000k+ 开发者的社区。
+
+
+ 2016 年 4 月,由 DevEco (晋剑 + Miya)将 FCC 引入中国,并举办了 2000+ 开发者参与的在线全民编程活动,到目前为止,已成功举办了 100+ 场 Coffee & Code / 编程黑客松 / 编程静修日等活动。在 FCC China , 有 20+% 的女性加入到了社区学习、提升编程能力。
+
+
+
+
+ {t('our_mission')}
+ 让更多人享受编程的乐趣,并改变自己的生活。
+
+
+
+ FCC 成都社区活动
+ 大型活动
+
+ - FCC 成都社区 React 技术专场交流活动
+ - 2017 成都首届 Web 前端交流大会
+ - 新耀杯 Code for City 黑客松大赛
+
+
+ 历史活动
+
+
+
+
+ | 序号 |
+ 日期 |
+ 主题 |
+ 形式 |
+
+
+
+
+ | 1 |
+ 20160609 |
+ 线下活动开启,宣布社区成立 |
+ 编程讨论 |
+
+
+ | 2 |
+ 20160703 |
+ 携手编程-成都社区主页初版 |
+ 动手编程 |
+
+
+ | 3 |
+ 20160911 |
+ 结对编程的理念 |
+ 个人分享 + 结对编程 |
+
+
+ | 4 |
+ 20161106 |
+ Console 的九大命令 + 学习路线分享 |
+ 个人分享 |
+
+
+ | 5 |
+ 20161119 |
+ Git 的使用与个人简历制作 |
+ 分享 + 编程 |
+
+
+
+
+ 显示部分历史活动,完整列表请参考原文档
+
+
+
+ 为什么是 FCC 成都社区
+
+ 在成都众多的技术大会、技术分享活动当中,很多的活动以技术分享为幌子,做着产品推广与宣传的事情,这导致了成都 IT 圈子技术分享的氛围越来越差,大家参与分享的热情越来越低。
+
+
+ FCC 成都社区的众多小伙伴,一致认为是时候为这座热爱的城市做一份自己的贡献了,社区提出所有活动全部免费参加、嘉宾分享内容中广告零容忍,成立嘉宾分享内容审查团队,确保每一次分享都是 100% 的干货。
+
+
+ FCC 成都社区的小伙伴们一直明白社区所肩负的使命,带动成都 IT 圈子技术交流的氛围,让更多的技术牛人帮助到更多的开发者,让成都成为全国 IT 行业的先锋,让成都吸引更多 IT 人才蓉漂。进入更多的校园普及更多的次的编程知识,倡导人人皆可编程,让成都这座城市未来充满无限可能。
+
+
+
+
+ FCC 成都社区规划
+
+ - 走进更多校园,普及人人皆可编程思想帮助更多的孩子们。
+ - 继续坚持做好两周一次的【Coffee and Code】的结对编程活动、编程道场活动,一对一指导开发者提升个人技术能力。
+ - 做好季度技术专场活动,让成都众多 IT 公司加入其中进行分享,带动成都 IT 圈子技术分享的热情。
+ - 做好成都 Web 前端交流大会,让国内一线技术大咖来到成都,给成都众多开发者带来国内一线开发公司的技术心得与经验。
+ - 联合成都众多大型 IT 公司,做好编程马拉松活动,让成都的众多开发者进行技术火花的碰撞。
+
+
+
+
- {t('our_team')}
- 。。。
+ 媒体报道
+
+
+
+
+
+
成都市高新电视台报道
+
2017 成都 Web 前端交流大会 (6 分 53 秒处)
+
+
+
+
+
+
+
四川财富广播 FM94.0 采访
+
FCC 成都社区:“人人皆可编程”,以独特的方式为城市带来美好改变
+
+
+
+
+
+
+
四川日报报道
+
揭秘“黑客马拉松”:喝 6 瓶红牛、24 小时里只睡 2 小时
+
+
+
+
));
diff --git a/pages/activity.tsx b/pages/activity.tsx
deleted file mode 100644
index e69de29bb..000000000
diff --git a/pages/api/core.ts b/pages/api/core.ts
index abd75ddf5..16ae8a067 100644
--- a/pages/api/core.ts
+++ b/pages/api/core.ts
@@ -56,13 +56,15 @@ export interface ArticleMeta {
const MDX_pattern = /\.mdx?$/;
export async function frontMatterOf(path: string) {
- const { readFile } = await import('fs/promises');
-
- const file = await readFile(path, 'utf-8');
-
- const [, frontMatter] = file.match(/^---[\r\n]([\s\S]+?[\r\n])---/) || [];
-
- return frontMatter && parse(frontMatter);
+ try {
+ const { readFile } = await import('fs/promises');
+ const file = await readFile(path, 'utf-8');
+ const [, frontMatter] = file.match(/^---[\r\n]([\s\S]+?[\r\n])---/) || [];
+ return frontMatter ? parse(frontMatter) : null;
+ } catch (error) {
+ console.error(`Error reading front matter from ${path}:`, error);
+ return null;
+ }
}
export async function* pageListOf(
@@ -71,36 +73,39 @@ export async function* pageListOf(
): AsyncGenerator {
const { readdir } = await import('fs/promises');
- const list = await readdir(prefix + path, { withFileTypes: true });
-
- for (const node of list) {
- let { name, path } = node;
+ try {
+ const list = await readdir(prefix + path, { withFileTypes: true });
- if (name.startsWith('.')) continue;
+ for (const node of list) {
+ let { name, path } = node;
- const isMDX = MDX_pattern.test(name);
+ if (name.startsWith('.')) continue;
- name = name.replace(MDX_pattern, '');
- path = `${path}/${name}`.replace(new RegExp(`^${prefix}`), '');
+ const isMDX = MDX_pattern.test(name);
- if (node.isFile())
- if (isMDX) {
- const article: ArticleMeta = { name, path, subs: [] };
- try {
- const meta = await frontMatterOf(`${node.path}/${node.name}`);
+ name = name.replace(MDX_pattern, '');
+ path = `${path}/${name}`.replace(new RegExp(`^${prefix}`), '');
- if (meta) article.meta = meta;
- } catch (error) {
- console.error(error);
+ if (node.isFile()) {
+ if (isMDX) {
+ const article: ArticleMeta = { name, path, subs: [] };
+ try {
+ const meta = await frontMatterOf(`${node.path}/${node.name}`);
+ if (meta) article.meta = meta;
+ yield article;
+ } catch (error) {
+ console.error(`Error reading front matter for ${node.path}/${node.name}:`, error);
+ }
}
- yield article;
- } else continue;
-
- if (!node.isDirectory()) continue;
-
- const subs = await Array.fromAsync(pageListOf(path, prefix));
-
- if (subs[0]) yield { name, subs };
+ } else if (node.isDirectory()) {
+ const subs = await Array.fromAsync(pageListOf(path, prefix));
+ if (subs.length > 0) {
+ yield { name, subs };
+ }
+ }
+ }
+ } catch (error) {
+ console.error(`Error reading directory ${prefix + path}:`, error);
}
}
diff --git a/pages/index.tsx b/pages/index.tsx
index 4eec01e8b..9964eabbc 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,6 +1,6 @@
import { observer } from 'mobx-react';
import { compose, translator } from 'next-ssr-middleware';
-import { Button,Card, Col, Container, Row } from 'react-bootstrap';
+import { Button, Col, Container, Row } from 'react-bootstrap';
import { CommunityStats } from '../components/Home/CommunityStats';
import { LatestBlogs } from '../components/Home/LatestBlogs';
@@ -8,11 +8,92 @@ import { Sponsors } from '../components/Home/Sponsors';
import { UpcomingEvents } from '../components/Home/UpcomingEvents';
import { PageHead } from '../components/Layout/PageHead';
import { i18n, t } from '../models/Translation';
+import { ArticleMeta, pageListOf, traverseTree } from './api/core';
import styles from '../styles/Home.module.less';
-export const getServerSideProps = compose(translator(i18n));
+interface HomePageProps {
+ latestArticles: ArticleMeta[];
+ upcomingEvents: ArticleMeta[];
+ sponsors: ArticleMeta[];
+}
-const HomePage = observer(() => (
+export const getStaticProps = async () => {
+ try {
+ console.log('Starting to fetch data...');
+ const [articles, activities, partners] = await Promise.all([
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Article/Translation')),
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner'))
+ ]);
+
+ console.log('Raw articles:', articles);
+ console.log('Raw activities:', activities);
+ console.log('Raw partners:', partners);
+
+ const latestArticles = articles
+ // .map(root => {
+ // let message = [...traverseTree(root, 'subs')];
+ // console.log('123:', root);
+ // return message;
+ // })
+ .flat()
+ .filter((article): article is ArticleMeta => 'meta' in article)
+ .sort((a, b) => {
+ const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
+ const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
+ return dateB - dateA; // Sort in descending order (newest first)
+ })
+ .slice(0, 3);
+
+ console.log('Processed latestArticles:', latestArticles);
+
+ const upcomingEvents = activities
+ .map(root => {
+ let message = [...traverseTree(root, 'subs')]
+ console.log('aabbcc:', message);
+ return message;
+ })
+ .flat()
+ .filter((event): event is ArticleMeta => 'meta' in event)
+ // .filter(event => {
+ // const eventDate = event.meta?.date ? new Date(event.meta.date) : null;
+ // return eventDate && eventDate > new Date(); // Only keep future events
+ // })
+ .sort((a, b) => {
+ const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
+ const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
+ return dateB - dateA; // Sort in ascending order (nearest future first)
+ })
+ .slice(0, 3);
+
+ console.log('Processed upcomingEvents:', upcomingEvents);
+
+ const sponsors = partners
+ // .map(root => [...traverseTree(root, 'subs')])
+ .flat()
+ .filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
+ .slice(0, 3);
+
+ console.log('Processed sponsors:', sponsors);
+
+ return {
+ props: { latestArticles, upcomingEvents, sponsors },
+ revalidate: 3600 // Revalidate every hour
+ };
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ return {
+ props: {
+ latestArticles: [],
+ upcomingEvents: [],
+ sponsors: []
+ },
+ revalidate: 3600
+ };
+ }
+};
+
+const HomePage = observer(({ latestArticles, upcomingEvents, sponsors }: HomePageProps) => (
@@ -24,7 +105,7 @@ const HomePage = observer(() => (
一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
-
-
- {/* */}
-
+
-
+
-
+
));
diff --git a/styles/About.module.less b/styles/About.module.less
deleted file mode 100644
index 3a811e0c6..000000000
--- a/styles/About.module.less
+++ /dev/null
@@ -1,15 +0,0 @@
-.main {
- margin: auto;
- padding: 2rem;
- max-width: 800px;
-}
-
-.main h1,
-.main h2 {
- color: #0070f3;
- text-align: center;
-}
-
-.main p {
- line-height: 1.6;
-}
From 9a14c8765cefe61a415fdf80af04646766f85e14 Mon Sep 17 00:00:00 2001
From: dethan3
Date: Fri, 9 May 2025 00:53:38 +0800
Subject: [PATCH 3/8] refactor: convert About page to use Bootstrap utility
classes and add comprehensive community content
---
pages/about.tsx | 1 +
pages/index.tsx | 19 +++++++------------
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/pages/about.tsx b/pages/about.tsx
index b11d5e751..8eaad4728 100644
--- a/pages/about.tsx
+++ b/pages/about.tsx
@@ -21,6 +21,7 @@ const AboutPage = observer(() => (
freeCodeCamp(简称 FCC)是由美国人 Quincy Larson 发起的开源项目,截止 2018-02-03,在 Github 上获得 29+万 Star(教育类排名第一)。有长达 1600 小时的课程, 并且是基于浏览器、课程免费、证书免费、结合了游戏化闯关的乐趣。FCC 是一个在 160 多个国家和 2000 多个城市的拥有与 1000k+ 开发者的社区。
+ {/* cspell:disable-next-line */}
2016 年 4 月,由 DevEco (晋剑 + Miya)将 FCC 引入中国,并举办了 2000+ 开发者参与的在线全民编程活动,到目前为止,已成功举办了 100+ 场 Coffee & Code / 编程黑客松 / 编程静修日等活动。在 FCC China , 有 20+% 的女性加入到了社区学习、提升编程能力。
diff --git a/pages/index.tsx b/pages/index.tsx
index 9964eabbc..894f82ccb 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,5 +1,4 @@
import { observer } from 'mobx-react';
-import { compose, translator } from 'next-ssr-middleware';
import { Button, Col, Container, Row } from 'react-bootstrap';
import { CommunityStats } from '../components/Home/CommunityStats';
@@ -7,7 +6,6 @@ import { LatestBlogs } from '../components/Home/LatestBlogs';
import { Sponsors } from '../components/Home/Sponsors';
import { UpcomingEvents } from '../components/Home/UpcomingEvents';
import { PageHead } from '../components/Layout/PageHead';
-import { i18n, t } from '../models/Translation';
import { ArticleMeta, pageListOf, traverseTree } from './api/core';
import styles from '../styles/Home.module.less';
@@ -19,21 +17,17 @@ interface HomePageProps {
export const getStaticProps = async () => {
try {
- console.log('Starting to fetch data...');
+ console.info('Starting to fetch data...');
const [articles, activities, partners] = await Promise.all([
Array.fromAsync(pageListOf('/article/Wiki/_posts/Article/Translation')),
Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner'))
]);
- console.log('Raw articles:', articles);
- console.log('Raw activities:', activities);
- console.log('Raw partners:', partners);
-
const latestArticles = articles
// .map(root => {
// let message = [...traverseTree(root, 'subs')];
- // console.log('123:', root);
+ // console.info('123:', root);
// return message;
// })
.flat()
@@ -45,12 +39,13 @@ export const getStaticProps = async () => {
})
.slice(0, 3);
- console.log('Processed latestArticles:', latestArticles);
+ console.info('Processed latestArticles:', latestArticles);
const upcomingEvents = activities
.map(root => {
let message = [...traverseTree(root, 'subs')]
- console.log('aabbcc:', message);
+ /* cspell:disable-next-line */
+ console.info('aabbcc:', message);
return message;
})
.flat()
@@ -66,7 +61,7 @@ export const getStaticProps = async () => {
})
.slice(0, 3);
- console.log('Processed upcomingEvents:', upcomingEvents);
+ console.info('Processed upcomingEvents:', upcomingEvents);
const sponsors = partners
// .map(root => [...traverseTree(root, 'subs')])
@@ -74,7 +69,7 @@ export const getStaticProps = async () => {
.filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
.slice(0, 3);
- console.log('Processed sponsors:', sponsors);
+ console.info('Processed sponsors:', sponsors);
return {
props: { latestArticles, upcomingEvents, sponsors },
From 0471d093c102299b67a1b305ef42305824499027 Mon Sep 17 00:00:00 2001
From: dethan3
Date: Thu, 15 May 2025 23:12:41 +0800
Subject: [PATCH 4/8] feat: Improve website design and layout
---
components/Home/CommunityStats.tsx | 52 ++++---
components/Home/LatestBlogs.tsx | 62 ++++----
components/Home/Sponsors.tsx | 54 ++++---
components/Home/UpcomingEvents.tsx | 66 ++++----
components/Navigator/MainNavigator.tsx | 7 +-
pages/_app.tsx | 37 +++--
pages/about.tsx | 71 +++++++--
pages/api/core.ts | 19 ++-
pages/index.tsx | 182 +++++++++++++++-------
styles/Home.module.less | 62 --------
styles/globals.less | 205 ++++++++++++++++++++++++-
11 files changed, 553 insertions(+), 264 deletions(-)
delete mode 100644 styles/Home.module.less
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
index 8bef15924..56aae799b 100644
--- a/components/Home/CommunityStats.tsx
+++ b/components/Home/CommunityStats.tsx
@@ -1,26 +1,32 @@
-import { Card,Col, Container, Row } from 'react-bootstrap';
+import { Card, Col, Container, Row } from 'react-bootstrap';
export const CommunityStats = () => (
-
-
- 社区数据
-
-
- {[
- { number: '1000+', label: '社区成员' },
- { number: '50+', label: '举办活动' },
- { number: '200+', label: '技术文章' },
- { number: '30+', label: '开源项目' },
- ].map(({ number, label }) => (
-
-
-
- {number}
- {label}
-
-
-
- ))}
-
-
+
+
+ 社区数据
+
+
+ {[
+ { number: '1000+', label: '社区成员' },
+ { number: '50+', label: '举办活动' },
+ { number: '200+', label: '技术文章' },
+ { number: '30+', label: '开源项目' },
+ ].map(({ number, label }) => (
+
+
+
+ {number}
+ {label}
+
+
+
+ ))}
+
+
+
);
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
index 30e092bcb..648345231 100644
--- a/components/Home/LatestBlogs.tsx
+++ b/components/Home/LatestBlogs.tsx
@@ -1,36 +1,46 @@
import Link from 'next/link';
+import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+
import { ArticleMeta } from '../../pages/api/core';
interface LatestBlogsProps {
articles: ArticleMeta[];
}
-export const LatestBlogs: React.FC = ({ articles }) => (
-
- 最新博客文章
-
- {articles.map((article) => (
-
-
-
- {article.name}
-
- 发布日期: {article.meta?.date || '未知日期'}
-
-
- 阅读文章
-
-
-
-
- ))}
-
+export const LatestBlogs: FC = ({ articles }) => (
+
+
+ 最新博客文章
+
+
+ {articles.map(({ name, meta, path }) => (
+
+
+
+ {name}
+
+ 发布日期: {meta?.date || '未知日期'}
+
+
+ 阅读文章
+
+
+
+
+ ))}
+
-
-
- 查看全部文章 →
-
-
-
+
+
+ 查看全部文章 →
+
+
+
+
);
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
index 5754f9401..a64719e89 100644
--- a/components/Home/Sponsors.tsx
+++ b/components/Home/Sponsors.tsx
@@ -1,30 +1,42 @@
+import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+
import { ArticleMeta } from '../../pages/api/core';
interface SponsorsProps {
sponsors: ArticleMeta[];
}
-export const Sponsors: React.FC = ({ sponsors }) => (
-
- 赞助商与合作伙伴
-
- {sponsors.map((sponsor) => (
-
-
-
- {sponsor.name}
- {sponsor.meta?.description || '暂无描述'}
-
-
-
- ))}
-
+export const Sponsors: FC = ({ sponsors }) => (
+
+
+ 赞助商与合作伙伴
+
+
+ {sponsors.map(({ name, meta }) => (
+
+
+
+ {name}
+
+ {meta?.description || '暂无描述'}
+
+
+
+
+ ))}
+
-
-
- 成为赞助商 →
-
-
-
+
+
+ 成为赞助商 →
+
+
+
+
);
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
index e8b48f76a..d93e4aa5d 100644
--- a/components/Home/UpcomingEvents.tsx
+++ b/components/Home/UpcomingEvents.tsx
@@ -1,36 +1,50 @@
import Link from 'next/link';
+import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
+
import { ArticleMeta } from '../../pages/api/core';
interface UpcomingEventsProps {
events: ArticleMeta[];
}
-export const UpcomingEvents: React.FC = ({ events }) => (
-
- 往期活动
-
- {events.map((event) => (
-
-
-
- {event.meta?.title}
- 时间: {event.meta?.start || 'void 0'}
- 地点: {event.meta?.address || 'void 0'}
- {/* TODO: 无 Path 不渲染 */}
-
- 查看详情
-
-
-
-
- ))}
-
+export const UpcomingEvents: FC = ({ events }) => (
+
+
+ 近期活动
+
+
+ {events.map(({ name, meta, path }) => (
+
+
+
+ {name}
+
+ 时间: {meta?.start || 'void 0'}
+
+
+ 地点: {meta?.address || 'void 0'}
+
+
+
+ 查看详情
+
+
+
+
+ ))}
+
-
-
- 查看全部活动 →
-
-
-
+
+
+ 查看全部活动 →
+
+
+
+
);
diff --git a/components/Navigator/MainNavigator.tsx b/components/Navigator/MainNavigator.tsx
index 02ca0bb51..412b30e6a 100644
--- a/components/Navigator/MainNavigator.tsx
+++ b/components/Navigator/MainNavigator.tsx
@@ -10,7 +10,7 @@ const LanguageMenu = dynamic(import('./LanguageMenu'), { ssr: false });
const Name = process.env.NEXT_PUBLIC_SITE_NAME || '';
export const MainNavigator: FC = observer(() => (
-
+
{Name}
@@ -26,7 +26,10 @@ export const MainNavigator: FC = observer(() => (
{t('about')}
-
+
{t('source_code')}
diff --git a/pages/_app.tsx b/pages/_app.tsx
index bbb3d891c..02684c359 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -6,7 +6,7 @@ import { enableStaticRendering, observer } from 'mobx-react';
import type { AppProps } from 'next/app';
import Head from 'next/head';
import { FC } from 'react';
-import { Image } from 'react-bootstrap';
+import { Container, Image } from 'react-bootstrap';
import { MDXLayout } from '../components/Layout/MDXLayout';
import { MainNavigator } from '../components/Navigator/MainNavigator';
@@ -39,23 +39,32 @@ const AppShell: FC = observer(({ Component, pageProps, router }) => (
) : (
-
+
)}
-
-
四川财富广播 FM94.0 采访
-
FCC 成都社区:“人人皆可编程”,以独特的方式为城市带来美好改变
+
+ 四川财富广播 FM94.0 采访
+
+
+ FCC 成都社区:“人人皆可编程”,以独特的方式为城市带来美好改变
+
@@ -148,7 +183,9 @@ const AboutPage = observer(() => (
四川日报报道
-
揭秘“黑客马拉松”:喝 6 瓶红牛、24 小时里只睡 2 小时
+
+ 揭秘“黑客马拉松”:喝 6 瓶红牛、24 小时里只睡 2 小时
+
diff --git a/pages/api/core.ts b/pages/api/core.ts
index 16ae8a067..4509bb570 100644
--- a/pages/api/core.ts
+++ b/pages/api/core.ts
@@ -56,15 +56,11 @@ export interface ArticleMeta {
const MDX_pattern = /\.mdx?$/;
export async function frontMatterOf(path: string) {
- try {
- const { readFile } = await import('fs/promises');
- const file = await readFile(path, 'utf-8');
- const [, frontMatter] = file.match(/^---[\r\n]([\s\S]+?[\r\n])---/) || [];
- return frontMatter ? parse(frontMatter) : null;
- } catch (error) {
- console.error(`Error reading front matter from ${path}:`, error);
- return null;
- }
+ const { readFile } = await import('fs/promises');
+ const file = await readFile(path, 'utf-8');
+ const [, frontMatter] = file.match(/^---[\r\n]([\s\S]+?[\r\n])---/) || [];
+
+ return frontMatter ? parse(frontMatter) : null;
}
export async function* pageListOf(
@@ -94,7 +90,10 @@ export async function* pageListOf(
if (meta) article.meta = meta;
yield article;
} catch (error) {
- console.error(`Error reading front matter for ${node.path}/${node.name}:`, error);
+ console.error(
+ `Error reading front matter for ${node.path}/${node.name}:`,
+ error,
+ );
}
}
} else if (node.isDirectory()) {
diff --git a/pages/index.tsx b/pages/index.tsx
index 894f82ccb..ea429fc3d 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -7,117 +7,187 @@ import { Sponsors } from '../components/Home/Sponsors';
import { UpcomingEvents } from '../components/Home/UpcomingEvents';
import { PageHead } from '../components/Layout/PageHead';
import { ArticleMeta, pageListOf, traverseTree } from './api/core';
-import styles from '../styles/Home.module.less';
interface HomePageProps {
latestArticles: ArticleMeta[];
upcomingEvents: ArticleMeta[];
sponsors: ArticleMeta[];
+ error?: {
+ message: string;
+ stack?: string;
+ };
}
export const getStaticProps = async () => {
try {
console.info('Starting to fetch data...');
const [articles, activities, partners] = await Promise.all([
- Array.fromAsync(pageListOf('/article/Wiki/_posts/Article/Translation')),
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Article')),
Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
- Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner'))
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner')),
]);
const latestArticles = articles
- // .map(root => {
- // let message = [...traverseTree(root, 'subs')];
- // console.info('123:', root);
- // return message;
- // })
+ .map(root => {
+ const message = [...traverseTree(root, 'subs')];
+ console.info('123:', root);
+
+ return message;
+ })
.flat()
.filter((article): article is ArticleMeta => 'meta' in article)
.sort((a, b) => {
const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
- return dateB - dateA; // Sort in descending order (newest first)
+
+ return dateB - dateA;
})
.slice(0, 3);
-
+
console.info('Processed latestArticles:', latestArticles);
const upcomingEvents = activities
- .map(root => {
- let message = [...traverseTree(root, 'subs')]
- /* cspell:disable-next-line */
- console.info('aabbcc:', message);
- return message;
- })
+ .map(root => [...traverseTree(root, 'subs')])
.flat()
.filter((event): event is ArticleMeta => 'meta' in event)
- // .filter(event => {
- // const eventDate = event.meta?.date ? new Date(event.meta.date) : null;
- // return eventDate && eventDate > new Date(); // Only keep future events
- // })
.sort((a, b) => {
const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
- return dateB - dateA; // Sort in ascending order (nearest future first)
+
+ return dateB - dateA;
})
.slice(0, 3);
console.info('Processed upcomingEvents:', upcomingEvents);
const sponsors = partners
- // .map(root => [...traverseTree(root, 'subs')])
.flat()
.filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
.slice(0, 3);
console.info('Processed sponsors:', sponsors);
- return {
+ return {
props: { latestArticles, upcomingEvents, sponsors },
- revalidate: 3600 // Revalidate every hour
+ revalidate: 3600,
};
} catch (error) {
console.error('Error fetching data:', error);
+
return {
props: {
latestArticles: [],
upcomingEvents: [],
- sponsors: []
+ sponsors: [],
+ error: {
+ message: error instanceof Error ? error.message : String(error),
+ stack: error instanceof Error ? error.stack : undefined,
+ },
},
- revalidate: 3600
+ revalidate: 3600,
};
}
};
-const HomePage = observer(({ latestArticles, upcomingEvents, sponsors }: HomePageProps) => (
-
-
-
-
-
- freeCodeCamp 成都社区
-
-
- 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
-
-
-
- 加入社区
-
-
- 查看活动
-
+const HomePage = observer(
+ ({ latestArticles, upcomingEvents, sponsors, error }: HomePageProps) => (
+
+
+
+ {error ? (
+
+
+
+
+
+
加载数据时发生错误
+
{error.message}
+ {process.env.NODE_ENV !== 'production' && error.stack && (
+
{error.stack}
+ )}
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-));
+ ) : (
+ <>
+
+
+
+
+
+ freeCodeCamp 成都社区
+
+
+ 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
+
+
+
+ 加入社区
+
+
+ 查看活动
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+ ),
+);
export default HomePage;
diff --git a/styles/Home.module.less b/styles/Home.module.less
deleted file mode 100644
index 43e89d03f..000000000
--- a/styles/Home.module.less
+++ /dev/null
@@ -1,62 +0,0 @@
-.main {
- padding: 4rem 0;
- min-height: 100vh;
-}
-
-.imagePlaceholder {
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
- border-radius: 16px;
- background: #f0f0f0;
- width: 80%;
- max-width: 400px;
- height: 300px;
-}
-
-.title {
- font-size: 4rem;
- line-height: 1.15;
- a {
- &:hover,
- &:focus,
- &:active {
- text-decoration: underline;
- }
- }
-}
-.description {
- margin: 4rem 0;
- line-height: 1.5;
-}
-
-.code {
- padding: 0.75rem;
- font-size: 1.1rem;
- font-family:
- Menlo,
- Monaco,
- Lucida Console,
- Liberation Mono,
- DejaVu Sans Mono,
- Bitstream Vera Sans Mono,
- Courier New,
- monospace;
-}
-
-.card {
- transition:
- color 0.15s ease,
- border-color 0.15s ease;
- color: inherit;
- &:hover,
- &:focus,
- &:active {
- border-color: #0070f3;
- color: #0070f3;
- }
- p {
- line-height: 1.5;
- }
-}
diff --git a/styles/globals.less b/styles/globals.less
index 123889418..e1f7ba6fd 100644
--- a/styles/globals.less
+++ b/styles/globals.less
@@ -1,11 +1,15 @@
+:root {
+ --fcc-primary: #0a0a23;
+ --fcc-secondary: #1b1b32;
+ --fcc-accent: #f1be32;
+ --fcc-light: #f5f6f7;
+}
+
html,
body {
margin: 0;
- background-image: linear-gradient(
- 150deg,
- #028dfa 60%,
- #0ee6e6 100%
- ) !important;
+ background: linear-gradient(135deg, #028dfa 0%, #ffffff 50%, #0ee6e6 100%);
+ background-attachment: fixed;
padding: 0;
font-family:
-apple-system,
@@ -21,6 +25,12 @@ body {
sans-serif;
}
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
a {
color: inherit;
text-decoration: none;
@@ -30,6 +40,106 @@ a {
box-sizing: border-box;
}
+main {
+ flex: 1;
+}
+
+.hero-section {
+ display: flex;
+ align-items: center;
+ margin: 0;
+ background: linear-gradient(135deg, #028dfa 0%, #ffffff 50%, #0ee6e6 100%);
+ padding: 5rem 0;
+ width: 100%;
+ min-height: 80vh;
+ color: var(--fcc-primary);
+}
+
+.section-wrapper {
+ margin: 0;
+ padding: 3rem 0;
+ width: 100%;
+}
+
+.section-wrapper-white {
+ background-color: white;
+}
+
+.section-wrapper-gray {
+ background-color: rgb(248, 249, 250);
+}
+
+.hero-dark-text {
+ color: var(--fcc-primary);
+}
+
+.accent-text {
+ color: #0a0a23;
+ font-weight: bold;
+}
+
+.btn-primary {
+ border-color: #028dfa;
+ background-color: #028dfa;
+ color: white;
+ font-weight: 600;
+}
+
+.btn-primary:hover {
+ border-color: #0275d8;
+ background-color: #0275d8;
+ color: white;
+}
+
+.btn-outline-primary {
+ border-color: #028dfa;
+ color: #028dfa;
+}
+
+.btn-outline-primary:hover {
+ background-color: #028dfa;
+ color: white;
+}
+
+.card {
+ transition:
+ transform 0.3s ease,
+ box-shadow 0.3s ease;
+}
+
+.card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
+}
+
+.section-heading {
+ position: relative;
+ margin-bottom: 30px;
+ padding-bottom: 15px;
+}
+
+.section-heading::after {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ background-color: var(--fcc-accent);
+ width: 50px;
+ height: 3px;
+ content: '';
+}
+
+.section-heading.text-center::after {
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+/* Responsive adjustments for navbar buttons */
+@media (max-width: 991.98px) {
+ .navbar .btn {
+ margin-top: 0.5rem;
+ }
+}
+
[contenteditable='true'],
article {
img {
@@ -49,6 +159,87 @@ div:has(.next-error-h1) {
}
:root {
- --bs-primary: #000000;
- --bs-primary-rgb: 2, 141, 250;
+ --bs-primary: var(--fcc-accent);
+ --bs-primary-rgb: 241, 190, 50;
+}
+
+/* Custom navbar styling */
+.navbar.bg-light {
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ background-color: white !important;
+ padding-top: 0.425rem !important;
+ padding-bottom: 0.425rem !important;
+ min-height: auto !important;
+}
+
+.navbar .nav-link {
+ position: relative;
+ transition: color 0.3s ease;
+ padding-top: 0.375rem !important;
+ padding-bottom: 0.375rem !important;
+ color: #000000 !important;
+ font-weight: 500;
+ font-size: 0.9rem;
+}
+
+.navbar .nav-link:hover {
+ color: #028dfa !important;
+}
+
+.navbar .nav-link::after {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ transition: all 0.3s ease;
+ background-color: #028dfa;
+ width: 0;
+ height: 2px;
+ content: '';
+}
+
+.navbar .nav-link:hover::after {
+ width: 80%;
+}
+
+.navbar .nav-link.active {
+ color: #028dfa !important;
+}
+
+.navbar .nav-link.active::after {
+ width: 80%;
+}
+
+.navbar .navbar-brand {
+ padding-top: 0.375rem !important;
+ padding-bottom: 0.375rem !important;
+ color: #000000 !important;
+ font-weight: 600;
+ font-size: 1.1rem;
+}
+
+/* Language menu styling */
+.dropdown-toggle.btn {
+ border-color: #dee2e6 !important;
+ padding: 0.25rem 0.5rem !important;
+ min-width: 100px;
+ color: #000000 !important;
+ font-size: 0.9rem !important;
+}
+
+.dropdown-menu {
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
+ border-radius: 0.25rem;
+ background-color: white !important;
+ min-width: 100px;
+}
+
+.dropdown-menu .dropdown-item {
+ padding: 0.5rem 1rem;
+ color: #000000 !important;
+ font-size: 0.9rem;
+}
+
+.dropdown-menu .dropdown-item:hover {
+ background-color: #f8f9fa;
}
From ae7c62592a663f51e274ae66fb2e281d36ca4dd9 Mon Sep 17 00:00:00 2001
From: dethan3
Date: Thu, 5 Jun 2025 02:48:49 +0000
Subject: [PATCH 5/8] refactor: optimize code
---
components/Home/CommunityStats.tsx | 15 +-
components/Home/LatestBlogs.tsx | 16 +-
components/Home/SectionTitle.tsx | 14 ++
components/Home/Sponsors.tsx | 11 +-
components/Home/UpcomingEvents.tsx | 11 +-
pages/_app.tsx | 35 ++--
pages/about.tsx | 201 +---------------------
pages/community.tsx | 0
pages/index.tsx | 256 ++++++++++++-----------------
styles/Home.module.less | 10 ++
styles/globals.less | 255 ++++++++++++++--------------
11 files changed, 282 insertions(+), 542 deletions(-)
create mode 100644 components/Home/SectionTitle.tsx
delete mode 100644 pages/community.tsx
create mode 100644 styles/Home.module.less
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
index 56aae799b..df94e8020 100644
--- a/components/Home/CommunityStats.tsx
+++ b/components/Home/CommunityStats.tsx
@@ -1,15 +1,10 @@
import { Card, Col, Container, Row } from 'react-bootstrap';
+import { SectionTitle } from './SectionTitle';
export const CommunityStats = () => (
-
+
- 社区数据
-
+
{[
{ number: '1000+', label: '社区成员' },
@@ -20,8 +15,8 @@ export const CommunityStats = () => (
- {number}
- {label}
+ {number}
+ {label}
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
index 648345231..a3a7b5491 100644
--- a/components/Home/LatestBlogs.tsx
+++ b/components/Home/LatestBlogs.tsx
@@ -1,23 +1,17 @@
-import Link from 'next/link';
import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
import { ArticleMeta } from '../../pages/api/core';
+import { SectionTitle } from './SectionTitle';
interface LatestBlogsProps {
articles: ArticleMeta[];
}
export const LatestBlogs: FC = ({ articles }) => (
-
+
- 最新博客文章
-
+
{articles.map(({ name, meta, path }) => (
@@ -27,9 +21,9 @@ export const LatestBlogs: FC = ({ articles }) => (
发布日期: {meta?.date || '未知日期'}
-
+
阅读文章
-
+
diff --git a/components/Home/SectionTitle.tsx b/components/Home/SectionTitle.tsx
new file mode 100644
index 000000000..4fa31a853
--- /dev/null
+++ b/components/Home/SectionTitle.tsx
@@ -0,0 +1,14 @@
+import React, { FC } from 'react';
+
+interface SectionTitleProps {
+ title: string;
+}
+
+export const SectionTitle: FC = ({ title }) => (
+ <>
+ {title}
+
+ >
+);
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
index a64719e89..f2622769d 100644
--- a/components/Home/Sponsors.tsx
+++ b/components/Home/Sponsors.tsx
@@ -2,21 +2,16 @@ import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
import { ArticleMeta } from '../../pages/api/core';
+import { SectionTitle } from './SectionTitle';
interface SponsorsProps {
sponsors: ArticleMeta[];
}
export const Sponsors: FC = ({ sponsors }) => (
-
+
- 赞助商与合作伙伴
-
+
{sponsors.map(({ name, meta }) => (
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
index d93e4aa5d..b62373b2d 100644
--- a/components/Home/UpcomingEvents.tsx
+++ b/components/Home/UpcomingEvents.tsx
@@ -3,21 +3,16 @@ import { FC } from 'react';
import { Button, Card, Col, Container, Row } from 'react-bootstrap';
import { ArticleMeta } from '../../pages/api/core';
+import { SectionTitle } from './SectionTitle';
interface UpcomingEventsProps {
events: ArticleMeta[];
}
export const UpcomingEvents: FC = ({ events }) => (
-
+
- 近期活动
-
+
{events.map(({ name, meta, path }) => (
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 02684c359..b78b035e8 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -39,31 +39,22 @@ const AppShell: FC = observer(({ Component, pageProps, router }) => (
) : (
-
-
-
+
)}
>
diff --git a/pages/about.tsx b/pages/about.tsx
index 6a4036a23..7c9afca5c 100644
--- a/pages/about.tsx
+++ b/pages/about.tsx
@@ -1,197 +1,12 @@
-import { observer } from 'mobx-react';
-import { compose, translator } from 'next-ssr-middleware';
-import { Container, Table } from 'react-bootstrap';
+import { GetServerSideProps } from 'next';
-import { PageHead } from '../components/Layout/PageHead';
-import { i18n, t } from '../models/Translation';
+export const getServerSideProps: GetServerSideProps = async () => ({
+ redirect: {
+ destination: '/article/Wiki/_posts/Profile/about',
+ permanent: false,
+ },
+ });
-export const getServerSideProps = compose(translator(i18n));
-
-const AboutPage = observer(() => (
-
-
-
- {t('about_us')}
-
- fCC 成都社区, 成立于 2016 年 6
- 月,是一个非营利性的公益性技术社区,是由一群热血有志青年爱好者,利用个人业余休息时间组建而成的技术社区,目的是为了搭建一个友好的交流、学习、互助的社区,帮助成都市众多的开发者,技术爱好者提升个人技术能力。社区致力于做西南地区首个有温度与情怀的技术社区,鼓励人人皆可编程实现个人梦想。
-
-
-
- 什么是 FCC
-
- freeCodeCamp(简称 FCC)是由美国人 Quincy Larson 发起的开源项目,截止
- 2018-02-03,在 Github 上获得 29+万 Star(教育类排名第一)。有长达 1600
- 小时的课程,
- 并且是基于浏览器、课程免费、证书免费、结合了游戏化闯关的乐趣。FCC
- 是一个在 160 多个国家和 2000 多个城市的拥有与 1000k+ 开发者的社区。
-
-
- {/* cspell:disable-next-line */}
- 2016 年 4 月,由 DevEco (晋剑 + Miya)将 FCC 引入中国,并举办了 2000+
- 开发者参与的在线全民编程活动,到目前为止,已成功举办了 100+ 场 Coffee &
- Code / 编程黑客松 / 编程静修日等活动。在 FCC China , 有 20+%
- 的女性加入到了社区学习、提升编程能力。
-
-
-
-
- {t('our_mission')}
- 让更多人享受编程的乐趣,并改变自己的生活。
-
-
-
- FCC 成都社区活动
- 大型活动
-
- - FCC 成都社区 React 技术专场交流活动
- - 2017 成都首届 Web 前端交流大会
- - 新耀杯 Code for City 黑客松大赛
-
-
- 历史活动
-
-
-
-
- | 序号 |
- 日期 |
- 主题 |
- 形式 |
-
-
-
-
- | 1 |
- 20160609 |
- 线下活动开启,宣布社区成立 |
- 编程讨论 |
-
-
- | 2 |
- 20160703 |
- 携手编程-成都社区主页初版 |
- 动手编程 |
-
-
- | 3 |
- 20160911 |
- 结对编程的理念 |
- 个人分享 + 结对编程 |
-
-
- | 4 |
- 20161106 |
- Console 的九大命令 + 学习路线分享 |
- 个人分享 |
-
-
- | 5 |
- 20161119 |
- Git 的使用与个人简历制作 |
- 分享 + 编程 |
-
-
-
-
-
- 显示部分历史活动,完整列表请参考原文档
-
-
-
-
- 为什么是 FCC 成都社区
-
- 在成都众多的技术大会、技术分享活动当中,很多的活动以技术分享为幌子,做着产品推广与宣传的事情,这导致了成都
- IT 圈子技术分享的氛围越来越差,大家参与分享的热情越来越低。
-
-
- FCC
- 成都社区的众多小伙伴,一致认为是时候为这座热爱的城市做一份自己的贡献了,社区提出所有活动全部免费参加、嘉宾分享内容中广告零容忍,成立嘉宾分享内容审查团队,确保每一次分享都是
- 100% 的干货。
-
-
- FCC 成都社区的小伙伴们一直明白社区所肩负的使命,带动成都 IT
- 圈子技术交流的氛围,让更多的技术牛人帮助到更多的开发者,让成都成为全国
- IT 行业的先锋,让成都吸引更多 IT
- 人才蓉漂。进入更多的校园普及更多的次的编程知识,倡导人人皆可编程,让成都这座城市未来充满无限可能。
-
-
-
-
- FCC 成都社区规划
-
- - 走进更多校园,普及人人皆可编程思想帮助更多的孩子们。
- -
- 继续坚持做好两周一次的【Coffee and
- Code】的结对编程活动、编程道场活动,一对一指导开发者提升个人技术能力。
-
- -
- 做好季度技术专场活动,让成都众多 IT 公司加入其中进行分享,带动成都 IT
- 圈子技术分享的热情。
-
- -
- 做好成都 Web
- 前端交流大会,让国内一线技术大咖来到成都,给成都众多开发者带来国内一线开发公司的技术心得与经验。
-
- -
- 联合成都众多大型 IT
- 公司,做好编程马拉松活动,让成都的众多开发者进行技术火花的碰撞。
-
-
-
-
-
- {t('our_team')}
- 。。。
-
-
-
- 媒体报道
-
-
-
-
-
-
成都市高新电视台报道
-
- 2017 成都 Web 前端交流大会 (6 分 53 秒处)
-
-
-
-
-
-
-
-
- 四川财富广播 FM94.0 采访
-
-
- FCC 成都社区:“人人皆可编程”,以独特的方式为城市带来美好改变
-
-
-
-
-
-
-
-
四川日报报道
-
- 揭秘“黑客马拉松”:喝 6 瓶红牛、24 小时里只睡 2 小时
-
-
-
-
-
-
-
-));
+const AboutPage = () => null;
export default AboutPage;
diff --git a/pages/community.tsx b/pages/community.tsx
deleted file mode 100644
index e69de29bb..000000000
diff --git a/pages/index.tsx b/pages/index.tsx
index ea429fc3d..d1bb4769f 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,11 +1,13 @@
import { observer } from 'mobx-react';
import { Button, Col, Container, Row } from 'react-bootstrap';
+import Image from 'react-bootstrap/Image';
import { CommunityStats } from '../components/Home/CommunityStats';
import { LatestBlogs } from '../components/Home/LatestBlogs';
import { Sponsors } from '../components/Home/Sponsors';
import { UpcomingEvents } from '../components/Home/UpcomingEvents';
import { PageHead } from '../components/Layout/PageHead';
+import styles from '../styles/Home.module.less';
import { ArticleMeta, pageListOf, traverseTree } from './api/core';
interface HomePageProps {
@@ -19,173 +21,117 @@ interface HomePageProps {
}
export const getStaticProps = async () => {
- try {
- console.info('Starting to fetch data...');
- const [articles, activities, partners] = await Promise.all([
- Array.fromAsync(pageListOf('/article/Wiki/_posts/Article')),
- Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
- Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner')),
- ]);
-
- const latestArticles = articles
- .map(root => {
- const message = [...traverseTree(root, 'subs')];
- console.info('123:', root);
-
- return message;
- })
- .flat()
- .filter((article): article is ArticleMeta => 'meta' in article)
- .sort((a, b) => {
- const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
- const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
-
- return dateB - dateA;
- })
- .slice(0, 3);
-
- console.info('Processed latestArticles:', latestArticles);
-
- const upcomingEvents = activities
- .map(root => [...traverseTree(root, 'subs')])
- .flat()
- .filter((event): event is ArticleMeta => 'meta' in event)
- .sort((a, b) => {
- const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
- const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
-
- return dateB - dateA;
- })
- .slice(0, 3);
-
- console.info('Processed upcomingEvents:', upcomingEvents);
-
- const sponsors = partners
- .flat()
- .filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
- .slice(0, 3);
-
- console.info('Processed sponsors:', sponsors);
-
- return {
- props: { latestArticles, upcomingEvents, sponsors },
- revalidate: 3600,
- };
- } catch (error) {
- console.error('Error fetching data:', error);
-
- return {
- props: {
- latestArticles: [],
- upcomingEvents: [],
- sponsors: [],
- error: {
- message: error instanceof Error ? error.message : String(error),
- stack: error instanceof Error ? error.stack : undefined,
- },
- },
- revalidate: 3600,
- };
- }
+ console.info('Starting to fetch data...');
+ const [articles, activities, partners] = await Promise.all([
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Article')),
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
+ Array.fromAsync(pageListOf('/article/Wiki/_posts/Partner')),
+ ]);
+
+ const latestArticles = articles
+ .map(root => {
+ const message = [...traverseTree(root, 'subs')];
+ console.info('123:', root);
+
+ return message;
+ })
+ .flat()
+ .filter((article): article is ArticleMeta => 'meta' in article)
+ .sort((a, b) => {
+ const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
+ const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
+
+ return dateB - dateA;
+ })
+ .slice(0, 3);
+
+ console.info('Processed latestArticles:', latestArticles);
+
+ const upcomingEvents = activities
+ .map(root => [...traverseTree(root, 'subs')])
+ .flat()
+ .filter((event): event is ArticleMeta => 'meta' in event)
+ .sort((a, b) => {
+ const dateA = a.meta?.date ? new Date(a.meta.date).getTime() : 0;
+ const dateB = b.meta?.date ? new Date(b.meta.date).getTime() : 0;
+
+ return dateB - dateA;
+ })
+ .slice(0, 3);
+
+ console.info('Processed upcomingEvents:', upcomingEvents);
+
+ const sponsors = partners
+ .flat()
+ .filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
+ .slice(0, 6);
+
+ console.info('Processed sponsors:', sponsors);
+
+ return {
+ props: { latestArticles, upcomingEvents, sponsors },
+ revalidate: 3600,
+ };
};
const HomePage = observer(
({ latestArticles, upcomingEvents, sponsors, error }: HomePageProps) => (
-
- {error ? (
-
+ <>
+
-
-
-
-
加载数据时发生错误
-
{error.message}
- {process.env.NODE_ENV !== 'production' && error.stack && (
-
{error.stack}
- )}
+
+
+
+ freeCodeCamp 成都社区
+
+
+ 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
+
+
+
+ 加入社区
+
+
+ 查看活动
+
+
+
+
+
+
- ) : (
- <>
-
-
-
-
-
- freeCodeCamp 成都社区
-
-
- 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
-
-
-
- 加入社区
-
-
- 查看活动
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- )}
+
+
+
+
+
+
+
+ >
),
);
diff --git a/styles/Home.module.less b/styles/Home.module.less
new file mode 100644
index 000000000..f80ade69f
--- /dev/null
+++ b/styles/Home.module.less
@@ -0,0 +1,10 @@
+.hero {
+ display: flex;
+ align-items: center;
+ margin: 0;
+ background: linear-gradient(135deg, #028dfa 0%, #ffffff 50%, #0ee6e6 100%);
+ padding: 5rem 0;
+ width: 100%;
+ min-height: 80vh;
+ color: var(--fcc-primary);
+}
diff --git a/styles/globals.less b/styles/globals.less
index e1f7ba6fd..66a3e2046 100644
--- a/styles/globals.less
+++ b/styles/globals.less
@@ -3,6 +3,9 @@
--fcc-secondary: #1b1b32;
--fcc-accent: #f1be32;
--fcc-light: #f5f6f7;
+
+ --bs-primary: var(--fcc-accent);
+ --bs-primary-rgb: 241, 190, 50;
}
html,
@@ -40,33 +43,13 @@ a {
box-sizing: border-box;
}
-main {
- flex: 1;
-}
-
-.hero-section {
- display: flex;
- align-items: center;
- margin: 0;
- background: linear-gradient(135deg, #028dfa 0%, #ffffff 50%, #0ee6e6 100%);
- padding: 5rem 0;
- width: 100%;
- min-height: 80vh;
+.hero-dark-text {
color: var(--fcc-primary);
}
-.section-wrapper {
- margin: 0;
- padding: 3rem 0;
- width: 100%;
-}
-
-.section-wrapper-white {
- background-color: white;
-}
-
-.section-wrapper-gray {
- background-color: rgb(248, 249, 250);
+.accent-text {
+ color: #0a0a23;
+ font-weight: bold;
}
.hero-dark-text {
@@ -78,59 +61,29 @@ main {
font-weight: bold;
}
-.btn-primary {
- border-color: #028dfa;
- background-color: #028dfa;
- color: white;
- font-weight: 600;
-}
-
-.btn-primary:hover {
- border-color: #0275d8;
- background-color: #0275d8;
- color: white;
-}
-
-.btn-outline-primary {
- border-color: #028dfa;
- color: #028dfa;
-}
+.btn {
+ &-primary {
+ border-color: #028dfa;
+ background-color: #028dfa;
+ color: white;
+ font-weight: 600;
-.btn-outline-primary:hover {
- background-color: #028dfa;
- color: white;
-}
-
-.card {
- transition:
- transform 0.3s ease,
- box-shadow 0.3s ease;
-}
-
-.card:hover {
- transform: translateY(-5px);
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
-}
-
-.section-heading {
- position: relative;
- margin-bottom: 30px;
- padding-bottom: 15px;
-}
+ &:hover {
+ border-color: #0275d8;
+ background-color: #0275d8;
+ color: white;
+ }
+ }
-.section-heading::after {
- position: absolute;
- bottom: 0;
- left: 0;
- background-color: var(--fcc-accent);
- width: 50px;
- height: 3px;
- content: '';
-}
+ &-outline-primary {
+ border-color: #028dfa;
+ color: #028dfa;
-.section-heading.text-center::after {
- left: 50%;
- transform: translateX(-50%);
+ &:hover {
+ background-color: #028dfa;
+ color: white;
+ }
+ }
}
/* Responsive adjustments for navbar buttons */
@@ -158,64 +111,61 @@ div:has(.next-error-h1) {
}
}
-:root {
- --bs-primary: var(--fcc-accent);
- --bs-primary-rgb: 241, 190, 50;
-}
-
/* Custom navbar styling */
-.navbar.bg-light {
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- background-color: white !important;
- padding-top: 0.425rem !important;
- padding-bottom: 0.425rem !important;
- min-height: auto !important;
-}
-
-.navbar .nav-link {
- position: relative;
- transition: color 0.3s ease;
- padding-top: 0.375rem !important;
- padding-bottom: 0.375rem !important;
- color: #000000 !important;
- font-weight: 500;
- font-size: 0.9rem;
-}
-
-.navbar .nav-link:hover {
- color: #028dfa !important;
-}
-
-.navbar .nav-link::after {
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- transition: all 0.3s ease;
- background-color: #028dfa;
- width: 0;
- height: 2px;
- content: '';
-}
-
-.navbar .nav-link:hover::after {
- width: 80%;
-}
-
-.navbar .nav-link.active {
- color: #028dfa !important;
-}
+.navbar {
+ &.bg-light {
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ background-color: white !important;
+ padding-top: 0.425rem !important;
+ padding-bottom: 0.425rem !important;
+ min-height: auto !important;
+ }
-.navbar .nav-link.active::after {
- width: 80%;
-}
+ .nav-link {
+ position: relative;
+ transition: color 0.3s ease;
+ padding-top: 0.375rem !important;
+ padding-bottom: 0.375rem !important;
+ color: #000000 !important;
+ font-weight: 500;
+ font-size: 0.9rem;
+
+ &:hover {
+ color: #028dfa !important;
+
+ &::after {
+ width: 80%;
+ }
+ }
+
+ &::after {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ transition: all 0.3s ease;
+ background-color: #028dfa;
+ width: 0;
+ height: 2px;
+ content: '';
+ }
+
+ &.active {
+ color: #028dfa !important;
+
+ &::after {
+ width: 80%;
+ }
+ }
+ }
-.navbar .navbar-brand {
- padding-top: 0.375rem !important;
- padding-bottom: 0.375rem !important;
- color: #000000 !important;
- font-weight: 600;
- font-size: 1.1rem;
+ .navbar-brand {
+ padding-top: 0.375rem !important;
+ padding-bottom: 0.375rem !important;
+ color: #000000 !important;
+ font-weight: 600;
+ font-size: 1.1rem;
+ }
}
/* Language menu styling */
@@ -232,14 +182,49 @@ div:has(.next-error-h1) {
border-radius: 0.25rem;
background-color: white !important;
min-width: 100px;
+ .dropdown-item {
+ padding: 0.5rem 1rem;
+ color: #000000 !important;
+ font-size: 0.9rem;
+ &:hover {
+ background-color: #f8f9fa;
+ }
+ }
}
-.dropdown-menu .dropdown-item {
- padding: 0.5rem 1rem;
- color: #000000 !important;
- font-size: 0.9rem;
+/* Article content styling */
+.markdown-content {
+ color: #000000;
}
-.dropdown-menu .dropdown-item:hover {
- background-color: #f8f9fa;
+.markdown-content h1,
+.markdown-content h2,
+.markdown-content h3,
+.markdown-content h4,
+.markdown-content h5,
+.markdown-content h6,
+.markdown-content p,
+.markdown-content li,
+.markdown-content td,
+.markdown-content th,
+.markdown-content blockquote {
+ color: #000000;
+}
+
+article {
+ color: #000000;
+}
+
+article h1,
+article h2,
+article h3,
+article h4,
+article h5,
+article h6,
+article p,
+article li,
+article td,
+article th,
+article blockquote {
+ color: #000000;
}
From efb40e0513846115d28d81a59b8f37318641aaaa Mon Sep 17 00:00:00 2001
From: dethan3
Date: Wed, 11 Jun 2025 03:33:15 +0000
Subject: [PATCH 6/8] refactor: optimize SectionTitle & redirection to about.md
---
components/Home/CommunityStats.tsx | 2 +-
components/Home/LatestBlogs.tsx | 2 +-
components/Home/SectionTitle.tsx | 10 ++-----
components/Home/Sponsors.tsx | 2 +-
components/Home/UpcomingEvents.tsx | 6 ++--
components/Navigator/MainNavigator.tsx | 4 ++-
next.config.ts | 2 ++
pages/about.tsx | 12 --------
pages/index.tsx | 8 ------
styles/globals.less | 39 ++++++++++----------------
10 files changed, 29 insertions(+), 58 deletions(-)
delete mode 100644 pages/about.tsx
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
index df94e8020..5c2fafbee 100644
--- a/components/Home/CommunityStats.tsx
+++ b/components/Home/CommunityStats.tsx
@@ -4,7 +4,7 @@ import { SectionTitle } from './SectionTitle';
export const CommunityStats = () => (
-
+ 社区数据
{[
{ number: '1000+', label: '社区成员' },
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
index a3a7b5491..9ec605a81 100644
--- a/components/Home/LatestBlogs.tsx
+++ b/components/Home/LatestBlogs.tsx
@@ -11,7 +11,7 @@ interface LatestBlogsProps {
export const LatestBlogs: FC = ({ articles }) => (
-
+ 最新文章
{articles.map(({ name, meta, path }) => (
diff --git a/components/Home/SectionTitle.tsx b/components/Home/SectionTitle.tsx
index 4fa31a853..99503014d 100644
--- a/components/Home/SectionTitle.tsx
+++ b/components/Home/SectionTitle.tsx
@@ -1,12 +1,8 @@
-import React, { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
-interface SectionTitleProps {
- title: string;
-}
-
-export const SectionTitle: FC = ({ title }) => (
+export const SectionTitle: FC = ({ children }) => (
<>
- {title}
+ {children}
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
index f2622769d..5e23ce1d0 100644
--- a/components/Home/Sponsors.tsx
+++ b/components/Home/Sponsors.tsx
@@ -11,7 +11,7 @@ interface SponsorsProps {
export const Sponsors: FC = ({ sponsors }) => (
-
+ 赞助商
{sponsors.map(({ name, meta }) => (
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
index b62373b2d..ff74a8e3f 100644
--- a/components/Home/UpcomingEvents.tsx
+++ b/components/Home/UpcomingEvents.tsx
@@ -12,7 +12,7 @@ interface UpcomingEventsProps {
export const UpcomingEvents: FC = ({ events }) => (
-
+ 近期活动
{events.map(({ name, meta, path }) => (
@@ -20,10 +20,10 @@ export const UpcomingEvents: FC = ({ events }) => (
{name}
- 时间: {meta?.start || 'void 0'}
+ 时间: {meta?.start || 'N/A'}
- 地点: {meta?.address || 'void 0'}
+ 地点: {meta?.address || 'N/A'}
diff --git a/components/Navigator/MainNavigator.tsx b/components/Navigator/MainNavigator.tsx
index 412b30e6a..7177f2b51 100644
--- a/components/Navigator/MainNavigator.tsx
+++ b/components/Navigator/MainNavigator.tsx
@@ -24,7 +24,9 @@ export const MainNavigator: FC = observer(() => (
{t('community')}
- {t('about')}
+
+ {t('about')}
+
({
diff --git a/pages/about.tsx b/pages/about.tsx
deleted file mode 100644
index 7c9afca5c..000000000
--- a/pages/about.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { GetServerSideProps } from 'next';
-
-export const getServerSideProps: GetServerSideProps = async () => ({
- redirect: {
- destination: '/article/Wiki/_posts/Profile/about',
- permanent: false,
- },
- });
-
-const AboutPage = () => null;
-
-export default AboutPage;
diff --git a/pages/index.tsx b/pages/index.tsx
index d1bb4769f..2c0d323bf 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -21,7 +21,6 @@ interface HomePageProps {
}
export const getStaticProps = async () => {
- console.info('Starting to fetch data...');
const [articles, activities, partners] = await Promise.all([
Array.fromAsync(pageListOf('/article/Wiki/_posts/Article')),
Array.fromAsync(pageListOf('/article/Wiki/_posts/Activity')),
@@ -31,7 +30,6 @@ export const getStaticProps = async () => {
const latestArticles = articles
.map(root => {
const message = [...traverseTree(root, 'subs')];
- console.info('123:', root);
return message;
})
@@ -45,8 +43,6 @@ export const getStaticProps = async () => {
})
.slice(0, 3);
- console.info('Processed latestArticles:', latestArticles);
-
const upcomingEvents = activities
.map(root => [...traverseTree(root, 'subs')])
.flat()
@@ -59,15 +55,11 @@ export const getStaticProps = async () => {
})
.slice(0, 3);
- console.info('Processed upcomingEvents:', upcomingEvents);
-
const sponsors = partners
.flat()
.filter((sponsor): sponsor is ArticleMeta => 'meta' in sponsor)
.slice(0, 6);
- console.info('Processed sponsors:', sponsors);
-
return {
props: { latestArticles, upcomingEvents, sponsors },
revalidate: 3600,
diff --git a/styles/globals.less b/styles/globals.less
index 66a3e2046..06af33f80 100644
--- a/styles/globals.less
+++ b/styles/globals.less
@@ -52,15 +52,6 @@ a {
font-weight: bold;
}
-.hero-dark-text {
- color: var(--fcc-primary);
-}
-
-.accent-text {
- color: #0a0a23;
- font-weight: bold;
-}
-
.btn {
&-primary {
border-color: #028dfa;
@@ -211,20 +202,20 @@ div:has(.next-error-h1) {
color: #000000;
}
-article {
- color: #000000;
-}
-
-article h1,
-article h2,
-article h3,
-article h4,
-article h5,
-article h6,
-article p,
-article li,
-article td,
-article th,
-article blockquote {
+article,
+.markdown-content {
color: #000000;
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ p,
+ li,
+ td,
+ th,
+ blockquote {
+ color: #000000;
+ }
}
From aa978d915d8419564e30ea288054d679dbf2142d Mon Sep 17 00:00:00 2001
From: dethan3
Date: Thu, 12 Jun 2025 00:50:34 +0000
Subject: [PATCH 7/8] restore original next.config.ts and simplify index.tsx
code
---
next.config.ts | 1 -
pages/index.tsx | 98 ++++++++++++++++++++++++-------------------------
2 files changed, 48 insertions(+), 51 deletions(-)
diff --git a/next.config.ts b/next.config.ts
index 6b6015997..df97a4ea2 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -2,7 +2,6 @@ import NextMDX from '@next/mdx';
import { withSentryConfig } from '@sentry/nextjs';
import CopyPlugin from 'copy-webpack-plugin';
import { readdirSync, statSync } from 'fs';
-import type { NextConfig } from 'next';
import setPWA from 'next-pwa';
// @ts-expect-error no official types
import withLess from 'next-with-less';
diff --git a/pages/index.tsx b/pages/index.tsx
index 2c0d323bf..4ba574906 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -70,60 +70,58 @@ const HomePage = observer(
({ latestArticles, upcomingEvents, sponsors, error }: HomePageProps) => (
- <>
-
-
-
-
-
- freeCodeCamp 成都社区
-
-
- 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
-
-
-
- 加入社区
-
-
- 查看活动
-
-
-
-
-
+
+
+
+
+ freeCodeCamp 成都社区
+
+
+ 一个友好的技术社区,致力于交流、学习和互助,帮助成都的开发者和技术爱好者提升个人技术能力。
+
+
+
-
-
-
-
-
-
-
+ 加入社区
+
+
+ 查看活动
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
- >
+
),
);
From 5a5b58eeba4a4017fd2259f494831b6fdb8fc02b Mon Sep 17 00:00:00 2001
From: TechQuery
Date: Sun, 6 Jul 2025 09:14:13 +0800
Subject: [PATCH 8/8] [optimize] simplify Source Code details
---
components/Home/CommunityStats.tsx | 11 +++---
components/Home/LatestBlogs.tsx | 20 +++++------
components/Home/SectionTitle.tsx | 1 +
components/Home/Sponsors.tsx | 14 ++++----
components/Home/UpcomingEvents.tsx | 26 +++++++-------
package.json | 12 +++----
pages/_document.tsx | 4 +--
pages/api/core.ts | 57 ++++++++++++++----------------
pages/article/Wiki | 2 +-
pages/index.tsx | 7 ++--
styles/globals.less | 37 +++----------------
11 files changed, 76 insertions(+), 115 deletions(-)
diff --git a/components/Home/CommunityStats.tsx b/components/Home/CommunityStats.tsx
index 5c2fafbee..ee79eb40e 100644
--- a/components/Home/CommunityStats.tsx
+++ b/components/Home/CommunityStats.tsx
@@ -1,10 +1,12 @@
import { Card, Col, Container, Row } from 'react-bootstrap';
import { SectionTitle } from './SectionTitle';
+
export const CommunityStats = () => (
社区数据
+
{[
{ number: '1000+', label: '社区成员' },
@@ -13,11 +15,10 @@ export const CommunityStats = () => (
{ number: '30+', label: '开源项目' },
].map(({ number, label }) => (
-
-
- {number}
- {label}
-
+
+ {number}
+
+ {label}
))}
diff --git a/components/Home/LatestBlogs.tsx b/components/Home/LatestBlogs.tsx
index 9ec605a81..55efcb69b 100644
--- a/components/Home/LatestBlogs.tsx
+++ b/components/Home/LatestBlogs.tsx
@@ -12,24 +12,22 @@ export const LatestBlogs: FC = ({ articles }) => (
最新文章
+
{articles.map(({ name, meta, path }) => (
-
-
- {name}
-
- 发布日期: {meta?.date || '未知日期'}
-
-
- 阅读文章
-
-
+
+ {name}
+
+ 发布日期: {meta?.date || '未知日期'}
+
+
+ 阅读文章
+
))}
-
查看全部文章 →
diff --git a/components/Home/SectionTitle.tsx b/components/Home/SectionTitle.tsx
index 99503014d..e2fb2492e 100644
--- a/components/Home/SectionTitle.tsx
+++ b/components/Home/SectionTitle.tsx
@@ -3,6 +3,7 @@ import { FC, PropsWithChildren } from 'react';
export const SectionTitle: FC = ({ children }) => (
<>
{children}
+
diff --git a/components/Home/Sponsors.tsx b/components/Home/Sponsors.tsx
index 5e23ce1d0..ac91a2093 100644
--- a/components/Home/Sponsors.tsx
+++ b/components/Home/Sponsors.tsx
@@ -12,21 +12,19 @@ export const Sponsors: FC = ({ sponsors }) => (
赞助商
+
{sponsors.map(({ name, meta }) => (
-
-
- {name}
-
- {meta?.description || '暂无描述'}
-
-
+
+ {name}
+
+ {meta?.description || '暂无描述'}
+
))}
-
成为赞助商 →
diff --git a/components/Home/UpcomingEvents.tsx b/components/Home/UpcomingEvents.tsx
index ff74a8e3f..a46c04419 100644
--- a/components/Home/UpcomingEvents.tsx
+++ b/components/Home/UpcomingEvents.tsx
@@ -13,28 +13,26 @@ export const UpcomingEvents: FC = ({ events }) => (
近期活动
+
{events.map(({ name, meta, path }) => (
-
-
- {name}
-
- 时间: {meta?.start || 'N/A'}
-
-
- 地点: {meta?.address || 'N/A'}
-
+
+ {name}
+
+ 时间: {meta?.start || 'N/A'}
+
+
+ 地点: {meta?.address || 'N/A'}
+
-
- 查看详情
-
-
+
+ 查看详情
+
))}
-
查看全部活动 →
diff --git a/package.json b/package.json
index bf2f2edb8..e83eb2852 100644
--- a/package.json
+++ b/package.json
@@ -75,6 +75,11 @@
"resolutions": {
"next": "$next"
},
+ "pnpm": {
+ "onlyBuiltDependencies": [
+ "sharp"
+ ]
+ },
"prettier": {
"singleQuote": true,
"trailingComma": "all",
@@ -97,12 +102,5 @@
"test": "lint-staged && npm run lint",
"pack-image": "docker build -t freecodecamp-chengdu/freecodecamp-chengdu.github.io:latest .",
"container": "docker rm -f freecodecamp-chengdu.github.io && docker run --name freecodecamp-chengdu.github.io -p 3000:3000 -d freecodecamp-chengdu/freecodecamp-chengdu.github.io:latest"
- },
- "pnpm": {
- "ignoredBuiltDependencies": [
- "@sentry/cli",
- "core-js",
- "sharp"
- ]
}
}
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 99033ec9f..87dacb5d8 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -15,11 +15,11 @@ export default function Document() {
/>
-
+
diff --git a/pages/api/core.ts b/pages/api/core.ts
index 4509bb570..e4fbf54cf 100644
--- a/pages/api/core.ts
+++ b/pages/api/core.ts
@@ -57,10 +57,12 @@ const MDX_pattern = /\.mdx?$/;
export async function frontMatterOf(path: string) {
const { readFile } = await import('fs/promises');
+
const file = await readFile(path, 'utf-8');
+
const [, frontMatter] = file.match(/^---[\r\n]([\s\S]+?[\r\n])---/) || [];
- return frontMatter ? parse(frontMatter) : null;
+ return frontMatter && parse(frontMatter);
}
export async function* pageListOf(
@@ -69,42 +71,37 @@ export async function* pageListOf(
): AsyncGenerator {
const { readdir } = await import('fs/promises');
- try {
- const list = await readdir(prefix + path, { withFileTypes: true });
+ const list = await readdir(prefix + path, { withFileTypes: true });
- for (const node of list) {
- let { name, path } = node;
+ for (const node of list) {
+ let { name, path } = node;
- if (name.startsWith('.')) continue;
+ if (name.startsWith('.')) continue;
- const isMDX = MDX_pattern.test(name);
+ const isMDX = MDX_pattern.test(name);
- name = name.replace(MDX_pattern, '');
- path = `${path}/${name}`.replace(new RegExp(`^${prefix}`), '');
+ name = name.replace(MDX_pattern, '');
+ path = `${path}/${name}`.replace(new RegExp(`^${prefix}`), '');
- if (node.isFile()) {
- if (isMDX) {
- const article: ArticleMeta = { name, path, subs: [] };
- try {
- const meta = await frontMatterOf(`${node.path}/${node.name}`);
- if (meta) article.meta = meta;
- yield article;
- } catch (error) {
- console.error(
- `Error reading front matter for ${node.path}/${node.name}:`,
- error,
- );
- }
- }
- } else if (node.isDirectory()) {
- const subs = await Array.fromAsync(pageListOf(path, prefix));
- if (subs.length > 0) {
- yield { name, subs };
- }
+ if (node.isFile() && isMDX) {
+ const article: ArticleMeta = { name, path, subs: [] };
+ try {
+ const meta = await frontMatterOf(`${node.path}/${node.name}`);
+
+ if (meta) article.meta = meta;
+ } catch (error) {
+ console.error(
+ `Error reading front matter for ${node.path}/${node.name}:`,
+ error,
+ );
}
+ yield article;
}
- } catch (error) {
- console.error(`Error reading directory ${prefix + path}:`, error);
+ if (!node.isDirectory()) continue;
+
+ const subs = await Array.fromAsync(pageListOf(path, prefix));
+
+ if (subs.length) yield { name, subs };
}
}
diff --git a/pages/article/Wiki b/pages/article/Wiki
index a9c1488a2..11cc5bce6 160000
--- a/pages/article/Wiki
+++ b/pages/article/Wiki
@@ -1 +1 @@
-Subproject commit a9c1488a2aff18b4b2abf5c9d478fc2f0e353c05
+Subproject commit 11cc5bce6bda307c480712b4afb5b7565f2364ff
diff --git a/pages/index.tsx b/pages/index.tsx
index 4ba574906..510121a75 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -28,11 +28,7 @@ export const getStaticProps = async () => {
]);
const latestArticles = articles
- .map(root => {
- const message = [...traverseTree(root, 'subs')];
-
- return message;
- })
+ .map(root => [...traverseTree(root, 'subs')])
.flat()
.filter((article): article is ArticleMeta => 'meta' in article)
.sort((a, b) => {
@@ -70,6 +66,7 @@ const HomePage = observer(
({ latestArticles, upcomingEvents, sponsors, error }: HomePageProps) => (
+
diff --git a/styles/globals.less b/styles/globals.less
index 06af33f80..e11f6ef42 100644
--- a/styles/globals.less
+++ b/styles/globals.less
@@ -28,12 +28,6 @@ body {
sans-serif;
}
-body {
- display: flex;
- flex-direction: column;
- min-height: 100vh;
-}
-
a {
color: inherit;
text-decoration: none;
@@ -77,13 +71,6 @@ a {
}
}
-/* Responsive adjustments for navbar buttons */
-@media (max-width: 991.98px) {
- .navbar .btn {
- margin-top: 0.5rem;
- }
-}
-
[contenteditable='true'],
article {
img {
@@ -111,7 +98,11 @@ div:has(.next-error-h1) {
padding-bottom: 0.425rem !important;
min-height: auto !important;
}
-
+ .btn {
+ @media (max-width: 991.98px) {
+ margin-top: 0.5rem;
+ }
+ }
.nav-link {
position: relative;
transition: color 0.3s ease;
@@ -184,24 +175,6 @@ div:has(.next-error-h1) {
}
/* Article content styling */
-.markdown-content {
- color: #000000;
-}
-
-.markdown-content h1,
-.markdown-content h2,
-.markdown-content h3,
-.markdown-content h4,
-.markdown-content h5,
-.markdown-content h6,
-.markdown-content p,
-.markdown-content li,
-.markdown-content td,
-.markdown-content th,
-.markdown-content blockquote {
- color: #000000;
-}
-
article,
.markdown-content {
color: #000000;