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": { "Index": {
"get_started": "Get Started", "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.", "integrate_and_manage": "Integrate and manage all your software testing.",
"oss_title": "Open Source", "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.", "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_title": "Universal",
"universal_detail": "Multi language support and dark theme allow anyone to use the system without any inconvenience.", "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", "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", "self_host": "Self host the application",
"run_as_docker": "Running TestPlat as a Docker container", "run_as_docker": "Running TestPlat as a Docker container",
"run_by_manually": "Running TestPlat manually" "run_by_manually": "Running TestPlat manually",
"roadmap": "Roadmap"
}, },
"Header": { "Header": {
"title": "Open Source Test Case Management Tool", "title": "Open Source Test Case Management Tool",

View File

@@ -1,7 +1,8 @@
{ {
"Index": { "Index": {
"get_started": "テスト管理を始める", "get_started": "テスト管理を始める",
"oss_tcmt": "オープンソーステストケース管理ツール", "oss_tcmt": "オープンソーステストケース管理",
"web_application": "ウェブアプリケーション",
"integrate_and_manage": "ソフトウェア開発にかかわるすべてのテストを統合管理", "integrate_and_manage": "ソフトウェア開発にかかわるすべてのテストを統合管理",
"oss_title": "オープンソース", "oss_title": "オープンソース",
"oss_detail": "TestPlatは無料でオープンソースです。アプリケーションをセルフホストすることができます。セキュリティ要件の厳しい環境でも導入することができます。", "oss_detail": "TestPlatは無料でオープンソースです。アプリケーションをセルフホストすることができます。セキュリティ要件の厳しい環境でも導入することができます。",
@@ -12,9 +13,13 @@
"universal_title": "ユニバーサル", "universal_title": "ユニバーサル",
"universal_detail": "多言語対応やダークテーマ機能により誰もが不自由なく使うことができます。", "universal_detail": "多言語対応やダークテーマ機能により誰もが不自由なく使うことができます。",
"organize_test_cases": "テストケースを整理とグラフィカルなテスト管理", "organize_test_cases": "テストケースを整理とグラフィカルなテスト管理",
"case_edit": "テストケース",
"case_home": "ダッシュボード",
"case_run": "テスト実行",
"self_host": "アプリのセルフホスト", "self_host": "アプリのセルフホスト",
"run_as_docker": "Docker containerによる実行", "run_as_docker": "Docker containerによる実行",
"run_by_manually": "手動での実行" "run_by_manually": "手動での実行",
"roadmap": "ロードマップ"
}, },
"Header": { "Header": {
"title": "オープンソーステストケース管理ツール", "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,31 +31,28 @@ export default function MainTitle() {
return ( return (
<> <>
{features.map((feature, index) => ( <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<Card {features.map((feature) => (
key={feature.title} <Card key={feature.title} className="max-w-[300px] min-h-[180px]">
className={`max-w-[300px] min-h-[180px] ${ <CardHeader className="flex gap-3">
index !== 0 ? "mt-4 sm:mt-0 sm:ml-4" : "" <div>
}`} <Avatar
> className="bg-green-100"
<CardHeader className="flex gap-3"> showFallback
<div> src=""
<Avatar fallback={feature.icon}
className="bg-green-100" />
showFallback </div>
src="" <div className="flex flex-col">
fallback={feature.icon} <h4 className="font-bold text-large">{feature.title}</h4>
/> </div>
</div> </CardHeader>
<div className="flex flex-col"> <CardBody className="pt-0">
<h4 className="font-bold text-large">{feature.title}</h4> <p className="text-default-500">{feature.detail}</p>
</div> </CardBody>
</CardHeader> </Card>
<CardBody className="pt-0"> ))}
<p className="text-default-500">{feature.detail}</p> </div>
</CardBody>
</Card>
))}
</> </>
); );
} }

View File

@@ -29,6 +29,8 @@ export default function MainTitle({ locale }: Props) {
})} })}
> >
{t("oss_tcmt")} {t("oss_tcmt")}
<br />
{t("web_application")}
</h1> </h1>
<h4 className={subtitle({ class: "mt-4" })}> <h4 className={subtitle({ class: "mt-4" })}>
{t("integrate_and_manage")} {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 { useTranslations } from "next-intl";
import { title, subtitle } from "@/components/primitives"; import { title, subtitle } from "@/components/primitives";
import { Divider } from "@nextui-org/react"; import { Divider } from "@nextui-org/react";
import Image from "next/image"; import PaneMainTitle from "./PaneMainTitle";
import heroImage from "./hero.png"; import PaneMainFeatures from "./PaneMainFeatures";
import MainTitle from "./MainTitle"; import PaneDemoImages from "./PaneDemoImages";
import MainFeatures from "./MainFeatures"; import PaneSelfHostProcedure from "./PaneSelfHostProcedure";
import SelfHostProcedure from "./SelfHostProcedure";
export default function Home(params: { locale: string }) { export default function Home(params: { locale: string }) {
const t = useTranslations("Index"); const t = useTranslations("Index");
const messages = {
title: t("organize_test_cases"),
caseEdit: t("case_edit"),
caseHome: t("case_home"),
caseRun: t("case_run"),
};
return ( return (
<section className="mx-auto max-w-screen-xl my-12"> <section className="mx-auto max-w-screen-xl my-12">
<div className="flex flex-wrap"> <div className="flex flex-wrap">
<div className="w-full md:w-7/12 order-last md:order-first p-4"> <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>
<div className="w-full md:w-5/12 p-4"> <div className="w-full md:w-5/12 p-4">
@@ -51,36 +57,35 @@ export default function Home(params: { locale: string }) {
</div> </div>
<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={{ style={{
marginTop: "6rem", marginTop: "6rem",
}} }}
> >
<MainFeatures /> <PaneMainFeatures />
</div> </div>
<Divider className="my-12" /> <Divider className="my-12" />
<PaneDemoImages messages={messages} />
<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>
<Divider className="my-12" /> <Divider className="my-12" />
<div className="flex flex-wrap mt-12"> <div className="flex flex-wrap mt-12">
<div className="w-full md:w-4/12 order-last md:order-first p-4"> <div className="w-full md:w-4/12 order-last md:order-first p-4">
<h2 className={title({ size: "sm" })}>{t("self_host")}</h2> <h2 className={title({ size: "sm" })}>{t("self_host")}</h2>
</div> </div>
<div className="w-full md:w-8/12 p-4"> <div className="w-full md:w-8/12 p-4">
<SelfHostProcedure /> <PaneSelfHostProcedure />
</div> </div>
</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> </section>
); );
} }