feat(site): optimize full-stack positioning and collaboration conversion pages

This commit is contained in:
zguiyang
2026-03-16 16:18:28 +08:00
parent ce6110588f
commit 411bbb00d1
13 changed files with 617 additions and 146 deletions

View File

@@ -5,7 +5,7 @@ import Container from "./ui/Container.tsx";
import { useTranslations, getLocalizedPath } from "@/i18n/utils";
import type { Lang } from "@/types/i18n";
import { useState, useEffect } from "react";
import { Menu, X, Home, Rocket, PenTool, Zap, User, Wrench, Mail } from "lucide-react";
import { Menu, X, Home, Rocket, PenTool, User, Briefcase, Mail } from "lucide-react";
import { defaultLang } from "@/i18n/ui";
import { type GlassHeaderProps } from "@/types";
import { motion } from "framer-motion";
@@ -40,11 +40,10 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
const navItems = [
{ key: 'nav.home', icon: Home, href: getLocalizedPath('/', lang) },
{ key: 'nav.about', icon: User, href: getLocalizedPath('/about', lang) },
{ key: 'nav.projects', icon: Rocket, href: getLocalizedPath('/projects', lang) },
{ key: 'nav.blog', icon: PenTool, href: getLocalizedPath('/blog', lang) },
{ key: 'nav.now', icon: Zap, href: getLocalizedPath('/now', lang) },
{ key: 'nav.uses', icon: Wrench, href: getLocalizedPath('/uses', lang) },
{ key: 'nav.about', icon: User, href: getLocalizedPath('/about', lang) },
{ key: 'nav.hire', icon: Briefcase, href: getLocalizedPath('/hire', lang) },
{ key: 'nav.contact', icon: Mail, href: getLocalizedPath('/contact', lang) },
];

View File

