Skip to content

Commit 8c8bc08

Browse files
authored
Merge pull request #302 from zigzagdev/chore/top-component-context-wrapping
Chore/top component context wrapping
2 parents 486232b + 4324a83 commit 8c8bc08

8 files changed

Lines changed: 81 additions & 23 deletions

File tree

client/src/app/features/top/cards/HeritageCard.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { ReactNode, MouseEvent } from "react";
22
import type { WorldHeritageVm, CriteriaCode } from "../../../../domain/types.ts";
33
import { BaseCard } from "@shared/uis/BaseCard.tsx";
4+
import { useLocale } from "@shared/locale/LocaleHooks.ts";
5+
import { useText } from "@shared/locale/ui-text.ts";
46

57
function MetaChip({ children }: { children: ReactNode }) {
68
return (
@@ -40,6 +42,9 @@ export function HeritageCard({
4042
item: WorldHeritageVm;
4143
onClickItem?: (id: number) => void;
4244
}) {
45+
const { locale } = useLocale();
46+
const text = useText();
47+
4348
const goDetail = () => {
4449
if (!onClickItem) return;
4550
onClickItem(item.id);
@@ -54,7 +59,7 @@ export function HeritageCard({
5459
goDetail();
5560
};
5661

57-
const title = item.heritageNameJp || "World Heritage";
62+
const title = locale === "ja" && item.heritageNameJp ? item.heritageNameJp : item.name;
5863
const subtitle = item.subtitle ?? "";
5964
const desc = (item.shortDescription ?? "").trim();
6065

@@ -74,7 +79,7 @@ export function HeritageCard({
7479
/>
7580
) : (
7681
<div className="grid h-56 w-full place-items-center bg-zinc-100 text-sm text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400 sm:h-64 lg:h-72">
77-
No image
82+
{text.noImage}
7883
</div>
7984
)}
8085

@@ -83,7 +88,7 @@ export function HeritageCard({
8388
{item.isEndangered && (
8489
<div className="absolute right-3 bottom-3">
8590
<span className="inline-flex items-center rounded-md bg-red-600 px-2 py-1 text-xs font-bold text-white shadow-sm">
86-
DANGER
91+
{text.danger}
8792
</span>
8893
</div>
8994
)}
@@ -101,7 +106,7 @@ export function HeritageCard({
101106
{item.category && (
102107
<div className="flex flex-col gap-1">
103108
<span className="text-[10px] uppercase tracking-wider text-zinc-500 dark:text-zinc-400 font-bold">
104-
Heritage Category
109+
{text.heritageCategory}
105110
</span>
106111
<div>
107112
<TagChip>{item.category}</TagChip>
@@ -112,7 +117,7 @@ export function HeritageCard({
112117
{criteria.length > 0 && (
113118
<div className="flex flex-col gap-1">
114119
<span className="text-[10px] uppercase tracking-wider text-zinc-500 dark:text-zinc-400 font-bold">
115-
Criteria
120+
{text.criteria}
116121
</span>
117122
<div className="flex flex-wrap gap-1.5">
118123
{criteria.map((c: CriteriaCode) => (
@@ -134,7 +139,7 @@ export function HeritageCard({
134139
{desc}
135140
</p>
136141
) : (
137-
<p className="text-sm text-zinc-500 dark:text-zinc-400">No overview available.</p>
142+
<p className="text-sm text-zinc-500 dark:text-zinc-400">{text.noOverview}</p>
138143
)}
139144
<div className="mt-auto flex items-center justify-between pt-2 border-t border-zinc-100 dark:border-zinc-800">
140145
<span className="text-xs text-zinc-500 dark:text-zinc-400" aria-hidden="true">
@@ -145,7 +150,7 @@ export function HeritageCard({
145150
onClick={handleViewDetailClick}
146151
className="inline-flex items-center gap-1 text-sm font-medium text-indigo-600 hover:underline dark:text-indigo-400"
147152
>
148-
View details <span></span>
153+
{text.viewDetails} <span></span>
149154
</button>
150155
</div>
151156
</div>

client/src/app/features/top/components/heritage-detail/HeritageDetailLayout.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { textType } from "@shared/styles/typography";
1111
import { useSetBreadcrumbLabel } from "@features/breadcrumbs/BreadCrumbHooks.ts";
1212
import { BreadcrumbList } from "@shared/components/BreadcrumbList.tsx";
1313
import { useLocale } from "@shared/locale/LocaleHooks.ts";
14+
import { useText } from "@shared/locale/ui-text.ts";
1415

1516
const DEFAULT_SEARCH: SearchValues = {
1617
region: "",
@@ -20,12 +21,6 @@ const DEFAULT_SEARCH: SearchValues = {
2021
yearInscribedTo: "",
2122
};
2223

23-
const TABS: readonly { label: string; href: `#${string}` }[] = [
24-
{ label: "Description", href: "#content" },
25-
{ label: "Maps", href: "#geo-map" },
26-
{ label: "Gallery", href: "#gallery" },
27-
] as const;
28-
2924
const formatCriteriaInline = (criteria: string[] | undefined) =>
3025
criteria?.length ? criteria.map((c) => `(${c})`).join("") : "—";
3126

@@ -59,30 +54,31 @@ function HeritageDetailTabs({
5954

6055
// Key exam info: visible without scrolling on all screen sizes.
6156
function KeyExamInfo({ item }: { item: WorldHeritageDetailVm }) {
57+
const t = useText();
6258
return (
6359
<div className="mx-auto w-full max-w-6xl px-4 mt-4">
6460
<div className="flex flex-wrap gap-x-6 gap-y-2">
6561
<div>
6662
<div className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wide">
67-
Region
63+
{t.region}
6864
</div>
6965
<div className="text-sm font-semibold text-zinc-900">{item.region ?? "—"}</div>
7066
</div>
7167
<div>
7268
<div className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wide">
73-
Category
69+
{t.category}
7470
</div>
7571
<div className="text-sm font-semibold text-zinc-900">{item.category ?? "—"}</div>
7672
</div>
7773
<div>
7874
<div className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wide">
79-
Year Inscribed
75+
{t.yearInscribed}
8076
</div>
8177
<div className="text-sm font-semibold text-zinc-900">{item.yearInscribed ?? "—"}</div>
8278
</div>
8379
<div>
8480
<div className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wide">
85-
Criteria
81+
{t.criteria}
8682
</div>
8783
<div className="text-sm font-semibold text-zinc-900">
8884
{formatCriteriaInline(item.criteria)}
@@ -98,6 +94,12 @@ export function HeritageDetailLayout({ item }: { item: WorldHeritageDetailVm })
9894
const setLabel = useSetBreadcrumbLabel();
9995
const navigate = useNavigate();
10096
const { locale, toggleLocale } = useLocale();
97+
const t = useText();
98+
const tabs: readonly { label: string; href: `#${string}` }[] = [
99+
{ label: t.description, href: "#content" },
100+
{ label: t.maps, href: "#geo-map" },
101+
{ label: t.gallery, href: "#gallery" },
102+
];
101103

102104
const handleSubmit = (q: Partial<SearchValues>) => {
103105
const next = { ...search, ...q };
@@ -124,7 +126,7 @@ export function HeritageDetailLayout({ item }: { item: WorldHeritageDetailVm })
124126
<HeritageSubHeader value={search} onChange={setSearch} onSubmit={handleSubmit} />
125127

126128
<div className="mx-auto w-full max-w-6xl px-4 mt-6 md:mt-8 flex items-center justify-between">
127-
<HeritageDetailTabs items={TABS} />
129+
<HeritageDetailTabs items={tabs} />
128130
<button
129131
onClick={toggleLocale}
130132
className="rounded-full border border-zinc-200 px-3 py-1.5 text-xs font-semibold text-zinc-700 hover:bg-zinc-100 shrink-0"

client/src/app/features/top/components/heritage-detail/HeritageHero.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import type { WorldHeritageDetailVm, WorldHeritageImageVm } from "../../../../../domain/types.ts";
22
import { useLocale } from "@shared/locale/LocaleHooks.ts";
3+
import { useText } from "@shared/locale/ui-text.ts";
34

45
export function HeritageHero({ item }: { item: WorldHeritageDetailVm }) {
56
const { locale } = useLocale();
7+
const t = useText();
68
const primaryImage: WorldHeritageImageVm | undefined =
79
item.images.find((img) => img.isPrimary) ?? item.images[0];
810

@@ -57,7 +59,7 @@ export function HeritageHero({ item }: { item: WorldHeritageDetailVm }) {
5759
rel="noreferrer"
5860
className="shrink-0 font-semibold text-zinc-700 hover:underline"
5961
>
60-
View on UNESCO
62+
{t.viewOnUnesco}
6163
</a>
6264
)}
6365
</figcaption>

client/src/app/features/top/components/heritage-detail/HeritageOverviewSection.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import type { WorldHeritageDetailVm } from "../../../../../domain/types.ts";
22
import { textType } from "@shared/styles/typography.ts";
33
import { useLocale } from "@shared/locale/LocaleHooks.ts";
4+
import { useText } from "@shared/locale/ui-text.ts";
45

56
export function HeritageOverViewSection({ item }: { item: WorldHeritageDetailVm }) {
67
const { locale } = useLocale();
8+
const t = useText();
79
return (
810
<section
911
id="overview"
1012
className="rounded-3xl border border-zinc-200 bg-white shadow-sm px-5 py-6 md:px-8 md:py-8"
1113
>
1214
<div className="flex items-start justify-between gap-3">
1315
<div className="min-w-0">
14-
<h2 className={`${textType.h2} text-zinc-900`}>Overview</h2>
16+
<h2 className={`${textType.h2} text-zinc-900`}>{t.overview}</h2>
1517
</div>
1618

1719
{item.unescoSiteUrl && (
@@ -22,7 +24,7 @@ export function HeritageOverViewSection({ item }: { item: WorldHeritageDetailVm
2224
className="shrink-0 rounded-full border border-sky-200 bg-sky-50
2325
px-3 py-1.5 text-xs font-semibold text-sky-900 hover:bg-sky-100"
2426
>
25-
View on UNESCO
27+
{t.viewOnUnesco}
2628
</a>
2729
)}
2830
</div>

client/src/app/features/top/components/heritage-detail/HeritageSidebar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { WorldHeritageDetailVm } from "../../../../../domain/types.ts";
22
import { DetailHeritageMap } from "@features/top/components/heritage-detail/DetailHeritageMap.tsx";
33
import { HeritageMetadataList } from "./HeritageMetadataList.tsx";
4+
import { useText } from "@shared/locale/ui-text.ts";
45

56
const formatCriteriaInline = (criteria: string[] | undefined) =>
67
criteria?.length ? criteria.map((c) => `(${c})`).join("") : "—";
@@ -19,6 +20,7 @@ const formatLongitude = (lng: number): string => {
1920
};
2021

2122
export function HeritageSidebar({ item }: { item: WorldHeritageDetailVm }) {
23+
const t = useText();
2224
const hasCoord =
2325
item.latitude != null && item.longitude != null && !isZeroCoord(item.latitude, item.longitude);
2426

@@ -60,12 +62,12 @@ export function HeritageSidebar({ item }: { item: WorldHeritageDetailVm }) {
6062
href={item.unescoSiteUrl}
6163
target="_blank"
6264
rel="noreferrer noopener"
63-
aria-label="View on UNESCO"
65+
aria-label={t.viewOnUnesco}
6466
className="mt-4 inline-flex w-full items-center justify-center rounded-xl
6567
border border-sky-200 bg-sky-50 px-3 py-2 text-sm font-semibold
6668
text-sky-900 hover:bg-sky-100"
6769
>
68-
View on UNESCO
70+
{t.viewOnUnesco}
6971
</a>
7072
)}
7173
</div>

client/src/locals/en/ui.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"heritageCategory": "Heritage Category",
3+
"criteria": "Criteria",
4+
"viewDetails": "View details",
5+
"danger": "DANGER",
6+
"noImage": "No image",
7+
"noOverview": "No overview available.",
8+
"region": "Region",
9+
"category": "Category",
10+
"yearInscribed": "Year Inscribed",
11+
"description": "Description",
12+
"maps": "Maps",
13+
"gallery": "Gallery",
14+
"overview": "Overview",
15+
"viewOnUnesco": "View on UNESCO"
16+
}

client/src/locals/ja/ui.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"heritageCategory": "遺産カテゴリ",
3+
"criteria": "登録基準",
4+
"viewDetails": "詳細を見る",
5+
"danger": "危機",
6+
"noImage": "画像なし",
7+
"noOverview": "概要はありません。",
8+
"region": "地域",
9+
"category": "カテゴリ",
10+
"yearInscribed": "登録年",
11+
"description": "説明",
12+
"maps": "地図",
13+
"gallery": "ギャラリー",
14+
"overview": "概要",
15+
"viewOnUnesco": "UNESCO で見る"
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import en from "../../locals/en/ui.json";
2+
import ja from "../../locals/ja/ui.json";
3+
import { type Locale } from "../../domain/criteria.ts";
4+
import { useLocale } from "./LocaleHooks.ts";
5+
6+
export type UiText = typeof en;
7+
8+
const TEXTS: Record<Locale, UiText> = { en, ja };
9+
10+
export const useText = (): UiText => {
11+
const { locale } = useLocale();
12+
return TEXTS[locale];
13+
};

0 commit comments

Comments
 (0)