LoginFrame.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { useEffect, useState } from "preact/hooks";
  2. import Input from "../components/form/Input.tsx";
  3. import Button from "../components/form/Button.tsx";
  4. interface LoginFrameProps {
  5. mode: "login" | "register";
  6. }
  7. export default function LoginFrame(props: LoginFrameProps) {
  8. const [email, setEmail] = useState("");
  9. const [password, setPassword] = useState("");
  10. const [confirmPassword, setConfirmPassword] = useState("");
  11. const [emailError, setEmailError] = useState(false);
  12. const [passwordError, setPasswordError] = useState(false);
  13. const [confirmPasswordError, setConfirmPasswordError] = useState(false);
  14. const checkUserLogin = async () => {
  15. const resp = await fetch("/api/user/login");
  16. const respJson = await resp.json();
  17. if (respJson.success) {
  18. // Redirect to main page if valid
  19. location.href = "/";
  20. return true;
  21. }
  22. return false;
  23. };
  24. const doUserLogin = async () => {
  25. const resp = await fetch("/api/user/login", {
  26. method: "POST",
  27. headers: { "Content-Type": "application/json" },
  28. body: JSON.stringify({
  29. email,
  30. password,
  31. }),
  32. });
  33. const respJson = await resp.json();
  34. if (respJson.success) {
  35. location.href = "/";
  36. return true;
  37. }
  38. return false;
  39. };
  40. const doUserRegister = async () => {
  41. const resp = await fetch("/api/user/register", {
  42. method: "POST",
  43. headers: { "Content-Type": "application/json" },
  44. body: JSON.stringify({
  45. email,
  46. password,
  47. }),
  48. });
  49. const respJson = await resp.json();
  50. if (respJson.success) {
  51. location.href = "/login";
  52. return true;
  53. }
  54. return false;
  55. };
  56. useEffect(() => {
  57. props.mode === "login" && checkUserLogin();
  58. }, []);
  59. const onSubmit = async () => {
  60. globalThis.$loading?.show();
  61. // Do request
  62. if (email && password && props.mode === "login") {
  63. await doUserLogin();
  64. } else if (
  65. email &&
  66. password &&
  67. confirmPassword &&
  68. props.mode === "register"
  69. ) {
  70. if (password !== confirmPassword) {
  71. setConfirmPasswordError(true);
  72. } else {
  73. await doUserRegister();
  74. }
  75. }
  76. // Set error
  77. if (!email) {
  78. setEmailError(true);
  79. }
  80. if (!password) {
  81. setPasswordError(true);
  82. }
  83. if (!confirmPassword && props.mode === "register") {
  84. setConfirmPasswordError(true);
  85. }
  86. globalThis.$loading?.hide();
  87. };
  88. return (
  89. <div className="w-[375px] mt-4 box-border p-4 text-gray-800 flex flex-col">
  90. <Input
  91. label="Email"
  92. error={emailError}
  93. type="text"
  94. placeholder="Your email"
  95. value={email}
  96. onInput={(e) => {
  97. setEmailError(false);
  98. setEmail((e.target as HTMLInputElement).value);
  99. }}
  100. />
  101. <Input
  102. label="Password"
  103. error={passwordError}
  104. type="password"
  105. placeholder="Your password"
  106. value={password}
  107. onInput={(e) => {
  108. setPasswordError(false);
  109. setPassword((e.target as HTMLInputElement).value);
  110. }}
  111. onKeyDown={(e) => {
  112. if (e.key === "Enter") {
  113. onSubmit();
  114. }
  115. }}
  116. />
  117. {props.mode === "register"
  118. ? (
  119. <Input
  120. label="Confirm Password"
  121. error={confirmPasswordError}
  122. type="password"
  123. placeholder="Confirm your password"
  124. value={confirmPassword}
  125. onInput={(e) => {
  126. setConfirmPasswordError(false);
  127. setConfirmPassword((e.target as HTMLInputElement).value);
  128. }}
  129. onKeyDown={(e) => {
  130. if (e.key === "Enter") {
  131. onSubmit();
  132. }
  133. }}
  134. />
  135. )
  136. : null}
  137. <Button variant="primary" className="h-[38px] mt-2 mb-2" type="button" onClick={onSubmit}>
  138. {props.mode === "register" ? "Register" : "Sign in"}
  139. </Button>
  140. <Button
  141. type="button"
  142. onClick={() => {
  143. location.href = props.mode === "register" ? "/login" : "/register";
  144. }}
  145. >
  146. {props.mode === "register" ? "Go Login" : "Go Register"}
  147. </Button>
  148. </div>
  149. );
  150. }