up
This commit is contained in:
@@ -1,17 +1,43 @@
|
|||||||
{
|
{
|
||||||
"appname": {
|
"appname": {
|
||||||
"home": "Home"
|
"home": "Home",
|
||||||
|
"login": "Login",
|
||||||
|
"forgot_password":"Forgot Password",
|
||||||
|
"register":"Register"
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"hello": "Hello",
|
"hello": "Hello",
|
||||||
"welcome": "Welcome",
|
"welcome": "Welcome",
|
||||||
"dark_mode":"Enable dark mode",
|
"dark_mode":"Enable dark mode",
|
||||||
"light_mode":"Enable light mode",
|
"light_mode":"Enable light mode",
|
||||||
"login_or_register":"Login/Register"
|
"login_or_register":"Login/Register",
|
||||||
|
"login_to_your_account":"Login to your account",
|
||||||
|
"your_email_address":"Your email address",
|
||||||
|
"email_address":"Email address",
|
||||||
|
"user_name":"User name",
|
||||||
|
"your_user_name":"Your user name",
|
||||||
|
"password":"Password",
|
||||||
|
"your_password":"Your password",
|
||||||
|
"i_forgot_password":"I forgot my password",
|
||||||
|
"remember_me_on_this_device":"Remember me on this device",
|
||||||
|
"dont_have_account_yet":"Don't have an account yet?",
|
||||||
|
"register_now":"Register now",
|
||||||
|
"show_password":"Show password",
|
||||||
|
"hidden_Password":"Hidden Password",
|
||||||
|
"please_enter_username_and_password":"Please enter username and password",
|
||||||
|
"forgot_password":"Forgot Password",
|
||||||
|
"enter_your_email_to_reset_password":"Enter your email address and your password will be reset and emailed to you.",
|
||||||
|
"back_to_login":"Back to login",
|
||||||
|
"please_enter_your_email":"Please enter your email",
|
||||||
|
"this_not_email":"This is not an email address.",
|
||||||
|
"create_new_account":"Create new account",
|
||||||
|
"already_have_an_account":"Already have an account?"
|
||||||
},
|
},
|
||||||
"button": {
|
"button": {
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel",
|
||||||
|
"sign_in":"Sign In",
|
||||||
|
"send_me_new_password":"Send me new password"
|
||||||
},
|
},
|
||||||
"footer":{
|
"footer":{
|
||||||
"doc":"Documentation",
|
"doc":"Documentation",
|
||||||
|
|||||||
@@ -1,17 +1,43 @@
|
|||||||
{
|
{
|
||||||
"appname": {
|
"appname": {
|
||||||
"home": "主页"
|
"home": "主页",
|
||||||
|
"login": "登录",
|
||||||
|
"forgot_password": "忘记密码",
|
||||||
|
"register": "注册"
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"hello": "你好",
|
"hello": "你好",
|
||||||
"welcome": "欢迎",
|
"welcome": "欢迎",
|
||||||
"dark_mode": "深色模式",
|
"dark_mode": "深色模式",
|
||||||
"light_mode": "亮色模式",
|
"light_mode": "亮色模式",
|
||||||
"login_or_register":"登录/注册"
|
"login_or_register": "登录/注册",
|
||||||
|
"login_to_your_account": "登录到您的账户",
|
||||||
|
"your_email_address": "您的邮箱地址",
|
||||||
|
"email_address": "邮箱地址",
|
||||||
|
"user_name": "用户名",
|
||||||
|
"your_user_name": "您的用户名",
|
||||||
|
"password": "密码",
|
||||||
|
"your_password": "您的密码",
|
||||||
|
"i_forgot_password": "我忘记了密码",
|
||||||
|
"remember_me_on_this_device": "记住我在这台设备上",
|
||||||
|
"dont_have_account_yet": "还没有账户?",
|
||||||
|
"register_now": "立即注册",
|
||||||
|
"show_password": "显示密码",
|
||||||
|
"hidden_Password": "隐藏密码",
|
||||||
|
"please_enter_username_and_password": "请输入用户名和密码",
|
||||||
|
"forgot_password": "忘记密码",
|
||||||
|
"enter_your_email_to_reset_password": "输入您的邮箱地址,您的密码将被重置并通过邮件发送给您。",
|
||||||
|
"back_to_login": "返回登录",
|
||||||
|
"please_enter_your_email": "请输入您的邮箱",
|
||||||
|
"this_not_email": "这不是一个有效的邮箱地址。",
|
||||||
|
"create_new_account":"创建新账户",
|
||||||
|
"already_have_an_account":"已经有账户了?"
|
||||||
},
|
},
|
||||||
"button": {
|
"button": {
|
||||||
"submit": "提交",
|
"submit": "提交",
|
||||||
"cancel": "取消"
|
"cancel": "取消",
|
||||||
|
"sign_in": "登录",
|
||||||
|
"send_me_new_password": "发送新密码"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"doc": "文档",
|
"doc": "文档",
|
||||||
|
|||||||
@@ -20,11 +20,18 @@ const router = createRouter({
|
|||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'login',
|
name: 'login',
|
||||||
// route level code-splitting
|
|
||||||
// this generates a separate chunk (About.[hash].js) for this route
|
|
||||||
// which is lazy-loaded when the route is visited.
|
|
||||||
component: () => import('../views/loginView.vue'),
|
component: () => import('../views/loginView.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/forgot_password',
|
||||||
|
name: 'forgot password',
|
||||||
|
component: () => import('../views/forgotPassword.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/register',
|
||||||
|
name: 'Register',
|
||||||
|
component: () => import('../views/registerView.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 可以在这里调用mos.value的方法
|
// 可以在这里调用mos.value的方法
|
||||||
//console.log('HomeView mounted', mos);
|
//console.log('HomeView mounted', mos);
|
||||||
|
document.title = 'Operations.';
|
||||||
});
|
});
|
||||||
|
|
||||||
function c(){
|
function c(){
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, watch, ref } from 'vue'
|
||||||
|
import MyOffcanvas from '@/components/MyOffcanvas.vue'
|
||||||
|
import { myfuncs } from '@/myfunc.ts'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
// 使用 vue-i18n 的 Composition API
|
||||||
|
const { t, locale } = useI18n()
|
||||||
|
const email = ref<HTMLInputElement | null>(null)
|
||||||
|
const mos = ref<InstanceType<typeof MyOffcanvas> | null>(null)
|
||||||
|
|
||||||
|
function resetPassword() {
|
||||||
|
// 在这里处理重置密码逻辑
|
||||||
|
const emailValue = email.value?.value
|
||||||
|
if (emailValue === undefined || emailValue.trim() === '') {
|
||||||
|
mos.value?.showAlert('info', t('message.please_enter_your_email'), 5000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!myfuncs.isValidEmail(emailValue)) {
|
||||||
|
mos.value?.showAlert('warning', t('message.this_not_email'), 5000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('sending password reset to:', emailValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
function functionupdataTitle() {
|
||||||
|
document.title = 'Operations.' + t('appname.forgot_password')
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
// 监听语言变化,更新标题
|
||||||
|
watch(locale, () => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="container container-tight py-4">
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<a href="." class="navbar-brand navbar-brand-autodark">
|
||||||
|
<img
|
||||||
|
src="/static/logo.svg"
|
||||||
|
width="110"
|
||||||
|
height="32"
|
||||||
|
alt="Tabler"
|
||||||
|
class="navbar-brand-image"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="card card-md">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-center mb-4">{{ t('message.forgot_password') }}</h2>
|
||||||
|
<p class="text-secondary mb-4">
|
||||||
|
{{ t('message.enter_your_email_to_reset_password') }}
|
||||||
|
</p>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">{{ t('message.email_address') }}</label>
|
||||||
|
<input
|
||||||
|
ref="email"
|
||||||
|
type="email"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_email_address')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-footer">
|
||||||
|
<button @click="resetPassword" class="btn btn-primary w-100">
|
||||||
|
<!-- Download SVG icon from http://tabler-icons.io/i/mail -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z"
|
||||||
|
/>
|
||||||
|
<path d="M3 7l9 6l9 -6" />
|
||||||
|
</svg>
|
||||||
|
{{ t('button.send_me_new_password') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center text-secondary mt-3">
|
||||||
|
<router-link to="/login">{{ t('message.back_to_login') }}</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<MyOffcanvas ref="mos" />
|
||||||
|
</template>
|
||||||
@@ -1,70 +1,181 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, watch, ref } from 'vue'
|
||||||
|
import MyOffcanvas from '@/components/MyOffcanvas.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
// 使用 vue-i18n 的 Composition API
|
||||||
|
const { t, locale } = useI18n()
|
||||||
|
|
||||||
|
const mos = ref<InstanceType<typeof MyOffcanvas> | null>(null)
|
||||||
|
|
||||||
|
const isShowPassword = ref(false)
|
||||||
|
const username = ref<HTMLInputElement | null>(null)
|
||||||
|
const password = ref<HTMLInputElement | null>(null)
|
||||||
|
const isRemember = ref<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
|
function togglePasswordVisibility() {
|
||||||
|
isShowPassword.value = !isShowPassword.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function login() {
|
||||||
|
// 在这里处理登录逻辑
|
||||||
|
|
||||||
|
const user = username.value?.value
|
||||||
|
const pass = password.value?.value
|
||||||
|
const remember = isRemember.value?.checked
|
||||||
|
|
||||||
|
username.value?.classList.remove('is-invalid')
|
||||||
|
password.value?.classList.remove('is-invalid')
|
||||||
|
|
||||||
|
if (!user || !pass) {
|
||||||
|
if (!user) {
|
||||||
|
username.value?.classList.add('is-invalid')
|
||||||
|
}
|
||||||
|
if (!pass) {
|
||||||
|
password.value?.classList.add('is-invalid')
|
||||||
|
}
|
||||||
|
|
||||||
|
mos.value?.showAlert('info', t('message.please_enter_username_and_password'), 5000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('登录信息:', { user, pass, remember })
|
||||||
|
}
|
||||||
|
|
||||||
|
function functionupdataTitle() {
|
||||||
|
document.title = 'Operations.' + t('appname.login')
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
// 监听语言变化,更新标题
|
||||||
|
watch(locale, () => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="page page-center">
|
<div class="page page-center">
|
||||||
<div class="container container-normal py-6">
|
<div class="container container-normal py-6">
|
||||||
<div class="row align-items-center g-4">
|
<div class="row align-items-center g-4">
|
||||||
<div class="col-lg">
|
<div class="col-lg">
|
||||||
<div class="container-tight">
|
<div class="container-tight">
|
||||||
|
|
||||||
<div class="card card-md">
|
<div class="card card-md">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="h2 text-center mb-4">Login to your account</h2>
|
<h2 class="h2 text-center mb-4">{{ t('message.login_to_your_account') }}</h2>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Email address</label>
|
<label class="form-label">{{ t('message.user_name') }}</label>
|
||||||
<input type="email" class="form-control" placeholder="your@email.com" autocomplete="off">
|
<input
|
||||||
|
ref="username"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_user_name')"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-label">
|
<label class="form-label">
|
||||||
Password
|
{{ t('message.password') }}
|
||||||
<span class="form-label-description">
|
<span class="form-label-description">
|
||||||
<a href="./forgot-password.html">I forgot password</a>
|
<router-link to="/forgot_password">{{
|
||||||
|
t('message.i_forgot_password')
|
||||||
|
}}</router-link>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="input-group input-group-flat">
|
<div class="input-group input-group-flat">
|
||||||
<input type="password" class="form-control" placeholder="Your password" autocomplete="off">
|
<input
|
||||||
|
ref="password"
|
||||||
|
:type="isShowPassword ? 'text' : 'password'"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_password')"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<a href="#" class="link-secondary" title="Show password" data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
<div
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" /><path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" /></svg>
|
class="link-secondary"
|
||||||
</a>
|
:title="
|
||||||
|
isShowPassword ? t('message.hidden_Password') : t('message.show_password')
|
||||||
|
"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
>
|
||||||
|
<!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||||
|
<svg
|
||||||
|
v-if="!isShowPassword"
|
||||||
|
@click="togglePasswordVisibility"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||||
|
<path
|
||||||
|
d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
v-if="isShowPassword"
|
||||||
|
@click="togglePasswordVisibility"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||||
|
<path
|
||||||
|
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87"
|
||||||
|
/>
|
||||||
|
<path d="M3 3l18 18" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-check">
|
<label class="form-check">
|
||||||
<input type="checkbox" class="form-check-input"/>
|
<input ref="isRemember" type="checkbox" class="form-check-input" />
|
||||||
<span class="form-check-label">Remember me on this device</span>
|
<span class="form-check-label">{{
|
||||||
|
t('message.remember_me_on_this_device')
|
||||||
|
}}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-footer">
|
<div class="form-footer">
|
||||||
<button type="submit" class="btn btn-primary w-100">Sign in</button>
|
<button @click="login" class="btn btn-primary w-100">
|
||||||
</div>
|
{{ t('button.sign_in') }}
|
||||||
|
</button>
|
||||||
</div>
|
|
||||||
<div class="hr-text">or</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col"><a href="#" class="btn w-100">
|
|
||||||
<!-- Download SVG icon from http://tabler-icons.io/i/brand-github -->
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /></svg>
|
|
||||||
Login with Github
|
|
||||||
</a></div>
|
|
||||||
<div class="col"><a href="#" class="btn w-100">
|
|
||||||
<!-- Download SVG icon from http://tabler-icons.io/i/brand-twitter -->
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-twitter" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M22 4.01c-1 .49 -1.98 .689 -3 .99c-1.121 -1.265 -2.783 -1.335 -4.38 -.737s-2.643 2.06 -2.62 3.737v1c-3.245 .083 -6.135 -1.395 -8 -4c0 0 -4.182 7.433 4 11c-1.872 1.247 -3.739 2.088 -6 2c3.308 1.803 6.913 2.423 10.034 1.517c3.58 -1.04 6.522 -3.723 7.651 -7.742a13.84 13.84 0 0 0 .497 -3.753c0 -.249 1.51 -2.772 1.818 -4.013z" /></svg>
|
|
||||||
Login with Twitter
|
|
||||||
</a></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center text-secondary mt-3">
|
<div class="text-center text-secondary mt-3">
|
||||||
Don't have account yet? <a href="./sign-up.html" tabindex="-1">Sign up</a>
|
{{ t('message.dont_have_account_yet') }}
|
||||||
|
<router-link to="/register">{{ t('message.register_now') }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg d-none d-lg-block">
|
<div class="col-lg d-none d-lg-block">
|
||||||
<img src="/static/illustrations/undraw_secure_login_pdn4.svg" height="300" class="d-block mx-auto" alt="">
|
<img
|
||||||
|
src="/static/illustrations/undraw_secure_login_pdn4.svg"
|
||||||
|
height="300"
|
||||||
|
class="d-block mx-auto"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<MyOffcanvas ref="mos" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, watch, ref } from 'vue'
|
||||||
|
import MyOffcanvas from '@/components/MyOffcanvas.vue'
|
||||||
|
import { myfuncs } from '@/myfunc.ts'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
// 使用 vue-i18n 的 Composition API
|
||||||
|
const { t, locale } = useI18n()
|
||||||
|
const mos = ref<InstanceType<typeof MyOffcanvas> | null>(null)
|
||||||
|
const isShowPassword = ref(false)
|
||||||
|
const username = ref<HTMLInputElement | null>(null)
|
||||||
|
const useremail = ref<HTMLInputElement | null>(null)
|
||||||
|
const userpassword = ref<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
|
|
||||||
|
function functionupdataTitle() {
|
||||||
|
document.title = 'Operations.' + t('appname.register')
|
||||||
|
}
|
||||||
|
function togglePasswordVisibility() {
|
||||||
|
isShowPassword.value = !isShowPassword.value
|
||||||
|
}
|
||||||
|
function createAccount() {
|
||||||
|
// 在这里处理创建新账户的逻辑
|
||||||
|
const user = username.value?.value
|
||||||
|
const email = useremail.value?.value
|
||||||
|
const pass = userpassword.value?.value
|
||||||
|
|
||||||
|
username.value?.classList.remove('is-invalid');
|
||||||
|
useremail.value?.classList.remove('is-invalid');
|
||||||
|
userpassword.value?.classList.remove('is-invalid');
|
||||||
|
|
||||||
|
if (
|
||||||
|
!user ||
|
||||||
|
!email ||
|
||||||
|
!pass
|
||||||
|
) {
|
||||||
|
|
||||||
|
if(!user){
|
||||||
|
username.value?.classList.add('is-invalid');
|
||||||
|
}
|
||||||
|
if(!email){
|
||||||
|
useremail.value?.classList.add('is-invalid');
|
||||||
|
}
|
||||||
|
if(!pass){
|
||||||
|
userpassword.value?.classList.add('is-invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
mos.value?.showAlert('info', t('message.please_enter_username_and_password'), 5000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!myfuncs.isValidEmail(email)) {
|
||||||
|
useremail.value?.classList.add('is-invalid');
|
||||||
|
mos.value?.showAlert('warning', t('message.this_not_email'), 5000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('创建新账户信息:', {
|
||||||
|
user: username.value?.value,
|
||||||
|
email: useremail.value?.value,
|
||||||
|
pass: userpassword.value?.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
// 监听语言变化,更新标题
|
||||||
|
watch(locale, () => {
|
||||||
|
functionupdataTitle()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="page page-center">
|
||||||
|
<div class="container container-tight py-4">
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<a href="." class="navbar-brand navbar-brand-autodark">
|
||||||
|
<img
|
||||||
|
src="/static/logo.svg"
|
||||||
|
width="110"
|
||||||
|
height="32"
|
||||||
|
alt="Tabler"
|
||||||
|
class="navbar-brand-image"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="card card-md">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-center mb-4">{{ t('message.create_new_account') }}</h2>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">{{ t('message.user_name') }}</label>
|
||||||
|
<input
|
||||||
|
ref="username"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_user_name')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">{{ t('message.email_address') }}</label>
|
||||||
|
<input
|
||||||
|
ref="useremail"
|
||||||
|
type="email"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_email_address')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">{{ t('message.password') }}</label>
|
||||||
|
<div class="input-group input-group-flat">
|
||||||
|
<input
|
||||||
|
ref="userpassword"
|
||||||
|
:type="isShowPassword ? 'text' : 'password'"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="t('message.your_password')"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
<span class="input-group-text">
|
||||||
|
<div class="link-secondary" title="Show password" data-bs-toggle="tooltip">
|
||||||
|
<!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||||
|
<svg
|
||||||
|
v-if="!isShowPassword"
|
||||||
|
@click="togglePasswordVisibility"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||||
|
<path
|
||||||
|
d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
v-if="isShowPassword"
|
||||||
|
@click="togglePasswordVisibility"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||||
|
<path
|
||||||
|
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87"
|
||||||
|
/>
|
||||||
|
<path d="M3 3l18 18" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="mb-3">
|
||||||
|
<label class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input"/>
|
||||||
|
<span class="form-check-label">Agree the <a href="./terms-of-service.html" tabindex="-1">terms and policy</a>.</span>
|
||||||
|
</label>
|
||||||
|
</div> -->
|
||||||
|
<div class="form-footer">
|
||||||
|
<button @click="createAccount" class="btn btn-primary w-100">
|
||||||
|
{{ t('message.create_new_account') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center text-secondary mt-3">
|
||||||
|
{{ t('message.already_have_an_account') }}
|
||||||
|
<router-link to="/login">{{ t('message.back_to_login') }}</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<MyOffcanvas ref="mos" />
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user