From e81a8b584ddbed8441ec08bd8ea07201a30807f1 Mon Sep 17 00:00:00 2001 From: Chengxun Lee <24319042+bclswl0827@users.noreply.github.com> Date: Fri, 6 Sep 2024 03:59:46 +0800 Subject: [PATCH] feat: Show flags next to earthquake data sources --- .../src/src/helpers/i18n/getFlagByCountry.tsx | 13 ++++ .../src/models/response/common/trace/0.json | 14 ++-- frontend/src/src/views/History/index.tsx | 69 ++++++++++++------- 3 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 frontend/src/src/helpers/i18n/getFlagByCountry.tsx diff --git a/frontend/src/src/helpers/i18n/getFlagByCountry.tsx b/frontend/src/src/helpers/i18n/getFlagByCountry.tsx new file mode 100644 index 00000000..fb6fec05 --- /dev/null +++ b/frontend/src/src/helpers/i18n/getFlagByCountry.tsx @@ -0,0 +1,13 @@ +export const getFlagByCountry = (countryCode: string) => { + if (!countryCode || countryCode.length !== 2 || !/^[a-zA-Z]+$/.test(countryCode)) { + return "🏳️"; + } + + const code = countryCode.toUpperCase(); + const offset = 127397; + const flag = Array.from(code) + .map((letter) => String.fromCodePoint(letter.charCodeAt(0) + offset)) + .join(""); + + return flag; +}; diff --git a/frontend/src/src/models/response/common/trace/0.json b/frontend/src/src/models/response/common/trace/0.json index 287d4570..c2af4e03 100644 --- a/frontend/src/src/models/response/common/trace/0.json +++ b/frontend/src/src/models/response/common/trace/0.json @@ -1,13 +1,19 @@ { - "time": "1970-01-01T23:59:59Z", + "time": "2024-09-05T19:26:27Z", "status": 200, "error": false, "path": "/api/v1/trace", - "message": "Successfully read available data source list", + "message": "Successfully read available data source properties", "data": [ { - "name": "null", - "value": "null" + "id": "hko", + "country": "HK", + "default": "en-US", + "locales": { + "en-US": "Hong Kong Observatory", + "zh-TW": "天文台全球地震資訊網", + "zh-CN": "天文台全球地震信息网" + } } ] } \ No newline at end of file diff --git a/frontend/src/src/views/History/index.tsx b/frontend/src/src/views/History/index.tsx index e9a4a03f..0d8115e4 100644 --- a/frontend/src/src/views/History/index.tsx +++ b/frontend/src/src/views/History/index.tsx @@ -18,6 +18,7 @@ import { apiConfig, traceCommonResponseModel1 } from "../../config/api"; import { i18nConfig } from "../../config/i18n"; import { RouterComponentProps } from "../../config/router"; import { ReduxStoreProps } from "../../config/store"; +import { getFlagByCountry } from "../../helpers/i18n/getFlagByCountry"; import { sendPromiseAlert } from "../../helpers/interact/sendPromiseAlert"; import { sendUserAlert } from "../../helpers/interact/sendUserAlert"; import { requestRestApi } from "../../helpers/request/requestRestApi"; @@ -31,6 +32,8 @@ import { handleSetCharts } from "./handleSetCharts"; import { handleSetLabels } from "./handleSetLabels"; const History = (props: RouterComponentProps) => { + const { fallback: fallbackLocale } = i18nConfig; + const { locale } = props; const { t } = useTranslation(); const { station } = useSelector(({ station }: ReduxStoreProps) => station); @@ -406,28 +409,47 @@ const History = (props: RouterComponentProps) => { })); }; - setForm((prev) => ({ - ...prev, - open: true, - selectOptions: res.data - .sort((a, b) => { - if ("name" in a && "value" in a && "name" in b && "value" in b) { - return a.name.localeCompare(b.name); - } - return 0; - }) - .map((source) => { - if ("name" in source && "value" in source) { - return { label: source.name, value: source.value }; - } - return { label: "", value: "" }; - }), - onSubmit: handleSubmitForm, - title: "views.history.forms.choose_source.title", - cancelText: "views.history.forms.choose_source.cancel", - submitText: "views.history.forms.choose_source.submit", - placeholder: "views.history.forms.choose_source.placeholder" - })); + setForm((prev) => { + const currentLocale = locale ?? fallbackLocale; + return { + ...prev, + open: true, + selectOptions: res.data + .sort((a, b) => { + if ("locales" in a && "locales" in b) { + const aLocale = + a.locales[currentLocale as keyof typeof a.locales] ?? + a.locales[a.default as keyof typeof a.locales]; + const bLocale = + b.locales[currentLocale as keyof typeof b.locales] ?? + b.locales[b.default as keyof typeof b.locales]; + return aLocale.localeCompare(bLocale); + } + return 0; + }) + .map((seisSource) => { + if ("locales" in seisSource) { + const source = + seisSource.locales[ + currentLocale as keyof typeof seisSource.locales + ] ?? + seisSource.locales[ + seisSource.default as keyof typeof seisSource.locales + ]; + return { + label: `${getFlagByCountry(seisSource.country)} ${source}`, + value: seisSource.id + }; + } + return { label: "", value: "" }; + }), + onSubmit: handleSubmitForm, + title: "views.history.forms.choose_source.title", + cancelText: "views.history.forms.choose_source.cancel", + submitText: "views.history.forms.choose_source.submit", + placeholder: "views.history.forms.choose_source.placeholder" + }; + }); }; const handleGetShareLink = async () => { @@ -451,9 +473,6 @@ const History = (props: RouterComponentProps) => { ); }; - const { locale } = props; - const { fallback: fallbackLocale } = i18nConfig; - return ( <>