import {useState} from 'react'; import {browserHistory} from 'react-router'; import styled from '@emotion/styled'; import {Alert} from 'sentry/components/alert'; import {Button} from 'sentry/components/button'; import SecretField from 'sentry/components/forms/fields/secretField'; import TextField from 'sentry/components/forms/fields/textField'; import Form from 'sentry/components/forms/form'; import Link from 'sentry/components/links/link'; import {IconGithub, IconGoogle, IconVsts} from 'sentry/icons'; import {t} from 'sentry/locale'; import ConfigStore from 'sentry/stores/configStore'; import {space} from 'sentry/styles/space'; import {AuthConfig} from 'sentry/types'; type LoginProvidersProps = Partial< Pick >; // TODO(epurkhiser): The abstraction here would be much nicer if we just // exposed a configuration object telling us what auth providers there are. function LoginProviders({ vstsLoginLink, githubLoginLink, googleLoginLink, }: LoginProvidersProps) { return ( {t('External Account Login')} {googleLoginLink && ( )} {githubLoginLink && ( )} {vstsLoginLink && ( )} ); } type Props = { authConfig: AuthConfig; }; function LoginForm({authConfig}: Props) { const [error, setError] = useState(''); const {githubLoginLink, vstsLoginLink} = authConfig; const hasLoginProvider = !!(githubLoginLink || vstsLoginLink); return (
{ // TODO(epurkhiser): There is likely more that needs to happen to update // the application state after user login. ConfigStore.set('user', response.user); // TODO(epurkhiser): Reconfigure sentry SDK identity browserHistory.push({pathname: response.nextUri}); }} onSubmitError={response => { // TODO(epurkhiser): Need much better error handling here setError(response.responseJSON.errors.__all__); }} footerStyle={{ borderTop: 'none', alignItems: 'center', marginBottom: 0, padding: 0, }} extraButton={ {t('Lost your password?')} } > {error && {error}} {hasLoginProvider && }
); } const FormWrapper = styled('div')<{hasLoginProvider: boolean}>` display: grid; gap: 60px; grid-template-columns: ${p => (p.hasLoginProvider ? '1fr 0.8fr' : '1fr')}; `; const ProviderHeading = styled('div')` margin: 0; font-size: 15px; font-weight: bold; line-height: 24px; `; const ProviderWrapper = styled('div')` position: relative; display: grid; grid-auto-rows: max-content; gap: ${space(1.5)}; &:before { position: absolute; display: block; content: ''; top: 0; bottom: 0; left: -30px; border-left: 1px solid ${p => p.theme.border}; } `; const LostPasswordLink = styled(Link)` color: ${p => p.theme.gray300}; font-size: ${p => p.theme.fontSizeMedium}; &:hover { color: ${p => p.theme.textColor}; } `; export default LoginForm;