feat(site): optimize full-stack positioning and collaboration conversion pages
This commit is contained in:
@@ -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) },
|
||||
];
|
||||
|
||||
|
||||
@@ -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: '你好,我是',
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user