refactor(about): modernize and unify About pages with improved design and translations
- Replaced `.mdx` files for `about` pages with `.astro` format to streamline layout and enhance flexibility. - Integrated `GlassHeader`, `HighlightBox`, and other reusable components for consistency. - Enhanced design with dynamic backgrounds, gradients, and interactive hover effects. - Updated i18n translations to support structured nested keys for improved localization and scalability. - Refined contact and skills sections with responsive layouts and clearer organization.
This commit is contained in:
@@ -78,9 +78,46 @@ export const translations = {
|
|||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
title: 'About Me',
|
title: 'About Me',
|
||||||
sectionTitle: 'About Me',
|
description: 'Learn more about my background, skills, and experiences',
|
||||||
learnMore: 'Learn More About Me',
|
intro: {
|
||||||
toolbox: 'My Toolbox',
|
title: 'Introduction',
|
||||||
|
content: "I'm a TypeScript Full Stack Engineer who loves development, technology, and exploring new possibilities. I enjoy bringing digital projects to life. 🚀",
|
||||||
|
belief: "I believe this is where ideas become reality. I'm exploring the freelance journey, striving to become a digital nomad.",
|
||||||
|
},
|
||||||
|
me: {
|
||||||
|
title: 'About me 🧠',
|
||||||
|
content: "I started my programming journey in 2016 when I accidentally encountered programming. This opportunity became the catalyst for my coding adventure, and I fell in love with programming during my subsequent self-learning journey. \n\nI enjoy creating websites and applications with code and sharing them with users. The sense of achievement I get from this process makes me increasingly fascinated. My dream is to become a lifelong coder.",
|
||||||
|
},
|
||||||
|
skills: {
|
||||||
|
title: 'My Skills 💪',
|
||||||
|
description: "Below are the technology stacks I'm currently familiar with or proficient in, as well as those I'm learning or planning to learn.",
|
||||||
|
mastered: {
|
||||||
|
title: "Skills I've Mastered",
|
||||||
|
items: ['HTML, CSS, JavaScript', 'Frontend Frameworks: Vue.js, React.js, Node.js, uniApp, WeChat Mini Program', 'TypeScript', 'Databases: MySQL, MongoDB', 'DevOps: Linux, Git', 'Others: Markdown, Docker, Kubernetes, Nginx, Apache, etc.'],
|
||||||
|
},
|
||||||
|
learning: {
|
||||||
|
title: "Skills I'm Learning/Planning to Learn",
|
||||||
|
items: ['Programming Languages: Python, Java, Go', 'Mobile Development: Flutter, Dart', 'iOS Development: Swift, SwiftUI'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
interests: {
|
||||||
|
title: 'My Interests 🌈',
|
||||||
|
items: [
|
||||||
|
{ title: 'Reading', content: 'I enjoy reading various books, especially technical ones.' },
|
||||||
|
{ title: 'Travel', content: 'I like visiting different places, particularly on road trips.' },
|
||||||
|
{ title: 'Food', content: 'I enjoy various cuisines, especially hot pot.' },
|
||||||
|
{ title: 'Mobile Games', content: 'I like playing League of Legends, Honor of Kings, PUBG Mobile, and other mobile games.' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
contact: {
|
||||||
|
title: 'Contact Me 📫',
|
||||||
|
warning: 'Since everyone\'s time is valuable, please add a note when contacting me, such as: collaboration, consultation, project requirements, etc. I may not reply to or might ignore messages without notes. Thank you for your cooperation!',
|
||||||
|
methods: {
|
||||||
|
email: 'Email: zhaoguiyang18@gmail.com',
|
||||||
|
qq: 'QQ: 2770723534',
|
||||||
|
wechat: 'WeChat: JoyCodeing',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
hero: {
|
hero: {
|
||||||
@@ -218,9 +255,46 @@ export const translations = {
|
|||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
title: '关于我',
|
title: '关于我',
|
||||||
sectionTitle: '关于我',
|
description: '了解更多关于我的背景、技能和经验',
|
||||||
learnMore: '了解更多',
|
intro: {
|
||||||
toolbox: '我的工具箱',
|
title: '简介',
|
||||||
|
content: '我是Joy Zhao, 一名Ts全栈工程师,也是本站的站长。\n\n热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。\n喜欢自驾,去追寻那些美丽的风景,尝试新的事物。',
|
||||||
|
belief: '我相信这里是想法变为现实的地方。我正在探索自由职业者之路,努力成为数字游民中的一员。',
|
||||||
|
},
|
||||||
|
me: {
|
||||||
|
title: '自我介绍 🧠',
|
||||||
|
content: '在2016年一次偶然的机会中接触到了编程,以此为契机,开始了我的编程之旅,并在后续的自学之旅中爱上了编程,我喜欢用代码编写出一个个的网页、应用,分享给用户使用,这其中获得的成就感让我愈发着迷。梦想是成为一名终身编码者。',
|
||||||
|
},
|
||||||
|
skills: {
|
||||||
|
title: '我的技能 💪',
|
||||||
|
description: '以下展示了我目前熟悉或精通的技术栈,以及正在/准备学习的技术栈。',
|
||||||
|
mastered: {
|
||||||
|
title: '已掌握的技能',
|
||||||
|
items: ['HTML、CSS、JavaScript', 'Vue.js、React.js、Node.js、uniApp、微信小程序等前端框架', 'TypeScript', 'MySQL、MongoDB', 'Linux、Git', '其他:Markdown、Docker、Kubernetes、Nginx、Apache等技术'],
|
||||||
|
},
|
||||||
|
learning: {
|
||||||
|
title: '正在/准备学习的技能',
|
||||||
|
items: ['Python、Java、Go', 'Flutter、Dart', 'Swift、SwiftUI'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
interests: {
|
||||||
|
title: '兴趣爱好 🌈',
|
||||||
|
items: [
|
||||||
|
{ title: '阅读', content: '喜欢阅读各种书籍,尤其是技术类书籍。' },
|
||||||
|
{ title: '旅游', content: '喜欢去不同的地方看看,尤其是自驾游。' },
|
||||||
|
{ title: '美食', content: '喜欢吃各种美食,尤其是火锅。' },
|
||||||
|
{ title: '手游', content: '喜欢玩英雄联盟、王者荣耀、绝地求生等手游。' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
contact: {
|
||||||
|
title: '联系我 📫',
|
||||||
|
warning: '由于大家的时间都很宝贵,所以请在联系我时添加备注,如:合作、咨询、项目需求等,不予备注的我可能不会回复或直接忽略,谢谢合作!',
|
||||||
|
methods: {
|
||||||
|
email: '邮箱:zhaoguiyang18@gmail.com',
|
||||||
|
qq: 'QQ: 2770723534',
|
||||||
|
wechat: '微信:JoyCodeing',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
hero: {
|
hero: {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { defaultLang, languages, flatTranslations } from './translations';
|
import { defaultLang, languages, flatTranslations, translations } from './translations';
|
||||||
import type { Lang } from '@/types/i18n';
|
import type { Lang } from '@/types/i18n';
|
||||||
|
|
||||||
export type TranslationKey = string;
|
export type TranslationKey = string;
|
||||||
@@ -6,27 +6,59 @@ export type TranslationKey = string;
|
|||||||
export function useTranslations(lang: Lang | undefined) {
|
export function useTranslations(lang: Lang | undefined) {
|
||||||
const currentLang = lang || defaultLang;
|
const currentLang = lang || defaultLang;
|
||||||
|
|
||||||
return function t(key: TranslationKey, ...args: any[]): string {
|
function t(key: TranslationKey, ...args: any[]): any {
|
||||||
let translation = flatTranslations[currentLang][key];
|
let translation: any = flatTranslations[currentLang][key];
|
||||||
|
|
||||||
if (!translation && currentLang !== defaultLang) {
|
// Fallback to raw translations for objects/arrays
|
||||||
translation = flatTranslations[defaultLang][key];
|
if (translation === undefined) {
|
||||||
|
const keys = key.split('.');
|
||||||
|
let current: any = translations[currentLang as keyof typeof translations];
|
||||||
|
for (const k of keys) {
|
||||||
|
if (current && typeof current === 'object' && k in current) {
|
||||||
|
current = current[k];
|
||||||
|
} else {
|
||||||
|
current = undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translation = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!translation) {
|
if (translation === undefined && currentLang !== defaultLang) {
|
||||||
|
translation = flatTranslations[defaultLang][key];
|
||||||
|
if (translation === undefined) {
|
||||||
|
const keys = key.split('.');
|
||||||
|
let current: any = translations[defaultLang as keyof typeof translations];
|
||||||
|
for (const k of keys) {
|
||||||
|
if (current && typeof current === 'object' && k in current) {
|
||||||
|
current = current[k];
|
||||||
|
} else {
|
||||||
|
current = undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translation = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (translation === undefined) {
|
||||||
console.warn(`Translation key not found: ${key}`);
|
console.warn(`Translation key not found: ${key}`);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace placeholders with arguments
|
// Replace placeholders with arguments if it's a string
|
||||||
if (args.length > 0) {
|
if (typeof translation === 'string' && args.length > 0) {
|
||||||
|
let result = translation;
|
||||||
args.forEach((arg, index) => {
|
args.forEach((arg, index) => {
|
||||||
translation = translation.replace(`{${index}}`, String(arg));
|
result = result.replace(`{${index}}`, String(arg));
|
||||||
});
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return translation;
|
return translation;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
169
src/pages/about.astro
Normal file
169
src/pages/about.astro
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
---
|
||||||
|
import Layout from "@/layouts/Layout.astro";
|
||||||
|
import GlassHeader from "@/components/GlassHeader";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import Container from "@/components/ui/Container.astro";
|
||||||
|
import HighlightBox from "@/components/markdown/HighlightBox.astro";
|
||||||
|
import { useTranslations } from "@/i18n/utils";
|
||||||
|
import type { Lang } from "@/types/i18n";
|
||||||
|
import { defaultLang } from "@/i18n/ui";
|
||||||
|
import { Sparkles, Heart, Zap, Mail, MessageSquare } from "lucide-react";
|
||||||
|
|
||||||
|
const lang = (Astro.currentLocale as Lang) || defaultLang;
|
||||||
|
const t = useTranslations(lang);
|
||||||
|
const pageTitle = t("about.title");
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={pageTitle}>
|
||||||
|
<GlassHeader client:only="react" lang={lang} />
|
||||||
|
|
||||||
|
<main class="min-h-screen relative overflow-hidden pt-16 sm:pt-20">
|
||||||
|
<!-- Background Decor -->
|
||||||
|
<div class="fixed inset-0 -z-10 h-full w-full bg-background">
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-primary/5 dark:from-primary/10 dark:via-transparent dark:to-primary/5"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="relative z-10 py-16 md:py-24">
|
||||||
|
<Container>
|
||||||
|
<div class="max-w-4xl mx-auto">
|
||||||
|
<div class="flex flex-col md:flex-row items-center gap-12 mb-16">
|
||||||
|
<div class="relative group">
|
||||||
|
<div class="absolute -inset-1 rounded-full bg-gradient-to-r from-primary to-purple-600 opacity-75 blur transition duration-1000 group-hover:opacity-100 group-hover:duration-200"></div>
|
||||||
|
<div class="relative h-48 w-48 rounded-full border-4 border-background overflow-hidden bg-muted">
|
||||||
|
<img
|
||||||
|
src="/avatar.png"
|
||||||
|
alt="Joy Zhao"
|
||||||
|
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||||
|
onerror="this.src='https://ui-avatars.com/api/?name=Joy+Zhao&background=0D8ABC&color=fff&size=200'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center md:text-left space-y-6">
|
||||||
|
<h1 class="text-4xl md:text-6xl font-bold tracking-tight">
|
||||||
|
<span class="bg-gradient-to-r from-foreground to-foreground/70 bg-clip-text text-transparent">
|
||||||
|
{t('about.title')}
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-xl text-muted-foreground leading-relaxed">
|
||||||
|
{t('about.description')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-8">
|
||||||
|
<!-- Intro Box -->
|
||||||
|
<HighlightBox type="tip" title={t('about.intro.title')}>
|
||||||
|
<div class="space-y-4 py-2">
|
||||||
|
<p class="text-lg leading-relaxed whitespace-pre-line">{t('about.intro.content')}</p>
|
||||||
|
<div class="p-4 rounded-xl bg-primary/5 border border-primary/10 italic text-primary/80">
|
||||||
|
{t('about.intro.belief')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</HighlightBox>
|
||||||
|
|
||||||
|
<!-- Self Intro -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Sparkles className="w-6 h-6 text-primary" />
|
||||||
|
{t('about.me.title')}
|
||||||
|
</h2>
|
||||||
|
<div class="prose dark:prose-invert max-w-none">
|
||||||
|
<p class="text-lg leading-relaxed text-muted-foreground whitespace-pre-line">
|
||||||
|
{t('about.me.content')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Skills Grid -->
|
||||||
|
<div class="grid md:grid-cols-2 gap-8">
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Zap className="w-6 h-6 text-yellow-500" />
|
||||||
|
{t('about.skills.mastered.title')}
|
||||||
|
</h2>
|
||||||
|
<ul class="space-y-3">
|
||||||
|
{(t('about.skills.mastered.items') as unknown as string[]).map((item: string) => (
|
||||||
|
<li class="flex items-start gap-3 text-muted-foreground">
|
||||||
|
<span class="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-primary"></span>
|
||||||
|
<span>{item}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Heart className="w-6 h-6 text-red-500" />
|
||||||
|
{t('about.skills.learning.title')}
|
||||||
|
</h2>
|
||||||
|
<ul class="space-y-3">
|
||||||
|
{(t('about.skills.learning.items') as unknown as string[]).map((item: string) => (
|
||||||
|
<li class="flex items-start gap-3 text-muted-foreground">
|
||||||
|
<span class="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-muted-foreground/30"></span>
|
||||||
|
<span>{item}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Interests -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-8">
|
||||||
|
<h2 class="text-2xl font-bold">
|
||||||
|
{t('about.interests.title')}
|
||||||
|
</h2>
|
||||||
|
<div class="grid sm:grid-cols-2 gap-6">
|
||||||
|
{(t('about.interests.items') as unknown as any[]).map((item) => (
|
||||||
|
<div class="p-4 rounded-xl bg-muted/30 border border-border/50 transition-colors hover:bg-muted/50">
|
||||||
|
<h3 class="font-bold mb-2">{item.title}</h3>
|
||||||
|
<p class="text-sm text-muted-foreground leading-relaxed">{item.content}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-8 overflow-hidden relative">
|
||||||
|
<div class="absolute top-0 right-0 p-8 opacity-5">
|
||||||
|
<Mail className="w-32 h-32" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative z-10 space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<MessageSquare className="w-6 h-6 text-primary" />
|
||||||
|
{t('about.contact.title')}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<HighlightBox type="warning" title={lang === 'zh' ? '注意' : 'Notice'}>
|
||||||
|
{t('about.contact.warning')}
|
||||||
|
</HighlightBox>
|
||||||
|
|
||||||
|
<div class="grid sm:grid-cols-3 gap-4 mt-8">
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<Mail className="w-5 h-5 text-primary" />
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">Email</span>
|
||||||
|
<span class="text-sm font-semibold break-all">{(t('about.contact.methods.email') as string).split(':')[1] || (t('about.contact.methods.email') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<span class="font-bold text-primary">QQ</span>
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">QQ</span>
|
||||||
|
<span class="text-sm font-semibold">{(t('about.contact.methods.qq') as string).split(':')[1] || (t('about.contact.methods.qq') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<MessageSquare className="w-5 h-5 text-primary" />
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">WeChat</span>
|
||||||
|
<span class="text-sm font-semibold">{(t('about.contact.methods.wechat') as string).split(':')[1] || (t('about.contact.methods.wechat') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<Footer client:load lang={lang} />
|
||||||
|
</Layout>
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
title: "About Me"
|
|
||||||
description: "Learn more about my background, skills, and experiences"
|
|
||||||
layout: "../layouts/AboutLayout.astro"
|
|
||||||
---
|
|
||||||
|
|
||||||
import HighlightBox from '../components/markdown/HighlightBox.astro';
|
|
||||||
|
|
||||||
# Joy Zhao
|
|
||||||
|
|
||||||
<HighlightBox type="info" title="Introduction">
|
|
||||||
I'm a TypeScript Full Stack Engineer who loves development, technology, and exploring new possibilities. I enjoy bringing digital projects to life. 🚀
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## About me 🧠
|
|
||||||
|
|
||||||
I started my programming journey in 2016 when I accidentally encountered programming. This opportunity became the catalyst for my coding adventure, and I fell in love with programming during my subsequent self-learning journey.
|
|
||||||
|
|
||||||
I enjoy creating websites and applications with code and sharing them with users. The sense of achievement I get from this process makes me increasingly fascinated. My dream is to become a lifelong coder.
|
|
||||||
|
|
||||||
<HighlightBox type="info">
|
|
||||||
我相信这里是想法变为现实的地方。我正在探索自由职业者之路,努力成为数字游民中的一员。
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## My Skills 💪
|
|
||||||
|
|
||||||
Below are the technology stacks I'm currently familiar with or proficient in, as well as those I'm learning or planning to learn. If your project requires technologies I'm not familiar with, don't worry - I have excellent collaborative relationships with various tech experts, including but not limited to backend developers, app developers, UI designers, product managers, etc., and can provide any services you need.
|
|
||||||
|
|
||||||
<HighlightBox type="tip" title="Skills I've Mastered">
|
|
||||||
|
|
||||||
- **HTML, CSS, JavaScript**
|
|
||||||
- **Frontend Frameworks**: Vue.js, React.js, Node.js, uniApp, WeChat Mini Program
|
|
||||||
- **TypeScript**
|
|
||||||
- **Databases**: MySQL, MongoDB
|
|
||||||
- **DevOps**: Linux, Git
|
|
||||||
- **Others**: Markdown, Docker, Kubernetes, Nginx, Apache, etc.
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
<HighlightBox type="note" title="Skills I'm Learning/Planning to Learn">
|
|
||||||
|
|
||||||
- **Programming Languages**: Python, Java, Go
|
|
||||||
- **Mobile Development**: Flutter, Dart
|
|
||||||
- **iOS Development**: Swift, SwiftUI
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## My Interests 🌈
|
|
||||||
|
|
||||||
<HighlightBox type="success" title="Hobbies & Interests">
|
|
||||||
|
|
||||||
- **Reading**: I enjoy reading various books, especially technical ones.
|
|
||||||
- **Travel**: I like visiting different places, particularly on road trips.
|
|
||||||
- **Food**: I enjoy various cuisines, especially hot pot.
|
|
||||||
- **Mobile Games**: I like playing League of Legends, Honor of Kings, PUBG Mobile, and other mobile games.
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## Contact Me 📫
|
|
||||||
|
|
||||||
<HighlightBox type="warning" title="Important Note">
|
|
||||||
Since everyone's time is valuable, please add a note when contacting me, such as: collaboration, consultation, project requirements, etc. I may not reply to or might ignore messages without notes. Thank you for your cooperation!
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
<HighlightBox type="info" title="Contact Information">
|
|
||||||
|
|
||||||
- **Email**: zhaoguiyang18@gmail.com
|
|
||||||
- **QQ**: 2770723534
|
|
||||||
- **WeChat**: JoyCodeing
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
169
src/pages/zh/about.astro
Normal file
169
src/pages/zh/about.astro
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
---
|
||||||
|
import Layout from "@/layouts/Layout.astro";
|
||||||
|
import GlassHeader from "@/components/GlassHeader";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import Container from "@/components/ui/Container.astro";
|
||||||
|
import HighlightBox from "@/components/markdown/HighlightBox.astro";
|
||||||
|
import { useTranslations } from "@/i18n/utils";
|
||||||
|
import type { Lang } from "@/types/i18n";
|
||||||
|
import { defaultLang } from "@/i18n/ui";
|
||||||
|
import { Sparkles, Heart, Zap, Mail, MessageSquare } from "lucide-react";
|
||||||
|
|
||||||
|
const lang = (Astro.currentLocale as Lang) || 'zh';
|
||||||
|
const t = useTranslations(lang);
|
||||||
|
const pageTitle = t("about.title");
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={pageTitle}>
|
||||||
|
<GlassHeader client:only="react" lang={lang} />
|
||||||
|
|
||||||
|
<main class="min-h-screen relative overflow-hidden pt-16 sm:pt-20">
|
||||||
|
<!-- Background Decor -->
|
||||||
|
<div class="fixed inset-0 -z-10 h-full w-full bg-background">
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-primary/5 dark:from-primary/10 dark:via-transparent dark:to-primary/5"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="relative z-10 py-16 md:py-24">
|
||||||
|
<Container>
|
||||||
|
<div class="max-w-4xl mx-auto">
|
||||||
|
<div class="flex flex-col md:flex-row items-center gap-12 mb-16">
|
||||||
|
<div class="relative group">
|
||||||
|
<div class="absolute -inset-1 rounded-full bg-gradient-to-r from-primary to-purple-600 opacity-75 blur transition duration-1000 group-hover:opacity-100 group-hover:duration-200"></div>
|
||||||
|
<div class="relative h-48 w-48 rounded-full border-4 border-background overflow-hidden bg-muted">
|
||||||
|
<img
|
||||||
|
src="/avatar.png"
|
||||||
|
alt="Joy Zhao"
|
||||||
|
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||||
|
onerror="this.src='https://ui-avatars.com/api/?name=Joy+Zhao&background=0D8ABC&color=fff&size=200'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center md:text-left space-y-6">
|
||||||
|
<h1 class="text-4xl md:text-6xl font-bold tracking-tight">
|
||||||
|
<span class="bg-gradient-to-r from-foreground to-foreground/70 bg-clip-text text-transparent">
|
||||||
|
{t('about.title')}
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-xl text-muted-foreground leading-relaxed">
|
||||||
|
{t('about.description')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-8">
|
||||||
|
<!-- Intro Box -->
|
||||||
|
<HighlightBox type="tip" title={t('about.intro.title')}>
|
||||||
|
<div class="space-y-4 py-2">
|
||||||
|
<p class="text-lg leading-relaxed whitespace-pre-line">{t('about.intro.content')}</p>
|
||||||
|
<div class="p-4 rounded-xl bg-primary/5 border border-primary/10 italic text-primary/80">
|
||||||
|
{t('about.intro.belief')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</HighlightBox>
|
||||||
|
|
||||||
|
<!-- Self Intro -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Sparkles className="w-6 h-6 text-primary" />
|
||||||
|
{t('about.me.title')}
|
||||||
|
</h2>
|
||||||
|
<div class="prose dark:prose-invert max-w-none">
|
||||||
|
<p class="text-lg leading-relaxed text-muted-foreground whitespace-pre-line">
|
||||||
|
{t('about.me.content')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Skills Grid -->
|
||||||
|
<div class="grid md:grid-cols-2 gap-8">
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Zap className="w-6 h-6 text-yellow-500" />
|
||||||
|
{t('about.skills.mastered.title')}
|
||||||
|
</h2>
|
||||||
|
<ul class="space-y-3">
|
||||||
|
{(t('about.skills.mastered.items') as unknown as string[]).map((item: string) => (
|
||||||
|
<li class="flex items-start gap-3 text-muted-foreground">
|
||||||
|
<span class="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-primary"></span>
|
||||||
|
<span>{item}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<Heart className="w-6 h-6 text-red-500" />
|
||||||
|
{t('about.skills.learning.title')}
|
||||||
|
</h2>
|
||||||
|
<ul class="space-y-3">
|
||||||
|
{(t('about.skills.learning.items') as unknown as string[]).map((item: string) => (
|
||||||
|
<li class="flex items-start gap-3 text-muted-foreground">
|
||||||
|
<span class="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-muted-foreground/30"></span>
|
||||||
|
<span>{item}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Interests -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-8">
|
||||||
|
<h2 class="text-2xl font-bold">
|
||||||
|
{t('about.interests.title')}
|
||||||
|
</h2>
|
||||||
|
<div class="grid sm:grid-cols-2 gap-6">
|
||||||
|
{(t('about.interests.items') as unknown as any[]).map((item) => (
|
||||||
|
<div class="p-4 rounded-xl bg-muted/30 border border-border/50 transition-colors hover:bg-muted/50">
|
||||||
|
<h3 class="font-bold mb-2">{item.title}</h3>
|
||||||
|
<p class="text-sm text-muted-foreground leading-relaxed">{item.content}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact -->
|
||||||
|
<div class="page-surface p-8 rounded-2xl border bg-card/40 backdrop-blur-md space-y-8 overflow-hidden relative">
|
||||||
|
<div class="absolute top-0 right-0 p-8 opacity-5">
|
||||||
|
<Mail className="w-32 h-32" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative z-10 space-y-6">
|
||||||
|
<h2 class="text-2xl font-bold flex items-center gap-3">
|
||||||
|
<MessageSquare className="w-6 h-6 text-primary" />
|
||||||
|
{t('about.contact.title')}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<HighlightBox type="warning" title={lang === 'zh' ? '注意' : 'Notice'}>
|
||||||
|
{t('about.contact.warning')}
|
||||||
|
</HighlightBox>
|
||||||
|
|
||||||
|
<div class="grid sm:grid-cols-3 gap-4 mt-8">
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<Mail className="w-5 h-5 text-primary" />
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">Email</span>
|
||||||
|
<span class="text-sm font-semibold break-all">{(t('about.contact.methods.email') as string).split(':')[1] || (t('about.contact.methods.email') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<span class="font-bold text-primary">QQ</span>
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">QQ</span>
|
||||||
|
<span class="text-sm font-semibold">{(t('about.contact.methods.qq') as string).split(':')[1] || (t('about.contact.methods.qq') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col p-4 rounded-xl bg-muted/30 border border-border/50 items-center text-center gap-2">
|
||||||
|
<MessageSquare className="w-5 h-5 text-primary" />
|
||||||
|
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">WeChat</span>
|
||||||
|
<span class="text-sm font-semibold">{(t('about.contact.methods.wechat') as string).split(':')[1] || (t('about.contact.methods.wechat') as string).split(': ')[1]}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<Footer client:load lang={lang} />
|
||||||
|
</Layout>
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
---
|
|
||||||
title: "关于我"
|
|
||||||
description: "了解更多关于我的背景、技能和经验"
|
|
||||||
layout: "../../layouts/AboutLayout.astro"
|
|
||||||
---
|
|
||||||
|
|
||||||
import HighlightBox from '../../components/markdown/HighlightBox.astro';
|
|
||||||
|
|
||||||
# 关于我
|
|
||||||
|
|
||||||
<HighlightBox type="info" title="简介">
|
|
||||||
我是Joy Zhao, 一名Ts全栈工程师,也是本站的站长。
|
|
||||||
|
|
||||||
热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。
|
|
||||||
喜欢自驾,去追寻那些美丽的风景,尝试新的事物。
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## 👨💻自我介绍 🧠
|
|
||||||
|
|
||||||
在2016年一次偶然的机会中接触到了编程,以此为契机,开始了我的编程之旅,并在后续的自学之旅中爱上了编程,我喜欢用代码编写出一个个的网页、应用,分享给用户使用,这其中获得的成就感让我愈发着迷。梦想是成为一名终身编码者。
|
|
||||||
|
|
||||||
## 💪我的技能
|
|
||||||
|
|
||||||
以下展示了我目前熟悉或精通的技术栈,以及正在/准备学习的技术栈。如果你的项目需要使用一些我不熟悉的技术,也请不要担心,我与一些技术大牛,包括不限于后端、App、UI设计师、产品经理等有着良好的合作关系,完全可以提供任何你需要的服务。
|
|
||||||
|
|
||||||
<HighlightBox type="info" title="已掌握的技能">
|
|
||||||
|
|
||||||
- **HTML、CSS、JavaScript**
|
|
||||||
- **Vue.js、React.js、Node.js、uniApp、微信小程序**等前端框架
|
|
||||||
- **TypeScript**
|
|
||||||
- **MySQL、MongoDB**
|
|
||||||
- **Linux、Git**
|
|
||||||
- **其他:Markdown、Docker、Kubernetes、Nginx、Apache**等技术
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
<HighlightBox type="tip" title="正在/准备学习的技能">
|
|
||||||
|
|
||||||
- **Python、Java、Go**
|
|
||||||
- **Flutter、Dart**
|
|
||||||
- **Swift、SwiftUI**
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## 🌈 兴趣爱好
|
|
||||||
|
|
||||||
<HighlightBox type="success" title="兴趣爱好">
|
|
||||||
|
|
||||||
- 阅读:喜欢阅读各种书籍,尤其是技术类书籍。
|
|
||||||
- 旅游:喜欢去不同的地方看看,尤其是自驾游。
|
|
||||||
- 美食:喜欢吃各种美食,尤其是火锅。
|
|
||||||
- 手游: 喜欢玩英雄联盟、王者荣耀、绝地求生等手游。
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
## 📱联系我
|
|
||||||
|
|
||||||
<HighlightBox type="warning" title="重要提示">
|
|
||||||
由于大家的时间都很宝贵,所以请在联系我时添加备注,如:合作、咨询、项目需求等,不予备注的我可能不会回复或直接忽略,谢谢合作!
|
|
||||||
</HighlightBox>
|
|
||||||
|
|
||||||
<HighlightBox type="info" title="联系方式">
|
|
||||||
|
|
||||||
- **邮箱:zhaoguiyang18@gmail.com**
|
|
||||||
- **QQ: 2770723534**
|
|
||||||
- **微信:JoyCodeing**
|
|
||||||
|
|
||||||
</HighlightBox>
|
|
||||||
Reference in New Issue
Block a user