feat: 全面重构网站工程化体系与 UI 架构

- 将单体 style.css 拆分为 tokens/reset/fonts/layout/responsive/组件级 CSS 模块
- 从 Google Fonts CDN 迁移至本地自托管字体(JetBrainsMono、NotoSansSC)
- 引入 Vitest + Testing Library 测试体系,新增单元测试
- 添加 GitHub Actions CI 流水线(lint → build → test)
- 新增 Prettier 格式化与 ESLint 规则强化
- 重构全部 YAML 数据文件,完善项目详情页(截图轮播、更新日志)
- 新增项目文档编写指南(docs/create-project.md)
This commit is contained in:
2026-05-22 13:34:41 +08:00
parent 5e79c96364
commit 6b58b55c32
83 changed files with 5890 additions and 3955 deletions
+16 -9
View File
@@ -11,17 +11,24 @@ export default function ProjectsPage() {
const catParam = searchParams.get('cat');
const {
search, setSearch,
tech, setTech,
platform, setPlatform,
status, setStatus,
sort, setSort,
allTech, allPlatforms, allStatuses,
search,
setSearch,
tech,
setTech,
platform,
setPlatform,
status,
setStatus,
sort,
setSort,
allTech,
allPlatforms,
allStatuses,
filteredProjects,
} = useProjectFilters();
const displayedProjects = catParam
? filteredProjects.filter(p => p.type.includes(catParam))
? filteredProjects.filter((p) => p.type.includes(catParam))
: filteredProjects;
const techOptions = [
@@ -54,7 +61,7 @@ export default function ProjectsPage() {
type="text"
className="search-input"
value={search}
onChange={e => setSearch(e.target.value)}
onChange={(e) => setSearch(e.target.value)}
placeholder={t('projects.search')}
/>
@@ -90,7 +97,7 @@ export default function ProjectsPage() {
{displayedProjects.length === 0 ? (
<div className="empty-state">{t('projects.noResults')}</div>
) : (
displayedProjects.map(p => <ProjectCard key={p.id} project={p} />)
displayedProjects.map((p) => <ProjectCard key={p.id} project={p} />)
)}
</div>
</div>