From 02fe08d785d5b29f60cb3e74086b71288c0c5359 Mon Sep 17 00:00:00 2001 From: whats2000 <60466660+whats2000@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:06:34 +0800 Subject: [PATCH] Feat: Make all text into i18next --- nsysu_selector_helper/package.json | 13 +- nsysu_selector_helper/src/App.tsx | 4 +- .../src/components/SectionHeader.tsx | 44 +- nsysu_selector_helper/src/i18n/i18nConfig.ts | 37 + .../src/i18n/locales/zh_TW/translation.json | 9 + nsysu_selector_helper/src/main.tsx | 15 +- nsysu_selector_helper/tsconfig.app.json | 3 +- nsysu_selector_helper/yarn.lock | 1004 ++++++++++++++++- 8 files changed, 1096 insertions(+), 33 deletions(-) create mode 100644 nsysu_selector_helper/src/i18n/i18nConfig.ts create mode 100644 nsysu_selector_helper/src/i18n/locales/zh_TW/translation.json diff --git a/nsysu_selector_helper/package.json b/nsysu_selector_helper/package.json index 58c95ca..f1a49a4 100644 --- a/nsysu_selector_helper/package.json +++ b/nsysu_selector_helper/package.json @@ -13,11 +13,15 @@ "@ant-design/icons": "^5.3.7", "@swc/plugin-styled-components": "^2.0.9", "antd": "^5.19.0", + "i18next": "^23.11.5", + "i18next-browser-languagedetector": "^8.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-i18next": "^14.1.2", "styled-components": "^6.1.11" }, "devDependencies": { + "@types/i18next-browser-languagedetector": "^3.0.0", "@types/node": "^20.14.9", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -25,9 +29,12 @@ "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react-swc": "^3.5.0", - "eslint": "^8.57.0", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-react": "^7.34.1", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", "prettier": "^3.3.2", "typescript": "^5.2.2", "vite": "^5.3.1" diff --git a/nsysu_selector_helper/src/App.tsx b/nsysu_selector_helper/src/App.tsx index 15ef601..898f2ad 100644 --- a/nsysu_selector_helper/src/App.tsx +++ b/nsysu_selector_helper/src/App.tsx @@ -7,7 +7,7 @@ import { NSYSUCourseAPI } from '@/api/NSYSUCourseAPI.ts'; import SectionHeader from '#/SectionHeader.tsx'; const App: FC = () => { - const [themeConfig, _setThemeConfig] = useThemeConfig(); + const [themeConfig] = useThemeConfig(); const [isLoading, setIsLoading] = useState(true); @@ -17,7 +17,7 @@ const App: FC = () => { history: {}, }); const [selectedSemester, setSelectedSemester] = useState(''); - const [courses, setCourses] = useState([]); + const [, setCourses] = useState([]); useEffect(() => { NSYSUCourseAPI.getAvailableSemesters().then((availableSemesters) => { diff --git a/nsysu_selector_helper/src/components/SectionHeader.tsx b/nsysu_selector_helper/src/components/SectionHeader.tsx index c38dcc6..ea41dab 100644 --- a/nsysu_selector_helper/src/components/SectionHeader.tsx +++ b/nsysu_selector_helper/src/components/SectionHeader.tsx @@ -9,6 +9,7 @@ import { Select, SelectProps, } from 'antd'; +import { useTranslation } from 'react-i18next'; import { BookFilled, BookOutlined, @@ -17,9 +18,10 @@ import { NotificationOutlined, MenuOutlined, } from '@ant-design/icons'; -import banner from '@/assets/banner.svg'; import styled from 'styled-components'; + import { AcademicYear } from '@/types'; +import banner from '@/assets/banner.svg'; const HeaderContainer = styled(Flex)<{ $primaryColor: string; @@ -97,6 +99,8 @@ const SectionHeader: FC = ({ selectedSemester, setSelectedSemester, }) => { + const { t } = useTranslation(); + const { token } = theme.useToken(); const primaryColor = token.colorPrimary; const textColor = '#ffffff'; @@ -104,15 +108,31 @@ const SectionHeader: FC = ({ const [drawerOpen, setDrawerOpen] = useState(false); const navTabs: MenuProps['items'] = [ - { key: 'all-courses', label: '所有課程', icon: }, - { key: 'semester-compulsory', label: '學期必修', icon: }, + { + key: 'all-courses', + label: t('all-courses'), + icon: , + }, + { + key: 'semester-compulsory', + label: t('semester-compulsory'), + icon: , + }, { key: 'course-detective', - label: '課程偵探', + label: t('course-detective'), icon: , }, - { key: 'selected-export', label: '已選匯出', icon: }, - { key: 'announcements', label: '公告', icon: }, + { + key: 'selected-export', + label: t('selected-export'), + icon: , + }, + { + key: 'announcements', + label: t('announcements'), + icon: , + }, ]; const semesterCodeMap = { @@ -127,11 +147,11 @@ const SectionHeader: FC = ({ .sort((a, b) => b.localeCompare(a)) .map((year) => ({ key: year, - label: `${year.slice(0, -1)} ${semesterCodeMap[parseInt(year.slice(-1))]}`, + label: `${year.slice(0, -1)} ${semesterCodeMap[parseInt(year.slice(-1)) as 1 | 2 | 3]}`, value: year, })); - const handleMenuClick = (e: any) => { + const handleMenuClick = (e: { key: string }) => { setSelectedKeys([e.key]); setDrawerOpen(false); }; @@ -148,8 +168,8 @@ const SectionHeader: FC = ({ setSelectedSemester(value)} + value={selectedSemester === '' ? t('loading') : selectedSemester} + onChange={(value) => setSelectedSemester(value as string)} options={semesterOptions} loading={!semesterOptions.length} style={{ width: 120 }} @@ -171,14 +191,14 @@ const SectionHeader: FC = ({ setDrawerOpen(false)} open={drawerOpen} >