LoginFrame.tsx 4.0 KB

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