Create Top page
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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": "オープンソーステストケース管理ツール",
|
||||
|
||||
BIN
frontend/public/top/caseEdit.png
Normal file
BIN
frontend/public/top/caseEdit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
BIN
frontend/public/top/caseHome.png
Normal file
BIN
frontend/public/top/caseHome.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
frontend/public/top/caseRun.png
Normal file
BIN
frontend/public/top/caseRun.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 184 KiB |
81
frontend/src/app/[locale]/PaneDemoImages.tsx
Normal file
81
frontend/src/app/[locale]/PaneDemoImages.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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 |
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user