refactor(i18n): migrate home sections to native next-intl hooks
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import ClipboardApp from "@/components/ClipboardApp";
|
||||
import { useI18n } from "@/components/providers/TranslationProvider";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { cn } from "@/lib/utils";
|
||||
import SystemDiagram from "@/components/web/SystemDiagram";
|
||||
import FAQSection from "@/components/web/FAQSection";
|
||||
@@ -10,16 +10,15 @@ import KeyFeatures from "@/components/web/KeyFeatures";
|
||||
import LazyLoadWrapper from "@/components/common/LazyLoadWrapper";
|
||||
|
||||
export default function HomeClient() {
|
||||
const { messages, lang } = useI18n();
|
||||
const t = useTranslations("text.home");
|
||||
const lang = useLocale();
|
||||
const youtube_videoId = lang === "zh" ? "I0RLCpcbUXs" : "ypt-po_R2Ds";
|
||||
const bilibili_videoId = lang === "zh" ? "BV1knrjYZEfn" : "BV1yErjYFEV7";
|
||||
return (
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
{/* Hero Section */}
|
||||
<h1 className="text-4xl font-bold mb-2 text-center">
|
||||
{messages.text.home.h1}
|
||||
</h1>
|
||||
<p className="text-xl mb-4 text-center">{messages.text.home.h1P}</p>
|
||||
<h1 className="text-4xl font-bold mb-2 text-center">{t("h1")}</h1>
|
||||
<p className="text-xl mb-4 text-center">{t("h1P")}</p>
|
||||
{/* App Section */}
|
||||
<section
|
||||
id="clipboard-app"
|
||||
@@ -29,7 +28,7 @@ export default function HomeClient() {
|
||||
<div className="w-full max-w-none">
|
||||
{/* sr-only--screen-only: visually hidden */}
|
||||
<h2 className={cn("sr-only", "text-3xl font-bold mb-8 text-center")}>
|
||||
{messages.text.home.h2ScreenOnly}
|
||||
{t("h2ScreenOnly")}
|
||||
</h2>
|
||||
<ClipboardApp />
|
||||
</div>
|
||||
@@ -44,24 +43,22 @@ export default function HomeClient() {
|
||||
<section className="mb-12" aria-label="Product Demo">
|
||||
<LazyLoadWrapper>
|
||||
<h2 className="text-3xl font-bold mb-6 text-center">
|
||||
{messages.text.home.h2Demo}
|
||||
{t("h2Demo")}
|
||||
</h2>
|
||||
<p className="text-center mb-6 text-muted-foreground">
|
||||
{messages.text.home.h2DemoDescription}
|
||||
{t("h2DemoDescription")}
|
||||
</p>
|
||||
<YouTubePlayer videoId={youtube_videoId} />
|
||||
|
||||
<div className="mt-4 text-center">
|
||||
<p className="mb-3 text-foreground">
|
||||
{messages.text.home.watchTip}
|
||||
</p>
|
||||
<p className="mb-3 text-foreground">{t("watchTip")}</p>
|
||||
<a
|
||||
className="flex justify-center gap-4 text-blue-500 hover:underline transition-colors"
|
||||
href={`https://www.youtube.com/watch?v=${youtube_videoId}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{messages.text.home.youtubeTip}
|
||||
{t("youtubeTip")}
|
||||
</a>
|
||||
<a
|
||||
className="flex justify-center gap-4 text-blue-500 hover:underline transition-colors"
|
||||
@@ -69,7 +66,7 @@ export default function HomeClient() {
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{messages.text.home.bilibiliTip}
|
||||
{t("bilibiliTip")}
|
||||
</a>
|
||||
</div>
|
||||
</LazyLoadWrapper>
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { useMessages } from "@/components/providers/TranslationProvider";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function HowItWorks() {
|
||||
const messages = useMessages();
|
||||
const t = useTranslations("text.HowItWorks");
|
||||
|
||||
const steps = [
|
||||
{
|
||||
number: 1,
|
||||
title: messages.text.HowItWorks.step1Title,
|
||||
description: messages.text.HowItWorks.step1Description,
|
||||
title: t("step1Title"),
|
||||
description: t("step1Description"),
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
title: messages.text.HowItWorks.step2Title,
|
||||
description: messages.text.HowItWorks.step2Description,
|
||||
title: t("step2Title"),
|
||||
description: t("step2Description"),
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
title: messages.text.HowItWorks.step3Title,
|
||||
description: messages.text.HowItWorks.step3Description,
|
||||
title: t("step3Title"),
|
||||
description: t("step3Description"),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -31,13 +31,11 @@ export default function HowItWorks() {
|
||||
{/* Header Section */}
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-6">
|
||||
{messages.text.HowItWorks.h2}
|
||||
{t("h2")}
|
||||
</h2>
|
||||
<p className="text-muted-foreground mb-8">
|
||||
{messages.text.HowItWorks.h2Description}
|
||||
</p>
|
||||
<p className="text-muted-foreground mb-8">{t("h2Description")}</p>
|
||||
<Button className="bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white rounded-full px-8 py-6 text-lg">
|
||||
{messages.text.HowItWorks.tryNowLabel}
|
||||
{t("tryNowLabel")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useMessages } from "@/components/providers/TranslationProvider";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
|
||||
interface KeyFeaturesProps {
|
||||
@@ -16,7 +16,7 @@ export default function KeyFeatures({
|
||||
showTitle = true,
|
||||
titleClassName = "",
|
||||
}: KeyFeaturesProps) {
|
||||
const messages = useMessages();
|
||||
const t = useTranslations("text.KeyFeatures");
|
||||
|
||||
// Set container styles
|
||||
const containerClasses = `container mx-auto px-4 py-8 ${className}`;
|
||||
@@ -28,48 +28,48 @@ export default function KeyFeatures({
|
||||
{showTitle &&
|
||||
(isInToolPage ? (
|
||||
<h2 className={`text-3xl ${titleClasses}`}>
|
||||
{messages.text.KeyFeatures.h2}
|
||||
{t("h2")}
|
||||
</h2>
|
||||
) : (
|
||||
<h1 className={`text-4xl ${titleClasses}`}>
|
||||
{messages.text.KeyFeatures.h2}
|
||||
{t("h2")}
|
||||
</h1>
|
||||
))}
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
<Image src="/lock.png" alt="Icon" width={80} height={80} />
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_1}</span>
|
||||
<span className="ml-6">{t("h3_1")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_1_P}</p>
|
||||
<p>{t("h3_1_P")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
<Image src="/teamwork.png" alt="Icon" width={80} height={80} />
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_2}</span>
|
||||
<span className="ml-6">{t("h3_2")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_2_P}</p>
|
||||
<p>{t("h3_2_P")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
<Image src="/rocket.png" alt="Icon" width={80} height={80} />
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_3}</span>
|
||||
<span className="ml-6">{t("h3_3")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_3_P}</p>
|
||||
<p>{t("h3_3_P")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
<Image src="/fresh-air.png" alt="Icon" width={80} height={80} />
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_4}</span>
|
||||
<span className="ml-6">{t("h3_4")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_4_P}</p>
|
||||
<p>{t("h3_4_P")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
<Image src="/planet-earth.png" alt="Icon" width={80} height={80} />
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_5}</span>
|
||||
<span className="ml-6">{t("h3_5")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_5_P}</p>
|
||||
<p>{t("h3_5_P")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-2 flex items-center">
|
||||
@@ -79,9 +79,9 @@ export default function KeyFeatures({
|
||||
width={100}
|
||||
height={83}
|
||||
/>
|
||||
<span className="ml-6">{messages.text.KeyFeatures.h3_6}</span>
|
||||
<span className="ml-6">{t("h3_6")}</span>
|
||||
</h3>
|
||||
<p>{messages.text.KeyFeatures.h3_6_P}</p>
|
||||
<p>{t("h3_6_P")}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { useMessages } from "@/components/providers/TranslationProvider";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function SystemDiagram() {
|
||||
const messages = useMessages();
|
||||
const t = useTranslations("text.SystemDiagram");
|
||||
|
||||
return (
|
||||
<section className="py-16 bg-background">
|
||||
<div className="container mx-auto px-4">
|
||||
<h2 className="text-3xl font-bold mb-12 text-center">
|
||||
{messages.text.SystemDiagram.h2}
|
||||
</h2>
|
||||
<h2 className="text-3xl font-bold mb-12 text-center">{t("h2")}</h2>
|
||||
<Image
|
||||
src="/SystemDiagram.webp"
|
||||
alt="PrivyDrop system diagram: Peer-to-peer file and clipboard sharing"
|
||||
@@ -20,7 +18,7 @@ export default function SystemDiagram() {
|
||||
className="mx-auto mb-6"
|
||||
/>
|
||||
<p className="mt-8 text-center max-w-2xl mx-auto">
|
||||
{messages.text.SystemDiagram.h2Description}
|
||||
{t("h2Description")}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user