@@ -11,13 +11,14 @@ export const translations = {
about: 'About',
projects: 'Projects',
blog: 'Blog',
hire: 'Hire',
uses: 'Uses',
contact: 'Contact',
now: 'Now',
},
site: {
title: 'Joey Zhao - Senior Frontend Engineer',
description: 'Senior Frontend Engineer building complex systems and AI-assisted products',
title: 'Joey Zhao - Full-stack Engineer',
description: 'Full-stack Engineer for custom development, outsourcing projects, and reliable delivery',
},
hero: {
greeting: "Hello, I'm",
@@ -197,13 +198,14 @@ export const translations = {
about: '关于',
projects: '项目',
blog: '博客',
hire: '合作',
uses: '工具',
contact: '联系',
now: '现在',
},
site: {
title: 'Joey Zhao - 资深前端工程师',
description: '专注复杂系统与 AI 协作工程实践的资深前端工程师',
title: 'Joey Zhao - 全栈工程师',
description: '承接定制开发、项目外包与高质量交付的全栈工程师',
},
hero: {
greeting: '你好,我是',

View File

@@ -10,12 +10,12 @@ export const personalInfo: PersonalInfo = {
website: 'https://zhaoguiyang.com',
twitter: 'https://twitter.com/zhaoguiyang',
position: {
en: 'Senior Frontend Engineer · Full-stack Developer',
zh: '资深前端工程师 · 全栈开发者',
en: 'Full-stack Engineer',
zh: '全栈工程师',
},
description: {
en: '8 years building enterprise systems, financial platforms, and blockchain infrastructure. Focused on frontend architecture, complex system design, and AI-assisted engineering workflows.',
zh: '8 年企业系统、金融平台与区块链基础设施研发经验,专注前端架构、复杂系统设计与 AI 协作工程化实践。',
en: '8 years building enterprise systems, financial platforms, and blockchain infrastructure. Available for custom development, outsourcing projects, bug fixing, and long-term remote collaboration.',
zh: '8 年企业系统、金融平台与区块链基础设施研发经验,可承接定制开发、项目外包、Bug 修复与长期远程合作。',
},
about: {
en: [

View File

@@ -3,12 +3,13 @@ import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import { personalInfo } from '@/lib/data';
import { personalInfo, uses, contactMethods } from '@/lib/data';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
const prefix = isZh ? '/zh' : '';
const focusAreas = isZh
? ['前端架构设计与模块治理', '大型企业应用工程化交付', '金融与区块链系统前端建设', 'AI 协作开发流程实践']
@@ -25,6 +26,10 @@ const experienceNotes = isZh
'Contributed to government- and fintech-related systems, including trading platforms, blockchain infrastructure, and industrial management systems.',
'Strong in cross-functional collaboration and remote async execution with long-term maintainability in mind.',
];
const workStyle = isZh
? ['远程优先、异步协作为主,关键节点同步决策', '强调可维护架构与稳定交付节奏', '文档化需求与边界,降低沟通与返工成本']
: ['Remote-first and async-friendly collaboration with sync checkpoints', 'Maintainable architecture and stable delivery cadence', 'Documented requirements and boundaries to reduce rework'];
---
<Layout title={isZh ? '关于' : 'About'}>
@@ -32,37 +37,85 @@ const experienceNotes = isZh
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<section class="page-content-main" id="overview">
<div class="mb-6 flex flex-wrap gap-2 text-sm">
<a href="#overview" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '概览' : 'Overview'}</a>
<a href="#experience" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '经验' : 'Experience'}</a>
<a href="#focus" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '技术焦点' : 'Focus'}</a>
<a href="#uses" class="rounded-md border border-border px-3 py-1 hover:bg-muted">Uses</a>
<a href="#contact-brief" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '联系' : 'Contact'}</a>
</div>
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '关于我' : 'About'}</h1>
<p class="mt-6 text-lg leading-relaxed text-muted-foreground">{personalInfo.description[lang]}</p>
</section>
<section class="page-content-main mt-12 grid gap-6 lg:grid-cols-2">
<article class="page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '背景' : 'Background'}</h2>
<section class="page-content-main mt-10 page-surface p-8" id="experience">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
<div class="mt-4 space-y-4 text-muted-foreground">
{personalInfo.about[lang].map((line) => <p>{line}</p>)}
</div>
</article>
<article class="page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '技术焦点' : 'Technical Focus'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
{focusAreas.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</article>
</section>
<section class="page-content-main mt-6 page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
<ul class="mt-5 space-y-3 text-muted-foreground">
{experienceNotes.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="focus">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '技术焦点' : 'Technical Focus'}</h2>
<ul class="mt-4 grid gap-3 md:grid-cols-2 text-muted-foreground">
{focusAreas.map((item) => (
<li class="flex gap-3 rounded-md border border-border/70 p-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="uses">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工具与工作流' : 'Uses'}</h2>
<div class="mt-5 grid gap-5 md:grid-cols-2">
{uses.map((group) => (
<article class="rounded-md border border-border/70 p-5">
<h3 class="text-base font-bold">{group.title[lang]}</h3>
<ul class="mt-3 space-y-1.5 text-sm text-muted-foreground">
{group.items.map((item) => <li>• {item}</li>)}
</ul>
</article>
))}
</div>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="work-style">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工作方式' : 'Work Style'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
{workStyle.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="contact-brief">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '联系(简版)' : 'Contact Brief'}</h2>
<p class="mt-3 text-muted-foreground">{isZh ? '优先沟通远程岗位机会,其次为项目合作咨询。' : 'Remote role opportunities are prioritized, followed by project collaboration.'}</p>
<ul class="mt-5 space-y-3 text-sm">
{contactMethods.slice(0, 2).map((method) => (
<li class="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between border-b border-border/70 pb-3">
<span class="font-semibold text-foreground">{method.label[lang]}</span>
{method.href ? (
<a href={method.href} target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 break-all">{method.value}</a>
) : (
<span class="text-muted-foreground break-all">{method.value}</span>
)}
</li>
))}
</ul>
<div class="mt-6 flex flex-wrap gap-3">
<a href={`${prefix}/contact`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '进入完整联系页' : 'Open Full Contact Page'}</a>
<a href={`${prefix}/contact#project-collaboration`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '项目合作入口' : 'Project Collaboration'}</a>
</div>
</section>
</Container>
</main>

View File

@@ -23,6 +23,12 @@ const isZh = lang === 'zh';
? '欢迎联系我沟通远程岗位或项目合作。默认优先响应远程岗位机会。'
: 'Open to remote role opportunities and project collaboration. Remote role discussions are prioritized.'}
</p>
<p class="mt-2 text-sm text-muted-foreground">
{isZh ? '想先了解合作方式与付款方式?请查看' : 'Want details on collaboration and payment terms first? Visit'}
{' '}
<a href={isZh ? '/zh/hire' : '/hire'} class="text-primary hover:text-primary/80">{isZh ? '合作页面' : 'Hire page'}</a>
</p>
</section>
<section class="page-content-main mt-10 grid gap-6 md:grid-cols-2">
@@ -55,6 +61,17 @@ const isZh = lang === 'zh';
: 'Suggestion: include role/project context, expected collaboration model, and timeline in your first message.'}
</p>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '需求信息模板' : 'Request Template'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
<li>1. {isZh ? '你是谁 / 团队背景' : 'Who you are / team context'}</li>
<li>2. {isZh ? '项目目标与当前现状' : 'Project goal and current status'}</li>
<li>3. {isZh ? '期望上线时间与协作周期' : 'Target timeline and collaboration window'}</li>
<li>4. {isZh ? '预算区间或岗位信息' : 'Budget range or role details'}</li>
<li>5. {isZh ? '优先沟通方式(邮箱/即时通讯)' : 'Preferred communication channel (email/chat)'}</li>
</ul>
</section>
</Container>
</main>

View File

@@ -1,3 +1,178 @@
---
return Astro.redirect('/contact', 301);
import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
const models = isZh
? [
{
title: '远程岗位合作',
desc: '适合长期加入团队,以资深前端/全栈角色参与核心产品建设。',
},
{
title: '项目制交付',
desc: '适合目标明确的系统建设、重构与性能优化项目,按阶段交付。',
},
{
title: '技术咨询/顾问',
desc: '适合架构评审、工程治理、复杂问题诊断与实施建议。',
},
]
: [
{
title: 'Remote Role',
desc: 'Long-term collaboration as a senior frontend/full-stack engineer on core products.',
},
{
title: 'Project Delivery',
desc: 'Milestone-based delivery for scoped system builds, refactors, and performance optimization.',
},
{
title: 'Technical Consulting',
desc: 'Architecture reviews, engineering governance, complex issue diagnosis, and execution guidance.',
},
];
const paymentOptions = isZh
? ['里程碑付款(推荐)', '月度结算(长期合作)', '咨询按小时或按天计费']
: ['Milestone-based payments (recommended)', 'Monthly settlement (for long-term collaboration)', 'Hourly or daily consulting billing'];
const startingPackages = isZh
? [
'Bug 修复¥800 起(按问题复杂度评估)',
'小型定制页面/落地页¥3000 起',
'后台模块开发¥6000 起(按里程碑)',
]
: [
'Bug fixing: from $120 (scoped by issue complexity)',
'Small custom page/landing page: from $450',
'Admin module delivery: from $850 (milestone-based)',
];
const process = isZh
? ['需求沟通与目标确认', '方案评估与范围定义', '里程碑排期与执行', '阶段验收与交付总结']
: ['Discovery and goal alignment', 'Solution assessment and scope definition', 'Milestone planning and execution', 'Stage acceptance and delivery summary'];
const boundaries = isZh
? [
'默认不承接违法或高风险灰色业务。',
'需求变更超出范围时,会先同步影响与补充报价。',
'交付文档、代码与协作记录会保持透明可追踪。',
]
: [
'No illegal or high-risk gray-area business engagements.',
'Out-of-scope changes are assessed first with impact and updated pricing.',
'Delivery docs, code, and collaboration records remain transparent and traceable.',
];
const faqItems = isZh
? [
{ q: '多久回复?', a: '默认 24 小时内给出初步回复,紧急问题可优先处理。' },
{ q: '如何开始合作?', a: '先在联系页提交背景与目标,我会给出范围评估与合作建议。' },
{ q: '需求变更多怎么办?', a: '超出原范围会先同步影响、排期和补充报价,再继续执行。' },
]
: [
{ q: 'Response time?', a: 'Initial response is usually within 24 hours, with priority handling for urgent issues.' },
{ q: 'How do we start?', a: 'Submit your context and goals on the contact page, then I provide scope assessment and recommendations.' },
{ q: 'What about scope changes?', a: 'Out-of-scope changes are reviewed with impact and revised pricing before execution.' },
];
---
<Layout title={isZh ? '合作' : 'Hire'}>
<GlassHeader lang={lang} client:load transition:persist="header" />
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '合作方式' : 'Work With Me'}</h1>
<p class="mt-4 text-lg leading-relaxed text-muted-foreground">
{isZh
? '这个页面用于明确合作方式、付款方式、交付流程与边界,方便你快速判断是否匹配。'
: 'This page outlines collaboration models, payment methods, delivery process, and boundaries to quickly assess fit.'}
</p>
</section>
<section class="page-content-main mt-10">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作方式' : 'Collaboration Models'}</h2>
<div class="mt-4 grid gap-4 md:grid-cols-3">
{models.map((model) => (
<article class="page-surface p-5">
<h3 class="text-lg font-bold">{model.title}</h3>
<p class="mt-2 text-sm text-muted-foreground">{model.desc}</p>
</article>
))}
</div>
</section>
<section class="page-content-main mt-6 grid gap-6 md:grid-cols-2">
<article class="page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '付款方式' : 'Payment Terms'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{paymentOptions.map((item) => <li>• {item}</li>)}
</ul>
</article>
<article class="page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '交付流程' : 'Delivery Process'}</h2>
<ol class="mt-4 space-y-2 text-sm text-muted-foreground list-decimal pl-5">
{process.map((item) => <li>{item}</li>)}
</ol>
</article>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '参考起步价' : 'Starting Packages'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{startingPackages.map((item) => <li>• {item}</li>)}
</ul>
<p class="mt-3 text-xs text-muted-foreground">
{isZh ? '说明:最终报价会根据需求复杂度、时间窗口与交付范围确认。' : 'Note: final pricing depends on complexity, timeline, and agreed delivery scope.'}
</p>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '合作边界与说明' : 'Engagement Boundaries'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{boundaries.map((item) => <li>• {item}</li>)}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '常见问题' : 'FAQ'}</h2>
<div class="mt-4 space-y-4">
{faqItems.map((item) => (
<div class="rounded-md border border-border/70 p-4">
<p class="text-sm font-semibold">{item.q}</p>
<p class="mt-2 text-sm text-muted-foreground">{item.a}</p>
</div>
))}
</div>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '下一步' : 'Next Step'}</h2>
<p class="mt-3 text-sm text-muted-foreground">
{isZh
? '如果你已经有明确岗位或项目需求,请进入联系页提交背景、目标、时间与预算信息。'
: 'If you already have a role or project in mind, continue to the contact page with context, goals, timeline, and budget.'}
</p>
<div class="mt-5 flex flex-wrap gap-3">
<a href={isZh ? '/zh/contact' : '/contact'} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">
{isZh ? '进入联系页' : 'Go to Contact'}
</a>
<a href={isZh ? '/zh/contact#project-collaboration' : '/contact#project-collaboration'} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">
{isZh ? '项目合作入口' : 'Project Collaboration'}
</a>
</div>
</section>
</Container>
</main>
<Footer lang={lang} client:load />
</Layout>

