LoginFrame.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /** @jsx h */
  2. /** @jsxFrag Fragment */
  3. import { Fragment, h } from "preact";
  4. import { useState, useEffect } from "preact/hooks";
  5. import { showLoading, hideLoading } from "utils/ui.ts";
  6. interface LoginFrameProps {
  7. mode: "login" | "register";
  8. }
  9. export default function LoginFrame(props: LoginFrameProps) {
  10. const [email, setEmail] = useState("");
  11. const [password, setPassword] = useState("");
  12. const [confirmPassword, setConfirmPassword] = useState("");
  13. const [emailError, setEmailError] = useState(false);
  14. const [passwordError, setPasswordError] = useState(false);
  15. const [confirmPasswordError, setConfirmPasswordError] = useState(false);
  16. const checkUserLogin = async () => {
  17. const resp = await fetch("/api/user/login");
  18. const respJson = await resp.json();
  19. if (respJson.success) {
  20. // Redirect to main page if valid
  21. location.href = "/";
  22. return true;
  23. }
  24. return false;
  25. };
  26. const doUserLogin = async () => {
  27. const resp = await fetch("/api/user/login", {
  28. method: "POST",
  29. headers: { "Content-Type": "application/json" },
  30. body: JSON.stringify({
  31. email,
  32. password,
  33. }),
  34. });
  35. const respJson = await resp.json();
  36. if (respJson.success) {
  37. location.href = "/";
  38. return true;
  39. }
  40. return false;
  41. };
  42. const doUserRegister = async () => {
  43. const resp = await fetch("/api/user/register", {
  44. method: "POST",
  45. headers: { "Content-Type": "application/json" },
  46. body: JSON.stringify({
  47. email,
  48. password,
  49. }),
  50. });
  51. const respJson = await resp.json();
  52. if (respJson.success) {
  53. location.href = "/login";
  54. return true;
  55. }
  56. return false;
  57. };
  58. useEffect(() => {
  59. props.mode === "login" && checkUserLogin();
  60. }, []);
  61. const onSubmit = async () => {
  62. showLoading();
  63. // Do request
  64. if (email && password && props.mode === "login") {
  65. await doUserLogin();
  66. } else if (
  67. email &&
  68. password &&
  69. confirmPassword &&
  70. props.mode === "register"
  71. ) {
  72. if (password !== confirmPassword) {
  73. setConfirmPasswordError(true);
  74. } else {
  75. await doUserRegister();
  76. }
  77. }
  78. // Set error
  79. if (!email) {
  80. setEmailError(true);
  81. }
  82. if (!password) {
  83. setPasswordError(true);
  84. }
  85. if (!confirmPassword && props.mode === "register") {
  86. setConfirmPasswordError(true);
  87. }
  88. hideLoading();
  89. };
  90. return (
  91. <div className="pd-login-frame">
  92. <span className="pd-login-input-label">Email</span>
  93. <input
  94. className={`pd-login-input${emailError ? " error" : ""}`}
  95. type="text"
  96. placeholder="Your email"
  97. value={email}
  98. onInput={(e) => {
  99. setEmailError(false);
  100. setEmail((e.target as HTMLInputElement).value);
  101. }}
  102. />
  103. <span className="pd-login-input-label">Password</span>
  104. <input
  105. className={`pd-login-input${passwordError ? " error" : ""}`}
  106. type="password"
  107. placeholder="Your password"
  108. value={password}
  109. onInput={(e) => {
  110. setPasswordError(false);
  111. setPassword((e.target as HTMLInputElement).value);
  112. }}
  113. />
  114. {props.mode === "register" ? (
  115. <>
  116. <span className="pd-login-input-label">Confirm Password</span>
  117. <input
  118. className={`pd-login-input${confirmPasswordError ? " error" : ""}`}
  119. type="password"
  120. placeholder="Confirm your password"
  121. value={confirmPassword}
  122. onInput={(e) => {
  123. setConfirmPasswordError(false);
  124. setConfirmPassword((e.target as HTMLInputElement).value);
  125. }}
  126. />
  127. </>
  128. ) : null}
  129. <button className="pd-login-btn" type="button" onClick={onSubmit}>
  130. {props.mode === "register" ? "Register" : "Sign in"}
  131. </button>
  132. </div>
  133. );
  134. }