Create Top page

This commit is contained in:
Takeshi Kimata
2024-05-11 21:48:26 +09:00
parent 76076f2c48
commit ccad7ecc60
11 changed files with 143 additions and 48 deletions

View File

@@ -1,7 +1,8 @@
{
"Index": {
"get_started": "Get Started",
"oss_tcmt": "Open Source Test Case Management Tool",
"oss_tcmt": "Open Source Test Case Management",
"web_application": "Web Application",
"integrate_and_manage": "Integrate and manage all your software testing.",
"oss_title": "Open Source",
"oss_detail": "TestPlat is free and open source. The application can be self-hosted. It can be deployed in environments with strict security requirements.",
@@ -12,9 +13,13 @@
"universal_title": "Universal",
"universal_detail": "Multi language support and dark theme allow anyone to use the system without any inconvenience.",
"organize_test_cases": "Organize test cases and manage tests graphically",
"case_edit": "Test Cases",
"case_home": "Dashboard",
"case_run": "Test Runs",
"self_host": "Self host the application",
"run_as_docker": "Running TestPlat as a Docker container",
"run_by_manually": "Running TestPlat manually"
"run_by_manually": "Running TestPlat manually",
"roadmap": "Roadmap"
},
"Header": {
"title": "Open Source Test Case Management Tool",

View File

@@ -1,7 +1,8 @@
{
"Index": {
"get_started": "テスト管理を始める",
"oss_tcmt": "オープンソーステストケース管理ツール",
"oss_tcmt": "オープンソーステストケース管理",
"web_application": "ウェブアプリケーション",
"integrate_and_manage": "ソフトウェア開発にかかわるすべてのテストを統合管理",
"oss_title": "オープンソース",
"oss_detail": "TestPlatは無料でオープンソースです。アプリケーションをセルフホストすることができます。セキュリティ要件の厳しい環境でも導入することができます。",
@@ -12,9 +13,13 @@
"universal_title": "ユニバーサル",
"universal_detail": "多言語対応やダークテーマ機能により誰もが不自由なく使うことができます。",
"organize_test_cases": "テストケースを整理とグラフィカルなテスト管理",
"case_edit": "テストケース",
"case_home": "ダッシュボード",
"case_run": "テスト実行",
"self_host": "アプリのセルフホスト",
"run_as_docker": "Docker containerによる実行",
"run_by_manually": "手動での実行"
"run_by_manually": "手動での実行",
"roadmap": "ロードマップ"
},
"Header": {
"title": "オープンソーステストケース管理ツール",

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -0,0 +1,81 @@
"use client";
import { title } from "@/components/primitives";
import { useState, useEffect } from "react";
import { Tabs, Tab, Image } from "@nextui-org/react";
type PaneDemoImagesMessages = {
title: string;
caseEdit: string;
caseHome: string;
caseRun: string;
};
type Props = {
messages: PaneDemoImagesMessages;
};
export default function DemoImages({ messages }: Props) {
const [currentTab, setcurrentTab] = useState("edit");
const [currentImage, setcurrentImage] = useState({
src: "/top/caseEdit.png",
alt: messages.caseEdit,
});
const tabs = [
{
key: "edit",
title: messages.caseEdit,
src: "/top/caseEdit.png",
alt: messages.caseEdit,
},
{
key: "home",
title: messages.caseHome,
src: "/top/caseHome.png",
alt: messages.caseHome,
},
{
key: "run",
title: messages.caseRun,
src: "/top/caseRun.png",
alt: messages.caseRun,
},
];
useEffect(() => {
const found = tabs.find((tab) => tab.key === currentTab);
const newImage = { src: found.src, alt: found.title };
setcurrentImage(newImage);
}, [currentTab]);
return (
<>
<div className="flex flex-wrap lg:text-left text-center">
<div className="w-full lg:w-5/12 p-4">
<h2 className={title({ size: "sm" })}>{messages.title}</h2>
<br />
<Tabs
aria-label="Options"
color={"primary"}
radius="full"
size="md"
className="mt-8"
selectedKey={currentTab}
onSelectionChange={setcurrentTab}
>
{tabs.map((tab) => (
<Tab key={tab.key} title={tab.title} />
))}
</Tabs>
</div>
<div className="flex justify-center w-full lg:w-7/12 p-4 min-h-96">
<Image
isBlurred
src={currentImage.src}
alt={currentImage.alt}
className="max-w-full px-5"
/>
</div>
</div>
</>
);
}

View File

@@ -31,13 +31,9 @@ export default function MainTitle() {
return (
<>
{features.map((feature, index) => (
<Card
key={feature.title}
className={`max-w-[300px] min-h-[180px] ${
index !== 0 ? "mt-4 sm:mt-0 sm:ml-4" : ""
}`}
>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{features.map((feature) => (
<Card key={feature.title} className="max-w-[300px] min-h-[180px]">
<CardHeader className="flex gap-3">
<div>
<Avatar
@@ -56,6 +52,7 @@ export default function MainTitle() {
</CardBody>
</Card>
))}
</div>
</>
);
}

View File

@@ -29,6 +29,8 @@ export default function MainTitle({ locale }: Props) {
})}
>
{t("oss_tcmt")}
<br />
{t("web_application")}
</h1>
<h4 className={subtitle({ class: "mt-4" })}>
{t("integrate_and_manage")}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

View File

@@ -1,20 +1,26 @@
import { useTranslations } from "next-intl";
import { title, subtitle } from "@/components/primitives";
import { Divider } from "@nextui-org/react";
import Image from "next/image";
import heroImage from "./hero.png";
import MainTitle from "./MainTitle";
import MainFeatures from "./MainFeatures";
import SelfHostProcedure from "./SelfHostProcedure";
import PaneMainTitle from "./PaneMainTitle";
import PaneMainFeatures from "./PaneMainFeatures";
import PaneDemoImages from "./PaneDemoImages";
import PaneSelfHostProcedure from "./PaneSelfHostProcedure";
export default function Home(params: { locale: string }) {
const t = useTranslations("Index");
const messages = {
title: t("organize_test_cases"),
caseEdit: t("case_edit"),
caseHome: t("case_home"),
caseRun: t("case_run"),
};
return (
<section className="mx-auto max-w-screen-xl my-12">
<div className="flex flex-wrap">
<div className="w-full md:w-7/12 order-last md:order-first p-4">
<MainTitle locale={params.locale} />
<PaneMainTitle locale={params.locale} />
</div>
<div className="w-full md:w-5/12 p-4">
@@ -51,36 +57,35 @@ export default function Home(params: { locale: string }) {
</div>
<div
className="flex flex-wrap flex-col items-center sm:flex-row sm:items-start"
className="flex flex-wrap flex-col items-center"
style={{
marginTop: "6rem",
}}
>
<MainFeatures />
<PaneMainFeatures />
</div>
<Divider className="my-12" />
<div className="flex flex-wrap mt-12">
<div className="w-full md:w-4/12 order-last md:order-first p-4">
<h2 className={title({ size: "sm" })}>{t("organize_test_cases")}</h2>
</div>
<div className="w-full md:w-8/12 p-4">
<Image src={heroImage} alt="Hero" className="max-w-2xl" />
</div>
</div>
<PaneDemoImages messages={messages} />
<Divider className="my-12" />
<div className="flex flex-wrap mt-12">
<div className="w-full md:w-4/12 order-last md:order-first p-4">
<h2 className={title({ size: "sm" })}>{t("self_host")}</h2>
</div>
<div className="w-full md:w-8/12 p-4">
<SelfHostProcedure />
<PaneSelfHostProcedure />
</div>
</div>
<Divider className="my-12" />
<div className="flex flex-wrap mt-12">
<div className="w-full md:w-4/12 order-last md:order-first p-4">
<h2 className={title({ size: "sm" })}>{t("roadmap")}</h2>
</div>
<div className="w-full md:w-8/12 p-4"></div>
</div>
</section>
);
}