accountIdentities.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import React from 'react';
  2. import {RouteComponentProps} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import {disconnectIdentity} from 'app/actionCreators/account';
  5. import Button from 'app/components/button';
  6. import {Panel, PanelBody, PanelHeader, PanelItem} from 'app/components/panels';
  7. import {t} from 'app/locale';
  8. import {Identity} from 'app/types';
  9. import AsyncView from 'app/views/asyncView';
  10. import EmptyMessage from 'app/views/settings/components/emptyMessage';
  11. import SettingsPageHeader from 'app/views/settings/components/settingsPageHeader';
  12. const ENDPOINT = '/users/me/social-identities/';
  13. type Props = RouteComponentProps<{}, {}>;
  14. type State = {
  15. identities: Identity[] | null;
  16. } & AsyncView['state'];
  17. class AccountIdentities extends AsyncView<Props, State> {
  18. getDefaultState() {
  19. return {
  20. ...super.getDefaultState(),
  21. identities: [],
  22. };
  23. }
  24. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  25. return [['identities', ENDPOINT]];
  26. }
  27. getTitle() {
  28. return t('Identities');
  29. }
  30. handleDisconnect = (identity: Identity) => {
  31. const {identities} = this.state;
  32. this.setState(
  33. state => {
  34. const newIdentities = state.identities?.filter(({id}) => id !== identity.id);
  35. return {
  36. identities: newIdentities ?? [],
  37. };
  38. },
  39. () =>
  40. disconnectIdentity(identity).catch(() => {
  41. this.setState({
  42. identities,
  43. });
  44. })
  45. );
  46. };
  47. renderBody() {
  48. return (
  49. <div>
  50. <SettingsPageHeader title="Identities" />
  51. <Panel>
  52. <PanelHeader>{t('Identities')}</PanelHeader>
  53. <PanelBody>
  54. {!this.state.identities?.length ? (
  55. <EmptyMessage>
  56. {t('There are no identities associated with this account')}
  57. </EmptyMessage>
  58. ) : (
  59. this.state.identities.map(identity => (
  60. <IdentityPanelItem key={identity.id}>
  61. <div>{identity.providerLabel}</div>
  62. <Button
  63. size="small"
  64. onClick={this.handleDisconnect.bind(this, identity)}
  65. >
  66. {t('Disconnect')}
  67. </Button>
  68. </IdentityPanelItem>
  69. ))
  70. )}
  71. </PanelBody>
  72. </Panel>
  73. </div>
  74. );
  75. }
  76. }
  77. const IdentityPanelItem = styled(PanelItem)`
  78. align-items: center;
  79. justify-content: space-between;
  80. `;
  81. export default AccountIdentities;