BOD-14 Backend server work + sending of messages WIP for front end

This commit is contained in:
Patrick Fic
2020-03-25 15:50:46 -07:00
parent 5b5ffe21cd
commit 84a5820d8d
32 changed files with 892 additions and 274 deletions

View File

@@ -0,0 +1,37 @@
import { Button } from "antd";
import React from "react";
import { connect } from "react-redux";
import { closeConversation, sendMessage, toggleConversationVisible } from "../../redux/messaging/messaging.actions";
import PhoneFormatter from "../../utils/PhoneFormatter";
const mapDispatchToProps = dispatch => ({
toggleConversationVisible: conversationId =>
dispatch(toggleConversationVisible(conversationId)),
closeConversation: phone => dispatch(closeConversation(phone)),
sendMessage: message => dispatch(sendMessage(message))
});
function ChatConversationClosedComponent({
conversation,
toggleConversationVisible,
closeConversation
}) {
return (
<div style={{ display: "flex" }}>
<div onClick={() => toggleConversationVisible(conversation.phone)}>
<PhoneFormatter>{conversation.phone}</PhoneFormatter>
</div>
<Button
type='dashed'
shape='circle-outline'
onClick={() => closeConversation(conversation.phone)}>
X
</Button>
</div>
);
}
export default connect(
null,
mapDispatchToProps
)(ChatConversationClosedComponent);

View File

@@ -1,22 +1,16 @@
import { Button, Card, Input } from "antd";
import Icon from '@ant-design/icons';
import React, { useEffect, useState } from "react";
import { Button, Card } from "antd";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import twilio from "twilio";
import {
closeConversation,
sendMessage,
toggleConversationVisible
} from "../../redux/messaging/messaging.actions";
import PhoneFormatter from "../../utils/PhoneFormatter";
import ChatConversationOpenComponent from "./chat-conversation.open.component";
import "./chat-conversation.styles.scss"; //https://bootsnipp.com/snippets/exR5v
import { MdSend } from "react-icons/md";
import { useTranslation } from "react-i18next";
const client = twilio(
"ACf1b1aaf0e04740828b49b6e58467d787",
"0bea5e29a6d77593183ab1caa01d23de"
);
import ChatConversationClosedComponent from "./chat-conversation.closed.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -24,35 +18,17 @@ const mapStateToProps = createStructuredSelector({
const mapDispatchToProps = dispatch => ({
toggleConversationVisible: conversationId =>
dispatch(toggleConversationVisible(conversationId)),
closeConversation: phone => dispatch(closeConversation(phone))
closeConversation: phone => dispatch(closeConversation(phone)),
sendMessage: message => dispatch(sendMessage(message))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(function ChatConversationComponent({
export function ChatConversationComponent({
conversation,
toggleConversationVisible,
closeConversation
}) {
const { t } = useTranslation();
const messages = [];
const [messages, setMessages] = useState([]);
useEffect(() => {
client.messages.list({ limit: 20 }, (error, items) => {
setMessages(
items.reduce((acc, value) => {
acc.push({
sid: value.sid,
direction: value.direction,
body: value.body
});
return acc;
}, [])
);
});
return () => {};
}, [setMessages]);
return (
<div>
<Card
@@ -60,15 +36,13 @@ export default connect(
conversation.open ? (
<div style={{ display: "flex" }}>
<div
onClick={() => toggleConversationVisible(conversation.phone)}
>
onClick={() => toggleConversationVisible(conversation.phone)}>
<PhoneFormatter>{conversation.phone}</PhoneFormatter>
</div>
<Button
type="danger"
shape="circle-outline"
onClick={() => closeConversation(conversation.phone)}
>
type='danger'
shape='circle-outline'
onClick={() => closeConversation(conversation.phone)}>
X
</Button>
</div>
@@ -78,44 +52,18 @@ export default connect(
width: conversation.open ? "400px" : "175px",
margin: "0px 10px"
}}
size="small"
>
size='small'>
{conversation.open ? (
<div>
<div className="messages" style={{ height: "400px" }}>
<ul>
{messages.map(item => (
<li
key={item.sid}
className={`${
item.direction === "inbound" ? "sent" : "replies"
}`}
>
<p> {item.body}</p>
</li>
))}
</ul>
</div>
<Input.Search
placeholder={t("messaging.labels.typeamessage")}
enterButton={<Icon component={MdSend} />}
/>
</div>
<ChatConversationOpenComponent messages={messages} />
) : (
<div style={{ display: "flex" }}>
<div onClick={() => toggleConversationVisible(conversation.phone)}>
<PhoneFormatter>{conversation.phone}</PhoneFormatter>
</div>
<Button
type="dashed"
shape="circle-outline"
onClick={() => closeConversation(conversation.phone)}
>
X
</Button>
</div>
<ChatConversationClosedComponent conversation={conversation} />
)}
</Card>
</div>
);
});
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ChatConversationComponent);

View File

@@ -0,0 +1,27 @@
import React from "react";
import ChatSendMessage from "../chat-send-message/chat-send-message.component";
export default function ChatConversationOpenComponent({
conversation,
messages
}) {
if (!!!messages) return <div>No Messages</div>;
return (
<div>
<div className='messages' style={{ height: "400px" }}>
<ul>
{messages.map(item => (
<li
key={item.sid}
className={`${
item.direction === "inbound" ? "sent" : "replies"
}`}>
<p> {item.body}</p>
</li>
))}
</ul>
</div>
<ChatSendMessage conversation={conversation} />
</div>
);
}

View File

@@ -0,0 +1,48 @@
import { Input } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { sendMessage } from "../../redux/messaging/messaging.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = dispatch => ({
sendMessage: message => dispatch(sendMessage(message))
});
function ChatSendMessageComponent({ conversation, bodyshop, sendMessage }) {
const [message, setMessage] = useState("");
const { t } = useTranslation();
console.log("message", message);
const handleEnter = () => {
console.log("Sending that message ");
sendMessage({
to: conversation.phone,
body: message,
messagingServiceSid: bodyshop.messagingservicesid
});
};
return (
<div style={{ display: "flex " }}>
<Input.TextArea
allowClear
autoSize={{ minRows: 1, maxRows: 4 }}
placeholder={t("messaging.labels.typeamessage")}
// enterButton={}
onChange={e => setMessage(e.target.value)}
onPressEnter={event => {
if (!!!event.shiftKey) handleEnter();
}}
/>
</div>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ChatSendMessageComponent);