View File

@@ -14,15 +14,27 @@ const prefix = isZh ? '/zh' : '';
const featuredProjects = projects[lang].filter((item) => item.featured).slice(0, 3);
const proofItems = isZh
? ['8 年 Web 开发经验', '企业级复杂系统交付', '金融与区块链基础设施', '远程协作与稳定交付']
: ['8 years in web engineering', 'Enterprise-grade complex systems', 'Finance & blockchain infrastructure', 'Remote-first stable delivery'];
? ['8 年全栈开发经验', '支持定制开发与项目外包', '可承接紧急 Bug 修复', '远程协作与稳定交付']
: ['8 years in full-stack engineering', 'Available for custom development and outsourcing', 'Open for urgent bug fixing', 'Remote-first stable delivery'];
const headline = isZh
? '资深前端工程师,构建复杂系统与 AI 协作产品'
: 'Senior Frontend Engineer building complex systems and AI-assisted products';
? '全栈工程师,专注复杂系统开发与高质量交付'
: 'Full-stack Engineer focused on complex system development and reliable delivery';
const intro = personalInfo.description[lang];
const serviceItems = isZh
? [
{ title: '网站/系统定制开发', desc: '从需求梳理到上线交付,适合中小型业务系统与管理后台。' },
{ title: '项目外包与模块开发', desc: '可按里程碑承接功能模块开发、重构与性能优化。' },
{ title: 'Bug 修复与线上排障', desc: '支持紧急问题排查与修复,默认 24 小时内给出初步反馈。' },
]
: [
{ title: 'Custom Website/System Development', desc: 'From requirement definition to production delivery for business systems.' },
{ title: 'Outsourcing & Module Delivery', desc: 'Milestone-based module development, refactoring, and performance optimization.' },
{ title: 'Bug Fixing & Production Troubleshooting', desc: 'Support for urgent issues with initial response within 24 hours.' },
];
const postModules = await import.meta.glob('./blog/posts/*.md', { eager: true });
const latestPosts = sortPostsByDate(
Object.values(postModules).map((post: any) => ({
@@ -45,8 +57,8 @@ const latestPosts = sortPostsByDate(
<p class="max-w-3xl text-lg leading-relaxed text-muted-foreground">{intro}</p>
<div class="flex flex-wrap gap-4 pt-2">
<a href={`${prefix}/contact`} class="inline-flex h-11 items-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground hover:bg-primary/90">{isZh ? '远程岗位沟通' : 'Hire for Remote Role'}</a>
<a href={`${prefix}/contact#project-collaboration`} class="inline-flex h-11 items-center rounded-lg border border-border px-6 text-sm font-semibold text-foreground hover:bg-muted">{isZh ? '发起项目合作' : 'Start a Project'}</a>
<a href={`${prefix}/hire`} class="inline-flex h-11 items-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground hover:bg-primary/90">{isZh ? '查看合作方式' : 'View Collaboration'}</a>
<a href={`${prefix}/contact`} class="inline-flex h-11 items-center rounded-lg border border-border px-6 text-sm font-semibold text-foreground hover:bg-muted">{isZh ? '立即联系' : 'Contact Now'}</a>
</div>
<ul class="grid gap-3 sm:grid-cols-2 pt-4">
@@ -56,6 +68,21 @@ const latestPosts = sortPostsByDate(
</ul>
</section>
<section class="page-content-main mt-20">
<div class="mb-8 flex items-end justify-between gap-4">
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '我能提供的服务' : 'Services I Offer'}</h2>
<a href={`${prefix}/hire`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看合作细节' : 'View Hire Page'}</a>
</div>
<div class="grid gap-4 md:grid-cols-3">
{serviceItems.map((item) => (
<article class="page-surface p-5">
<h3 class="text-base font-bold">{item.title}</h3>
<p class="mt-2 text-sm text-muted-foreground">{item.desc}</p>
</article>
))}
</div>
</section>
<section class="page-content-main mt-20">
<div class="mb-8 flex items-end justify-between gap-4">
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '精选工程案例' : 'Selected Engineering Cases'}</h2>

View File

@@ -1,40 +1,3 @@
---
import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import { uses } from '@/lib/data';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
return Astro.redirect('/about#uses', 301);
---
<Layout title={isZh ? '工具' : 'Uses'}>
<GlassHeader lang={lang} client:load transition:persist="header" />
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '工具与工作流' : 'Uses'}</h1>
<p class="mt-4 text-lg text-muted-foreground">
{isZh ? '我在日常研发中稳定使用的工具与协作方式。' : 'Tools and workflows I use for daily engineering work.'}
</p>
</section>
<section class="page-content-main mt-10 grid gap-6 md:grid-cols-2">
{uses.map((group) => (
<article class="page-surface p-6">
<h2 class="text-lg font-bold">{group.title[lang]}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{group.items.map((item) => <li>• {item}</li>)}
</ul>
</article>
))}
</section>
</Container>
</main>
<Footer lang={lang} client:load />
</Layout>

View File

@@ -3,12 +3,13 @@ import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import { personalInfo } from '@/lib/data';
import { personalInfo, uses, contactMethods } from '@/lib/data';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
const prefix = isZh ? '/zh' : '';
const focusAreas = isZh
? ['前端架构设计与模块治理', '大型企业应用工程化交付', '金融与区块链系统前端建设', 'AI 协作开发流程实践']
@@ -25,6 +26,10 @@ const experienceNotes = isZh
'Contributed to government- and fintech-related systems, including trading platforms, blockchain infrastructure, and industrial management systems.',
'Strong in cross-functional collaboration and remote async execution with long-term maintainability in mind.',
];
const workStyle = isZh
? ['远程优先、异步协作为主,关键节点同步决策', '强调可维护架构与稳定交付节奏', '文档化需求与边界,降低沟通与返工成本']
: ['Remote-first and async-friendly collaboration with sync checkpoints', 'Maintainable architecture and stable delivery cadence', 'Documented requirements and boundaries to reduce rework'];
---
<Layout title={isZh ? '关于' : 'About'}>
@@ -32,37 +37,85 @@ const experienceNotes = isZh
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<section class="page-content-main" id="overview">
<div class="mb-6 flex flex-wrap gap-2 text-sm">
<a href="#overview" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '概览' : 'Overview'}</a>
<a href="#experience" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '经验' : 'Experience'}</a>
<a href="#focus" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '技术焦点' : 'Focus'}</a>
<a href="#uses" class="rounded-md border border-border px-3 py-1 hover:bg-muted">Uses</a>
<a href="#contact-brief" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '联系' : 'Contact'}</a>
</div>
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '关于我' : 'About'}</h1>
<p class="mt-6 text-lg leading-relaxed text-muted-foreground">{personalInfo.description[lang]}</p>
</section>
<section class="page-content-main mt-12 grid gap-6 lg:grid-cols-2">
<article class="page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '背景' : 'Background'}</h2>
<section class="page-content-main mt-10 page-surface p-8" id="experience">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
<div class="mt-4 space-y-4 text-muted-foreground">
{personalInfo.about[lang].map((line) => <p>{line}</p>)}
</div>
</article>
<article class="page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '技术焦点' : 'Technical Focus'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
{focusAreas.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</article>
</section>
<section class="page-content-main mt-6 page-surface p-8">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
<ul class="mt-5 space-y-3 text-muted-foreground">
{experienceNotes.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="focus">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '技术焦点' : 'Technical Focus'}</h2>
<ul class="mt-4 grid gap-3 md:grid-cols-2 text-muted-foreground">
{focusAreas.map((item) => (
<li class="flex gap-3 rounded-md border border-border/70 p-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="uses">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工具与工作流' : 'Uses'}</h2>
<div class="mt-5 grid gap-5 md:grid-cols-2">
{uses.map((group) => (
<article class="rounded-md border border-border/70 p-5">
<h3 class="text-base font-bold">{group.title[lang]}</h3>
<ul class="mt-3 space-y-1.5 text-sm text-muted-foreground">
{group.items.map((item) => <li>• {item}</li>)}
</ul>
</article>
))}
</div>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="work-style">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工作方式' : 'Work Style'}</h2>
<ul class="mt-4 space-y-3 text-muted-foreground">
{workStyle.map((item) => (
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item}</span></li>
))}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-8" id="contact-brief">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '联系(简版)' : 'Contact Brief'}</h2>
<p class="mt-3 text-muted-foreground">{isZh ? '优先沟通远程岗位机会,其次为项目合作咨询。' : 'Remote role opportunities are prioritized, followed by project collaboration.'}</p>
<ul class="mt-5 space-y-3 text-sm">
{contactMethods.slice(0, 2).map((method) => (
<li class="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between border-b border-border/70 pb-3">
<span class="font-semibold text-foreground">{method.label[lang]}</span>
{method.href ? (
<a href={method.href} target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 break-all">{method.value}</a>
) : (
<span class="text-muted-foreground break-all">{method.value}</span>
)}
</li>
))}
</ul>
<div class="mt-6 flex flex-wrap gap-3">
<a href={`${prefix}/contact`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '进入完整联系页' : 'Open Full Contact Page'}</a>
<a href={`${prefix}/contact#project-collaboration`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '项目合作入口' : 'Project Collaboration'}</a>
</div>
</section>
</Container>
</main>

View File

@@ -23,6 +23,12 @@ const isZh = lang === 'zh';
? '欢迎联系我沟通远程岗位或项目合作。默认优先响应远程岗位机会。'
: 'Open to remote role opportunities and project collaboration. Remote role discussions are prioritized.'}
</p>
<p class="mt-2 text-sm text-muted-foreground">
{isZh ? '想先了解合作方式与付款方式?请查看' : 'Want details on collaboration and payment terms first? Visit'}
{' '}
<a href={isZh ? '/zh/hire' : '/hire'} class="text-primary hover:text-primary/80">{isZh ? '合作页面' : 'Hire page'}</a>
</p>
</section>
<section class="page-content-main mt-10 grid gap-6 md:grid-cols-2">
@@ -55,6 +61,17 @@ const isZh = lang === 'zh';
: 'Suggestion: include role/project context, expected collaboration model, and timeline in your first message.'}
</p>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '需求信息模板' : 'Request Template'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
<li>1. {isZh ? '你是谁 / 团队背景' : 'Who you are / team context'}</li>
<li>2. {isZh ? '项目目标与当前现状' : 'Project goal and current status'}</li>
<li>3. {isZh ? '期望上线时间与协作周期' : 'Target timeline and collaboration window'}</li>
<li>4. {isZh ? '预算区间或岗位信息' : 'Budget range or role details'}</li>
<li>5. {isZh ? '优先沟通方式(邮箱/即时通讯)' : 'Preferred communication channel (email/chat)'}</li>
</ul>
</section>
</Container>
</main>

View File

@@ -1,3 +1,178 @@
---
return Astro.redirect('/zh/contact', 301);
import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
const models = isZh
? [
{
title: '远程岗位合作',
desc: '适合长期加入团队,以资深前端/全栈角色参与核心产品建设。',
},
{
title: '项目制交付',
desc: '适合目标明确的系统建设、重构与性能优化项目,按阶段交付。',
},
{
title: '技术咨询/顾问',
desc: '适合架构评审、工程治理、复杂问题诊断与实施建议。',
},
]
: [
{
title: 'Remote Role',
desc: 'Long-term collaboration as a senior frontend/full-stack engineer on core products.',
},
{
title: 'Project Delivery',
desc: 'Milestone-based delivery for scoped system builds, refactors, and performance optimization.',
},
{
title: 'Technical Consulting',
desc: 'Architecture reviews, engineering governance, complex issue diagnosis, and execution guidance.',
},
];
const paymentOptions = isZh
? ['里程碑付款(推荐)', '月度结算(长期合作)', '咨询按小时或按天计费']
: ['Milestone-based payments (recommended)', 'Monthly settlement (for long-term collaboration)', 'Hourly or daily consulting billing'];
const startingPackages = isZh
? [
'Bug 修复¥800 起(按问题复杂度评估)',
'小型定制页面/落地页¥3000 起',
'后台模块开发¥6000 起(按里程碑)',
]
: [
'Bug fixing: from $120 (scoped by issue complexity)',
'Small custom page/landing page: from $450',
'Admin module delivery: from $850 (milestone-based)',
];
const process = isZh
? ['需求沟通与目标确认', '方案评估与范围定义', '里程碑排期与执行', '阶段验收与交付总结']
: ['Discovery and goal alignment', 'Solution assessment and scope definition', 'Milestone planning and execution', 'Stage acceptance and delivery summary'];
const boundaries = isZh
? [
'默认不承接违法或高风险灰色业务。',
'需求变更超出范围时,会先同步影响与补充报价。',
'交付文档、代码与协作记录会保持透明可追踪。',
]
: [
'No illegal or high-risk gray-area business engagements.',
'Out-of-scope changes are assessed first with impact and updated pricing.',
'Delivery docs, code, and collaboration records remain transparent and traceable.',
];
const faqItems = isZh
? [
{ q: '多久回复?', a: '默认 24 小时内给出初步回复,紧急问题可优先处理。' },
{ q: '如何开始合作?', a: '先在联系页提交背景与目标,我会给出范围评估与合作建议。' },
{ q: '需求变更多怎么办?', a: '超出原范围会先同步影响、排期和补充报价,再继续执行。' },
]
: [
{ q: 'Response time?', a: 'Initial response is usually within 24 hours, with priority handling for urgent issues.' },
{ q: 'How do we start?', a: 'Submit your context and goals on the contact page, then I provide scope assessment and recommendations.' },
{ q: 'What about scope changes?', a: 'Out-of-scope changes are reviewed with impact and revised pricing before execution.' },
];
---
<Layout title={isZh ? '合作' : 'Hire'}>
<GlassHeader lang={lang} client:load transition:persist="header" />
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '合作方式' : 'Work With Me'}</h1>
<p class="mt-4 text-lg leading-relaxed text-muted-foreground">
{isZh
? '这个页面用于明确合作方式、付款方式、交付流程与边界,方便你快速判断是否匹配。'
: 'This page outlines collaboration models, payment methods, delivery process, and boundaries to quickly assess fit.'}
</p>
</section>
<section class="page-content-main mt-10">
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作方式' : 'Collaboration Models'}</h2>
<div class="mt-4 grid gap-4 md:grid-cols-3">
{models.map((model) => (
<article class="page-surface p-5">
<h3 class="text-lg font-bold">{model.title}</h3>
<p class="mt-2 text-sm text-muted-foreground">{model.desc}</p>
</article>
))}
</div>
</section>
<section class="page-content-main mt-6 grid gap-6 md:grid-cols-2">
<article class="page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '付款方式' : 'Payment Terms'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{paymentOptions.map((item) => <li>• {item}</li>)}
</ul>
</article>
<article class="page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '交付流程' : 'Delivery Process'}</h2>
<ol class="mt-4 space-y-2 text-sm text-muted-foreground list-decimal pl-5">
{process.map((item) => <li>{item}</li>)}
</ol>
</article>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '参考起步价' : 'Starting Packages'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{startingPackages.map((item) => <li>• {item}</li>)}
</ul>
<p class="mt-3 text-xs text-muted-foreground">
{isZh ? '说明:最终报价会根据需求复杂度、时间窗口与交付范围确认。' : 'Note: final pricing depends on complexity, timeline, and agreed delivery scope.'}
</p>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '合作边界与说明' : 'Engagement Boundaries'}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{boundaries.map((item) => <li>• {item}</li>)}
</ul>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '常见问题' : 'FAQ'}</h2>
<div class="mt-4 space-y-4">
{faqItems.map((item) => (
<div class="rounded-md border border-border/70 p-4">
<p class="text-sm font-semibold">{item.q}</p>
<p class="mt-2 text-sm text-muted-foreground">{item.a}</p>
</div>
))}
</div>
</section>
<section class="page-content-main mt-6 page-surface p-6">
<h2 class="text-xl font-bold">{isZh ? '下一步' : 'Next Step'}</h2>
<p class="mt-3 text-sm text-muted-foreground">
{isZh
? '如果你已经有明确岗位或项目需求,请进入联系页提交背景、目标、时间与预算信息。'
: 'If you already have a role or project in mind, continue to the contact page with context, goals, timeline, and budget.'}
</p>
<div class="mt-5 flex flex-wrap gap-3">
<a href={isZh ? '/zh/contact' : '/contact'} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">
{isZh ? '进入联系页' : 'Go to Contact'}
</a>
<a href={isZh ? '/zh/contact#project-collaboration' : '/contact#project-collaboration'} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">
{isZh ? '项目合作入口' : 'Project Collaboration'}
</a>
</div>
</section>
</Container>
</main>
<Footer lang={lang} client:load />
</Layout>

