login.ejs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <div id="loginContainer">
  2. <div id="loginContent">
  3. <div id='loginForm'>
  4. <img id="loginImageSeal" src="assets/images/WesterosSealCircle.png"/>
  5. <span class="loginSpan" id="loginSubheader">MEMBER LOGIN</span>
  6. <div class="loginFieldContainer">
  7. <svg id="profileSVG" class="loginSVG" viewBox="40 37 65.36 61.43">
  8. <g>
  9. <path d="M86.77,58.12A13.79,13.79,0,1,0,73,71.91,13.79,13.79,0,0,0,86.77,58.12M97,103.67a3.41,3.41,0,0,0,3.39-3.84,27.57,27.57,0,0,0-54.61,0,3.41,3.41,0,0,0,3.39,3.84Z"/>
  10. </g>
  11. </svg>
  12. <span class="loginErrorSpan" id="loginEmailError">* Invalid Value</span>
  13. <input id="loginUsername" class="loginField" type="text" placeholder="EMAIL"/>
  14. </div>
  15. <div class="loginFieldContainer">
  16. <svg id="lockSVG" class="loginSVG" viewBox="40 32 60.36 70.43">
  17. <g>
  18. <path d="M86.16,54a16.38,16.38,0,1,0-32,0H44V102.7H96V54Zm-25.9-3.39a9.89,9.89,0,1,1,19.77,0A9.78,9.78,0,0,1,79.39,54H60.89A9.78,9.78,0,0,1,60.26,50.59ZM70,96.2a6.5,6.5,0,0,1-6.5-6.5,6.39,6.39,0,0,1,3.1-5.4V67h6.5V84.11a6.42,6.42,0,0,1,3.39,5.6A6.5,6.5,0,0,1,70,96.2Z"/>
  19. </g>
  20. </svg>
  21. <span class="loginErrorSpan" id="loginPasswordError">* Required</span>
  22. <input id="loginPassword" class="loginField" type="password" placeholder="PASSWORD"/>
  23. </div>
  24. <div id="loginOptions">
  25. <span class="loginSpanDim">
  26. <a href="https://help.mojang.com/customer/en/portal/articles/329524-change-or-forgot-password">forgot password?</a>
  27. </span>
  28. <label id="checkmarkContainer">
  29. <input id="loginRememberOption" type="checkbox" checked>
  30. <span id="loginRememberText" class="loginSpanDim">remember me?</span>
  31. <span class="loginCheckmark"></span>
  32. </label>
  33. </div>
  34. <button id="loginButton" disabled>
  35. <div id="loginButtonContent">
  36. LOGIN
  37. <svg id="loginSVG" viewBox="0 0 24.87 13.97">
  38. <defs>
  39. <style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
  40. </defs>
  41. <polyline class="arrowLine" points="0.71 13.26 12.56 1.41 24.16 13.02"/>
  42. </svg>
  43. <div class="circle-loader">
  44. <div class="checkmark draw"></div>
  45. </div>
  46. <!--<div class="spinningCircle" id="loginSpinner"></div>-->
  47. </div>
  48. </button>
  49. <div id="loginDisclaimer">
  50. <span class="loginSpanDim" id="loginRegisterSpan">
  51. <a href="https://minecraft.net/en-us/store/minecraft/">Need an Account?</a>
  52. </span>
  53. <p class="loginDisclaimerText">Your password is sent directly to mojang and never stored.</p>
  54. <p class="loginDisclaimerText">WesterosCraft is not affiliated with Mojang AB.</p>
  55. </div>
  56. </div>
  57. </div>
  58. <div id="loginErrorContainer">
  59. <div id="loginErrorContent">
  60. <span id="loginErrorTitle">LOGIN FAILED:<br>INVALID CREDENTIALS</span>
  61. <span id="loginErrorDesc">Either the email or password you supplied is invalid. Please ensure everything is correct and try again.</span>
  62. <button id="loginErrorAcknowledge">Try Again</button>
  63. </div>
  64. </div>
  65. <script type="application/javascript">
  66. //const validEmail = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
  67. // Validation Regexes.
  68. const validUsername = /^[a-zA-Z0-9_]{1,16}$/
  69. const basicEmail = /^\S+@\S+\.\S+$/
  70. // DOM cache.
  71. const loginEmailError = document.getElementById('loginEmailError')
  72. const loginUsername = document.getElementById('loginUsername')
  73. const loginPasswordError = document.getElementById('loginPasswordError')
  74. const loginPassword = document.getElementById('loginPassword')
  75. const checkmarkContainer = document.getElementById('checkmarkContainer')
  76. const loginRememberOption = document.getElementById('loginRememberOption')
  77. const loginButton = document.getElementById('loginButton')
  78. // Control variables.
  79. let lu = false, lp = false
  80. // Show error element.
  81. function showError(element, value){
  82. element.innerHTML = value
  83. element.style.opacity = 1
  84. }
  85. // Shake error element.
  86. function shakeError(element){
  87. if(element.style.opacity == 1){
  88. element.classList.remove('shake')
  89. void element.offsetWidth
  90. element.classList.add('shake')
  91. }
  92. }
  93. // Validate email field is neither empty nor invalid.
  94. function validateEmail(value){
  95. if(value){
  96. if(!basicEmail.test(value) && !validUsername.test(value)){
  97. showError(loginEmailError, '* Invalid Value')
  98. loginDisabled(true)
  99. lu = false
  100. } else {
  101. loginEmailError.style.opacity = 0
  102. lu = true
  103. if(lp){
  104. loginDisabled(false)
  105. }
  106. }
  107. } else {
  108. lu = false
  109. showError(loginEmailError, '* Required')
  110. loginDisabled(true)
  111. }
  112. }
  113. // Validate password field is not empty.
  114. function validatePassword(value){
  115. if(value){
  116. loginPasswordError.style.opacity = 0
  117. lp = true
  118. if(lu){
  119. loginDisabled(false)
  120. }
  121. } else {
  122. lp = false
  123. showError(loginPasswordError, '* Required')
  124. loginDisabled(true)
  125. }
  126. }
  127. // Emphasize errors with shake when focus is lost.
  128. loginUsername.addEventListener('focusout', (e) => {
  129. validateEmail(e.target.value)
  130. shakeError(loginEmailError)
  131. })
  132. loginPassword.addEventListener('focusout', (e) => {
  133. validatePassword(e.target.value)
  134. shakeError(loginPasswordError)
  135. })
  136. // Validate input for each field.
  137. loginUsername.addEventListener('input', (e) => {
  138. validateEmail(e.target.value)
  139. })
  140. loginPassword.addEventListener('input', (e) => {
  141. validatePassword(e.target.value)
  142. })
  143. // Enable or disable login button.
  144. function loginDisabled(v){
  145. if(loginButton.disabled !== v){
  146. loginButton.disabled = v
  147. }
  148. }
  149. // Enable or disable loading elements.
  150. function loginLoading(v){
  151. loginButton.setAttribute('loading', v)
  152. if(v){
  153. loginButton.innerHTML = loginButton.innerHTML.replace('LOGIN', 'LOGGING IN')
  154. } else {
  155. loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'LOGIN')
  156. }
  157. }
  158. // Disable or enable login form.
  159. function formDisabled(v){
  160. loginDisabled(v)
  161. loginUsername.disabled = true
  162. loginPassword.disabled = true
  163. checkmarkContainer.setAttribute('disabled', true)
  164. loginRememberOption.disabled = true
  165. }
  166. loginButton.addEventListener('click', () => {
  167. // Disable form.
  168. formDisabled(true)
  169. // Show loading stuff.
  170. loginLoading(true)
  171. // Temp for debugging, use procedure with real code.
  172. setTimeout(() => {
  173. loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'SUCCESS')
  174. loginButton.style.color = '#ffffff'
  175. $('.circle-loader').toggleClass('load-complete')
  176. $('.checkmark').toggle()
  177. }, 2500)
  178. })
  179. </script>
  180. <!-- Will reuse this down the line, then it will be removed from this file. -->
  181. <!--<div id="loginLoading">
  182. <div id="loginLoadingContent">
  183. <div id="loadSpinnerContainer">
  184. <img id="loadCenterImage" src="assets/images/westeroscraftlogo1.png">
  185. <img id="loadSpinnerImage" class="rotating" src="assets/images/westeroscraftlogo2.png">
  186. </div>
  187. <span id="loadDescText">LOGGING IN</span>
  188. </div>
  189. </div>-->
  190. </div>