Repository navigation
Change Criteria UI #123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change Criteria UI #123
Changes from all commits
0c37cb0
4da44cf
e52f4b7
e03ef92
234b7aa
b737ae6
e657bc9
f2c3d3d
058ed04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,12 +1,15 @@ | ||||||
| import type { WorldHeritageDetailVm, WorldHeritageImageVm } from "../../types"; | ||||||
| import { HeroImage } from "./HeroImage"; | ||||||
| import "./heritage-detail.css"; | ||||||
| import { CriteriaTags } from "@shared/uis/CriteriaTags.tsx"; | ||||||
| import type { Locale } from "../../../../../domain/criteria.ts"; | ||||||
|
||||||
| import type { Locale } from "../../../../../domain/criteria.ts"; | |
| import type { Locale } from "../../../../../domain/criteria"; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,42 +1,64 @@ | ||||||
| import type { WorldHeritageDetailVm } from "../../types"; | ||||||
| import "./heritage-detail.css"; | ||||||
| import { HeritageMetadataList } from "./HeritageMetadataList"; | ||||||
| import { CriteriaTags } from "@shared/uis/CriteriaTags.tsx"; | ||||||
| import type { Locale } from "../../../../../domain/criteria.ts"; | ||||||
|
||||||
| import type { Locale } from "../../../../../domain/criteria.ts"; | |
| import type { Locale } from "../../../../../domain/criteria"; |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CSS classes 'heritage-detail__chips' and 'heritage-detail__muted' are used but not defined in any CSS file. These classes need to be added to the heritage-detail.css file or the elements should use existing classes. Without these styles, the criteria tags and the fallback dash may not be displayed correctly.
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CSS classes 'heritage-detail__subsection' and 'heritage-detail__subsection--danger' are used but not defined in the CSS file. These classes should be added to heritage-detail.css to properly style these sections, or the existing 'heritage-detail__section' and 'heritage-detail__section--danger' classes should be used instead.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,35 +1,38 @@ | ||||||
| import type { WorldHeritageDetailVm } from "../../types"; | ||||||
| import "./heritage-detail.css"; | ||||||
| import { HeritageMetadataList } from "./HeritageMetadataList"; | ||||||
| import type { Locale } from "../../../../../domain/criteria"; | ||||||
|
|
||||||
| type Props = { | ||||||
| item: WorldHeritageDetailVm; | ||||||
| locale: Locale; | ||||||
| }; | ||||||
|
|
||||||
| const formatCriteriaInline = (criteria: string[] | undefined) => | ||||||
| criteria?.length ? criteria.map((c) => `(${c})`).join("") : "—"; | ||||||
|
|
||||||
| export function HeritageSidebar({ item }: Props) { | ||||||
|
||||||
| export function HeritageSidebar({ item }: Props) { | |
| export function HeritageSidebar({ item, locale }: Props) { |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The aria-label attribute on a div element has no semantic meaning without an appropriate ARIA role. Consider changing this div to a section element or adding role="region" to make the aria-label effective for screen readers.
| <div className="heritage-detail__map-card" aria-label="Map"> | |
| <div className="heritage-detail__map-card" aria-label="Map" role="region"> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,55 @@ | ||||||||||||||||||
| import en from "../locals/en/world-heritage-criteria.json"; | ||||||||||||||||||
| import ja from "../locals/ja/world-heritage-criteria.json"; | ||||||||||||||||||
|
|
||||||||||||||||||
| export type CriteriaText = { | ||||||||||||||||||
| title: string; | ||||||||||||||||||
| description: string; | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const CRITERIA_CODES = [ | ||||||||||||||||||
| "i", | ||||||||||||||||||
| "ii", | ||||||||||||||||||
| "iii", | ||||||||||||||||||
| "iv", | ||||||||||||||||||
| "v", | ||||||||||||||||||
| "vi", | ||||||||||||||||||
| "vii", | ||||||||||||||||||
| "viii", | ||||||||||||||||||
| "ix", | ||||||||||||||||||
| "x", | ||||||||||||||||||
| ] as const; | ||||||||||||||||||
|
|
||||||||||||||||||
| export type CriteriaCode = (typeof CRITERIA_CODES)[number]; | ||||||||||||||||||
| export type CriteriaDict = Record<CriteriaCode, CriteriaText>; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const LOCALES = ["en", "ja"] as const; | ||||||||||||||||||
| export type Locale = (typeof LOCALES)[number]; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const UNESCO_CRITERIA_SOURCE_URL = "https://whc.unesco.org/en/criteria/"; | ||||||||||||||||||
| const CRITERIA_BY_LOCALE: Record<Locale, CriteriaDict> = { | ||||||||||||||||||
| en: en as CriteriaDict, | ||||||||||||||||||
| ja: ja as CriteriaDict, | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const getCriteriaDict = (locale: Locale): CriteriaDict => CRITERIA_BY_LOCALE[locale]; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const getCriteria = (code: CriteriaCode, locale: Locale): CriteriaText => { | ||||||||||||||||||
| const entry = CRITERIA_BY_LOCALE[locale]?.[code]; | ||||||||||||||||||
| if (entry) return entry; | ||||||||||||||||||
|
|
||||||||||||||||||
| const fallback = CRITERIA_BY_LOCALE.en?.[code]; | ||||||||||||||||||
| if (fallback) return fallback; | ||||||||||||||||||
|
|
||||||||||||||||||
| return { title: code, description: "" }; | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const getCriteriaSafe = (code: CriteriaCode, locale: string): CriteriaText => { | ||||||||||||||||||
| const safeLocale: Locale = (LOCALES as readonly string[]).includes(locale) | ||||||||||||||||||
| ? (locale as Locale) | ||||||||||||||||||
| : "en"; | ||||||||||||||||||
| return CRITERIA_BY_LOCALE[safeLocale][code]; | ||||||||||||||||||
|
||||||||||||||||||
| return CRITERIA_BY_LOCALE[safeLocale][code]; | |
| const entry = CRITERIA_BY_LOCALE[safeLocale]?.[code]; | |
| if (entry) return entry; | |
| const fallback = CRITERIA_BY_LOCALE.en?.[code]; | |
| if (fallback) return fallback; | |
| return { title: code, description: "" }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| { | ||
| "i": { | ||
| "title": "Masterpiece", | ||
| "description": "Represents a masterpiece of human creative genius." | ||
| }, | ||
| "ii": { | ||
| "title": "Interchange of values", | ||
| "description": "Shows an important interchange of human values over time or within a cultural area." | ||
| }, | ||
| "iii": { | ||
| "title": "Unique testimony", | ||
| "description": "Bears a unique or exceptional testimony to a cultural tradition or civilization." | ||
| }, | ||
| "iv": { | ||
| "title": "Architectural ensemble", | ||
| "description": "An outstanding example of a type of building, architectural or technological ensemble, or landscape illustrating a significant stage in human history." | ||
| }, | ||
| "v": { | ||
| "title": "Traditional human settlement", | ||
| "description": "An outstanding example of traditional human settlement or land-use representative of a culture." | ||
| }, | ||
| "vi": { | ||
| "title": "Associative significance", | ||
| "description": "Directly associated with events, living traditions, ideas, beliefs, or artistic works of outstanding universal significance." | ||
| }, | ||
| "vii": { | ||
| "title": "Natural beauty", | ||
| "description": "Contains superlative natural phenomena or areas of exceptional natural beauty." | ||
| }, | ||
| "viii": { | ||
| "title": "Earth’s history", | ||
| "description": "Outstanding examples representing major stages of Earth’s history, including geological processes." | ||
| }, | ||
| "ix": { | ||
| "title": "Ecological processes", | ||
| "description": "Outstanding examples representing significant ongoing ecological and biological processes." | ||
| }, | ||
| "x": { | ||
| "title": "Biodiversity", | ||
| "description": "Contains important natural habitats for in-situ conservation of biological diversity." | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript imports should omit .tsx/.ts extensions in non-test runtime code files. The codebase convention is to use imports without extensions for relative paths. Remove the .tsx and .ts extensions from these import statements.