Skip to content

Commit

Permalink
feat(twitter-dm): add twitter direct message feature
Browse files Browse the repository at this point in the history
close #1127
  • Loading branch information
khangaridb authored and batamar committed Oct 21, 2019
1 parent 7d51321 commit 9c3f01c
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/modules/common/components/IntegrationIcon.tsx
Expand Up @@ -19,7 +19,7 @@ const RoundedBackground = styledTS<{ type: string; size?: number }>(
background: ${props =>
(props.type === 'form' && darken(colors.colorCoreYellow, 32)) ||
(props.type === 'messenger' && colors.colorPrimary) ||
(props.type === 'twitter' && colors.socialTwitter) ||
(props.type === 'twitter-dm' && colors.socialTwitter) ||
(props.type === 'facebook' && colors.socialFacebook) ||
(props.type === 'gmail' && colors.socialGmail) ||
(props.type.includes('nylas') && colors.socialGmail) ||
Expand Down Expand Up @@ -50,8 +50,8 @@ class IntegrationIcon extends React.PureComponent<Props> {
case 'facebook-messenger':
icon = 'messenger';
break;
case 'twitter':
icon = 'twitter-1';
case 'twitter-dm':
icon = 'twitter';
break;
case 'messenger':
icon = 'comment';
Expand Down
4 changes: 4 additions & 0 deletions src/modules/common/components/Label.tsx
Expand Up @@ -83,6 +83,10 @@ const LabelStyled = styledTS<{
&.label-googleMeet {
background: ${colors.socialGoogleMeet};
}
&.label-twitter {
background: ${colors.socialTwitter}
}
`;

type Props = {
Expand Down
Expand Up @@ -31,7 +31,11 @@ import { AddMessageMutationVariables, IConversation } from '../../../types';

const Editor = asyncComponent(
() => import(/* webpackChunkName: "Editor-in-Inbox" */ './Editor'),
{ height: '137px', width: '100%', color: '#fff' }
{
height: '137px',
width: '100%',
color: '#fff'
}
);

type Props = {
Expand Down Expand Up @@ -191,7 +195,6 @@ class RespondBox extends React.Component<Props, State> {

uploadHandler({
files,

beforeUpload: () => {
return;
},
Expand Down
Expand Up @@ -50,6 +50,10 @@ class IntegrationList extends React.Component<Props> {
return 'nylas gmail';
}

if (kind === KIND_CHOICES.TWITTER_DM) {
return 'twitter';
}

if (kind === KIND_CHOICES.NYLAS_IMAP) {
return 'nylas imap';
}
Expand Down
Expand Up @@ -112,6 +112,8 @@ class ManageIntegrations extends React.Component<Props, State> {
type = 'gmail';
} else if (kind === KIND_CHOICES.NYLAS_GMAIL) {
type = 'nylas-gmail';
} else if (kind === KIND_CHOICES.TWITTER_DM) {
type = 'twitter';
} else if (kind === KIND_CHOICES.NYLAS_IMAP) {
type = 'nylas-imap';
}
Expand All @@ -133,6 +135,8 @@ class ManageIntegrations extends React.Component<Props, State> {
icon = 'mail-alt';
} else if (kind === KIND_CHOICES.CALLPRO) {
icon = 'phone-call';
} else if (kind === KIND_CHOICES.TWITTER_DM) {
icon = 'twitter';
} else if (kind === KIND_CHOICES.CHATFUEL) {
icon = 'comment-dots';
} else if (kind === KIND_CHOICES.NYLAS_GMAIL) {
Expand Down
11 changes: 11 additions & 0 deletions src/modules/settings/integrations/components/store/Entry.tsx
Expand Up @@ -12,6 +12,7 @@ import Settings from '../../containers/engages/Settings';
import Facebook from '../../containers/facebook/Form';
import KnowledgeBase from '../../containers/knowledgebase/Form';
import Lead from '../../containers/lead/Form';
import Twitter from '../../containers/twitter/Twitter';
import { Box, IntegrationItem, Type } from './styles';

type Props = {
Expand Down Expand Up @@ -189,6 +190,16 @@ class Entry extends React.Component<Props> {
);
}

if (createModal === 'twitter') {
const trigger = <a href="#add">+ {__('Add')}</a>;

const content = props => <Twitter {...props} />;

return (
<ModalTrigger title="Add twitter" trigger={trigger} content={content} />
);
}

return <Link to={createUrl}>+ {__('Add')}</Link>;
}

Expand Down
80 changes: 80 additions & 0 deletions src/modules/settings/integrations/components/twitter/Twitter.tsx
@@ -0,0 +1,80 @@
import FormControl from 'modules/common/components/form/Control';
import Form from 'modules/common/components/form/Form';
import FormGroup from 'modules/common/components/form/Group';
import ControlLabel from 'modules/common/components/form/Label';
import Spinner from 'modules/common/components/Spinner';
import { ModalFooter } from 'modules/common/styles/main';
import { IButtonMutateProps, IFormProps } from 'modules/common/types';
import * as React from 'react';
import Accounts from '../../containers/Accounts';
import SelectBrand from '../../containers/SelectBrand';

type Props = {
renderButton: (props: IButtonMutateProps) => JSX.Element;
onAccountSelect: (accountId?: string) => void;
onRemoveAccount: (accountId: string) => void;
closeModal: () => void;
accountId: string;
twitterAccountId: string;
};

class Twitter extends React.Component<Props, { loading: boolean }> {
constructor(props: Props) {
super(props);

this.state = {
loading: false
};
}

generateDoc = (values: { name: string; brandId: string }) => {
const { accountId, twitterAccountId } = this.props;

return {
...values,
kind: 'twitter-dm',
accountId,
data: { twitterAccountId }
};
};

renderContent = (formProps: IFormProps) => {
const { onRemoveAccount, onAccountSelect, renderButton } = this.props;
const { values, isSubmitted } = formProps;

return (
<>
{this.state.loading && <Spinner />}
<FormGroup>
<ControlLabel required={true}>Name</ControlLabel>
<FormControl {...formProps} name="name" required={true} />
</FormGroup>

<SelectBrand isRequired={true} formProps={formProps} />

<Accounts
kind="twitter"
addLink="twitter/login"
onSelect={onAccountSelect}
onRemove={onRemoveAccount}
formProps={formProps}
/>

<ModalFooter>
{renderButton({
name: 'integration',
values: this.generateDoc(values),
isSubmitted,
callback: this.props.closeModal
})}
</ModalFooter>
</>
);
};

render() {
return <Form renderContent={this.renderContent} />;
}
}

export default Twitter;
10 changes: 10 additions & 0 deletions src/modules/settings/integrations/constants.ts
Expand Up @@ -72,13 +72,15 @@ export const KIND_CHOICES = {
NYLAS_IMAP: 'nylas-imap',
LEAD: 'lead',
CALLPRO: 'callpro',
TWITTER_DM: 'twitter-dm',
CHATFUEL: 'chatfuel',
ALL_LIST: [
'messenger',
'facebook-post',
'facebook-messenger',
'lead',
'callpro',
'twitter-dm',
'chatfuel',
'gmail',
'nylas-gmail',
Expand Down Expand Up @@ -233,6 +235,14 @@ export const INTEGRATIONS = [
logo: '/images/integrations/callpro.png',
createModal: 'callpro'
},
{
name: 'Twitter',
description: 'Connect to your twitter DMs here in your Inbox',
inMessenger: false,
kind: 'twitter-dm',
logo: '/images/integrations/twitter.png',
createModal: 'twitter'
},
{
name: 'Chatfuel',
description: 'Connect your chatfuel account',
Expand Down
97 changes: 97 additions & 0 deletions src/modules/settings/integrations/containers/twitter/Twitter.tsx
@@ -0,0 +1,97 @@
import client from 'apolloClient';
import gql from 'graphql-tag';
import ButtonMutate from 'modules/common/components/ButtonMutate';
import { IButtonMutateProps, IRouterProps } from 'modules/common/types';
import { Alert } from 'modules/common/utils';
import { mutations, queries } from 'modules/settings/integrations/graphql';
import * as React from 'react';
import { withRouter } from 'react-router';
import Twitter from '../../components/twitter/Twitter';
import { getRefetchQueries } from '../utils';

type Props = {
type?: string;
closeModal: () => void;
};

type FinalProps = {} & IRouterProps & Props;

type State = {
twitterAccountId: string;
accountId: string;
};

class GmailContainer extends React.Component<FinalProps, State> {
constructor(props: FinalProps) {
super(props);

this.state = { twitterAccountId: '', accountId: '' };
}

onAccountSelect = (accountId?: string) => {
if (!accountId) {
return this.setState({ twitterAccountId: '', accountId: '' });
}

client
.query({
query: gql(queries.fetchApi),
variables: {
path: '/twitter/get-account',
params: { accountId }
}
})
.then(({ data, loading }: any) => {
if (!loading) {
this.setState({
twitterAccountId: data.integrationsFetchApi,
accountId
});
}
})
.catch(error => {
Alert.error(error.message);
});
};

onRemoveAccount = () => {
this.setState({ twitterAccountId: '' });
};

renderButton = ({
name,
values,
isSubmitted,
callback
}: IButtonMutateProps) => {
return (
<ButtonMutate
mutation={mutations.integrationsCreateExternalIntegration}
variables={values}
callback={callback}
refetchQueries={getRefetchQueries('gmail')}
isSubmitted={isSubmitted}
type="submit"
successMessage={`You successfully added a ${name}`}
/>
);
};

render() {
const { closeModal } = this.props;
const { accountId, twitterAccountId } = this.state;

const updatedProps = {
closeModal,
accountId,
twitterAccountId,
onAccountSelect: this.onAccountSelect,
onRemoveAccount: this.onRemoveAccount,
renderButton: this.renderButton
};

return <Twitter {...updatedProps} />;
}
}

export default withRouter<FinalProps>(GmailContainer);
3 changes: 2 additions & 1 deletion src/modules/settings/integrations/types.ts
Expand Up @@ -103,7 +103,8 @@ export type IntegrationTypes =
| 'facebook'
| 'gmail'
| 'nylas-gmail'
| 'nylas-imap';
| 'nylas-imap'
| 'twitter';

export type IntegrationsQueryResponse = {
integrations: IIntegration[];
Expand Down

0 comments on commit 9c3f01c

Please sign in to comment.