auth.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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-white"
  8. @submit.prevent="auth"
  9. >
  10. <div class="flex flex-col justify-center items-center">
  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. <button
  81. type="button"
  82. class="relative"
  83. @click="useDebug().show"
  84. >
  85. <Icon
  86. name="material-symbols:bug-report-outline-rounded"
  87. class="absolute -top-2 -left-3 h-8 w-8 opacity-40 hover:opacity-100"
  88. />
  89. </button>
  90. </DevOnly>
  91. </div>
  92. <div class="w-full">
  93. <div
  94. class="w-full flex gap-2 justify-center items-center py-2 opacity-50 hover:opacity-100 duration-150 mb-0.5 cursor-pointer"
  95. @click="infoAuthForm = true"
  96. >
  97. <img
  98. src="@/assets/icons/alert-circle 1.svg"
  99. alt="alert circle"
  100. class="h-7 w-7 text-background-100 rotate-180"
  101. >
  102. <p class="font-light text-lg">
  103. Откуда брать данные?
  104. </p>
  105. </div>
  106. <button
  107. class="w-full py-2 bg-primary flex gap-3 justify-center items-center group disabled:opacity-50 duration-150"
  108. :disabled="isLoading"
  109. type="submit"
  110. >
  111. <Icon
  112. v-if="isLoading"
  113. name="svg-spinners:ring-resize"
  114. class="w-6 h-6 text-background-100 opacity-75 group-hover:opacity-100"
  115. />
  116. <img
  117. v-else
  118. src="@/assets/icons/login 1.svg"
  119. alt="logout"
  120. class="w-6 h-6 opacity-75 group-hover:opacity-100"
  121. >
  122. <p
  123. class="text-2xl text-background-100 font-semibold opacity-75 group-hover:opacity-100 duration-150"
  124. v-text="isLoading ? 'Загрузка...' : 'Войти в аккаунт'"
  125. />
  126. </button>
  127. </div>
  128. </form>
  129. </template>
  130. <script setup lang="ts">
  131. import { useUser } from '~/store/useUser'
  132. import { useDebug } from '~/store/useDebug'
  133. definePageMeta({
  134. layout: 'none',
  135. })
  136. const emit = defineEmits(['isClosed'])
  137. const { $config: { public: { ACCOUNT_LOGIN, ACCOUNT_PASSWD } } } = useNuxtApp()
  138. const router = useRouter()
  139. const user = useUser()
  140. const api = useApi()
  141. const infoAuthForm = ref(false)
  142. const isLoading = ref(false)
  143. const errorMsg = reactive({
  144. show: false,
  145. msg: '',
  146. })
  147. const authData = reactive({
  148. login: ACCOUNT_LOGIN || '',
  149. password: ACCOUNT_PASSWD || '',
  150. })
  151. async function auth() {
  152. isLoading.value = true
  153. errorMsg.show = false
  154. await api
  155. .post('/user/login', authData)
  156. .then((res) => {
  157. user.setUserData(res)
  158. router.push('/profile')
  159. emit('isClosed')
  160. })
  161. .catch((err) => {
  162. const res = err.response
  163. errorMsg.show = true
  164. if (res) errorMsg.msg = res._data.error
  165. else errorMsg.msg = 'Проблемы с подключением к серверу. Попробуйте позже'
  166. })
  167. isLoading.value = false
  168. }
  169. </script>