feat(home): Add PrimaryFeatures component

- Add PrimaryFeatures component with MobileFriendlyCard, DockerCard, and LSPCard.
- Update HomePage to include PrimaryFeatures component between MainView and FAQs.
This commit is contained in:
cfngc4594 2025-04-17 21:42:58 +08:00
parent fcb75269eb
commit f2d14d07b2
8 changed files with 146 additions and 1 deletions

View File

@ -185,6 +185,21 @@
"quickStart": "Quickstart", "quickStart": "Quickstart",
"contactUs": "Contact Us" "contactUs": "Contact Us"
}, },
"PrimaryFeatures": {
"title": "Features",
"MobileFriendlyCard": {
"title": "Mobile Friendly",
"description": "Responsive design with TailwindCSS, automatically adapts to different devices (quiz interface adaptation still in development)"
},
"DockerCard": {
"title": "Ready to Use",
"description": "Pre-built Docker images for quick deployment, saving configuration time"
},
"LSPCard": {
"title": "Say Goodbye to Primitive Editors",
"description": "Integrated with real-time detection, code completion, and type hints"
}
},
"FAQs": { "FAQs": {
"title": "Frequently Asked Questions", "title": "Frequently Asked Questions",
"description": "Can't find your answer? Contact us!", "description": "Can't find your answer? Contact us!",

View File

@ -185,6 +185,21 @@
"quickStart": "即刻启程", "quickStart": "即刻启程",
"contactUs": "联系我们" "contactUs": "联系我们"
}, },
"PrimaryFeatures": {
"title": "特性",
"MobileFriendlyCard": {
"title": "移动端友好",
"description": "采用 TailwindCSS 实现响应式布局,界面可自动适配不同设备(答题界面适配功能仍在开发中)"
},
"DockerCard": {
"title": "开箱即用",
"description": "提供预构建的 Docker 镜像,支持快速部署,节省配置时间"
},
"LSPCard": {
"title": "告别原始编辑器",
"description": "集成实时检测、代码补全、类型提示"
}
},
"FAQs": { "FAQs": {
"title": "常见问题", "title": "常见问题",
"description": "未找到答案?欢迎联系我们!", "description": "未找到答案?欢迎联系我们!",

BIN
public/docker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
public/lsp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
public/mobile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

View File

@ -2,12 +2,14 @@ import FAQs from "@/components/faqs";
import { Header } from "@/components/header"; import { Header } from "@/components/header";
import { Footer } from "@/components/footer"; import { Footer } from "@/components/footer";
import { MainView } from "@/components/main-view"; import { MainView } from "@/components/main-view";
import { PrimaryFeatures } from "@/components/primary-features";
export default function HomePage() { export default function HomePage() {
return ( return (
<> <>
<Header /> <Header />
<MainView /> <MainView />
<PrimaryFeatures />
<FAQs /> <FAQs />
<Footer /> <Footer />
</> </>

View File

@ -18,7 +18,7 @@ export function WorkspaceEditorHeader({
return ( return (
<header <header
{...props} {...props}
className={cn("flex items-center flex-none h-8 relative", className)} className={cn("flex items-center flex-none h-8 relative border-b", className)}
> >
<div className="absolute flex w-full items-center justify-between px-2"> <div className="absolute flex w-full items-center justify-between px-2">
<div className="flex items-center"> <div className="flex items-center">

View File

@ -0,0 +1,113 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import Image from "next/image";
import { useTranslations } from "next-intl";
const MobileFriendlyCard = () => {
const t = useTranslations("HomePage.PrimaryFeatures.MobileFriendlyCard");
return (
<Card className="relative lg:row-span-2">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] lg:rounded-l-[calc(2rem+1px)]">
<CardHeader>
<CardTitle className="mt-2 text-lg/7 font-medium tracking-tight max-lg:text-center">
{t("title")}
</CardTitle>
<CardDescription className="mt-2 max-w-lg text-sm/6 max-lg:text-center">
{t("description")}
</CardDescription>
</CardHeader>
<CardContent className="relative min-h-[30rem] w-full grow [container-type:inline-size] max-lg:mx-auto max-lg:max-w-sm">
<div className="absolute inset-x-10 bottom-0 top-10 overflow-hidden rounded-t-[12cqw] border-x-[3cqw] border-t-[3cqw] border-gray-700 bg-gray-900 shadow-2xl">
<Image
className="size-full object-cover object-top"
src="/mobile.png"
alt=""
fill
/>
</div>
</CardContent>
</div>
</Card>
);
};
const DockerCard = () => {
const t = useTranslations("HomePage.PrimaryFeatures.DockerCard");
return (
<Card className="relative max-lg:row-start-1">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)]">
<CardHeader>
<CardTitle className="mt-2 text-lg/7 font-medium tracking-tight max-lg:text-center">
{t("title")}
</CardTitle>
<CardDescription className="mt-2 max-w-lg text-sm/6 max-lg:text-center">
{t("description")}
</CardDescription>
</CardHeader>
<CardContent className="flex flex-1 items-center justify-center px-8 max-lg:pb-12 max-lg:pt-10 sm:px-10 lg:pb-2">
<Image
className="max-lg:max-w-xs"
src="/docker.png"
alt=""
height={250}
width={250}
/>
</CardContent>
</div>
</Card>
);
};
const LSPCard = () => {
const t = useTranslations("HomePage.PrimaryFeatures.LSPCard");
return (
<Card className="relative max-lg:row-start-3 lg:col-start-2 lg:row-start-2">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(theme(borderRadius.lg)+1px)]">
<CardHeader>
<CardTitle className="mt-2 text-lg/7 font-medium tracking-tight max-lg:text-center">
{t("title")}
</CardTitle>
<CardDescription className="mt-2 max-w-lg text-sm/6 max-lg:text-center">
{t("description")}
</CardDescription>
</CardHeader>
<CardContent className="flex flex-1 items-center [container-type:inline-size] max-lg:py-6 lg:pb-2">
<Image
className="rounded-xl"
src="/lsp.png"
alt=""
height={1200}
width={800}
/>
</CardContent>
</div>
</Card>
);
};
export function PrimaryFeatures() {
const t = useTranslations("HomePage.PrimaryFeatures");
return (
<div className="bg-background py-24 sm:py-32 border-t">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
<p className="mx-auto mt-2 max-w-lg text-pretty text-center text-4xl font-medium tracking-tight text-foreground sm:text-5xl">
{t("title")}
</p>
<div className="mt-10 grid gap-4 sm:mt-16 lg:grid-cols-2 lg:grid-rows-2">
<MobileFriendlyCard />
<DockerCard />
<LSPCard />
</div>
</div>
</div>
);
}