diff --git a/src/App.vue b/src/App.vue
index 2b69df2..ef7ec04 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,10 +1,13 @@
diff --git a/src/components/views/HomeView.vue b/src/components/views/HomeView.vue
index 209554e..db196f0 100644
--- a/src/components/views/HomeView.vue
+++ b/src/components/views/HomeView.vue
@@ -1,8 +1,12 @@
@@ -33,19 +67,22 @@ async function tryLogin() {
-
-
+
+
-
-
+
+
+
-
- LOGIN
+
+ {{ t('$vuetify.user.login') }}
-
- REGISTER
+
+ {{ t('$vuetify.user.logout') }}
@@ -57,27 +94,29 @@ async function tryLogin() {
-
-
+
-
-
+ {{ t('$vuetify.login.failedNote') }}
+
- PLEASE CONFIRM YOU HAVE READ AND AGREE TO THE
- TERMS OF SERVICE
+ {{ t('$vuetify.login.agreement') }}
+ {{ t('$vuetify.login.termsOfService') }}
-
+
-
-
+
@@ -93,4 +132,8 @@ async function tryLogin() {
.login-dialong-input {
margin: 10px 0;
}
+
+.home-menu-button {
+ width: 100px;
+}
\ No newline at end of file
diff --git a/src/plugins/vuetify.ts b/src/plugins/vuetify.ts
index 1f149da..6dea1d4 100644
--- a/src/plugins/vuetify.ts
+++ b/src/plugins/vuetify.ts
@@ -1,7 +1,17 @@
import {createVuetify} from "vuetify";
import {aliases, mdi} from "vuetify/iconsets/mdi";
+import en from "../script/i18n/en.ts";
+import zhHans from "../script/i18n/zhHans.ts";
+const messages: any = {
+ en, zhHans
+}
export const vuetify = createVuetify({
+ locale: {
+ locale: localStorage.getItem('locale') ?? 'en',
+ fallback: 'en',
+ messages
+ },
icons: {
defaultSet: 'mdi',
aliases,
@@ -13,5 +23,8 @@ export const vuetify = createVuetify({
global: {
ripple: true
}
+ },
+ theme: {
+ defaultTheme: localStorage.getItem('theme') ?? 'light'
}
})
\ No newline at end of file
diff --git a/src/script/functions.ts b/src/script/functions.ts
index 4d89069..4fa49d6 100644
--- a/src/script/functions.ts
+++ b/src/script/functions.ts
@@ -10,6 +10,12 @@ interface LoginInfo {
}
}
+interface Msg {
+ code: number,
+ msg?: string,
+ value?: any
+}
+
async function request(path: string, init: RequestInit): Promise {
const useSiteConfig = useSiteConfigStore()
const siteConfig = useSiteConfig.siteConfig
@@ -31,7 +37,7 @@ async function login(username: string, password: string): Promise {
try {
const response = await responsePromise
const body: LoginInfo = await response.json()
- if(body.code == 0) {
+ if (body.code == 0) {
userinfoStore.setToken(body.value?.token ?? '')
return true
} else {
@@ -42,4 +48,29 @@ async function login(username: string, password: string): Promise {
}
}
-export { request, login }
\ No newline at end of file
+function logout() {
+ const userinfoStore = useUserinfoStore()
+ userinfoStore.setToken('')
+ window.location.reload()
+}
+
+async function checkLogin(): Promise {
+ const userinfoStore = useUserinfoStore()
+ if (userinfoStore.isLogin) {
+ try {
+ const reponse = await request('loginCheck', {
+ headers: {
+ 'Authorization': `Bearer ${userinfoStore.token}`
+ }
+ })
+ const body: Msg = await reponse.json()
+ return body.code == 0
+ } catch (_) {
+ return false
+ }
+ } else {
+ return false
+ }
+}
+
+export {request, login, logout, checkLogin}
\ No newline at end of file
diff --git a/src/script/i18n/en.ts b/src/script/i18n/en.ts
new file mode 100644
index 0000000..2f8282f
--- /dev/null
+++ b/src/script/i18n/en.ts
@@ -0,0 +1,28 @@
+import {en as locale_en} from "vuetify/locale";
+import LocaleInterface from "./locale-interface.ts";
+const en: LocaleInterface = {
+ ...locale_en,
+ menu: {
+ home: 'HOME',
+ services: 'SERVICES',
+ search: 'search'
+ },
+ user: {
+ login: 'Login',
+ logout: 'Logout'
+ },
+ login: {
+ title: 'Login',
+ username: 'USERNAME',
+ password: 'PASSWORD',
+ failedNote: 'Login failed, please check your username and password',
+ rememberMe: 'Remember me',
+ agreement: 'PLEASE CONFIRM YOU HAVE READ AND AGREE TO THE',
+ termsOfService: 'TERMS OF SERVICE',
+ button: {
+ login: 'LOGIN',
+ cancel: 'CANCEL'
+ }
+ }
+}
+export default en
\ No newline at end of file
diff --git a/src/script/i18n/locale-interface.ts b/src/script/i18n/locale-interface.ts
new file mode 100644
index 0000000..188670b
--- /dev/null
+++ b/src/script/i18n/locale-interface.ts
@@ -0,0 +1,127 @@
+export default interface LocaleInterface {
+ menu: {
+ home: string,
+ services: string,
+ search: string
+ },
+ user: {
+ login: string,
+ logout: string
+ },
+ login: {
+ title: string,
+ username: string,
+ password: string,
+ failedNote: string,
+ rememberMe: string,
+ agreement: string,
+ termsOfService: string,
+ button: {
+ login: string,
+ cancel: string
+ }
+ },
+ // ==================
+ // vuetify
+ // ==================
+ badge: string;
+ open: string;
+ close: string;
+ dismiss: string;
+ confirmEdit: {
+ ok: string;
+ cancel: string;
+ };
+ dataIterator: {
+ noResultsText: string;
+ loadingText: string;
+ };
+ dataTable: {
+ itemsPerPageText: string;
+ ariaLabel: {
+ sortDescending: string;
+ sortAscending: string;
+ sortNone: string;
+ activateNone: string;
+ activateDescending: string;
+ activateAscending: string;
+ };
+ sortBy: string;
+ };
+ dataFooter: {
+ itemsPerPageText: string;
+ itemsPerPageAll: string;
+ nextPage: string;
+ prevPage: string;
+ firstPage: string;
+ lastPage: string;
+ pageText: string;
+ };
+ dateRangeInput: {
+ divider: string;
+ };
+ datePicker: {
+ itemsSelected: string;
+ range: {
+ title: string;
+ header: string;
+ };
+ title: string;
+ header: string;
+ input: {
+ placeholder: string;
+ };
+ };
+ noDataText: string;
+ carousel: {
+ prev: string;
+ next: string;
+ ariaLabel: {
+ delimiter: string;
+ };
+ };
+ calendar: {
+ moreEvents: string;
+ today: string;
+ };
+ input: {
+ clear: string;
+ prependAction: string;
+ appendAction: string;
+ otp: string;
+ };
+ fileInput: {
+ counter: string;
+ counterSize: string;
+ };
+ timePicker: {
+ am: string;
+ pm: string;
+ title: string;
+ };
+ pagination: {
+ ariaLabel: {
+ root: string;
+ next: string;
+ previous: string;
+ page: string;
+ currentPage: string;
+ first: string;
+ last: string;
+ };
+ };
+ stepper: {
+ next: string;
+ prev: string;
+ };
+ rating: {
+ ariaLabel: {
+ item: string;
+ };
+ };
+ loading: string;
+ infiniteScroll: {
+ loadMore: string;
+ empty: string;
+ }
+}
\ No newline at end of file
diff --git a/src/script/i18n/zhHans.ts b/src/script/i18n/zhHans.ts
new file mode 100644
index 0000000..80ed3b9
--- /dev/null
+++ b/src/script/i18n/zhHans.ts
@@ -0,0 +1,28 @@
+import {zhHans as locale_zhHans} from "vuetify/locale";
+import LocaleInterface from "./locale-interface.ts";
+const zhHans: LocaleInterface = {
+ ...locale_zhHans,
+ menu: {
+ home: '首页',
+ services: '服务',
+ search: '搜索'
+ },
+ user: {
+ login: '登录',
+ logout: '退出'
+ },
+ login: {
+ title: '登录',
+ username: '用户名',
+ password: '密码',
+ failedNote: '登录失败,请检查用户名和密码',
+ rememberMe: '保持登录',
+ agreement: '我已阅读并同意',
+ termsOfService: '服务条款',
+ button: {
+ login: '登录',
+ cancel: '取消'
+ }
+ }
+}
+export default zhHans
\ No newline at end of file
diff --git a/src/stores/userinfo-store.ts b/src/stores/userinfo-store.ts
index 78e3e9d..2083d03 100644
--- a/src/stores/userinfo-store.ts
+++ b/src/stores/userinfo-store.ts
@@ -2,18 +2,22 @@ import {defineStore} from "pinia";
import {computed, ref} from "vue";
export const useUserinfoStore = defineStore('userinfo', () => {
- const token = ref('')
+ const localToken = localStorage.getItem('token') ?? ''
+ const token = ref(localToken)
const username = ref('')
- const isLogin = computed(() => token.value.length == 0)
+ const isLogin = computed(() => token.value.length != 0)
const setToken = (t: string): void => {
token.value = t
localStorage.setItem('token', t)
}
+ const clearToken = () => {
+ setToken('')
+ }
const getToken = (): string => {
if (token.value.length == 0) {
- token.value = localStorage.getItem('token') ?? ''
+ token.value = localToken
}
return token.value
}
- return {token, username, isLogin, setToken, getToken}
+ return {token, username, isLogin, setToken, getToken, clearToken}
})
\ No newline at end of file