From 4f5899b2a3f5ae7c1f542c948a16ff84779d4afa Mon Sep 17 00:00:00 2001 From: Application-drop-up Date: Tue, 23 Jun 2026 10:02:18 +0900 Subject: [PATCH 1/3] feat(i18n): add ui-text keys for World Heritage Basics section --- client/src/locals/en/ui.json | 4 +++- client/src/locals/ja/ui.json | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/locals/en/ui.json b/client/src/locals/en/ui.json index 898007b..93bea0e 100644 --- a/client/src/locals/en/ui.json +++ b/client/src/locals/en/ui.json @@ -61,5 +61,7 @@ "searchOtherSites": "Search other sites", "exampleSites": "Example sites", "viewAllResults": "View all results", - "unescoCriteriaSource": "UNESCO official criteria page" + "unescoCriteriaSource": "UNESCO official criteria page", + "worldHeritageBasics": "World Heritage Basics", + "worldHeritageBasicsDescription": "Every site is inscribed under one or more of these 10 selection criteria. Explore what each one means." } diff --git a/client/src/locals/ja/ui.json b/client/src/locals/ja/ui.json index 51c3bd7..58b862e 100644 --- a/client/src/locals/ja/ui.json +++ b/client/src/locals/ja/ui.json @@ -61,5 +61,7 @@ "searchOtherSites": "他の遺産を検索", "exampleSites": "実例", "viewAllResults": "すべての結果を見る", - "unescoCriteriaSource": "UNESCO 公式の登録基準ページ" + "unescoCriteriaSource": "UNESCO 公式の登録基準ページ", + "worldHeritageBasics": "世界遺産の基礎知識", + "worldHeritageBasicsDescription": "すべての世界遺産は、以下の10個の登録基準のいずれか(または複数)を満たして登録されています。各基準の意味を見てみましょう。" } From fd0eae2d299c793c71d29f55eed44b1c83ee2de0 Mon Sep 17 00:00:00 2001 From: Application-drop-up Date: Tue, 23 Jun 2026 10:02:28 +0900 Subject: [PATCH 2/3] feat(top): add WorldHeritageBasics section Links to all 10 UNESCO selection criteria pages in a 2-column grid, giving users an entry point to /heritages/criteria/:code that didn't previously exist anywhere in the app. --- .../top/components/WorldHeritageBasics.tsx | 36 ++++++++++++++++++ .../__tests__/WorldHeritageBasics.test.tsx | 38 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 client/src/app/features/top/components/WorldHeritageBasics.tsx create mode 100644 client/src/app/features/top/components/__tests__/WorldHeritageBasics.test.tsx diff --git a/client/src/app/features/top/components/WorldHeritageBasics.tsx b/client/src/app/features/top/components/WorldHeritageBasics.tsx new file mode 100644 index 0000000..2b5fa8e --- /dev/null +++ b/client/src/app/features/top/components/WorldHeritageBasics.tsx @@ -0,0 +1,36 @@ +import { Link } from "react-router-dom"; +import { CRITERIA_CODES, getCriteria } from "../../../../domain/criteria"; +import { useLocale } from "@shared/locale/LocaleHooks.ts"; +import { useText } from "@shared/locale/ui-text.ts"; + +export function WorldHeritageBasics() { + const { locale } = useLocale(); + const text = useText(); + + return ( +
+

{text.worldHeritageBasics}

+

{text.worldHeritageBasicsDescription}

+ +
    + {CRITERIA_CODES.map((code) => { + const { title } = getCriteria(code, locale); + + return ( +
  • + + + ({code}) + + {title} + +
  • + ); + })} +
+
+ ); +} diff --git a/client/src/app/features/top/components/__tests__/WorldHeritageBasics.test.tsx b/client/src/app/features/top/components/__tests__/WorldHeritageBasics.test.tsx new file mode 100644 index 0000000..95de795 --- /dev/null +++ b/client/src/app/features/top/components/__tests__/WorldHeritageBasics.test.tsx @@ -0,0 +1,38 @@ +/** @jest-environment jsdom */ + +import { render, screen } from "@testing-library/react"; +import { MemoryRouter } from "react-router-dom"; +import { LocaleProvider } from "@shared/locale/LocaleProvider.tsx"; +import { WorldHeritageBasics } from "../WorldHeritageBasics"; +import { CRITERIA_CODES } from "../../../../../domain/criteria"; + +const renderBasics = () => + render( + + + + + , + ); + +describe("WorldHeritageBasics", () => { + test("見出しと説明文を表示する", () => { + renderBasics(); + + expect(screen.getByRole("heading", { name: "World Heritage Basics" })).toBeInTheDocument(); + expect( + screen.getByText( + "Every site is inscribed under one or more of these 10 selection criteria. Explore what each one means.", + ), + ).toBeInTheDocument(); + }); + + test("10個の登録基準すべてに /heritages/criteria/:code へのリンクを表示する", () => { + renderBasics(); + + CRITERIA_CODES.forEach((code) => { + const link = screen.getByRole("link", { name: new RegExp(`^\\(${code}\\)`) }); + expect(link).toHaveAttribute("href", `/heritages/criteria/${code}`); + }); + }); +}); From dfb605ea37a4abb6c843ec29dbc9aa620c893a28 Mon Sep 17 00:00:00 2001 From: Application-drop-up Date: Tue, 23 Jun 2026 10:02:37 +0900 Subject: [PATCH 3/3] feat(top): render WorldHeritageBasics on the top page --- client/src/app/features/top/components/TopPage.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/app/features/top/components/TopPage.tsx b/client/src/app/features/top/components/TopPage.tsx index d75089a..f748c8d 100644 --- a/client/src/app/features/top/components/TopPage.tsx +++ b/client/src/app/features/top/components/TopPage.tsx @@ -1,5 +1,6 @@ import type { ReactNode } from "react"; import { Map } from "./Map.tsx"; +import { WorldHeritageBasics } from "./WorldHeritageBasics.tsx"; export default function TopPage({ hero, @@ -26,6 +27,8 @@ export default function TopPage({ + +
{content} {pagination}