Skip to content

Commit 6f56b9e

Browse files
committed
Add project and open source detail pages
1 parent 89192cc commit 6f56b9e

9 files changed

Lines changed: 549 additions & 113 deletions

File tree

app/detail-page.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import type { CSSProperties, ReactNode } from 'react';
2+
import Link from 'next/link';
3+
import {
4+
PiArrowDownBold,
5+
PiArrowLeftBold,
6+
PiArrowRightBold,
7+
PiArrowUpRightBold,
8+
PiCheckCircle,
9+
PiGithubLogo,
10+
PiLightbulb,
11+
PiMagnifyingGlass,
12+
PiWrench,
13+
} from 'react-icons/pi';
14+
15+
export type DetailStep = {
16+
label: string;
17+
title: string;
18+
copy: string;
19+
icon: 'problem' | 'reasoning' | 'solution' | 'result';
20+
};
21+
22+
type DetailPageProps = {
23+
category: string;
24+
title: string;
25+
subtitle: string;
26+
intro: string;
27+
accent: string;
28+
highlight: string;
29+
externalHref: string;
30+
externalLabel: string;
31+
backHref: string;
32+
backLabel: string;
33+
logo?: string;
34+
role?: string;
35+
metrics?: Array<[string, string]>;
36+
steps: DetailStep[];
37+
previous?: { href: string; label: string };
38+
next?: { href: string; label: string };
39+
externalIcon?: ReactNode;
40+
};
41+
42+
const stepIcons = {
43+
problem: PiMagnifyingGlass,
44+
reasoning: PiLightbulb,
45+
solution: PiWrench,
46+
result: PiCheckCircle,
47+
};
48+
49+
export default function DetailPage({
50+
category,
51+
title,
52+
subtitle,
53+
intro,
54+
accent,
55+
highlight,
56+
externalHref,
57+
externalLabel,
58+
backHref,
59+
backLabel,
60+
logo,
61+
role,
62+
metrics,
63+
steps,
64+
previous,
65+
next,
66+
externalIcon,
67+
}: DetailPageProps) {
68+
return <main className="detail-page" style={{ '--detail-accent': accent } as CSSProperties}>
69+
<nav className="detail-nav" aria-label="详情页导航">
70+
<a className="detail-back" href={backHref}><PiArrowLeftBold aria-hidden="true" />{backLabel}</a>
71+
<Link className="detail-brand" href="/">ZHEWEN TAN</Link>
72+
<a className="detail-external-mini" href={externalHref} target="_blank" rel="noopener noreferrer">{externalLabel}<PiArrowUpRightBold aria-hidden="true" /></a>
73+
</nav>
74+
75+
<section className="detail-hero">
76+
<div className="detail-hero-main">
77+
<p className="detail-kicker">{category}{role ? ` · ${role}` : ''}</p>
78+
<div className="detail-title-row">
79+
{logo && <span className="detail-logo"><img src={logo} alt="" /></span>}
80+
<div><small>{subtitle}</small><h1>{title}</h1></div>
81+
</div>
82+
<p className="detail-intro">{intro}</p>
83+
<div className="detail-actions">
84+
<a href="#story">查看完整思路 <PiArrowDownBold aria-hidden="true" /></a>
85+
<a href={externalHref} target="_blank" rel="noopener noreferrer">{externalIcon ?? <PiGithubLogo aria-hidden="true" />}{externalLabel}<PiArrowUpRightBold aria-hidden="true" /></a>
86+
</div>
87+
</div>
88+
<aside className="detail-highlight"><small>KEY TAKEAWAY</small><strong>{highlight}</strong></aside>
89+
</section>
90+
91+
{metrics && metrics.length > 0 && <section className="detail-metrics" aria-label="项目指标">
92+
{metrics.map(([label, value]) => <div key={label}><span>{label}</span><strong>{value}</strong></div>)}
93+
</section>}
94+
95+
<section className="detail-story" id="story">
96+
<header><span>ENGINEERING STORY</span><h2>从问题到结果</h2><p>按真实工作顺序展开,而不是只展示一个最终结论。</p></header>
97+
<div className="detail-flow">
98+
{steps.map((step, index) => {
99+
const Icon = stepIcons[step.icon];
100+
return <div className="detail-flow-item" key={step.label}>
101+
<article className="detail-step">
102+
<div className="detail-step-top"><span>{String(index + 1).padStart(2, '0')}</span><Icon aria-hidden="true" /></div>
103+
<small>{step.label}</small>
104+
<h3>{step.title}</h3>
105+
<p>{step.copy}</p>
106+
</article>
107+
{index < steps.length - 1 && <span className="detail-connector" aria-hidden="true"><PiArrowRightBold /></span>}
108+
</div>;
109+
})}
110+
</div>
111+
</section>
112+
113+
<section className="detail-final-cta">
114+
<div><small>UPSTREAM / PROJECT</small><h2>继续查看公开项目</h2><p>站内页面解释我的工作,外部链接保留项目原始上下文与最新进展。</p></div>
115+
<a href={externalHref} target="_blank" rel="noopener noreferrer">{externalIcon ?? <PiGithubLogo aria-hidden="true" />}{externalLabel}<PiArrowUpRightBold aria-hidden="true" /></a>
116+
</section>
117+
118+
<nav className="detail-pagination" aria-label="详情页切换">
119+
{previous ? <a href={previous.href}><PiArrowLeftBold aria-hidden="true" /><span><small>上一个</small>{previous.label}</span></a> : <span />}
120+
{next ? <a href={next.href}><span><small>下一个</small>{next.label}</span><PiArrowRightBold aria-hidden="true" /></a> : <span />}
121+
</nav>
122+
</main>;
123+
}

0 commit comments

Comments
 (0)