feat: add translate for zh-Hans

This commit is contained in:
JiPai
2024-09-05 20:19:28 +08:00
parent d3108ebf65
commit fe032d3d0f
12 changed files with 521 additions and 295 deletions

View File

@@ -1,40 +1,38 @@
"use client";
'use client'
import { cn } from "@/lib/utils";
import { Tab } from "@headlessui/react";
import { motion } from "framer-motion";
import { Layers, Terminal, Users } from "lucide-react";
import { Container } from "./Container";
import { cn } from '@/lib/utils'
import { Tab } from '@headlessui/react'
import { motion } from 'framer-motion'
import { Layers, Terminal, Users } from 'lucide-react'
import { Container } from './Container'
import { useTranslations } from 'next-intl'
interface Feature {
name: React.ReactNode;
summary: string;
description: string;
image: string;
icon: React.ComponentType;
name: React.ReactNode
summary: string
description: string
image: string
icon: React.ComponentType
}
const features: Array<Feature> = [
{
name: "Open Source Templates",
summary: "One click to deploy open source templates.",
description:
"Deploy open source templates with one click, powered by Docker Compose, (Plausible, Calcom, Pocketbase, etc.)",
image: "/secondary/templates.png",
name: 'secondaryFeatures.templates',
summary: 'secondaryFeatures.templatesSummary',
description: 'secondaryFeatures.templatesDes',
image: '/secondary/templates.png',
icon: function ReportingIcon() {
return (
<>
<Layers className="size-5 text-primary" />
</>
);
)
},
},
{
name: "Real-Time Traefik Configuration",
summary:
" Modify Traefik settings on-the-fly via a graphical interface or API.",
description:
"Users can adjust Traefik's configuration, including middleware, forwarding rules, and SSL certificates through an intuitive interface or API. This feature enables seamless traffic routing and security adjustments without the need to restart services",
image: "/secondary/traefik.png",
name: 'secondaryFeatures.traefik',
summary: 'secondaryFeatures.traefikSummary',
description: 'secondaryFeatures.traefikDes',
image: '/secondary/traefik.png',
icon: function ReportingIcon() {
return (
<>
@@ -84,7 +82,12 @@ const features: Array<Feature> = [
d="M299.847 285.567c10.027 58.288 105.304 42.877 91.619-15.91-12.271-52.716-94.951-38.124-91.619 15.91m-113.855 9.427c12.996 50.745 94.24 37.753 91.178-13.149-3.669-60.964-103.603-49.2-91.178 13.149m132.351 58.517c.044 7.79 1.843 15.403.289 24.148-1.935 3.656-5.729 4.043-9.001 5.52-4.524-.71-8.328-3.68-10.143-7.912-1.161-9.202.433-18.111.726-27.316l18.129 5.56z"
fill="#fff"
/>
<ellipse cx="208.4" cy="286.718" rx="13.719" ry="14.86" />
<ellipse
cx="208.4"
cy="286.718"
rx="13.719"
ry="14.86"
/>
<ellipse
cx="214.64"
cy="290.071"
@@ -92,9 +95,19 @@ const features: Array<Feature> = [
ry="3.777"
fill="#fff"
/>
<ellipse cx="323.348" cy="283.017" rx="13.491" ry="14.86" />
<ellipse
cx="323.348"
cy="283.017"
rx="13.491"
ry="14.86"
/>
<g fill="#fff">
<ellipse cx="329.485" cy="286.371" rx="3.181" ry="3.777" />
<ellipse
cx="329.485"
cy="286.371"
rx="3.181"
ry="3.777"
/>
<path d="M279.137 354.685c-5.986 14.507 3.338 43.515 19.579 22.119-1.161-9.202.433-18.111.726-27.316l-20.305 5.197z" />
</g>
<path
@@ -213,63 +226,60 @@ const features: Array<Feature> = [
</g>
</svg>
</>
);
)
},
},
{
name: "User Permission Management",
summary:
"Detailed control over user permissions for accessing and managing projects and services.",
description:
"Allows administrators to define specific roles and permissions for each user, including the ability to create, modify, or delete applications and databases. This feature ensures secure and efficient management of large and diverse teams.",
image: "/secondary/users.png",
name: 'secondaryFeatures.users',
summary: 'secondaryFeatures.usersSummary',
description: 'secondaryFeatures.usersDes',
image: '/secondary/users.png',
icon: function InventoryIcon() {
return (
<>
<Users className="size-5 text-primary" />
</>
);
)
},
},
{
name: "Terminal Access",
summary:
"Direct access to each container's and server terminal for advanced management.",
description:
"Provides an interface to access the command line of any active container, allowing developers to execute commands, manage services, and troubleshoot directly from the dashboard",
image: "/secondary/terminal.png",
name: 'secondaryFeatures.terminal',
summary: 'secondaryFeatures.terminalSummary',
description: 'secondaryFeatures.terminalDes',
image: '/secondary/terminal.png',
icon: function ContactsIcon() {
return (
<>
<Terminal className="size-5 text-primary" />
</>
);
)
},
},
];
]
function Feature({
feature,
isActive,
className,
...props
}: React.ComponentPropsWithoutRef<"div"> & {
feature: Feature;
isActive: boolean;
}: React.ComponentPropsWithoutRef<'div'> & {
feature: Feature
isActive: boolean
}) {
const t = useTranslations('HomePage')
return (
<div
className={cn(
className,
!isActive ? "opacity-75 hover:opacity-100 " : "rounded-xl",
" p-4 relative",
!isActive ? 'opacity-75 hover:opacity-100 ' : 'rounded-xl',
' relative p-4',
)}
{...props}
>
<div
className={cn(
"size-9 rounded-lg flex items-center justify-center",
isActive ? "bg-border" : "bg-muted",
'flex size-9 items-center justify-center rounded-lg',
isActive ? 'bg-border' : 'bg-muted',
)}
>
<feature.icon />
@@ -277,9 +287,9 @@ function Feature({
{isActive && (
<motion.span
layoutId="bubble"
className="absolute inset-0 z-10 bg-white/5 mix-blend-difference rounded-xl"
className="absolute inset-0 z-10 rounded-xl bg-white/5 mix-blend-difference"
transition={{
type: "spring",
type: 'spring',
bounce: 0.2,
duration: 0.6,
}}
@@ -287,20 +297,20 @@ function Feature({
)}
<h3
className={cn(
"mt-6 text-sm font-medium",
isActive ? "text-primary" : "text-primary/85",
'mt-6 text-sm font-medium',
isActive ? 'text-primary' : 'text-primary/85',
)}
>
{feature.name}
</h3>
<p className="mt-2 font-display text-xl text-foreground">
{feature.summary}
{t(feature.summary)}
</p>
<p className="mt-4 text-sm text-muted-foreground">
{feature.description}
{t(feature.description)}
</p>
</div>
);
)
}
function FeaturesMobile() {
@@ -308,7 +318,11 @@ function FeaturesMobile() {
<div className="-mx-4 mt-20 flex flex-col gap-y-10 overflow-hidden px-4 sm:-mx-6 sm:px-6 lg:hidden">
{features.map((feature) => (
<div key={feature.summary}>
<Feature feature={feature} className="mx-auto max-w-2xl" isActive />
<Feature
feature={feature}
className="mx-auto max-w-2xl"
isActive
/>
<div className="relative mt-10 pb-10">
<div className="absolute -inset-x-4 bottom-0 top-8 bg-muted sm:-inset-x-6" />
<div className="relative mx-auto w-[52.75rem] overflow-hidden rounded-xl bg-white shadow-lg shadow-slate-900/5 ring-1 ring-slate-500/10">
@@ -323,10 +337,11 @@ function FeaturesMobile() {
</div>
))}
</div>
);
)
}
function FeaturesDesktop() {
const t = useTranslations('HomePage')
return (
<Tab.Group as="div" className="hidden lg:mt-20 lg:block">
{({ selectedIndex }) => (
@@ -340,7 +355,7 @@ function FeaturesDesktop() {
name: (
<Tab className="ui-not-focus-visible:outline-none">
<span className="absolute inset-0" />
{feature.name}
{t(feature.name)}
</Tab>
),
}}
@@ -356,10 +371,13 @@ function FeaturesDesktop() {
static
key={feature.summary}
className={cn(
"px-5 transition duration-500 ease-in-out ui-not-focus-visible:outline-none",
featureIndex !== selectedIndex && "opacity-60",
'px-5 transition duration-500 ease-in-out ui-not-focus-visible:outline-none',
featureIndex !== selectedIndex &&
'opacity-60',
)}
style={{ transform: `translateX(-${selectedIndex * 100}%)` }}
style={{
transform: `translateX(-${selectedIndex * 100}%)`,
}}
aria-hidden={featureIndex !== selectedIndex}
>
<div className="w-[52.75rem] overflow-hidden rounded-xl bg-red-500 shadow-lg shadow-slate-900/5 ring-1 ring-slate-500/10">
@@ -378,30 +396,29 @@ function FeaturesDesktop() {
</>
)}
</Tab.Group>
);
)
}
export function SecondaryFeatures() {
const t = useTranslations('HomePage')
return (
<section
id="secondary-features"
aria-label="Features for simplifying everyday business tasks"
className="pb-14 pt-20 sm:pb-20 sm:pt-32 lg:pb-32 bg-black"
className="bg-black pb-14 pt-20 sm:pb-20 sm:pt-32 lg:pb-32"
>
<Container className="max-w-[95rem]">
<div className="mx-auto max-w-2xl md:text-center">
<h2 className="font-display text-3xl tracking-tight text-primary sm:text-4xl">
Advanced Management Tools
{t('secondaryFeatures.title')}
</h2>
<p className="mt-4 text-lg tracking-tight text-muted-foreground">
Elevate your infrastructure with tools that offer precise control,
detailed monitoring, and enhanced security, ensuring seamless
management and robust performance.
{t('secondaryFeatures.des')}
</p>
</div>
<FeaturesMobile />
<FeaturesDesktop />
</Container>
</section>
);
)
}