diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 83673ca..08f6a02 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,7 +1,9 @@ import { notFound } from "next/navigation" -import { setRequestLocale } from 'next-intl/server' +import { setRequestLocale, getTranslations } from 'next-intl/server' import Link from "next/link" import { LocaleSwitcher } from "@/components/locale/LocaleSwitcher" +import { AnnouncementBar } from "@/components/layout/AnnouncementBar" +import type { Metadata } from "next" const locales = ['zh', 'en'] @@ -9,6 +11,20 @@ export async function generateStaticParams() { return locales.map((locale) => ({ locale })) } +export async function generateMetadata({ + params +}: { + params: Promise<{ locale: string }> +}): Promise { + const { locale } = await params + const t = await getTranslations('home') + + return { + title: t('metaTitle'), + description: t('metaDescription'), + } +} + export default async function LocaleLayout({ children, params @@ -23,13 +39,15 @@ export default async function LocaleLayout({ setRequestLocale(locale) + // Get translations + const t = await getTranslations('layout') + const tNav = await getTranslations('navigation') + const tHome = await getTranslations('home') + return (
{/* Top announcement bar */} -
- DISCOVER THE FUTURE OF AI AGENTS - arrow_forward -
+ {/* Navigation */}
@@ -49,36 +67,39 @@ export default async function LocaleLayout({ className="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors" href={`/${locale}`} > - HOME + {tNav('home')} - PROJECTS + {tNav('projects')} - BLOG + {tNav('blog')} - ABOUT + {tNav('about')} {/* Right side */}
- + - SUBMIT PROJECT + {tNav('submitProject')}
@@ -98,27 +119,31 @@ export default async function LocaleLayout({
-

STAY UPDATED

+

{t('stayUpdated')}

- Get the latest AI tools and trends delivered straight to your inbox. No spam, just intelligence. + {t('stayUpdatedDesc')}

- +
@@ -144,26 +169,26 @@ export default async function LocaleLayout({ Agent Park

- Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts. + {t('footerDesc')}

-

Resources

+

{t('resources')}

    -
  • Blog
  • +
  • {tNav('blog')}
  • Newsletter
  • Documentation
-

Legal

+

{t('legal')}

    -
  • Privacy Policy
  • -
  • Terms of Service
  • +
  • {t('privacyPolicy')}
  • +
  • {t('termsOfService')}
-

Follow Us

+

{t('followUs')}

X Li @@ -172,9 +197,9 @@ export default async function LocaleLayout({
-

© 2025 Agent Park. All rights reserved.

+

{t('copyright')}

- DESIGNED FOR AI BUILDERS + {t('designedFor')}
diff --git a/src/components/layout/AnnouncementBar.tsx b/src/components/layout/AnnouncementBar.tsx new file mode 100644 index 0000000..2084ef3 --- /dev/null +++ b/src/components/layout/AnnouncementBar.tsx @@ -0,0 +1,52 @@ +'use client' + +import { useState, useEffect } from 'react' +import Link from 'next/link' + +interface AnnouncementBarProps { + text: string + href: string + locale: string +} + +export function AnnouncementBar({ text, href, locale }: AnnouncementBarProps) { + const [isVisible, setIsVisible] = useState(true) + + useEffect(() => { + // Check if user has closed the announcement before + const hasClosed = localStorage.getItem('announcement-closed') + if (hasClosed === 'true') { + setIsVisible(false) + } + }, []) + + const handleClose = (e: React.MouseEvent) => { + e.preventDefault() // Prevent link navigation + e.stopPropagation() + setIsVisible(false) + localStorage.setItem('announcement-closed', 'true') + } + + if (!isVisible) { + return null + } + + return ( + + {text} + arrow_forward + + {/* Close button */} + + + ) +} diff --git a/src/messages/en.json b/src/messages/en.json index 8f49ac0..d73e3e6 100644 --- a/src/messages/en.json +++ b/src/messages/en.json @@ -3,15 +3,19 @@ "search": "Search", "loading": "Loading...", "noResults": "No results found", + "noProjects": "No projects yet", "viewMore": "View More", - "backToHome": "Back to Home" + "backToHome": "Back to Home", + "viewDetails": "VIEW DETAILS" }, "home": { "title": "AI Project Navigator", "subtitle": "Discover and explore AI projects", "featuredProjects": "Featured Projects", "browseByTag": "Browse by Tag", - "searchPlaceholder": "Search AI projects..." + "searchPlaceholder": "Search AI projects...", + "metaTitle": "Agent Park - AI Project Navigator", + "metaDescription": "Discover and explore quality AI projects from across the web" }, "project": { "details": "Project Details", @@ -21,11 +25,34 @@ "website": "Website", "github": "GitHub", "huggingface": "HuggingFace", - "paper": "Paper" + "paper": "Paper", + "submitYourProject": "Submit Your Project", + "submitProjectTitle": "Submit Your Project", + "submitProjectDescription": "Have an AI tool worth sharing? Add it to Agent Park.", + "submitNow": "SUBMIT NOW" }, "navigation": { "home": "Home", "projects": "Projects", - "about": "About" + "blog": "Blog", + "about": "About", + "submitProject": "SUBMIT PROJECT" + }, + "layout": { + "announcement": "DISCOVER THE FUTURE OF AI AGENTS", + "announcementHref": "/projects", + "stayUpdated": "STAY UPDATED", + "stayUpdatedDesc": "Get the latest AI tools and trends delivered straight to your inbox. No spam, just intelligence.", + "email": "E-mail", + "subscribe": "SUBSCRIBE", + "subscribeConsent": "Subscribe to Agent Park updates", + "footerDesc": "Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts.", + "resources": "Resources", + "legal": "Legal", + "privacyPolicy": "Privacy Policy", + "termsOfService": "Terms of Service", + "followUs": "Follow Us", + "copyright": "© 2025 Agent Park. All rights reserved.", + "designedFor": "DESIGNED FOR AI BUILDERS" } } diff --git a/src/messages/zh.json b/src/messages/zh.json index 5803633..8e62449 100644 --- a/src/messages/zh.json +++ b/src/messages/zh.json @@ -3,15 +3,19 @@ "search": "搜索", "loading": "加载中...", "noResults": "未找到结果", + "noProjects": "暂无项目", "viewMore": "查看更多", - "backToHome": "返回首页" + "backToHome": "返回首页", + "viewDetails": "查看详情" }, "home": { "title": "AI 项目导航", "subtitle": "发现和探索全网优质 AI 项目", "featuredProjects": "精选项目", "browseByTag": "按标签浏览", - "searchPlaceholder": "搜索 AI 项目..." + "searchPlaceholder": "搜索 AI 项目...", + "metaTitle": "Agent Park - AI 项目导航", + "metaDescription": "发现和探索全网优质 AI 项目" }, "project": { "details": "项目详情", @@ -21,11 +25,34 @@ "website": "官网", "github": "GitHub", "huggingface": "HuggingFace", - "paper": "论文" + "paper": "论文", + "submitYourProject": "提交你的项目", + "submitProjectTitle": "提交你的项目", + "submitProjectDescription": "有值得分享的 AI 工具吗?将其添加到 Agent Park。", + "submitNow": "立即提交" }, "navigation": { "home": "首页", "projects": "项目列表", - "about": "关于" + "blog": "博客", + "about": "关于", + "submitProject": "提交项目" + }, + "layout": { + "announcement": "发现 AI 代理的未来", + "announcementHref": "/projects", + "stayUpdated": "保持更新", + "stayUpdatedDesc": "获取最新的 AI 工具和趋势,直接发送到您的收件箱。没有垃圾邮件,只有智能。", + "email": "电子邮箱", + "subscribe": "订阅", + "subscribeConsent": "订阅 Agent Park 更新", + "footerDesc": "发现和探索来自全网的高质量 AI 项目。为开发者和爱好者精心策划。", + "resources": "资源", + "legal": "法律", + "privacyPolicy": "隐私政策", + "termsOfService": "服务条款", + "followUs": "关注我们", + "copyright": "© 2025 Agent Park. 保留所有权利。", + "designedFor": "专为 AI 构建者设计" } }