Login.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <!-- Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <template>
  3. <!-- TODO: Only a dummy implementation for the login... -->
  4. <div class="flex flex-col justify-center items-center h-full min-h-screen">
  5. <div class="w-full max-w-md">
  6. <div class="flex flex-col grow justify-center">
  7. <div class="grow p-8 my-5">
  8. <div class="flex justify-center p-2">
  9. <CommonLogo />
  10. </div>
  11. <div class="flex justify-center p-2 mb-6 text-2xl font-extrabold">
  12. {{ 'Zammad' }}
  13. </div>
  14. <form class="text-left">
  15. <fieldset class="relative floating-input">
  16. <input
  17. id="username"
  18. v-model="loginFormValues.login"
  19. type="text"
  20. v-bind:placeholder="i18n.t('Username / Email')"
  21. class="block mt-1 w-full h-14 text-sm bg-gray-300 rounded border-none focus:outline-none"
  22. />
  23. <label
  24. for="username"
  25. class="absolute top-0 left-0 py-5 px-3 h-full text-base transition-all duration-100 ease-in-out origin-left pointer-events-none"
  26. >
  27. {{ i18n.t('Username / Email') }}
  28. </label>
  29. </fieldset>
  30. <fieldset class="relative floating-input">
  31. <input
  32. id="password"
  33. v-model="loginFormValues.password"
  34. type="password"
  35. v-bind:placeholder="i18n.t('Password')"
  36. class="block mt-1 w-full h-14 text-sm bg-gray-300 rounded border-none focus:outline-none"
  37. />
  38. <label
  39. for="password"
  40. class="absolute top-0 left-0 py-5 px-3 h-full text-base transition-all duration-100 ease-in-out origin-left pointer-events-none"
  41. >
  42. {{ i18n.t('Password') }}
  43. </label>
  44. </fieldset>
  45. <!-- <label
  46. class="mt-4 cursor-pointer inline-flex items-center select-none"
  47. >
  48. <input type="checkbox" />
  49. <span class="ml-2">{{ i18n.t('Remember me') }}</span>
  50. </label> -->
  51. </form>
  52. <div class="flex grow justify-between items-baseline mt-1">
  53. <a class="text-yellow underline cursor-pointer select-none">
  54. {{ i18n.t('Register') }}
  55. </a>
  56. <a class="text-yellow cursor-pointer select-none">
  57. {{ i18n.t('Forgot password?') }}
  58. </a>
  59. </div>
  60. <div class="flex grow justify-center items-center mx-8 mt-8">
  61. <button
  62. class="py-2 px-4 w-full h-14 text-xl font-semibold text-black bg-yellow rounded select-none"
  63. v-on:click="login"
  64. >
  65. {{ i18n.t('Sign in') }}
  66. </button>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </template>
  73. <script setup lang="ts">
  74. import useNotifications from '@common/composables/useNotifications'
  75. import useAuthenticationStore from '@common/stores/authenticated'
  76. import { useRouter } from 'vue-router'
  77. import { NotificationTypes } from '@common/types/notification'
  78. import CommonLogo from '@common/components/common/CommonLogo.vue'
  79. interface Props {
  80. invalidatedSession?: string
  81. }
  82. const props = defineProps<Props>()
  83. // Output a hint, when the session is longer valid, maybe because because the session
  84. // was deleted on the server.
  85. if (props.invalidatedSession === '1') {
  86. const { notify } = useNotifications()
  87. notify({
  88. message: __('The session is no longer valid. Please log in again.'),
  89. type: NotificationTypes.WARN,
  90. })
  91. }
  92. const authentication = useAuthenticationStore()
  93. const loginFormValues = {
  94. login: '',
  95. password: '',
  96. }
  97. const router = useRouter()
  98. const login = (): void => {
  99. authentication
  100. .login(loginFormValues.login, loginFormValues.password)
  101. .then(() => {
  102. router.replace('/')
  103. })
  104. .catch((errors) => {
  105. const { notify } = useNotifications()
  106. notify({
  107. message: errors[0],
  108. type: NotificationTypes.WARN,
  109. })
  110. })
  111. }
  112. </script>
  113. <style lang="postcss">
  114. .floating-input > input::placeholder {
  115. color: transparent;
  116. }
  117. .floating-input > input:focus,
  118. .floating-input > input:not(:placeholder-shown) {
  119. @apply pt-8;
  120. }
  121. .floating-input > input:focus ~ label,
  122. .floating-input > input:not(:placeholder-shown) ~ label {
  123. @apply opacity-75 scale-75 -translate-y-3 translate-x-1;
  124. }
  125. </style>