AuthForm.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { useAtomValue } from 'jotai';
  2. import { FormEvent, useEffect, useRef, useState } from 'react';
  3. import { authAtom, useLogin, useLogout } from '../../../../state/auth';
  4. import { decodeToken, parseTokenExpire } from '../../../../utility';
  5. import { Button, InputGroup } from '../../../UI';
  6. import classes from '../AppDetails.module.css';
  7. export const AuthForm = (): JSX.Element => {
  8. const { isAuthenticated, token } = useAtomValue(authAtom);
  9. const login = useLogin();
  10. const logout = useLogout();
  11. const [tokenExpires, setTokenExpires] = useState('');
  12. const [formData, setFormData] = useState({
  13. password: '',
  14. duration: '14d',
  15. });
  16. const passwordInputRef = useRef<HTMLInputElement>(null);
  17. useEffect(() => {
  18. passwordInputRef.current?.focus();
  19. }, []);
  20. useEffect(() => {
  21. if (token) {
  22. const decoded = decodeToken(token);
  23. const expiresIn = parseTokenExpire(decoded.exp);
  24. setTokenExpires(expiresIn);
  25. }
  26. }, [token]);
  27. const formHandler = (e: FormEvent) => {
  28. e.preventDefault();
  29. login(formData);
  30. setFormData({
  31. password: '',
  32. duration: '14d',
  33. });
  34. };
  35. return (
  36. <>
  37. {!isAuthenticated ? (
  38. <form onSubmit={formHandler}>
  39. <InputGroup>
  40. <label htmlFor="password">Password</label>
  41. <input
  42. type="password"
  43. id="password"
  44. name="password"
  45. placeholder="••••••"
  46. autoComplete="current-password"
  47. ref={passwordInputRef}
  48. value={formData.password}
  49. onChange={(e) =>
  50. setFormData({ ...formData, password: e.target.value })
  51. }
  52. />
  53. <span>
  54. See
  55. <a
  56. href="https://github.com/pawelmalak/flame/wiki/Authentication"
  57. target="blank"
  58. >
  59. {` project wiki `}
  60. </a>
  61. to read more about authentication
  62. </span>
  63. </InputGroup>
  64. <InputGroup>
  65. <label htmlFor="duration">Session duration</label>
  66. <select
  67. id="duration"
  68. name="duration"
  69. value={formData.duration}
  70. onChange={(e) =>
  71. setFormData({ ...formData, duration: e.target.value })
  72. }
  73. >
  74. <option value="1h">1 hour</option>
  75. <option value="1d">1 day</option>
  76. <option value="14d">2 weeks</option>
  77. <option value="30d">1 month</option>
  78. <option value="1y">1 year</option>
  79. </select>
  80. </InputGroup>
  81. <Button>Login</Button>
  82. </form>
  83. ) : (
  84. <div>
  85. <p className={classes.text}>
  86. You are logged in. Your session will expire{' '}
  87. <span>{tokenExpires}</span>
  88. </p>
  89. <Button click={logout}>Logout</Button>
  90. </div>
  91. )}
  92. </>
  93. );
  94. };