ExternalLogin: convert to tsx
This commit is contained in:
parent
5731b9b1c7
commit
7630c64ddd
|
@ -11,7 +11,7 @@ const messages = defineMessages({
|
||||||
hidePassword: { id: 'input.password.hide_password', defaultMessage: 'Hide password' },
|
hidePassword: { id: 'input.password.hide_password', defaultMessage: 'Hide password' },
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IInput extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'type'> {
|
interface IInput extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'type' | 'autoComplete' | 'autoCorrect' | 'autoCapitalize' | 'required'> {
|
||||||
autoFocus?: boolean,
|
autoFocus?: boolean,
|
||||||
defaultValue?: string,
|
defaultValue?: string,
|
||||||
className?: string,
|
className?: string,
|
||||||
|
@ -20,7 +20,7 @@ interface IInput extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'onCh
|
||||||
placeholder?: string,
|
placeholder?: string,
|
||||||
value?: string,
|
value?: string,
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void,
|
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void,
|
||||||
type: 'text' | 'email' | 'tel' | 'password'
|
type: 'text' | 'email' | 'tel' | 'password',
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input = React.forwardRef<HTMLInputElement, IInput>(
|
const Input = React.forwardRef<HTMLInputElement, IInput>(
|
||||||
|
|
|
@ -13,7 +13,7 @@ const Logout: React.FC = () => {
|
||||||
const [done, setDone] = useState(false);
|
const [done, setDone] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(dispatch(logOut(intl)) as any)
|
dispatch(logOut(intl) as any)
|
||||||
.then(() => setDone(true))
|
.then(() => setDone(true))
|
||||||
.catch(console.warn);
|
.catch(console.warn);
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import { externalLogin, loginWithCode } from 'soapbox/actions/external_auth';
|
||||||
|
import { Button, Form, FormActions, FormGroup, Input, Spinner } from 'soapbox/components/ui';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
instanceLabel: { id: 'login.fields.instance_label', defaultMessage: 'Instance' },
|
||||||
|
instancePlaceholder: { id: 'login.fields.instance_placeholder', defaultMessage: 'example.com' },
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Form for logging into a remote instance */
|
||||||
|
const ExternalLoginForm: React.FC = () => {
|
||||||
|
const code = new URLSearchParams(window.location.search).get('code');
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [host, setHost] = useState('');
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleHostChange: React.ChangeEventHandler<HTMLInputElement> = ({ currentTarget }) => {
|
||||||
|
setHost(currentTarget.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
dispatch(externalLogin(host) as any)
|
||||||
|
.then(() => setLoading(false))
|
||||||
|
.catch(() => setLoading(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (code) {
|
||||||
|
dispatch(loginWithCode(code));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
return <Spinner />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form onSubmit={handleSubmit}>
|
||||||
|
<FormGroup labelText={intl.formatMessage(messages.instanceLabel)}>
|
||||||
|
<Input
|
||||||
|
aria-label={intl.formatMessage(messages.instancePlaceholder)}
|
||||||
|
placeholder={intl.formatMessage(messages.instancePlaceholder)}
|
||||||
|
type='text'
|
||||||
|
name='host'
|
||||||
|
onChange={handleHostChange}
|
||||||
|
autoComplete='off'
|
||||||
|
autoCorrect='off'
|
||||||
|
autoCapitalize='off'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormActions>
|
||||||
|
<Button theme='primary' type='submit' disabled={isLoading}>
|
||||||
|
<FormattedMessage id='login.log_in' defaultMessage='Log in' />
|
||||||
|
</Button>
|
||||||
|
</FormActions>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExternalLoginForm;
|
|
@ -1,82 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { externalLogin, loginWithCode } from 'soapbox/actions/external_auth';
|
|
||||||
import { Spinner } from 'soapbox/components/ui';
|
|
||||||
import { SimpleForm, FieldsGroup, TextInput } from 'soapbox/features/forms';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
instanceLabel: { id: 'login.fields.instance_label', defaultMessage: 'Instance' },
|
|
||||||
instancePlaceholder: { id: 'login.fields.instance_placeholder', defaultMessage: 'example.com' },
|
|
||||||
});
|
|
||||||
|
|
||||||
export default @connect()
|
|
||||||
@injectIntl
|
|
||||||
class ExternalLoginForm extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
state = {
|
|
||||||
host: '',
|
|
||||||
isLoading: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleHostChange = ({ target }) => {
|
|
||||||
this.setState({ host: target.value });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit = e => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
const { host } = this.state;
|
|
||||||
|
|
||||||
this.setState({ isLoading: true });
|
|
||||||
|
|
||||||
dispatch(externalLogin(host))
|
|
||||||
.then(() => this.setState({ isLoading: false }))
|
|
||||||
.catch(() => this.setState({ isLoading: false }));
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const code = new URLSearchParams(window.location.search).get('code');
|
|
||||||
|
|
||||||
if (code) {
|
|
||||||
this.setState({ code });
|
|
||||||
this.props.dispatch(loginWithCode(code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { intl } = this.props;
|
|
||||||
const { isLoading, code } = this.state;
|
|
||||||
|
|
||||||
if (code) {
|
|
||||||
return <Spinner />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SimpleForm onSubmit={this.handleSubmit} className='external-login'>
|
|
||||||
<fieldset disabled={isLoading}>
|
|
||||||
<FieldsGroup>
|
|
||||||
<TextInput
|
|
||||||
label={intl.formatMessage(messages.instanceLabel)}
|
|
||||||
placeholder={intl.formatMessage(messages.instancePlaceholder)}
|
|
||||||
name='host'
|
|
||||||
value={this.state.host}
|
|
||||||
onChange={this.handleHostChange}
|
|
||||||
autoComplete='off'
|
|
||||||
autoCorrect='off'
|
|
||||||
autoCapitalize='off'
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</FieldsGroup>
|
|
||||||
</fieldset>
|
|
||||||
<div className='actions'>
|
|
||||||
<button name='button' type='submit' className='btn button button-primary'>
|
|
||||||
<FormattedMessage id='login.log_in' defaultMessage='Log in' />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</SimpleForm>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
import ExternalLoginForm from './components/external_login_form';
|
|
||||||
|
|
||||||
export default class ExternalLoginPage extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <ExternalLoginForm />;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ExternalLoginForm from './components/external-login-form';
|
||||||
|
|
||||||
|
/** Page for logging into a remote instance */
|
||||||
|
const ExternalLoginPage: React.FC = () => {
|
||||||
|
return <ExternalLoginForm />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExternalLoginPage;
|
Loading…
Reference in New Issue