feat(i18n): HomePage accepts t/locale props, replaces hardcoded strings
This commit is contained in:
@@ -22,53 +22,74 @@ export type PostPreview = {
|
||||
title: string;
|
||||
description: string;
|
||||
pubDate: string;
|
||||
category: 'technical' | 'company';
|
||||
category: "technical" | "company";
|
||||
emoji?: string;
|
||||
readTime: number;
|
||||
};
|
||||
|
||||
export type HomeTranslations = {
|
||||
heroDesc1: string;
|
||||
heroDesc2: string;
|
||||
latestPostsTitle: string;
|
||||
viewAll: string;
|
||||
minRead: string;
|
||||
dateLocale: string;
|
||||
};
|
||||
|
||||
const CATEGORY_STYLE = {
|
||||
company: {
|
||||
thumb: 'from-primary/20 to-primary/40',
|
||||
tag: 'text-primary bg-primary/10',
|
||||
defaultEmoji: '🔥',
|
||||
thumb: "from-primary/20 to-primary/40",
|
||||
tag: "text-primary bg-primary/10",
|
||||
defaultEmoji: "🔥",
|
||||
},
|
||||
technical: {
|
||||
thumb: 'from-secondary/50 to-secondary/70',
|
||||
tag: 'text-secondary-foreground bg-secondary/40',
|
||||
defaultEmoji: '⚙️',
|
||||
thumb: "from-secondary/50 to-secondary/70",
|
||||
tag: "text-secondary-foreground bg-secondary/40",
|
||||
defaultEmoji: "⚙️",
|
||||
},
|
||||
} as const;
|
||||
|
||||
const LatestPosts = ({ posts }: { posts: PostPreview[] }) => {
|
||||
const LatestPosts = ({
|
||||
posts,
|
||||
t,
|
||||
locale,
|
||||
}: {
|
||||
posts: PostPreview[];
|
||||
t: HomeTranslations;
|
||||
locale: string;
|
||||
}) => {
|
||||
const blogBase = locale === "zh-cn" ? "/zh-cn/blog" : "/blog";
|
||||
if (posts.length === 0) return null;
|
||||
return (
|
||||
<section className="px-6 py-16 md:px-12 lg:px-24">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<div className="mb-10 flex items-baseline justify-between">
|
||||
<h2 className="font-heading text-foreground text-3xl font-bold md:text-4xl">
|
||||
Latest from the Blog
|
||||
{t.latestPostsTitle}
|
||||
</h2>
|
||||
<a
|
||||
href="/blog"
|
||||
href={blogBase}
|
||||
className="text-primary text-sm font-bold hover:underline"
|
||||
>
|
||||
View all →
|
||||
{t.viewAll}
|
||||
</a>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
{posts.map((post, idx) => {
|
||||
const style = CATEGORY_STYLE[post.category];
|
||||
const emoji = post.emoji ?? style.defaultEmoji;
|
||||
const date = new Date(post.pubDate).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
});
|
||||
const date = new Date(post.pubDate).toLocaleDateString(
|
||||
t.dateLocale,
|
||||
{
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
},
|
||||
);
|
||||
return (
|
||||
<motion.a
|
||||
key={post.slug}
|
||||
href={`/blog/${post.slug}`}
|
||||
href={`${blogBase}/${post.slug}`}
|
||||
initial={{ opacity: 0, y: 24 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
@@ -94,7 +115,7 @@ const LatestPosts = ({ posts }: { posts: PostPreview[] }) => {
|
||||
{post.description}
|
||||
</p>
|
||||
<p className="text-muted-foreground/70 text-xs">
|
||||
{date} · {post.readTime} min read
|
||||
{date} · {post.readTime} {t.minRead}
|
||||
</p>
|
||||
</div>
|
||||
</motion.a>
|
||||
@@ -106,7 +127,7 @@ const LatestPosts = ({ posts }: { posts: PostPreview[] }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Hero = () => {
|
||||
const Hero = ({ t }: { t: HomeTranslations }) => {
|
||||
const bodyRef = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
if (!bodyRef.current) return;
|
||||
@@ -144,14 +165,10 @@ const Hero = () => {
|
||||
Ignis Network
|
||||
</div>
|
||||
<p className="text-muted-foreground max-w-3xl text-lg leading-relaxed md:text-xl">
|
||||
We're a startup company that builds resilient digital infrastructure
|
||||
designed to endure, with AI applied where it meaningfully adds
|
||||
strength and insight.
|
||||
{t.heroDesc1}
|
||||
</p>
|
||||
<p className="text-muted-foreground mt-2 max-w-2xl text-lg leading-relaxed md:text-xl">
|
||||
We focus on stability, clarity, and long-term reliability — creating
|
||||
systems that smartly carry what matters, support growth over time,
|
||||
and let everything else move forward with confidence.
|
||||
{t.heroDesc2}
|
||||
</p>
|
||||
|
||||
<motion.div
|
||||
@@ -517,13 +534,17 @@ function _CTA() {
|
||||
|
||||
export default function Home({
|
||||
latestPosts = [],
|
||||
t,
|
||||
locale = "en",
|
||||
}: {
|
||||
latestPosts?: PostPreview[];
|
||||
t: HomeTranslations;
|
||||
locale?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="bg-background selection:bg-primary/20 selection:text-primary-foreground min-h-screen">
|
||||
<Hero />
|
||||
<LatestPosts posts={latestPosts} />
|
||||
<Hero t={t} />
|
||||
<LatestPosts posts={latestPosts} t={t} locale={locale} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user