Skip to content

Commit

Permalink
inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Souza authored and Peter Souza committed Jul 21, 2021
1 parent 9cbd108 commit c3a0259
Show file tree
Hide file tree
Showing 40 changed files with 295 additions and 425 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#APP_CONFIG
REACT_APP_NLU_ENDPOINT=https://your-api/
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<h1 align="center" style="border-bottom: none;">💬 React Chatbot UI</h1>
<h4 align="center">This React app, is a fully customizable web-based client for Chatbots.</h4>
<p align="center">
<img src="./docs/images/app_sample_0.png" alt="React chat logo" width="240"/>
</p>

#### A solid foundation

React, Redux, Ant Design Icons. A perfect combination of best frameworks.

<p align="center">
<img src="./docs/images/icon-react.png" alt="React chat logo" width="60px"/>
<img src="./docs/images/icon-redux.png" alt="React chat logo" width="60px"/>
<img src="./docs/images/icon-antdesign.png" alt="React chat logo" width="60px"/>
</p>

#### Responsive

<p align="center">
<img src="./docs/images/responsive-view.gif" alt="Responsive view gif" width="240"/>
</p>

#### How to use

```bash
$ git clone https://github.com/PeterPimentel/react-web-chat
$ cd react-web-chat/
$ npm install
```