View File

@@ -14,15 +14,27 @@ const prefix = isZh ? '/zh' : '';
const featuredProjects = projects[lang].filter((item) => item.featured).slice(0, 3);
const proofItems = isZh
? ['8 年 Web 开发经验', '企业级复杂系统交付', '金融与区块链基础设施', '远程协作与稳定交付']
: ['8 years in web engineering', 'Enterprise-grade complex systems', 'Finance & blockchain infrastructure', 'Remote-first stable delivery'];
? ['8 年全栈开发经验', '支持定制开发与项目外包', '可承接紧急 Bug 修复', '远程协作与稳定交付']
: ['8 years in full-stack engineering', 'Available for custom development and outsourcing', 'Open for urgent bug fixing', 'Remote-first stable delivery'];
const headline = isZh
? '资深前端工程师,构建复杂系统与 AI 协作产品'
: 'Senior Frontend Engineer building complex systems and AI-assisted products';
? '全栈工程师,专注复杂系统开发与高质量交付'
: 'Full-stack Engineer focused on complex system development and reliable delivery';
const intro = personalInfo.description[lang];
const serviceItems = isZh
? [
{ title: '网站/系统定制开发', desc: '从需求梳理到上线交付,适合中小型业务系统与管理后台。' },
{ title: '项目外包与模块开发', desc: '可按里程碑承接功能模块开发、重构与性能优化。' },
{ title: 'Bug 修复与线上排障', desc: '支持紧急问题排查与修复,默认 24 小时内给出初步反馈。' },
]
: [
{ title: 'Custom Website/System Development', desc: 'From requirement definition to production delivery for business systems.' },
{ title: 'Outsourcing & Module Delivery', desc: 'Milestone-based module development, refactoring, and performance optimization.' },
{ title: 'Bug Fixing & Production Troubleshooting', desc: 'Support for urgent issues with initial response within 24 hours.' },
];
const postModules = await import.meta.glob('./blog/posts/*.md', { eager: true });
const latestPosts = sortPostsByDate(
Object.values(postModules).map((post: any) => ({
@@ -45,8 +57,8 @@ const latestPosts = sortPostsByDate(
<p class="max-w-3xl text-lg leading-relaxed text-muted-foreground">{intro}</p>
<div class="flex flex-wrap gap-4 pt-2">
<a href={`${prefix}/contact`} class="inline-flex h-11 items-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground hover:bg-primary/90">{isZh ? '远程岗位沟通' : 'Hire for Remote Role'}</a>
<a href={`${prefix}/contact#project-collaboration`} class="inline-flex h-11 items-center rounded-lg border border-border px-6 text-sm font-semibold text-foreground hover:bg-muted">{isZh ? '发起项目合作' : 'Start a Project'}</a>
<a href={`${prefix}/hire`} class="inline-flex h-11 items-center rounded-lg bg-primary px-6 text-sm font-semibold text-primary-foreground hover:bg-primary/90">{isZh ? '查看合作方式' : 'View Collaboration'}</a>
<a href={`${prefix}/contact`} class="inline-flex h-11 items-center rounded-lg border border-border px-6 text-sm font-semibold text-foreground hover:bg-muted">{isZh ? '立即联系' : 'Contact Now'}</a>
</div>
<ul class="grid gap-3 sm:grid-cols-2 pt-4">
@@ -56,6 +68,21 @@ const latestPosts = sortPostsByDate(
</ul>
</section>
<section class="page-content-main mt-20">
<div class="mb-8 flex items-end justify-between gap-4">
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '我能提供的服务' : 'Services I Offer'}</h2>
<a href={`${prefix}/hire`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看合作细节' : 'View Hire Page'}</a>
</div>
<div class="grid gap-4 md:grid-cols-3">
{serviceItems.map((item) => (
<article class="page-surface p-5">
<h3 class="text-base font-bold">{item.title}</h3>
<p class="mt-2 text-sm text-muted-foreground">{item.desc}</p>
</article>
))}
</div>
</section>
<section class="page-content-main mt-20">
<div class="mb-8 flex items-end justify-between gap-4">
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '精选工程案例' : 'Selected Engineering Cases'}</h2>

View File

@@ -1,40 +1,3 @@
---
import Layout from '@/layouts/Layout.astro';
import GlassHeader from '@/components/GlassHeader';
import Footer from '@/components/Footer';
import Container from '@/components/ui/Container.astro';
import { uses } from '@/lib/data';
import type { Lang } from '@/types/i18n';
import { defaultLang } from '@/i18n/ui';
const lang = (Astro.currentLocale as Lang) || defaultLang;
const isZh = lang === 'zh';
return Astro.redirect('/zh/about#uses', 301);
---
<Layout title={isZh ? '工具' : 'Uses'}>
<GlassHeader lang={lang} client:load transition:persist="header" />
<main class="min-h-screen pt-24 pb-20">
<Container>
<section class="page-content-main">
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">{isZh ? '工具与工作流' : 'Uses'}</h1>
<p class="mt-4 text-lg text-muted-foreground">
{isZh ? '我在日常研发中稳定使用的工具与协作方式。' : 'Tools and workflows I use for daily engineering work.'}
</p>
</section>
<section class="page-content-main mt-10 grid gap-6 md:grid-cols-2">
{uses.map((group) => (
<article class="page-surface p-6">
<h2 class="text-lg font-bold">{group.title[lang]}</h2>
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
{group.items.map((item) => <li>• {item}</li>)}
</ul>
</article>
))}
</section>
</Container>
</main>
<Footer lang={lang} client:load />
</Layout>