feat(site): refocus portfolio for personal brand and AI full-stack profile
This commit is contained in:
45
src/components/ContactCard.astro
Normal file
45
src/components/ContactCard.astro
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
import { contactIntents, contactMethods } from '@/lib/data';
|
||||
import type { Lang } from '@/types/i18n';
|
||||
|
||||
interface Props {
|
||||
lang: Lang;
|
||||
showIntents?: boolean;
|
||||
}
|
||||
|
||||
const { lang, showIntents = true } = Astro.props;
|
||||
const isZh = lang === 'zh';
|
||||
---
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="contact-card">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '联系我' : 'Contact'}</h2>
|
||||
<p class="mt-3 text-sm text-muted-foreground">
|
||||
{isZh
|
||||
? '欢迎交流岗位机会、专项协作,或工程实践相关话题。'
|
||||
: 'Open to role opportunities, scoped collaboration, and engineering discussions.'}
|
||||
</p>
|
||||
|
||||
{showIntents && (
|
||||
<div class="mt-5 grid gap-4 md:grid-cols-3">
|
||||
{contactIntents.map((intent) => (
|
||||
<article class="rounded-md border border-border/70 p-4">
|
||||
<h3 class="text-sm font-bold">{intent.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{intent.description[lang]}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ul class="mt-6 space-y-3 text-sm">
|
||||
{contactMethods.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 last:border-none last:pb-0">
|
||||
<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>
|
||||
</section>
|
||||
@@ -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, User, Briefcase, Mail } from "lucide-react";
|
||||
import { Menu, X, Home, Rocket, PenTool, User, Briefcase, Clock3 } from "lucide-react";
|
||||
import { defaultLang } from "@/i18n/ui";
|
||||
import { type GlassHeaderProps } from "@/types";
|
||||
import { motion } from "framer-motion";
|
||||
@@ -40,11 +40,11 @@ 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.about', icon: User, href: getLocalizedPath('/about', lang) },
|
||||
{ key: 'nav.now', icon: Clock3, href: getLocalizedPath('/now', lang) },
|
||||
{ key: 'nav.hire', icon: Briefcase, href: getLocalizedPath('/hire', lang) },
|
||||
{ key: 'nav.contact', icon: Mail, href: getLocalizedPath('/contact', lang) },
|
||||
];
|
||||
|
||||
const isActive = (path: string) => {
|
||||
|
||||
@@ -17,8 +17,8 @@ export const translations = {
|
||||
now: 'Now',
|
||||
},
|
||||
site: {
|
||||
title: 'Joey Zhao - Full-stack Engineer',
|
||||
description: 'Full-stack Engineer for custom development, outsourcing projects, and reliable delivery',
|
||||
title: 'Joey Z. - AI Full-stack Engineer',
|
||||
description: 'AI full-stack engineer focused on complex systems, product delivery, and long-term maintainability',
|
||||
},
|
||||
hero: {
|
||||
greeting: "Hello, I'm",
|
||||
@@ -202,8 +202,8 @@ export const translations = {
|
||||
now: '现在',
|
||||
},
|
||||
site: {
|
||||
title: 'Joey Zhao - 全栈工程师',
|
||||
description: '承接定制开发、项目外包与高质量交付的全栈工程师',
|
||||
title: 'Joey Z. - AI 全栈工程师',
|
||||
description: '专注复杂系统、产品交付与长期可维护性的 AI 全栈工程师',
|
||||
},
|
||||
hero: {
|
||||
greeting: '你好,我是',
|
||||
@@ -266,7 +266,7 @@ export const translations = {
|
||||
description: '了解更多关于我的背景、技能和经验',
|
||||
intro: {
|
||||
title: '简介',
|
||||
content: '我是Joey Zhao, 一名Ts全栈工程师,也是本站的站长。\n\n热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。\n喜欢自驾,去追寻那些美丽的风景,尝试新的事物。',
|
||||
content: '我是Joey Z., 一名Ts全栈工程师,也是本站的站长。\n\n热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。\n喜欢自驾,去追寻那些美丽的风景,尝试新的事物。',
|
||||
belief: '我相信这里是想法变为现实的地方。我正在探索自由职业者之路,努力成为数字游民中的一员。',
|
||||
},
|
||||
me: {
|
||||
|
||||
@@ -12,7 +12,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const lang = Astro.currentLocale as Lang || defaultLang;
|
||||
const { title = "Joey Zhao - Portfolio", description = "Engineering-focused personal website" } =
|
||||
const { title = "Joey Z. - Portfolio", description = "Engineering-focused personal website" } =
|
||||
Astro.props;
|
||||
const t = useTranslations(lang);
|
||||
---
|
||||
|
||||
@@ -2,30 +2,46 @@ import type { ContactIntent, ContactMethod } from '@/types';
|
||||
|
||||
export const contactIntents: ContactIntent[] = [
|
||||
{
|
||||
id: 'remote-role',
|
||||
id: 'role-opportunity',
|
||||
title: {
|
||||
en: 'Remote Role',
|
||||
zh: '远程岗位沟通',
|
||||
en: 'Role Opportunity',
|
||||
zh: '岗位机会沟通',
|
||||
},
|
||||
description: {
|
||||
en: 'Preferred for senior frontend/full-stack roles on complex products and systems.',
|
||||
zh: '优先沟通资深前端/全栈远程岗位,偏好复杂产品与系统场景。',
|
||||
en: 'Open to senior frontend/full-stack roles where architecture and execution quality matter.',
|
||||
zh: '欢迎资深前端/全栈岗位沟通,偏好重视架构与交付质量的团队。',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'project-collaboration',
|
||||
id: 'case-collaboration',
|
||||
title: {
|
||||
en: 'Project Collaboration',
|
||||
zh: '项目合作咨询',
|
||||
en: 'Case Collaboration',
|
||||
zh: '专项协作讨论',
|
||||
},
|
||||
description: {
|
||||
en: 'Available for scoped project work involving architecture, delivery, and optimization.',
|
||||
zh: '可承接范围明确的项目合作,包括架构设计、交付落地与性能优化。',
|
||||
en: 'Best for a scoped module, architecture upgrade, or technical diagnosis with clear goals.',
|
||||
zh: '适用于目标清晰的模块建设、架构升级或技术诊断类协作。',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'knowledge-exchange',
|
||||
title: {
|
||||
en: 'Knowledge Exchange',
|
||||
zh: '内容与经验交流',
|
||||
},
|
||||
description: {
|
||||
en: 'Happy to discuss engineering practice, AI workflow experiments, or case-study insights.',
|
||||
zh: '欢迎交流工程实践、AI 协作实验与案例复盘经验。',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const contactMethods: ContactMethod[] = [
|
||||
{
|
||||
label: { en: 'Phone', zh: '电话' },
|
||||
value: '18190678380',
|
||||
href: 'tel:18190678380',
|
||||
},
|
||||
{
|
||||
label: { en: 'Email', zh: '邮箱' },
|
||||
value: '2770723534@qq.com',
|
||||
|
||||
@@ -3,3 +3,18 @@ export { projects } from './projects';
|
||||
export { services } from './services';
|
||||
export { uses } from './uses';
|
||||
export { contactIntents, contactMethods } from './contact';
|
||||
export {
|
||||
identityFacts,
|
||||
heroPrinciples,
|
||||
heroSkillGroups,
|
||||
brandProofPoints,
|
||||
brandMethodCards,
|
||||
brandTimeline,
|
||||
aboutNarrative,
|
||||
aboutCapabilities,
|
||||
aboutPrinciples,
|
||||
collaborationModels,
|
||||
collaborationFitSignals,
|
||||
collaborationProcess,
|
||||
collaborationFaq,
|
||||
} from './personal-brand';
|
||||
|
||||
415
src/lib/data/personal-brand.ts
Normal file
415
src/lib/data/personal-brand.ts
Normal file
@@ -0,0 +1,415 @@
|
||||
import type { LocalizedText } from '@/types';
|
||||
|
||||
export interface LocalizedCard {
|
||||
title: LocalizedText;
|
||||
description: LocalizedText;
|
||||
}
|
||||
|
||||
export interface TimelineItem {
|
||||
period: LocalizedText;
|
||||
title: LocalizedText;
|
||||
summary: LocalizedText;
|
||||
highlights?: LocalizedText[];
|
||||
}
|
||||
|
||||
export interface QAItem {
|
||||
question: LocalizedText;
|
||||
answer: LocalizedText;
|
||||
}
|
||||
|
||||
export interface FactItem {
|
||||
label: LocalizedText;
|
||||
value: LocalizedText;
|
||||
}
|
||||
|
||||
export interface SkillGroup {
|
||||
name: LocalizedText;
|
||||
items: string[];
|
||||
}
|
||||
|
||||
export const identityFacts: FactItem[] = [
|
||||
{
|
||||
label: { en: 'Name', zh: '姓名' },
|
||||
value: { en: 'Joey Z.', zh: 'Joey Z.' },
|
||||
},
|
||||
{
|
||||
label: { en: 'Experience', zh: '工作经验' },
|
||||
value: { en: '8 years in Web development', zh: '8 年 Web 开发经验' },
|
||||
},
|
||||
];
|
||||
|
||||
export const heroPrinciples: LocalizedText[] = [
|
||||
{
|
||||
en: 'Open to remote opportunities now. If your team is hiring, I would love to connect.',
|
||||
zh: '目前寻求远程工作机会,如你正在招聘,欢迎联系我。',
|
||||
},
|
||||
{
|
||||
en: 'Evolving from frontend toward full-stack, and building as an AI-era product engineer with an always-learning mindset.',
|
||||
zh: '我正在从前端走向全栈,持续进化为 AI 时代的产品工程师,不给自己设限。',
|
||||
},
|
||||
];
|
||||
|
||||
export const heroSkillGroups: SkillGroup[] = [
|
||||
{
|
||||
name: { en: 'Frontend Core', zh: '前端核心' },
|
||||
items: [
|
||||
'React',
|
||||
'Vue3',
|
||||
'Next.js',
|
||||
'Nuxt.js',
|
||||
'TypeScript',
|
||||
'SSR',
|
||||
'Mini Program',
|
||||
'uni-app',
|
||||
'Cross-platform Development',
|
||||
'Vite',
|
||||
'Webpack',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: { en: 'Visualization', zh: '可视化能力' },
|
||||
items: ['ECharts', 'AntV', 'G6', 'Realtime Monitoring'],
|
||||
},
|
||||
{
|
||||
name: { en: 'Full-stack', zh: '全栈协作' },
|
||||
items: ['Node.js (Express/NestJS)', 'PostgreSQL', 'Redis'],
|
||||
},
|
||||
{
|
||||
name: { en: 'Engineering', zh: '工程实践' },
|
||||
items: ['Component Library', 'Code Review', 'Tech Specs', 'Delivery Process'],
|
||||
},
|
||||
{
|
||||
name: { en: 'DevOps', zh: '运维能力' },
|
||||
items: ['Linux', 'Docker', 'CI/CD', 'Jenkins'],
|
||||
},
|
||||
];
|
||||
|
||||
export const brandProofPoints: LocalizedText[] = [
|
||||
{
|
||||
en: '8 years across enterprise, fintech, and blockchain products',
|
||||
zh: '8 年企业级、金融科技、区块链系统经验',
|
||||
},
|
||||
{
|
||||
en: 'Hands-on lead for architecture, core modules, and engineering workflows',
|
||||
zh: '可主导架构、核心模块和工程化流程落地',
|
||||
},
|
||||
{
|
||||
en: 'Strong in complex interactions, visual systems, and high-volume data workflows',
|
||||
zh: '擅长复杂交互、可视化系统和大数据量业务流程',
|
||||
},
|
||||
{
|
||||
en: 'Combines AI tooling with delivery to improve speed and clarity',
|
||||
zh: '将 AI 工具用于研发提效、项目理解与文档沉淀',
|
||||
},
|
||||
];
|
||||
|
||||
export const brandMethodCards: LocalizedCard[] = [
|
||||
{
|
||||
title: {
|
||||
en: 'Problem Framing First',
|
||||
zh: '先定义问题',
|
||||
},
|
||||
description: {
|
||||
en: 'I align business context, technical boundaries, and delivery constraints before implementation.',
|
||||
zh: '编码之前先对齐业务上下文、技术边界和交付约束。',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: {
|
||||
en: 'Architecture for Iteration',
|
||||
zh: '为迭代设计架构',
|
||||
},
|
||||
description: {
|
||||
en: 'I build module boundaries and component conventions so systems can evolve safely.',
|
||||
zh: '通过模块边界与组件规范,确保系统能稳定演进。',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: {
|
||||
en: 'Execution with Transparency',
|
||||
zh: '透明化执行',
|
||||
},
|
||||
description: {
|
||||
en: 'I keep progress visible via milestones, docs, and explicit decision records.',
|
||||
zh: '通过里程碑、文档和决策记录,让推进过程可视、可追踪。',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const brandTimeline: TimelineItem[] = [
|
||||
{
|
||||
period: {
|
||||
en: '2026.02 — Now',
|
||||
zh: '2026.02 — 至今',
|
||||
},
|
||||
title: {
|
||||
en: 'AI Full-stack Transition · Independent Product Building',
|
||||
zh: 'AI 全栈转型 · 独立工具产品实践',
|
||||
},
|
||||
summary: {
|
||||
en: 'Using full-stack skills to build practical tool products, while advancing AI agent development capabilities.',
|
||||
zh: '以全栈能力持续开发实用型工具产品,同时系统学习并实践 AI Agent 开发能力。',
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
en: 'From frontend specialization toward AI full-stack product engineering',
|
||||
zh: '从前端专项能力向 AI 全栈产品工程能力升级',
|
||||
},
|
||||
{
|
||||
en: 'Combining product thinking with engineering execution in AI-era workflows',
|
||||
zh: '在 AI 时代工作流中融合产品思维与工程落地能力',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
period: {
|
||||
en: '2025.07 — 2026.01',
|
||||
zh: '2025.07 — 2026.01',
|
||||
},
|
||||
title: {
|
||||
en: 'Frontend Tech Lead · Company A',
|
||||
zh: '前端技术负责人 · 某技术公司 A',
|
||||
},
|
||||
summary: {
|
||||
en: 'Led complex frontend refactor, visualization modules, and AI-assisted project analysis under weak documentation.',
|
||||
zh: '在文档薄弱场景下主导复杂前端重构、可视化模块建设和 AI 辅助代码分析。',
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
en: 'Optimized engineering structure and build workflow for better stability',
|
||||
zh: '优化前端工程结构与构建流程,提升系统稳定性',
|
||||
},
|
||||
{
|
||||
en: 'Generated technical docs via AI-assisted analysis to reduce onboarding cost',
|
||||
zh: '通过 AI 工具梳理技术说明,降低团队理解和上手成本',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
period: {
|
||||
en: '2021.03 — 2025.06',
|
||||
zh: '2021.03 — 2025.06',
|
||||
},
|
||||
title: {
|
||||
en: 'Frontend Engineer · Company B',
|
||||
zh: '前端开发 · 某科技公司 B',
|
||||
},
|
||||
summary: {
|
||||
en: 'Led architecture for 3 core systems and delivered from zero to one with Vue3 + TypeScript.',
|
||||
zh: '主导 3 个核心项目架构设计,使用 Vue3 + TypeScript 推进从 0 到 1 建设。',
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
en: 'Built 30+ reusable business components and internal component library',
|
||||
zh: '沉淀 30+ 通用业务组件并构建内部组件库',
|
||||
},
|
||||
{
|
||||
en: 'Drove technical standards and team engineering sharing',
|
||||
zh: '制定技术规范并持续推动团队工程实践分享',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
period: {
|
||||
en: '2020.10 — 2021.03',
|
||||
zh: '2020.10 — 2021.03',
|
||||
},
|
||||
title: {
|
||||
en: 'Frontend Engineer · Company C',
|
||||
zh: '前端开发 · 某科技公司 C',
|
||||
},
|
||||
summary: {
|
||||
en: 'Owned architecture selection for 2 blockchain systems and built key reusable components.',
|
||||
zh: '主导 2 个区块链项目架构选型并封装核心业务组件。',
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
en: 'Wrote onboarding manual and trained 5 new engineers',
|
||||
zh: '编写前端新人手册并完成 5 名新员工培训',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
period: {
|
||||
en: '2019.04 — 2020.09',
|
||||
zh: '2019.04 — 2020.09',
|
||||
},
|
||||
title: {
|
||||
en: 'Frontend Team Lead · Company D',
|
||||
zh: '前端组长 · 某科技公司 D',
|
||||
},
|
||||
summary: {
|
||||
en: 'Set up a unified multi-end frontend framework for app, admin, mini-program, and public account.',
|
||||
zh: '搭建多端统一前端开发框架,覆盖 App、管理后台、小程序与公众号。',
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
en: 'Pushed coding/Git conventions and delivered 8 projects on schedule',
|
||||
zh: '推动代码与 Git 规范落地,支撑 8 个项目按时上线',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
period: {
|
||||
en: '2018.03 — 2019.03',
|
||||
zh: '2018.03 — 2019.03',
|
||||
},
|
||||
title: {
|
||||
en: 'Frontend Engineer · Company E',
|
||||
zh: '前端开发 · 某科技公司 E',
|
||||
},
|
||||
summary: {
|
||||
en: 'Maintained 3 core products across Web and mobile while ensuring stable iterative delivery.',
|
||||
zh: '参与 Web 与移动端项目开发,维护 3 个核心产品并保障系统稳定迭代。',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const aboutNarrative: LocalizedText[] = [
|
||||
{
|
||||
en: 'I focus on complex business systems where architecture and long-term maintainability are critical.',
|
||||
zh: '我长期专注复杂业务系统,核心关注点是架构质量和长期可维护性。',
|
||||
},
|
||||
{
|
||||
en: 'My strengths combine frontend architecture, engineering processes, and cross-role collaboration.',
|
||||
zh: '我的优势在于前端架构能力、工程化推进能力和跨角色协作。',
|
||||
},
|
||||
{
|
||||
en: 'This website is my long-term knowledge base for projects, methods, and practical lessons.',
|
||||
zh: '这个网站会持续沉淀项目案例、工作方法与可复用经验。',
|
||||
},
|
||||
];
|
||||
|
||||
export const aboutCapabilities: LocalizedText[] = [
|
||||
{
|
||||
en: 'Complex frontend system architecture and module governance',
|
||||
zh: '复杂前端系统架构与模块治理',
|
||||
},
|
||||
{
|
||||
en: 'Data visualization and real-time interaction system implementation',
|
||||
zh: '数据可视化与实时交互系统开发',
|
||||
},
|
||||
{
|
||||
en: 'From-zero-to-one product frontend setup and engineering standardization',
|
||||
zh: '从 0 到 1 前端体系建设与工程规范落地',
|
||||
},
|
||||
{
|
||||
en: 'AI-assisted code understanding, documentation, and troubleshooting',
|
||||
zh: 'AI 辅助代码理解、文档沉淀与问题排查',
|
||||
},
|
||||
];
|
||||
|
||||
export const aboutPrinciples: LocalizedText[] = [
|
||||
{
|
||||
en: 'Prefer clear architecture over temporary speed gains.',
|
||||
zh: '短期速度可以妥协,但架构清晰度不能妥协。',
|
||||
},
|
||||
{
|
||||
en: 'Treat delivery quality as a system, not a one-time output.',
|
||||
zh: '交付质量是系统能力,不是一次性产出。',
|
||||
},
|
||||
{
|
||||
en: 'Document decisions to reduce team communication cost.',
|
||||
zh: '关键决策文档化,降低团队协作成本。',
|
||||
},
|
||||
];
|
||||
|
||||
export const collaborationModels: LocalizedCard[] = [
|
||||
{
|
||||
title: {
|
||||
en: 'Role Collaboration',
|
||||
zh: '岗位型协作',
|
||||
},
|
||||
description: {
|
||||
en: 'Join as a senior frontend/full-stack contributor for medium to long-term product building.',
|
||||
zh: '以资深前端/全栈角色加入团队,参与中长期产品建设。',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: {
|
||||
en: 'Case-based Delivery',
|
||||
zh: '专项课题交付',
|
||||
},
|
||||
description: {
|
||||
en: 'Deliver a scoped module, architecture upgrade, or performance optimization initiative.',
|
||||
zh: '围绕明确范围的模块建设、架构升级或性能优化进行阶段性交付。',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: {
|
||||
en: 'Advisory Session',
|
||||
zh: '顾问与评审',
|
||||
},
|
||||
description: {
|
||||
en: 'Provide technical diagnosis and implementation guidance for difficult engineering problems.',
|
||||
zh: '面向复杂工程问题提供技术诊断与实施建议。',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const collaborationFitSignals: LocalizedText[] = [
|
||||
{
|
||||
en: 'You value long-term maintainability, not just quick patching.',
|
||||
zh: '你重视长期可维护性,而不仅是短期修补。',
|
||||
},
|
||||
{
|
||||
en: 'Your team needs a reliable engineer to own ambiguous, complex modules.',
|
||||
zh: '你的团队需要有人能接住复杂且边界不清的核心模块。',
|
||||
},
|
||||
{
|
||||
en: 'You prefer transparent communication and documented decisions.',
|
||||
zh: '你希望协作过程透明,关键决策可追溯。',
|
||||
},
|
||||
];
|
||||
|
||||
export const collaborationProcess: LocalizedText[] = [
|
||||
{
|
||||
en: 'Align context and expected outcomes',
|
||||
zh: '对齐上下文与预期结果',
|
||||
},
|
||||
{
|
||||
en: 'Define scope, constraints, and ownership boundaries',
|
||||
zh: '明确范围、约束与责任边界',
|
||||
},
|
||||
{
|
||||
en: 'Execute in visible milestones with regular updates',
|
||||
zh: '以可见里程碑推进并定期同步',
|
||||
},
|
||||
{
|
||||
en: 'Review outcomes and capture reusable learnings',
|
||||
zh: '复盘结果并沉淀可复用经验',
|
||||
},
|
||||
];
|
||||
|
||||
export const collaborationFaq: QAItem[] = [
|
||||
{
|
||||
question: {
|
||||
en: 'Do you only do project-based work?',
|
||||
zh: '你只做项目制合作吗?',
|
||||
},
|
||||
answer: {
|
||||
en: 'No. Role collaboration and long-term engineering participation are both welcome.',
|
||||
zh: '不是。岗位型长期协作和阶段性项目合作都可以。',
|
||||
},
|
||||
},
|
||||
{
|
||||
question: {
|
||||
en: 'What should I send before the first discussion?',
|
||||
zh: '第一次沟通前需要准备什么?',
|
||||
},
|
||||
answer: {
|
||||
en: 'A short context summary, desired outcome, timeline, and current blockers are enough to start.',
|
||||
zh: '提供背景、目标、时间窗口和当前卡点即可开始沟通。',
|
||||
},
|
||||
},
|
||||
{
|
||||
question: {
|
||||
en: 'Can we start with a small scope first?',
|
||||
zh: '可以先从小范围开始吗?',
|
||||
},
|
||||
answer: {
|
||||
en: 'Yes. A small pilot is often the fastest way to validate collaboration fit.',
|
||||
zh: '可以。先做小范围试点通常是验证匹配度最快的方式。',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { PersonalInfo } from '@/types';
|
||||
|
||||
export const personalInfo: PersonalInfo = {
|
||||
name: 'Joey Zhao',
|
||||
location: 'Hangzhou, China',
|
||||
name: 'Joey Z.',
|
||||
location: 'Chengdu, China',
|
||||
avatar: 'https://avatars.githubusercontent.com/u/24975063?v=4',
|
||||
email: '2770723534@qq.com',
|
||||
github: 'https://github.com/zguiyang',
|
||||
@@ -10,23 +10,23 @@ export const personalInfo: PersonalInfo = {
|
||||
website: 'https://zhaoguiyang.com',
|
||||
twitter: '',
|
||||
position: {
|
||||
en: 'Full-stack Engineer',
|
||||
zh: '全栈工程师',
|
||||
en: 'AI Full-stack Engineer',
|
||||
zh: 'AI 全栈工程师',
|
||||
},
|
||||
description: {
|
||||
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 修复与长期远程合作。',
|
||||
en: '8 years building enterprise systems, financial platforms, and blockchain infrastructure. Focused on architecture discipline, delivery quality, and long-term maintainability.',
|
||||
zh: '8 年企业系统、金融平台与区块链基础设施研发经验,关注架构纪律、交付质量与长期可维护性。',
|
||||
},
|
||||
about: {
|
||||
en: [
|
||||
'I build reliable web systems with strong architecture discipline and delivery ownership.',
|
||||
'My core experience comes from enterprise, finance, and blockchain product domains.',
|
||||
'I work effectively in remote-first teams with clear async communication and stable execution cadence.',
|
||||
'I build reliable web systems with clear module boundaries and strong delivery ownership.',
|
||||
'My core experience comes from enterprise, fintech, and blockchain product domains.',
|
||||
'I use this site as an evolving knowledge base of projects, decisions, and practical learnings.',
|
||||
],
|
||||
zh: [
|
||||
'我专注构建稳定、可维护、可扩展的 Web 系统,并对交付结果负责。',
|
||||
'核心经验来自企业级、金融科技与区块链产品场景。',
|
||||
'擅长远程协作与异步沟通,能够保持稳定节奏持续交付。',
|
||||
'我把这个网站当作持续更新的公开工作台,记录案例、方法与实践复盘。',
|
||||
],
|
||||
},
|
||||
stats: {
|
||||
@@ -38,7 +38,7 @@ export const personalInfo: PersonalInfo = {
|
||||
frontend: ['TypeScript', 'React', 'Vue', 'Astro'],
|
||||
backend: ['Node.js', 'NestJS', 'Fastify'],
|
||||
database: ['PostgreSQL', 'MySQL', 'MongoDB'],
|
||||
devops: ['Linux', 'Git', 'Docker', 'Nginx'],
|
||||
devops: ['Linux', 'Git', 'Docker', 'CI/CD', 'Jenkins', 'Nginx'],
|
||||
mobile: ['React Native', 'Flutter'],
|
||||
},
|
||||
terminal: {
|
||||
|
||||
@@ -3,33 +3,21 @@ 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, uses, contactMethods } from '@/lib/data';
|
||||
import ContactCard from '@/components/ContactCard.astro';
|
||||
import {
|
||||
personalInfo,
|
||||
uses,
|
||||
aboutNarrative,
|
||||
aboutCapabilities,
|
||||
aboutPrinciples,
|
||||
brandTimeline,
|
||||
} 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 协作开发流程实践']
|
||||
: ['Frontend architecture and module governance', 'Large-scale enterprise application delivery', 'Financial and blockchain system engineering', 'AI-assisted development workflow practices'];
|
||||
|
||||
const experienceNotes = isZh
|
||||
? [
|
||||
'8 年专业开发经验,持续参与复杂业务系统建设。',
|
||||
'参与多个政府与金融科技相关系统,包括交易平台、区块链基础设施、产业管理系统。',
|
||||
'擅长跨角色协作与远程异步沟通,注重稳定交付与长期可维护性。',
|
||||
]
|
||||
: [
|
||||
'8 years of professional development experience across complex business systems.',
|
||||
'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'}>
|
||||
@@ -40,37 +28,64 @@ const workStyle = isZh
|
||||
<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="#story" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '故事' : 'Story'}</a>
|
||||
<a href="#capabilities" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '能力' : 'Capabilities'}</a>
|
||||
<a href="#principles" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '原则' : 'Principles'}</a>
|
||||
<a href="#timeline" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '时间线' : 'Timeline'}</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>
|
||||
<p class="mt-6 text-lg leading-relaxed text-muted-foreground">
|
||||
{isZh
|
||||
? '我是一名长期在复杂业务场景中工作的 AI 全栈工程师。这个页面主要展示我的经历、能力与做事方式。'
|
||||
: 'I am an AI full-stack engineer working in complex product environments. This page focuses on my experience, capability, and way of working.'}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-10 page-surface p-8" id="experience">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
|
||||
<section class="page-content-main mt-10 page-surface p-8" id="story">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '个人叙事' : 'Narrative'}</h2>
|
||||
<div class="mt-4 space-y-4 text-muted-foreground">
|
||||
{personalInfo.about[lang].map((line) => <p>{line}</p>)}
|
||||
{aboutNarrative.map((line) => <p>{line[lang]}</p>)}
|
||||
</div>
|
||||
<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>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="capabilities">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '核心能力' : 'Core Capabilities'}</h2>
|
||||
<ul class="mt-4 grid gap-3 md:grid-cols-2 text-muted-foreground">
|
||||
{aboutCapabilities.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[lang]}</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>
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="principles">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工作原则' : 'Working Principles'}</h2>
|
||||
<ul class="mt-4 space-y-3 text-muted-foreground">
|
||||
{aboutPrinciples.map((item) => (
|
||||
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item[lang]}</span></li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="timeline">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经历时间线' : 'Career Timeline'}</h2>
|
||||
<div class="mt-5 space-y-4">
|
||||
{brandTimeline.map((item) => (
|
||||
<article class="rounded-md border border-border/70 p-5">
|
||||
<p class="text-xs font-semibold uppercase tracking-wider text-primary/80">{item.period[lang]}</p>
|
||||
<h3 class="mt-1 text-base font-bold">{item.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.summary[lang]}</p>
|
||||
{item.highlights && item.highlights.length > 0 && (
|
||||
<ul class="mt-3 space-y-1.5 text-sm text-foreground/90">
|
||||
{item.highlights.map((line) => <li>• {line[lang]}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</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">
|
||||
@@ -85,35 +100,17 @@ const workStyle = isZh
|
||||
</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.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>
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="next-step">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '下一步' : 'Next Step'}</h2>
|
||||
<p class="mt-3 text-muted-foreground">
|
||||
{isZh
|
||||
? '如果你想进一步判断合作匹配度,可以继续查看案例页与合作页。'
|
||||
: 'If you want to assess collaboration fit, continue to the project cases and collaboration page.'}
|
||||
</p>
|
||||
|
||||
<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>
|
||||
<a href={`${prefix}/projects`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '查看案例' : 'View Projects'}</a>
|
||||
<a href={`${prefix}/hire`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '查看合作页' : 'View Hire Page'}</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 border-t border-border/70 pt-4 text-sm">
|
||||
@@ -121,6 +118,8 @@ const workStyle = isZh
|
||||
<a href={personalInfo.github} target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 break-all">{personalInfo.github}</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ContactCard lang={lang} />
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ Object.values(allPosts).forEach((post: any) => {
|
||||
});
|
||||
|
||||
// Page title and description
|
||||
const title = `${categoryName} - Blog | Joey Zhao`;
|
||||
const title = `${categoryName} - Blog | Joey Z.`;
|
||||
const description = `Explore articles about ${categoryName}. Dive into my thoughts on ${categoryName} and related topics.`;
|
||||
---
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ const sortedBlogPosts = sortPostsByDate(blogPosts);
|
||||
|
||||
---
|
||||
|
||||
<BlogLayout title="Writing - Joey Zhao" description="Engineering notes on architecture, delivery, and AI-assisted development workflows.">
|
||||
<BlogLayout title="Writing - Joey Z." description="Engineering notes on architecture, delivery, and AI-assisted development workflows.">
|
||||
<main class="min-h-screen">
|
||||
<!-- Header Section -->
|
||||
<Container className="pt-24 pb-12">
|
||||
|
||||
@@ -73,7 +73,7 @@ if (tagName === decodedTag) {
|
||||
}
|
||||
|
||||
// Generate page title and description
|
||||
const title = `#${tagName} - Blog | Joey Zhao`;
|
||||
const title = `#${tagName} - Blog | Joey Z.`;
|
||||
const description = `Explore articles tagged with #${tagName}. Dive into my thoughts on ${tagName} and related topics.`;
|
||||
---
|
||||
|
||||
|
||||
@@ -1,79 +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 { contactIntents, 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';
|
||||
return Astro.redirect('/about#contact-card', 301);
|
||||
---
|
||||
|
||||
<Layout title={isZh ? '联系' : 'Contact'}>
|
||||
<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 ? '联系' : 'Contact'}</h1>
|
||||
<p class="mt-4 text-lg text-muted-foreground">
|
||||
{isZh
|
||||
? '欢迎联系我沟通远程岗位或项目合作。默认优先响应远程岗位机会。'
|
||||
: '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">
|
||||
{contactIntents.map((intent) => (
|
||||
<article id={intent.id} class="page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{intent.title[lang]}</h2>
|
||||
<p class="mt-3 text-muted-foreground">{intent.description[lang]}</p>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '联系方式' : 'Contact Methods'}</h2>
|
||||
<ul class="mt-4 space-y-3 text-sm">
|
||||
{contactMethods.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>
|
||||
|
||||
<p class="mt-5 text-xs text-muted-foreground">
|
||||
{isZh
|
||||
? '联系建议:请在邮件中注明岗位/项目背景、期望合作方式与时间窗口。'
|
||||
: '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>
|
||||
|
||||
<Footer lang={lang} client:load />
|
||||
</Layout>
|
||||
|
||||
@@ -3,85 +3,18 @@ import Layout from '@/layouts/Layout.astro';
|
||||
import GlassHeader from '@/components/GlassHeader';
|
||||
import Footer from '@/components/Footer';
|
||||
import Container from '@/components/ui/Container.astro';
|
||||
import ContactCard from '@/components/ContactCard.astro';
|
||||
import {
|
||||
collaborationModels,
|
||||
collaborationFitSignals,
|
||||
collaborationProcess,
|
||||
collaborationFaq,
|
||||
} 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 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'}>
|
||||
@@ -93,18 +26,18 @@ const faqItems = isZh
|
||||
<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.'}
|
||||
? '这个页面只做一件事:帮助你快速判断我们是否匹配。'
|
||||
: 'This page does one thing: help you quickly evaluate whether we are a good fit.'}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-10">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作方式' : 'Collaboration Models'}</h2>
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作模型(Mock)' : 'Collaboration Models (Mock)'}</h2>
|
||||
<div class="mt-4 grid gap-4 md:grid-cols-3">
|
||||
{models.map((model) => (
|
||||
{collaborationModels.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>
|
||||
<h3 class="text-lg font-bold">{model.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{model.description[lang]}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
@@ -112,44 +45,36 @@ const faqItems = isZh
|
||||
|
||||
<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>
|
||||
<h2 class="text-xl font-bold">{isZh ? '匹配信号' : 'Good Fit Signals'}</h2>
|
||||
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
|
||||
{paymentOptions.map((item) => <li>• {item}</li>)}
|
||||
{collaborationFitSignals.map((item) => <li>• {item[lang]}</li>)}
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '交付流程' : 'Delivery Process'}</h2>
|
||||
<h2 class="text-xl font-bold">{isZh ? '合作流程' : 'Collaboration Process'}</h2>
|
||||
<ol class="mt-4 space-y-2 text-sm text-muted-foreground list-decimal pl-5">
|
||||
{process.map((item) => <li>{item}</li>)}
|
||||
{collaborationProcess.map((item) => <li>{item[lang]}</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>
|
||||
<h2 class="text-xl font-bold">{isZh ? '默认协作约定' : 'Default Working Agreement'}</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>)}
|
||||
<li>• {isZh ? '以清晰目标和边界为前提,不做无定义范围的推进。' : 'We start with clear outcomes and boundaries, not ambiguous execution.'}</li>
|
||||
<li>• {isZh ? '同步节奏可按周设置,关键节点保持可见状态更新。' : 'Cadence is usually weekly, with visible updates at key checkpoints.'}</li>
|
||||
<li>• {isZh ? '文档和决策记录优先,降低沟通成本与返工风险。' : 'Documentation and decision logs are prioritized to reduce rework.'}</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '常见问题' : 'FAQ'}</h2>
|
||||
<h2 class="text-xl font-bold">{isZh ? '常见问题(Mock)' : 'FAQ (Mock)'}</h2>
|
||||
<div class="mt-4 space-y-4">
|
||||
{faqItems.map((item) => (
|
||||
{collaborationFaq.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>
|
||||
<p class="text-sm font-semibold">{item.question[lang]}</p>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.answer[lang]}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -159,18 +84,20 @@ const faqItems = isZh
|
||||
<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.'}
|
||||
? '如果你觉得方向匹配,直接在本页下方联系卡片里选择你习惯的方式联系我。'
|
||||
: 'If this direction fits, use the contact card below and send a short context brief.'}
|
||||
</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 href="#contact-card" class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">
|
||||
{isZh ? '查看联系卡片' : 'Open Contact Card'}
|
||||
</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 href={isZh ? '/zh/projects' : '/projects'} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">
|
||||
{isZh ? '先看案例' : 'View Cases First'}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ContactCard lang={lang} showIntents={false} />
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -3,7 +3,14 @@ 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, projects } from '@/lib/data';
|
||||
import {
|
||||
personalInfo,
|
||||
projects,
|
||||
identityFacts,
|
||||
heroPrinciples,
|
||||
heroSkillGroups,
|
||||
brandTimeline,
|
||||
} from '@/lib/data';
|
||||
import type { Lang } from '@/types/i18n';
|
||||
import { defaultLang } from '@/i18n/ui';
|
||||
import { sortPostsByDate } from '@/utils/blog-utils';
|
||||
@@ -12,28 +19,7 @@ const lang = (Astro.currentLocale as Lang) || defaultLang;
|
||||
const isZh = lang === 'zh';
|
||||
const prefix = isZh ? '/zh' : '';
|
||||
const featuredProjects = projects[lang].filter((item) => item.featured).slice(0, 3);
|
||||
|
||||
const proofItems = isZh
|
||||
? ['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
|
||||
? '全栈工程师,专注复杂系统开发与高质量交付'
|
||||
: '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 terminalFacts = identityFacts.filter((item) => item.label.en !== 'Experience');
|
||||
|
||||
const postModules = await import.meta.glob('./blog/posts/*.md', { eager: true });
|
||||
const latestPosts = sortPostsByDate(
|
||||
@@ -51,42 +37,104 @@ const latestPosts = sortPostsByDate(
|
||||
|
||||
<main class="min-h-screen pt-24 pb-20">
|
||||
<Container>
|
||||
<section class="page-content-main space-y-8">
|
||||
<p class="text-sm font-semibold uppercase tracking-[0.2em] text-primary">{isZh ? 'ENGINEERING PROFILE' : 'ENGINEERING PROFILE'}</p>
|
||||
<h1 class="text-4xl font-bold tracking-tight text-foreground sm:text-5xl lg:text-6xl">{headline}</h1>
|
||||
<p class="max-w-3xl text-lg leading-relaxed text-muted-foreground">{intro}</p>
|
||||
<section class="page-content-main space-y-6">
|
||||
<p class="text-sm font-semibold uppercase tracking-[0.2em] text-primary">{isZh ? 'TERMINAL PROFILE' : 'TERMINAL PROFILE'}</p>
|
||||
|
||||
<div class="flex flex-wrap gap-4 pt-2">
|
||||
<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 class="space-y-3">
|
||||
<h1 class="text-4xl font-bold tracking-tight text-foreground sm:text-5xl lg:text-6xl">{personalInfo.name}</h1>
|
||||
<p class="text-lg font-medium text-primary/90">{personalInfo.position[lang]}</p>
|
||||
</div>
|
||||
|
||||
<ul class="grid gap-3 sm:grid-cols-2 pt-4">
|
||||
{proofItems.map((item) => (
|
||||
<li class="page-surface p-4 text-sm font-medium text-foreground/90">{item}</li>
|
||||
<div class="space-y-3 text-xs leading-relaxed sm:text-sm">
|
||||
{heroPrinciples.map((line, index) => (
|
||||
<p
|
||||
class={
|
||||
index === 0
|
||||
? 'inline-flex items-center rounded-md border border-primary/35 bg-primary/10 px-3 py-1.5 font-semibold text-primary'
|
||||
: 'text-foreground/80'
|
||||
}
|
||||
>
|
||||
{index === 0 && <span class="mr-2 text-[10px] uppercase tracking-wider text-primary/80">{isZh ? 'Now Hiring' : 'Open to Work'}</span>}
|
||||
{line[lang]}
|
||||
</p>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article class="page-surface overflow-hidden border border-border/80">
|
||||
<div class="flex items-center justify-between border-b border-border/80 px-4 py-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-red-400"></span>
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-yellow-400"></span>
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-green-400"></span>
|
||||
</div>
|
||||
<p class="text-xs font-mono text-muted-foreground">joey@engineer:~</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6 p-5 font-mono text-sm">
|
||||
<div class="space-y-2">
|
||||
<p><span class="text-primary">$</span> whoami</p>
|
||||
<p class="pl-4 text-foreground">{personalInfo.name}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<p><span class="text-primary">$</span> profile --summary</p>
|
||||
<div class="grid gap-2 pl-4 text-muted-foreground sm:grid-cols-2">
|
||||
{terminalFacts.map((fact) => (
|
||||
<p><span class="text-foreground/90">{fact.label[lang]}:</span> {fact.value[lang]}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<p><span class="text-primary">$</span> stack --list</p>
|
||||
<div class="space-y-3 pl-4">
|
||||
{heroSkillGroups.map((group) => (
|
||||
<div>
|
||||
<p class="text-xs uppercase tracking-wide text-primary/80">{group.name[lang]}</p>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
{group.items.map((item) => (
|
||||
<span class="rounded-md border border-border/80 bg-muted/40 px-2 py-1 text-xs text-foreground/90">{item}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</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>
|
||||
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '经历速览' : 'Career Snapshot'}</h2>
|
||||
<a href={`${prefix}/about#timeline`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看完整经历' : 'View Full Timeline'}</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 class="relative pl-6">
|
||||
<div class="absolute left-[0.7rem] top-2 h-[calc(100%-0.5rem)] w-px bg-border"></div>
|
||||
<div class="space-y-6">
|
||||
{brandTimeline.map((item) => (
|
||||
<article class="relative rounded-lg border border-border/70 bg-card/60 p-5">
|
||||
<span class="absolute -left-[1.06rem] top-6 h-3 w-3 rounded-full border-2 border-primary bg-background"></span>
|
||||
<p class="text-xs font-semibold uppercase tracking-wider text-primary/80">{item.period[lang]}</p>
|
||||
<h3 class="mt-2 text-base font-bold leading-snug">{item.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.summary[lang]}</p>
|
||||
{item.highlights && item.highlights.length > 0 && (
|
||||
<ul class="mt-3 space-y-1.5 text-sm text-foreground/90">
|
||||
{item.highlights.map((line) => <li>• {line[lang]}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</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>
|
||||
<a href={`${prefix}/projects`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看全部案例' : 'View All Cases'}</a>
|
||||
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '项目经历' : 'Project Experience'}</h2>
|
||||
<a href={`${prefix}/projects`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看全部项目' : 'View All Projects'}</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-3">
|
||||
@@ -122,12 +170,12 @@ const latestPosts = sortPostsByDate(
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-20 page-surface p-8">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '下一步' : 'Next Step'}</h2>
|
||||
<p class="mt-3 text-muted-foreground">{isZh ? '如果你正在招聘远程工程师,或希望推进复杂系统项目,我很乐意沟通。' : 'If you are hiring for a remote engineering role or need help shipping a complex system, I would love to connect.'}</p>
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '关于合作' : 'About Collaboration'}</h2>
|
||||
<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 ? '联系我' : 'Contact Me'}</a>
|
||||
<a href={`${prefix}/about`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '了解更多' : 'About Me'}</a>
|
||||
<a href={`${prefix}/about`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '查看完整经历' : 'Read Full Profile'}</a>
|
||||
<a href={`${prefix}/hire#contact-card`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '合作与联系' : 'Collaborate & Contact'}</a>
|
||||
</div>
|
||||
<p class="mt-4 text-xs text-muted-foreground">{personalInfo.name} · {personalInfo.position[lang]} · {personalInfo.location}</p>
|
||||
</section>
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
@@ -9,6 +9,6 @@ layout: "../layouts/AboutLayout.astro"
|
||||
The old **Services** page has been replaced by focused pages:
|
||||
|
||||
- [Uses](/uses)
|
||||
- [Contact](/contact)
|
||||
- [About (Contact Card)](/about#contact-card)
|
||||
|
||||
If you are hiring for a remote role, please start from [Contact](/contact).
|
||||
If you are hiring for a remote role, please start from [Hire](/hire) and use the contact card on that page.
|
||||
|
||||
@@ -3,33 +3,21 @@ 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, uses, contactMethods } from '@/lib/data';
|
||||
import ContactCard from '@/components/ContactCard.astro';
|
||||
import {
|
||||
personalInfo,
|
||||
uses,
|
||||
aboutNarrative,
|
||||
aboutCapabilities,
|
||||
aboutPrinciples,
|
||||
brandTimeline,
|
||||
} 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 协作开发流程实践']
|
||||
: ['Frontend architecture and module governance', 'Large-scale enterprise application delivery', 'Financial and blockchain system engineering', 'AI-assisted development workflow practices'];
|
||||
|
||||
const experienceNotes = isZh
|
||||
? [
|
||||
'8 年专业开发经验,持续参与复杂业务系统建设。',
|
||||
'参与多个政府与金融科技相关系统,包括交易平台、区块链基础设施、产业管理系统。',
|
||||
'擅长跨角色协作与远程异步沟通,注重稳定交付与长期可维护性。',
|
||||
]
|
||||
: [
|
||||
'8 years of professional development experience across complex business systems.',
|
||||
'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'}>
|
||||
@@ -40,37 +28,64 @@ const workStyle = isZh
|
||||
<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="#story" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '故事' : 'Story'}</a>
|
||||
<a href="#capabilities" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '能力' : 'Capabilities'}</a>
|
||||
<a href="#principles" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '原则' : 'Principles'}</a>
|
||||
<a href="#timeline" class="rounded-md border border-border px-3 py-1 hover:bg-muted">{isZh ? '时间线' : 'Timeline'}</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>
|
||||
<p class="mt-6 text-lg leading-relaxed text-muted-foreground">
|
||||
{isZh
|
||||
? '我是一名长期在复杂业务场景中工作的 AI 全栈工程师。这个页面主要展示我的经历、能力与做事方式。'
|
||||
: 'I am an AI full-stack engineer working in complex product environments. This page focuses on my experience, capability, and way of working.'}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-10 page-surface p-8" id="experience">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经验概览' : 'Experience'}</h2>
|
||||
<section class="page-content-main mt-10 page-surface p-8" id="story">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '个人叙事' : 'Narrative'}</h2>
|
||||
<div class="mt-4 space-y-4 text-muted-foreground">
|
||||
{personalInfo.about[lang].map((line) => <p>{line}</p>)}
|
||||
{aboutNarrative.map((line) => <p>{line[lang]}</p>)}
|
||||
</div>
|
||||
<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>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="capabilities">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '核心能力' : 'Core Capabilities'}</h2>
|
||||
<ul class="mt-4 grid gap-3 md:grid-cols-2 text-muted-foreground">
|
||||
{aboutCapabilities.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[lang]}</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>
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="principles">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '工作原则' : 'Working Principles'}</h2>
|
||||
<ul class="mt-4 space-y-3 text-muted-foreground">
|
||||
{aboutPrinciples.map((item) => (
|
||||
<li class="flex gap-3"><span class="mt-2 h-1.5 w-1.5 rounded-full bg-primary"></span><span>{item[lang]}</span></li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="timeline">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '经历时间线' : 'Career Timeline'}</h2>
|
||||
<div class="mt-5 space-y-4">
|
||||
{brandTimeline.map((item) => (
|
||||
<article class="rounded-md border border-border/70 p-5">
|
||||
<p class="text-xs font-semibold uppercase tracking-wider text-primary/80">{item.period[lang]}</p>
|
||||
<h3 class="mt-1 text-base font-bold">{item.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.summary[lang]}</p>
|
||||
{item.highlights && item.highlights.length > 0 && (
|
||||
<ul class="mt-3 space-y-1.5 text-sm text-foreground/90">
|
||||
{item.highlights.map((line) => <li>• {line[lang]}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</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">
|
||||
@@ -85,35 +100,17 @@ const workStyle = isZh
|
||||
</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.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>
|
||||
<section class="page-content-main mt-6 page-surface p-8" id="next-step">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '下一步' : 'Next Step'}</h2>
|
||||
<p class="mt-3 text-muted-foreground">
|
||||
{isZh
|
||||
? '如果你想进一步判断合作匹配度,可以继续查看案例页与合作页。'
|
||||
: 'If you want to assess collaboration fit, continue to the project cases and collaboration page.'}
|
||||
</p>
|
||||
|
||||
<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>
|
||||
<a href={`${prefix}/projects`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '查看案例' : 'View Projects'}</a>
|
||||
<a href={`${prefix}/hire`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '查看合作页' : 'View Hire Page'}</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 border-t border-border/70 pt-4 text-sm">
|
||||
@@ -121,6 +118,8 @@ const workStyle = isZh
|
||||
<a href={personalInfo.github} target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 break-all">{personalInfo.github}</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ContactCard lang={lang} />
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ if (categoryName === decodedCategory) {
|
||||
}
|
||||
|
||||
// Generate page title and description
|
||||
const title = `${categoryName} - 博客 | Joey Zhao`;
|
||||
const title = `${categoryName} - 博客 | Joey Z.`;
|
||||
const description = `探索关于${categoryName}的文章。深入了解我对${categoryName}及相关主题的思考。`;
|
||||
---
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ const tags = extractTags(allPostsArray);
|
||||
|
||||
---
|
||||
|
||||
<BlogLayout title="写作 - Joey Zhao" description="聚焦架构设计、工程交付与 AI 协作开发实践的技术写作。">
|
||||
<BlogLayout title="写作 - Joey Z." description="聚焦架构设计、工程交付与 AI 协作开发实践的技术写作。">
|
||||
<main class="min-h-screen">
|
||||
<!-- 头部区域 -->
|
||||
<Container className="pt-24 pb-12">
|
||||
|
||||
@@ -74,7 +74,7 @@ if (!tagName) {
|
||||
}
|
||||
|
||||
// 动态生成页面标题和描述
|
||||
const pageTitle = `# ${tagName} - 博客 | Joey Zhao`;
|
||||
const pageTitle = `# ${tagName} - 博客 | Joey Z.`;
|
||||
const pageDescription = `浏览带有 # ${tagName} 标签的文章。深入了解我关于 ${tagName} 及相关主题的想法。`;
|
||||
---
|
||||
|
||||
|
||||
@@ -1,79 +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 { contactIntents, 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';
|
||||
return Astro.redirect('/zh/about#contact-card', 301);
|
||||
---
|
||||
|
||||
<Layout title={isZh ? '联系' : 'Contact'}>
|
||||
<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 ? '联系' : 'Contact'}</h1>
|
||||
<p class="mt-4 text-lg text-muted-foreground">
|
||||
{isZh
|
||||
? '欢迎联系我沟通远程岗位或项目合作。默认优先响应远程岗位机会。'
|
||||
: '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">
|
||||
{contactIntents.map((intent) => (
|
||||
<article id={intent.id} class="page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{intent.title[lang]}</h2>
|
||||
<p class="mt-3 text-muted-foreground">{intent.description[lang]}</p>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '联系方式' : 'Contact Methods'}</h2>
|
||||
<ul class="mt-4 space-y-3 text-sm">
|
||||
{contactMethods.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>
|
||||
|
||||
<p class="mt-5 text-xs text-muted-foreground">
|
||||
{isZh
|
||||
? '联系建议:请在邮件中注明岗位/项目背景、期望合作方式与时间窗口。'
|
||||
: '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>
|
||||
|
||||
<Footer lang={lang} client:load />
|
||||
</Layout>
|
||||
|
||||
@@ -3,85 +3,18 @@ import Layout from '@/layouts/Layout.astro';
|
||||
import GlassHeader from '@/components/GlassHeader';
|
||||
import Footer from '@/components/Footer';
|
||||
import Container from '@/components/ui/Container.astro';
|
||||
import ContactCard from '@/components/ContactCard.astro';
|
||||
import {
|
||||
collaborationModels,
|
||||
collaborationFitSignals,
|
||||
collaborationProcess,
|
||||
collaborationFaq,
|
||||
} 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 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'}>
|
||||
@@ -93,18 +26,18 @@ const faqItems = isZh
|
||||
<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.'}
|
||||
? '这个页面只做一件事:帮助你快速判断我们是否匹配。'
|
||||
: 'This page does one thing: help you quickly evaluate whether we are a good fit.'}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-10">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作方式' : 'Collaboration Models'}</h2>
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '合作模型(Mock)' : 'Collaboration Models (Mock)'}</h2>
|
||||
<div class="mt-4 grid gap-4 md:grid-cols-3">
|
||||
{models.map((model) => (
|
||||
{collaborationModels.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>
|
||||
<h3 class="text-lg font-bold">{model.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{model.description[lang]}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
@@ -112,44 +45,36 @@ const faqItems = isZh
|
||||
|
||||
<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>
|
||||
<h2 class="text-xl font-bold">{isZh ? '匹配信号' : 'Good Fit Signals'}</h2>
|
||||
<ul class="mt-4 space-y-2 text-sm text-muted-foreground">
|
||||
{paymentOptions.map((item) => <li>• {item}</li>)}
|
||||
{collaborationFitSignals.map((item) => <li>• {item[lang]}</li>)}
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '交付流程' : 'Delivery Process'}</h2>
|
||||
<h2 class="text-xl font-bold">{isZh ? '合作流程' : 'Collaboration Process'}</h2>
|
||||
<ol class="mt-4 space-y-2 text-sm text-muted-foreground list-decimal pl-5">
|
||||
{process.map((item) => <li>{item}</li>)}
|
||||
{collaborationProcess.map((item) => <li>{item[lang]}</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>
|
||||
<h2 class="text-xl font-bold">{isZh ? '默认协作约定' : 'Default Working Agreement'}</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>)}
|
||||
<li>• {isZh ? '以清晰目标和边界为前提,不做无定义范围的推进。' : 'We start with clear outcomes and boundaries, not ambiguous execution.'}</li>
|
||||
<li>• {isZh ? '同步节奏可按周设置,关键节点保持可见状态更新。' : 'Cadence is usually weekly, with visible updates at key checkpoints.'}</li>
|
||||
<li>• {isZh ? '文档和决策记录优先,降低沟通成本与返工风险。' : 'Documentation and decision logs are prioritized to reduce rework.'}</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-6 page-surface p-6">
|
||||
<h2 class="text-xl font-bold">{isZh ? '常见问题' : 'FAQ'}</h2>
|
||||
<h2 class="text-xl font-bold">{isZh ? '常见问题(Mock)' : 'FAQ (Mock)'}</h2>
|
||||
<div class="mt-4 space-y-4">
|
||||
{faqItems.map((item) => (
|
||||
{collaborationFaq.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>
|
||||
<p class="text-sm font-semibold">{item.question[lang]}</p>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.answer[lang]}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -159,18 +84,20 @@ const faqItems = isZh
|
||||
<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.'}
|
||||
? '如果你觉得方向匹配,直接在本页下方联系卡片里选择你习惯的方式联系我。'
|
||||
: 'If this direction fits, use the contact card below and send a short context brief.'}
|
||||
</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 href="#contact-card" class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">
|
||||
{isZh ? '查看联系卡片' : 'Open Contact Card'}
|
||||
</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 href={isZh ? '/zh/projects' : '/projects'} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">
|
||||
{isZh ? '先看案例' : 'View Cases First'}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ContactCard lang={lang} showIntents={false} />
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -3,7 +3,14 @@ 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, projects } from '@/lib/data';
|
||||
import {
|
||||
personalInfo,
|
||||
projects,
|
||||
identityFacts,
|
||||
heroPrinciples,
|
||||
heroSkillGroups,
|
||||
brandTimeline,
|
||||
} from '@/lib/data';
|
||||
import type { Lang } from '@/types/i18n';
|
||||
import { defaultLang } from '@/i18n/ui';
|
||||
import { sortPostsByDate } from '@/utils/blog-utils';
|
||||
@@ -12,28 +19,7 @@ const lang = (Astro.currentLocale as Lang) || defaultLang;
|
||||
const isZh = lang === 'zh';
|
||||
const prefix = isZh ? '/zh' : '';
|
||||
const featuredProjects = projects[lang].filter((item) => item.featured).slice(0, 3);
|
||||
|
||||
const proofItems = isZh
|
||||
? ['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
|
||||
? '全栈工程师,专注复杂系统开发与高质量交付'
|
||||
: '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 terminalFacts = identityFacts.filter((item) => item.label.en !== 'Experience');
|
||||
|
||||
const postModules = await import.meta.glob('./blog/posts/*.md', { eager: true });
|
||||
const latestPosts = sortPostsByDate(
|
||||
@@ -51,42 +37,104 @@ const latestPosts = sortPostsByDate(
|
||||
|
||||
<main class="min-h-screen pt-24 pb-20">
|
||||
<Container>
|
||||
<section class="page-content-main space-y-8">
|
||||
<p class="text-sm font-semibold uppercase tracking-[0.2em] text-primary">{isZh ? 'ENGINEERING PROFILE' : 'ENGINEERING PROFILE'}</p>
|
||||
<h1 class="text-4xl font-bold tracking-tight text-foreground sm:text-5xl lg:text-6xl">{headline}</h1>
|
||||
<p class="max-w-3xl text-lg leading-relaxed text-muted-foreground">{intro}</p>
|
||||
<section class="page-content-main space-y-6">
|
||||
<p class="text-sm font-semibold uppercase tracking-[0.2em] text-primary">{isZh ? 'TERMINAL PROFILE' : 'TERMINAL PROFILE'}</p>
|
||||
|
||||
<div class="flex flex-wrap gap-4 pt-2">
|
||||
<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 class="space-y-3">
|
||||
<h1 class="text-4xl font-bold tracking-tight text-foreground sm:text-5xl lg:text-6xl">{personalInfo.name}</h1>
|
||||
<p class="text-lg font-medium text-primary/90">{personalInfo.position[lang]}</p>
|
||||
</div>
|
||||
|
||||
<ul class="grid gap-3 sm:grid-cols-2 pt-4">
|
||||
{proofItems.map((item) => (
|
||||
<li class="page-surface p-4 text-sm font-medium text-foreground/90">{item}</li>
|
||||
<div class="space-y-3 text-xs leading-relaxed sm:text-sm">
|
||||
{heroPrinciples.map((line, index) => (
|
||||
<p
|
||||
class={
|
||||
index === 0
|
||||
? 'inline-flex items-center rounded-md border border-primary/35 bg-primary/10 px-3 py-1.5 font-semibold text-primary'
|
||||
: 'text-foreground/80'
|
||||
}
|
||||
>
|
||||
{index === 0 && <span class="mr-2 text-[10px] uppercase tracking-wider text-primary/80">{isZh ? 'Now Hiring' : 'Open to Work'}</span>}
|
||||
{line[lang]}
|
||||
</p>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article class="page-surface overflow-hidden border border-border/80">
|
||||
<div class="flex items-center justify-between border-b border-border/80 px-4 py-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-red-400"></span>
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-yellow-400"></span>
|
||||
<span class="h-2.5 w-2.5 rounded-full bg-green-400"></span>
|
||||
</div>
|
||||
<p class="text-xs font-mono text-muted-foreground">joey@engineer:~</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6 p-5 font-mono text-sm">
|
||||
<div class="space-y-2">
|
||||
<p><span class="text-primary">$</span> whoami</p>
|
||||
<p class="pl-4 text-foreground">{personalInfo.name}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<p><span class="text-primary">$</span> profile --summary</p>
|
||||
<div class="grid gap-2 pl-4 text-muted-foreground sm:grid-cols-2">
|
||||
{terminalFacts.map((fact) => (
|
||||
<p><span class="text-foreground/90">{fact.label[lang]}:</span> {fact.value[lang]}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<p><span class="text-primary">$</span> stack --list</p>
|
||||
<div class="space-y-3 pl-4">
|
||||
{heroSkillGroups.map((group) => (
|
||||
<div>
|
||||
<p class="text-xs uppercase tracking-wide text-primary/80">{group.name[lang]}</p>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
{group.items.map((item) => (
|
||||
<span class="rounded-md border border-border/80 bg-muted/40 px-2 py-1 text-xs text-foreground/90">{item}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</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>
|
||||
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '经历速览' : 'Career Snapshot'}</h2>
|
||||
<a href={`${prefix}/about#timeline`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看完整经历' : 'View Full Timeline'}</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 class="relative pl-6">
|
||||
<div class="absolute left-[0.7rem] top-2 h-[calc(100%-0.5rem)] w-px bg-border"></div>
|
||||
<div class="space-y-6">
|
||||
{brandTimeline.map((item) => (
|
||||
<article class="relative rounded-lg border border-border/70 bg-card/60 p-5">
|
||||
<span class="absolute -left-[1.06rem] top-6 h-3 w-3 rounded-full border-2 border-primary bg-background"></span>
|
||||
<p class="text-xs font-semibold uppercase tracking-wider text-primary/80">{item.period[lang]}</p>
|
||||
<h3 class="mt-2 text-base font-bold leading-snug">{item.title[lang]}</h3>
|
||||
<p class="mt-2 text-sm text-muted-foreground">{item.summary[lang]}</p>
|
||||
{item.highlights && item.highlights.length > 0 && (
|
||||
<ul class="mt-3 space-y-1.5 text-sm text-foreground/90">
|
||||
{item.highlights.map((line) => <li>• {line[lang]}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</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>
|
||||
<a href={`${prefix}/projects`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看全部案例' : 'View All Cases'}</a>
|
||||
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl">{isZh ? '项目经历' : 'Project Experience'}</h2>
|
||||
<a href={`${prefix}/projects`} class="text-sm font-semibold text-primary hover:text-primary/80">{isZh ? '查看全部项目' : 'View All Projects'}</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-3">
|
||||
@@ -122,12 +170,12 @@ const latestPosts = sortPostsByDate(
|
||||
</section>
|
||||
|
||||
<section class="page-content-main mt-20 page-surface p-8">
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '下一步' : 'Next Step'}</h2>
|
||||
<p class="mt-3 text-muted-foreground">{isZh ? '如果你正在招聘远程工程师,或希望推进复杂系统项目,我很乐意沟通。' : 'If you are hiring for a remote engineering role or need help shipping a complex system, I would love to connect.'}</p>
|
||||
<h2 class="text-2xl font-bold tracking-tight">{isZh ? '关于合作' : 'About Collaboration'}</h2>
|
||||
<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 ? '联系我' : 'Contact Me'}</a>
|
||||
<a href={`${prefix}/about`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '了解更多' : 'About Me'}</a>
|
||||
<a href={`${prefix}/about`} class="inline-flex h-10 items-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground">{isZh ? '查看完整经历' : 'Read Full Profile'}</a>
|
||||
<a href={`${prefix}/hire#contact-card`} class="inline-flex h-10 items-center rounded-lg border border-border px-5 text-sm font-semibold hover:bg-muted">{isZh ? '合作与联系' : 'Collaborate & Contact'}</a>
|
||||
</div>
|
||||
<p class="mt-4 text-xs text-muted-foreground">{personalInfo.name} · {personalInfo.position[lang]} · {personalInfo.location}</p>
|
||||
</section>
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
@@ -9,6 +9,6 @@ layout: "../../layouts/AboutLayout.astro"
|
||||
原 **服务** 页面已拆分为更清晰的页面:
|
||||
|
||||
- [工具](/zh/uses)
|
||||
- [联系](/zh/contact)
|
||||
- [关于(联系卡片)](/zh/about#contact-card)
|
||||
|
||||
如需沟通远程岗位,请优先前往 [联系](/zh/contact)。
|
||||
如需沟通远程岗位,请优先查看 [合作](/zh/hire),并使用页面内的联系卡片。
|
||||
|
||||
Reference in New Issue
Block a user