diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4f47aa9a..9a7d7590 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -20,6 +20,7 @@ "dbaeumer.vscode-eslint", "Nuxtr.nuxtr-vscode", "Prisma.prisma", + "lokalise.i18n-ally", // Do not install Prettier. It will conflict with eslint. "-esbenp.prettier-vscode" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 13590514..1d6aa34d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,11 +13,16 @@ "eslint.options": { "overrideConfigFile": "./eslint.config.js" }, - "eslint.experimental.useFlatConfig": true, + "eslint.useFlatConfig": true, "eslint.lintTask.enable": true, "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, "editor.insertSpaces": true, - "editor.tabSize": 2 + "editor.tabSize": 2, + "i18n-ally.localesPaths": [ + "locales" + ], + "i18n-ally.enabledParsers": ["js", "ts", "json"], + "i18n-ally.enabledFrameworks": ["vue-sfc", "vue"] } diff --git a/components/custom/sidebar.vue b/components/custom/sidebar.vue index 9282508b..955483c2 100644 --- a/components/custom/sidebar.vue +++ b/components/custom/sidebar.vue @@ -4,8 +4,10 @@ import { cn } from '@/lib/utils' import { useClerk } from 'vue-clerk' import type { AllClubs } from '~/types/api/user/all_clubs' +const { t } = useI18n({ + useScope: 'local', +}) const clerk = useClerk() - const route = useRoute() const isPresidentOrVicePresident = ref(false) @@ -31,33 +33,33 @@ if (import.meta.client) {

- 学校事务 + {{ t('school_affairs') }}

- 社团信息 + {{ t('cas_information') }}

@@ -70,44 +72,44 @@ if (import.meta.client) {

- CAS管理 + {{ t('manage') }}

- 信息 + {{ t('info') }}

@@ -115,3 +117,38 @@ if (import.meta.client) {
+ + +{ + "zh": { + "home": "首页", + "school_affairs": "校务", + "forms": "表格", + "cas_information": "CAS信息", + "clubs": "社团", + "rating": "期末评价", + "manage": "CAS管理", + "reservation": "预约教室", + "manage_reservation": "管理预约", + "statuses": "教室状态", + "record": "活动签到", + "info": "信息", + "about": "关于 Enspire" + }, + "en": { + "home": "Home", + "school_affairs": "School Affairs", + "forms": "Forms", + "cas_information": "CAS Information", + "clubs": "Clubs", + "rating": "Rating", + "manage": "CAS Management", + "reservation": "Reservation", + "manage_reservation": "Manage Reservation", + "statuses": "Statuses", + "record": "Record", + "info": "Info", + "about": "About Enspire" + } +} + diff --git a/i18n.config.ts b/i18n.config.ts new file mode 100644 index 00000000..92028679 --- /dev/null +++ b/i18n.config.ts @@ -0,0 +1,12 @@ +import en from './locales/en.json' +import zh from './locales/zh.json' + +export default defineI18nConfig(() => ({ + legacy: false, + locale: 'en', + fallbackLocale: 'zh', + messages: { + zh, + en, + }, +})) diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 00000000..0db3279e --- /dev/null +++ b/locales/en.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/locales/zh.json b/locales/zh.json new file mode 100644 index 00000000..0db3279e --- /dev/null +++ b/locales/zh.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/nuxt.config.ts b/nuxt.config.ts index 30187629..ed2693f0 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -24,6 +24,7 @@ export default defineNuxtConfig({ '@sentry/nuxt/module', '@nuxt/image', 'dayjs-nuxt', + '@nuxtjs/i18n', ], build: { @@ -71,5 +72,22 @@ export default defineNuxtConfig({ }, }, + future: { + compatibilityVersion: 4, + }, + + i18n: { + vueI18n: './i18n.config.ts', + detectBrowserLanguage: { + useCookie: true, + cookieKey: 'i18n_redirected', + redirectOn: 'root', + }, + }, + compatibilityDate: '2024-08-31', + + devtools: { + enabled: true, + }, }) diff --git a/package.json b/package.json index f6e74ba7..2db19c84 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@netlify/integrations": "^0.5.4", "@netlify/sentry": "^0.0.10", "@nuxt/content": "^2.13.4", + "@nuxtjs/i18n": "^9.1.0", "@radix-icons/vue": "^1.0.0", "@sentry/nuxt": "^8.34.0", "@tanstack/vue-table": "^8.20.5", @@ -88,5 +89,11 @@ }, "prisma": { "schema": "db/schema.prisma" + }, + "pnpm": { + "overrides": { + "@intlify/core": "10.0.5", + "@intlify/shared": "10.0.5" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4026f1e..eafaf569 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17187,11 +17187,14 @@ snapshots: vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)): dependencies: + '@intlify/core-base': 10.0.5 + '@intlify/shared': 10.0.5 '@vue/devtools-api': 6.6.4 vue: 3.5.12(typescript@5.6.3) vue-screen-utils@1.0.0-beta.13(vue@3.5.12(typescript@5.6.3)): dependencies: + '@vue/devtools-api': 6.6.4 vue: 3.5.12(typescript@5.6.3) vue-tsc@2.1.6(typescript@5.6.3):