1. Rename the file `.env.example` to `.env`
1. Run the app in the development mode `npm start`.
1. Open [http://localhost:3000](http://localhost:3000) to view it full screen in the browser.
1. It is possible to see in the file `samples/embedded-chat/index.html` how to embedded the chat into your page.

<span style="color:#660000">Please note this app is only the UI, you need implement the back-end app to connect to the NLU service.<span>

---

#### Customize

##### 🌈 Colors

In the `src/styles/colors.css` you can customize the colors of your chat.

---

😃 If you like this project and used it in yout chatbot please let me know!
Binary file added docs/images/app_sample_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/icon-antdesign.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/icon-react.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/icon-redux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/react-chat-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/responsive-view.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/video/responsive-view.mov
Binary file not shown.
40 changes: 22 additions & 18 deletions examples/embedded-chat/index.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./reactWebChat.css">
<title>Document</title>
</head>
<body>
<div id="ps-web-chat-app">
<iframe class="ps-web-chat-position ps-web-chat-iframe scale-in-br" src="http://localhost:3000"></iframe>
<div id="ps-chat-skeleton" class="ps-web-chat-position scale-in-br"></div>
<button class="ps-button-circle">
<img id="ps-button-chat-image" src="https://ssl.gstatic.com/bt/C3341AA7A1A076756462EE2E5CD71C11/2x/btw_ic_speeddial_white_24dp_2x.png" alt="" />
</button>
</div>
<script src="./reactWebChat.js" type="text/javascript"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="./reactWebChat.css" />
<title>Document</title>
</head>
<body>
<div id="ps-web-chat-app">
<iframe class="ps-web-chat-position ps-web-chat-iframe scale-in-br" src="http://localhost:3000"></iframe>
<div id="ps-chat-skeleton" class="ps-web-chat-position scale-in-br"></div>
<button class="ps-button-circle">
<img
id="ps-button-chat-image"
src="https://ssl.gstatic.com/bt/C3341AA7A1A076756462EE2E5CD71C11/2x/btw_ic_speeddial_white_24dp_2x.png"
alt=""
/>
</button>
</div>
<script src="./reactWebChat.js" type="text/javascript"></script>
</body>
</html>
9 changes: 0 additions & 9 deletions src/App.test.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from 'react';
import { ConnectedChat } from './components/ConnectedChat/ConnectedChat';
import { ConnectedFooter } from './components/ConnectedFooter/ConnectedFooter';
import { ConnectedToast } from './components/ConnectedToast/ConnectedToast';
import { Header } from './components/Header/Header';

function App() {
return (
<div className="App">
<Header />
<ConnectedChat />
<ConnectedToast />
<ConnectedFooter />
</div>
);
Expand Down
Binary file removed src/assets/images/react_chat_logo.png
Binary file not shown.
2 changes: 1 addition & 1 deletion src/components/ConnectedChat/ConnectedChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const ConnectedChat: FunctionComponent = () => {
return (
<main className={styles.chat}>
{messages.map((msg) => (
<MessageHandler key={msg.id} message={msg.message} from={msg.from} type={msg.type} />
<MessageHandler key={msg.uid} message={msg.message} from={msg.from} type={msg.type} />
))}
<div ref={ref} />
<Modal />
Expand Down
2 changes: 1 addition & 1 deletion src/components/ConnectedChat/connectedChat.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.chat {
padding: 64px 0 64px 0;
padding: 72px 0;
height: 100%;
width: 100%;
}
31 changes: 20 additions & 11 deletions src/components/ConnectedFooter/ConnectedFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React, { FunctionComponent, useState, useCallback, ChangeEvent } from 'react';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { ArrowRightOutlined } from '@ant-design/icons';
import { sendMessage } from '../../redux/messageStore';
import { getContext } from '../../redux/selectors/context';
import { generateUID } from '../../util/uidGeneratorUtil';

import { fetchMessagesSuccess } from '../../redux/messageStore';
import styles from './connectedFooter.module.css';

export const ConnectedFooter: FunctionComponent = () => {
const [message, setMessage] = useState('');
const dispatch = useDispatch();
const context = useSelector(getContext);

const handleInput = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -17,15 +20,21 @@ export const ConnectedFooter: FunctionComponent = () => {
);

const handleSendMessage = useCallback(() => {
const id = Math.random() * 100000;
dispatch(
fetchMessagesSuccess({
id: id.toString(),
message,
type: 'TEXT',
from: 'USER',
}),
);
const uid = generateUID();

if (message && message.trim().length > 0) {
dispatch(
sendMessage(
{
uid,
message,
type: 'TEXT',
from: 'USER',
},
context,
),
);
}
setMessage('');
}, [message, setMessage, dispatch]);

Expand Down
19 changes: 19 additions & 0 deletions src/components/ConnectedToast/ConnectedToast.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.toast {
position: fixed;
left: 0;
top: 64px;

display: flex;
align-items: center;
justify-content: center;

width: 100%;
height: 32px;

border-radius: 0 0 10px 10px;
background-color: var(--grey-strong);
}

.message {
color: var(--error);
}
36 changes: 36 additions & 0 deletions src/components/ConnectedToast/ConnectedToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { FunctionComponent, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { modalToggle } from '../../redux/layoutStore';
import { getToastState } from '../../redux/selectors/layout';

import styles from './ConnectedToast.module.css';

export const ConnectedToast: FunctionComponent = () => {
const toastState = useSelector(getToastState);
const dispatch = useDispatch();

//Automatic Toast dismmiss
useEffect(() => {
const interval = setInterval(() => {
dispatch(
modalToggle({
visible: false,
content: '',
}),
);
}, 7000);
return () => {
clearInterval(interval);
};
}, []);

if (!toastState.visible) {
return null;
}

return (
<div className={styles.toast}>
<p className={`${styles.message} typo-h60`}>{toastState.content}</p>
</div>
);
};
2 changes: 1 addition & 1 deletion src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const Header: FunctionComponent = () => {
alt="chatbot avatar"
/>
</div>
<span className={`${styles.botName} typo-h30`}>Botinho</span>
<span className={`${styles.botName} typo-h30`}>Chatbot</span>
<div className={styles.closeButton}>
<MoreOutlined className={`${styles.closeButtonIcon} typo-h30`} />
</div>
Expand Down
13 changes: 0 additions & 13 deletions src/components/Icons/Brand.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/Messages/ImageMessage/ImageMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const ImageMessage: FunctionComponent<ImageMessageProps> = ({ source, fro
return (
<div className={containerStyle}>
<div className={styles.messageContainer} onClick={handleImageClick}>
<img className="typo-h50" src={source} alt="" />
<img src={source} alt="" />
</div>
</div>
);
Expand Down
Loading

0 comments on commit c3a0259

Please sign in to comment.