Login.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <script setup lang="ts">
  2. import {useUserStore} from '@/pinia'
  3. const thisYear = new Date().getFullYear()
  4. import {LockOutlined, UserOutlined} from '@ant-design/icons-vue'
  5. import {reactive, ref} from 'vue'
  6. import {useRoute, useRouter} from 'vue-router'
  7. import gettext from '@/gettext'
  8. import {Form, message} from 'ant-design-vue'
  9. import auth from '@/api/auth'
  10. import install from '@/api/install'
  11. const route = useRoute()
  12. const router = useRouter()
  13. install.get_lock().then(async (r: { lock: boolean }) => {
  14. if (!r.lock) {
  15. await router.push('/install')
  16. }
  17. })
  18. const {$gettext} = gettext
  19. const loading = ref(false)
  20. const modelRef = reactive({
  21. username: '',
  22. password: ''
  23. })
  24. const rulesRef = reactive({
  25. username: [
  26. {
  27. required: true,
  28. message: () => $gettext('Please input your username!'),
  29. }
  30. ],
  31. password: [
  32. {
  33. required: true,
  34. message: () => $gettext('Please input your password!'),
  35. }
  36. ]
  37. })
  38. const {validate, validateInfos} = Form.useForm(modelRef, rulesRef)
  39. const onSubmit = () => {
  40. validate().then(() => {
  41. // modelRef
  42. auth.login(modelRef.username, modelRef.password).then(async () => {
  43. message.success($gettext('Login successful'), 1)
  44. const next = (route.query?.next || '').toString() || '/'
  45. await router.push(next)
  46. }).catch(e => {
  47. message.error($gettext(e.message ?? 'Server error'))
  48. })
  49. })
  50. }
  51. const user = useUserStore()
  52. if (user.is_login) {
  53. const next = (route.query?.next || '').toString() || '/dashboard'
  54. router.push(next)
  55. }
  56. </script>
  57. <template>
  58. <div class="container">
  59. <div class="login-form">
  60. <div class="project-title">
  61. <h1>Nginx UI</h1>
  62. </div>
  63. <a-form id="components-form-demo-normal-login">
  64. <a-form-item v-bind="validateInfos.username">
  65. <a-input
  66. v-model:value="modelRef.username"
  67. :placeholder="$gettext('Username')"
  68. >
  69. <template #prefix>
  70. <UserOutlined style="color: rgba(0, 0, 0, 0.25)"/>
  71. </template>
  72. </a-input>
  73. </a-form-item>
  74. <a-form-item v-bind="validateInfos.password">
  75. <a-input-password
  76. v-model:value="modelRef.password"
  77. :placeholder="$gettext('Password')"
  78. >
  79. <template #prefix>
  80. <LockOutlined style="color: rgba(0, 0, 0, 0.25)"/>
  81. </template>
  82. </a-input-password>
  83. </a-form-item>
  84. <a-form-item>
  85. <a-button @click="onSubmit" type="primary" :block="true" html-type="submit" :loading="loading">
  86. <translate>Login</translate>
  87. </a-button>
  88. </a-form-item>
  89. </a-form>
  90. <div class="footer">
  91. <p>Copyright © 2020 - {{ thisYear }} Nginx UI</p>
  92. Language
  93. <set-language class="set_lang" style="display: inline"/>
  94. </div>
  95. </div>
  96. </div>
  97. </template>
  98. <style lang="less">
  99. .container {
  100. display: flex;
  101. align-items: center;
  102. justify-content: center;
  103. height: 100%;
  104. .login-form {
  105. max-width: 400px;
  106. width: 80%;
  107. .project-title {
  108. margin: 50px;
  109. h1 {
  110. font-size: 50px;
  111. font-weight: 100;
  112. text-align: center;
  113. }
  114. }
  115. .anticon {
  116. color: #a8a5a5 !important;
  117. }
  118. .login-form-button {
  119. }
  120. .footer {
  121. padding: 30px;
  122. text-align: center;
  123. }
  124. }
  125. }
  126. </style>