auth.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <Form
  3. v-model:is-visible="infoAuthForm"
  4. form-message="Введите данные АСУ Проколледж"
  5. />
  6. <form
  7. class="w-full h-full flex flex-col items-center justify-between pt-8 text-foreground"
  8. @submit.prevent="auth"
  9. >
  10. <div class="flex flex-col justify-center items-center show">
  11. <h1 class="text-4xl font-bold text-center">
  12. Войдите в аккаунт
  13. </h1>
  14. <p class="opacity-50">
  15. представьтесь, пожалуйста
  16. </p>
  17. </div>
  18. <div>
  19. <ClientOnly>
  20. <lottie-player
  21. class="w-[200px] h-[200px]"
  22. autoplay
  23. loop
  24. mode="normal"
  25. src="/lottie/eyes.json"
  26. />
  27. </ClientOnly>
  28. </div>
  29. <div class="w-full flex flex-col items-center px-12">
  30. <input
  31. v-model="authData.login"
  32. :class="{
  33. 'opacity-50 cursor-not-allowed': isLoading,
  34. }"
  35. class="w-full text-xl font-light mb-3 bg-transparent border-2 border-foreground text-foreground border-opacity-50 focus:border-opacity-100 focus:invalid:border-red-500 invalid:border-red-800 outline-none px-6 py-2 rounded-lg duration-150"
  36. placeholder="Логин"
  37. type="text"
  38. autocomplete="username"
  39. :disabled="isLoading"
  40. required
  41. >
  42. <input
  43. v-model="authData.password"
  44. :class="{
  45. 'opacity-50 cursor-not-allowed': isLoading,
  46. }"
  47. class="w-full text-xl font-light mb-3 bg-transparent border-2 border-foreground text-foreground border-opacity-50 focus:border-opacity-100 focus:invalid:border-red-500 invalid:border-red-800 outline-none px-6 py-2 rounded-lg duration-150"
  48. placeholder="Пароль"
  49. type="password"
  50. autocomplete="current-password"
  51. :disabled="isLoading"
  52. required
  53. >
  54. <div
  55. class="duration-150"
  56. :class="errorMsg.show ? 'h-1' : 'h-0'"
  57. />
  58. <div
  59. :class="errorMsg.show ? 'h-fit' : 'h-0'"
  60. class="flex items-center duration-150 mb-3"
  61. >
  62. <BaseMessage
  63. class="w-full"
  64. :class="
  65. errorMsg.show
  66. ? 'opacity-100 h-fit duration-100'
  67. : 'opacity-0 h-0 duration-100'
  68. "
  69. type="danger"
  70. :text="errorMsg.msg"
  71. />
  72. </div>
  73. <div
  74. class="duration-150"
  75. :class="errorMsg.show ? 'h-1' : 'h-0'"
  76. />
  77. </div>
  78. <div>
  79. <DevOnly>
  80. <IBugReport
  81. class="h-8 w-8 opacity-40 hover:opacity-100"
  82. @click="useDebug().show"
  83. />
  84. </DevOnly>
  85. </div>
  86. <div class="w-full">
  87. <div
  88. class="w-full flex gap-2 justify-center items-center py-2 opacity-50 hover:opacity-100 duration-150 mb-0.5 cursor-pointer"
  89. @click="infoAuthForm = true"
  90. >
  91. <IAlertCircle class="h-7 w-7 rotate-180" />
  92. <p class="font-light text-lg">
  93. Откуда брать данные?
  94. </p>
  95. </div>
  96. <button
  97. class="w-full py-2 bg-primary flex gap-3 justify-center items-center group disabled:opacity-50 duration-150"
  98. :disabled="isLoading"
  99. type="submit"
  100. >
  101. <ILoader
  102. v-if="isLoading"
  103. class="w-6 h-6 text-background-100 opacity-75 group-hover:opacity-100"
  104. />
  105. <ILogin
  106. v-else
  107. class="w-6 h-6 text-background-100 opacity-75 group-hover:opacity-100"
  108. />
  109. <p
  110. class="text-2xl text-background-100 font-semibold opacity-75 group-hover:opacity-100 duration-150"
  111. v-text="isLoading ? 'Загрузка...' : 'Войти в аккаунт'"
  112. />
  113. </button>
  114. </div>
  115. </form>
  116. </template>
  117. <script setup lang="ts">
  118. import { useUser } from '~/store/useUser'
  119. import { useDebug } from '~/store/useDebug'
  120. definePageMeta({
  121. layout: 'none',
  122. middleware: 'guest-only',
  123. })
  124. const emit = defineEmits(['isClosed'])
  125. const { $config: { public: { ACCOUNT_LOGIN, ACCOUNT_PASSWD } } } = useNuxtApp()
  126. const router = useRouter()
  127. const user = useUser()
  128. const api = useApi()
  129. const infoAuthForm = ref(false)
  130. const isLoading = ref(false)
  131. const errorMsg = reactive({
  132. show: false,
  133. msg: '',
  134. })
  135. const authData = reactive({
  136. login: ACCOUNT_LOGIN || '',
  137. password: ACCOUNT_PASSWD || '',
  138. })
  139. async function auth() {
  140. isLoading.value = true
  141. errorMsg.show = false
  142. await api
  143. .post('/user/login', authData)
  144. .then((res) => {
  145. user.setAuthData(res.access_token, res.user_id)
  146. router.push('/setup/branch')
  147. emit('isClosed')
  148. })
  149. .catch((err) => {
  150. const res = err.response
  151. errorMsg.show = true
  152. if (res) errorMsg.msg = res._data.error
  153. else errorMsg.msg = 'Проблемы с подключением к серверу. Попробуйте позже'
  154. })
  155. isLoading.value = false
  156. }
  157. </script>