github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/pages/IntroPages/SignIn/index.tsx (about)

     1  import React, { useState } from 'react';
     2  import { Link, useHistory, useLocation } from 'react-router-dom';
     3  import cx from 'classnames';
     4  import Icon from '@webapp/ui/Icon';
     5  import { faGithub } from '@fortawesome/free-brands-svg-icons/faGithub';
     6  import InputField from '@webapp/ui/InputField';
     7  import StatusMessage from '@webapp/ui/StatusMessage';
     8  import { logIn } from '@webapp/services/users';
     9  import useNavigateUserIntroPages from '@webapp/hooks/navigateUserIntroPages.hook';
    10  import {
    11    isGithubEnabled,
    12    isGitlabEnabled,
    13    isGoogleEnabled,
    14    isInternalAuthEnabled,
    15    isSignupEnabled,
    16  } from '@webapp/util/features';
    17  import { PAGES } from '@webapp/pages/constants';
    18  import { GitlabIcon, GoogleIcon } from '../Icons';
    19  import Divider from '../Divider';
    20  import inputStyles from '../InputGroup.module.css';
    21  import styles from '../IntroPages.module.css';
    22  import buttonStyles from './buttons.module.css';
    23  
    24  function SignInPage() {
    25    const history = useHistory();
    26    const location = useLocation();
    27    const [form, setForm] = useState({
    28      username: '',
    29      password: '',
    30      errors: [],
    31    });
    32  
    33    const handleFormChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    34      const { name } = event.target;
    35      const { value } = event.target;
    36      setForm({ ...form, [name]: value });
    37    };
    38  
    39    async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    40      event.preventDefault();
    41      try {
    42        const { username, password } = {
    43          ...form,
    44        };
    45  
    46        const res = await logIn({ username, password });
    47        if (res.isOk) {
    48          history.replace(
    49            (location.state as ShamefulAny)?.redir || PAGES.CONTINOUS_SINGLE_VIEW
    50          );
    51          return;
    52        }
    53  
    54        throw res.error;
    55      } catch (e: ShamefulAny) {
    56        setForm({ ...form, errors: e.errors || [e.message] });
    57      }
    58    }
    59  
    60    useNavigateUserIntroPages();
    61    const hasTLS = window.location.protocol === 'https:';
    62  
    63    return (
    64      <div className={styles.loginWrapper}>
    65        <form className={styles.form} onSubmit={handleSubmit}>
    66          <div className={styles.formHeader}>
    67            <div className={styles.logo} />
    68            <h1>Welcome to Pyroscope</h1>
    69            {isInternalAuthEnabled ||
    70            isGoogleEnabled ||
    71            isGithubEnabled ||
    72            isGitlabEnabled ? (
    73              <h3>Log in to continue</h3>
    74            ) : (
    75              <>
    76                <p>
    77                  No authentication methods are enabled. To learn more, please
    78                  refer to{' '}
    79                  <a
    80                    className={styles.link}
    81                    href="https://pyroscope.io/docs/auth-overview/"
    82                    target="_blank"
    83                    rel="noreferrer"
    84                  >
    85                    documentation
    86                  </a>
    87                  .
    88                </p>
    89              </>
    90            )}
    91          </div>
    92          {isInternalAuthEnabled ? (
    93            <>
    94              <div>
    95                <StatusMessage type="error" message={form.errors?.join(', ')} />
    96                <InputField
    97                  id="username"
    98                  type="text"
    99                  name="username"
   100                  label="Username"
   101                  placeholder="Username"
   102                  className={inputStyles.inputGroup}
   103                  value={form.username}
   104                  onChange={handleFormChange}
   105                  required
   106                />
   107                <InputField
   108                  id="password"
   109                  type="password"
   110                  name="password"
   111                  label="Password"
   112                  placeholder="Password"
   113                  className={inputStyles.inputGroup}
   114                  value={form.password}
   115                  onChange={handleFormChange}
   116                  required
   117                />
   118              </div>
   119              <button
   120                className={cx(styles.button, 'sign-in-button')}
   121                data-testid="sign-in-button"
   122                type="submit"
   123              >
   124                Log in
   125              </button>
   126            </>
   127          ) : null}
   128          {isInternalAuthEnabled &&
   129          (isGoogleEnabled ||
   130            isGithubEnabled ||
   131            isGitlabEnabled ||
   132            isSignupEnabled) ? (
   133            <Divider />
   134          ) : null}
   135          <div className={cx(buttonStyles.buttonContainer)}>
   136            {isGoogleEnabled && (
   137              <a
   138                id="google-link"
   139                href={`./auth/google/login${hasTLS ? '?tls=true' : ''}`}
   140                className={cx(styles.button, buttonStyles.buttonGoogle)}
   141              >
   142                <GoogleIcon /> Sign in with Google
   143              </a>
   144            )}
   145            {isGithubEnabled && (
   146              <a
   147                id="github-link"
   148                href={`./auth/github/login${hasTLS ? '?tls=true' : ''}`}
   149                className={cx(styles.button, buttonStyles.buttonGithub)}
   150              >
   151                <Icon icon={faGithub} /> Sign in with GitHub
   152              </a>
   153            )}
   154            {isGitlabEnabled && (
   155              <a
   156                id="gitlab-link"
   157                href={`./auth/gitlab/login${hasTLS ? '?tls=true' : ''}`}
   158                className={cx(styles.button, buttonStyles.buttonGitlab)}
   159              >
   160                <GitlabIcon /> Sign in with GitLab
   161              </a>
   162            )}
   163  
   164            {isSignupEnabled && (
   165              <Link
   166                to={PAGES.SIGNUP}
   167                className={cx(styles.button, styles.buttonDark)}
   168              >
   169                Sign up
   170              </Link>
   171            )}
   172          </div>
   173        </form>
   174      </div>
   175    );
   176  }
   177  
   178  export default SignInPage;