mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: add translate for zh-Hans
This commit is contained in:
@@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user