├── .babelrc ├── .gitignore ├── LICENSE ├── Pipfile ├── README.md ├── django_react_bot ├── django_react_bot │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── frontend │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── src │ │ ├── actions │ │ │ ├── chats.js │ │ │ └── types.js │ │ ├── components │ │ │ ├── App.js │ │ │ ├── chatbot │ │ │ │ ├── Dashboard.js │ │ │ │ ├── MessageBox.js │ │ │ │ └── MessageWindow.js │ │ │ └── layout │ │ │ │ ├── Footer.js │ │ │ │ └── Header.js │ │ ├── index.js │ │ ├── reducers │ │ │ ├── chats.js │ │ │ └── index.js │ │ └── store.js │ ├── static │ │ └── css │ │ │ ├── chat_interface.css │ │ │ ├── footer.css │ │ │ ├── index.css │ │ │ ├── style.css │ │ │ └── temporary.css │ ├── templates │ │ └── frontend │ │ │ └── index.html │ ├── tests.py │ ├── urls.py │ └── views.py └── manage.py ├── package-lock.json ├── package.json ├── requirements.txt └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "plugins": ["transform-class-properties"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | django = "*" 10 | djangorestframework = "*" 11 | django-rest-knox = "*" 12 | gunicorn = "*" 13 | whitenoise = "*" 14 | dj-database-url = "*" 15 | psycopg2 = "*" 16 | 17 | [requires] 18 | python_version = "3.7" 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django-React-ChatBot 2 | **_"A basic chatbot created with Django + React + Love"_** 3 | 4 | 5 | #### Run this command to initiate and activate virtual environment 6 | ``` 7 | virtualenv venv --python=python3 8 | source venv/bin/activate 9 | ``` 10 | 11 | #### Run this command to install required Django packages using pip 12 | ``` 13 | pip install -r requirements.txt 14 | ``` 15 | 16 | #### Run the below commands to install required react packages using npm 17 | ``` 18 | npm init -y 19 | npm i react react-dom prop-types 20 | npm i -D @babel/core babel-loader @babel/preset-env @babel/preset-react babel-plugin-transform-class-properties 21 | npm i -D webpack webpack-cli 22 | ``` 23 | -------------------------------------------------------------------------------- /django_react_bot/django_react_bot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secretstardev/react-django-chatbot/e69203d164e895fb4fbab737ccfb6df3af14c537/django_react_bot/django_react_bot/__init__.py -------------------------------------------------------------------------------- /django_react_bot/django_react_bot/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for django_react_bot project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'nfxo3yr-c5bj+s28o7y06ckfd+1-92_9^kxoguk26gyx8kd6iv' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ["127.0.0.1"] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'frontend' 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'django_react_bot.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'django_react_bot.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'Asia/Kolkata' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | -------------------------------------------------------------------------------- /django_react_bot/django_react_bot/urls.py: -------------------------------------------------------------------------------- 1 | """django_react_bot URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('', include('frontend.urls')), 22 | ] 23 | -------------------------------------------------------------------------------- /django_react_bot/django_react_bot/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for django_react_bot project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_react_bot.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /django_react_bot/frontend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secretstardev/react-django-chatbot/e69203d164e895fb4fbab737ccfb6df3af14c537/django_react_bot/frontend/__init__.py -------------------------------------------------------------------------------- /django_react_bot/frontend/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /django_react_bot/frontend/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class FrontendConfig(AppConfig): 5 | name = 'frontend' 6 | -------------------------------------------------------------------------------- /django_react_bot/frontend/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secretstardev/react-django-chatbot/e69203d164e895fb4fbab737ccfb6df3af14c537/django_react_bot/frontend/migrations/__init__.py -------------------------------------------------------------------------------- /django_react_bot/frontend/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/actions/chats.js: -------------------------------------------------------------------------------- 1 | import { GET_CHATS, ADD_CHAT } from './types'; 2 | 3 | 4 | 5 | // GET CHATS 6 | export const getChats = () => (dispatch) => { 7 | dispatch({ 8 | type: GET_CHATS, 9 | payload: [] 10 | }); 11 | } 12 | 13 | // ADD CHAT 14 | export const addChat = (chat) => (dispatch) => { 15 | fetch('https://jsonplaceholder.typicode.com/posts', { 16 | method: 'POST', 17 | headers: { 18 | 'content-type': 'application/json' 19 | }, 20 | body: JSON.stringify(chat) 21 | }) 22 | .then(res => res.json()) 23 | .then(post => dispatch({ 24 | type: ADD_CHAT, 25 | payload: { 26 | usermessage: chat, 27 | botmessage: { 28 | index: chat.index+1, 29 | message: post.message, 30 | isbotmessage: true 31 | } 32 | } 33 | })); 34 | } 35 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/actions/types.js: -------------------------------------------------------------------------------- 1 | export const GET_CHATS = "GET_CHATS"; 2 | export const ADD_CHAT = "ADD_CHAT"; 3 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import ReactDOM from 'react-dom'; 4 | 5 | import Header from './layout/Header'; 6 | import Dashboard from './chatbot/Dashboard'; 7 | import store from '../store'; 8 | 9 | 10 | class App extends Component { 11 | render() { 12 | return ( 13 | 14 | 15 |
16 |
17 | 18 |
19 | 20 | 21 | ) 22 | } 23 | } 24 | 25 | 26 | ReactDOM.render(, document.getElementById("app")); 27 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/chatbot/Dashboard.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from 'react'; 2 | import MessageWindow from './MessageWindow'; 3 | import MessageBox from './MessageBox'; 4 | import '../../../static/css/chat_interface.css'; 5 | import '../../../static/css/temporary.css'; 6 | 7 | 8 | 9 | export default function Dashboard() { 10 | return( 11 | 12 |
13 | 14 | 15 |
16 |
17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/chatbot/MessageBox.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import { addChat } from '../../actions/chats'; 6 | 7 | import '../../../static/css/chat_interface.css'; 8 | import '../../../static/css/temporary.css'; 9 | 10 | 11 | class SendButton extends Component{ 12 | render(){ 13 | return (
14 |
send
15 |
); 16 | } 17 | } 18 | 19 | class MessageTextBoxContainer extends Component{ 20 | render(){ 21 | return( 22 |
23 | 24 |
25 | ); 26 | } 27 | } 28 | 29 | 30 | export class MessageBox extends Component { 31 | constructor(props){ 32 | super(props); 33 | this.state = { 34 | "messages": [], 35 | "current_message":"" 36 | } 37 | 38 | this.onClick = this.onClick.bind(this); 39 | this._handleKeyPress = this._handleKeyPress.bind(this); 40 | this.onChange = this.onChange.bind(this); 41 | this.addMessageBox = this.addMessageBox.bind(this); 42 | } 43 | 44 | static propTypes = { 45 | addChat: PropTypes.func.isRequired, 46 | messages: PropTypes.array.isRequired 47 | }; 48 | 49 | 50 | addMessageBox(enter=true){ 51 | const index = this.props.messages.length+1; 52 | const chat = { 53 | index: index, 54 | message: this.state.current_message, 55 | isbotmessage: false 56 | }; 57 | 58 | this.props.addChat(chat); 59 | 60 | this.setState({ 61 | current_message: "" 62 | }); 63 | 64 | } 65 | 66 | 67 | onClick(){ 68 | this.addMessageBox(); 69 | } 70 | 71 | onChange(e) { 72 | this.setState({ 73 | current_message: e.target.value 74 | }); 75 | } 76 | 77 | _handleKeyPress(e) { 78 | let enter_pressed = false; 79 | if(e.key === "Enter"){ 80 | enter_pressed = true; 81 | this.addMessageBox(enter_pressed) 82 | } 83 | } 84 | 85 | render() { 86 | return ( 87 |
88 | 92 | 93 |
94 | ); 95 | } 96 | } 97 | 98 | 99 | const mapStateToProps = state => ({ 100 | messages: state.chats.messages 101 | }); 102 | 103 | 104 | export default connect(mapStateToProps, { addChat })(MessageBox); 105 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/chatbot/MessageWindow.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import { getChats } from '../../actions/chats'; 6 | 7 | import '../../../static/css/chat_interface.css'; 8 | import '../../../static/css/temporary.css'; 9 | 10 | 11 | class Avatar extends Component { 12 | render(){ 13 | return( 14 |
15 | ); 16 | } 17 | } 18 | 19 | class UserMessageBox extends Component{ 20 | 21 | render(){ 22 | return( 23 |
  • 24 | 25 |
    26 |
    {this.props.message}
    27 |
    28 |
  • 29 | ); 30 | } 31 | } 32 | 33 | class MessagesContainer extends Component{ 34 | constructor(props) { 35 | super(props); 36 | this.createBotMessages = this.createBotMessages.bind(this); 37 | } 38 | 39 | scrollToBottom = () => { 40 | var el = this.refs.scroll; 41 | el.scrollTop = el.scrollHeight; 42 | } 43 | 44 | componentDidMount() { 45 | this.scrollToBottom(); 46 | } 47 | 48 | componentDidUpdate() { 49 | this.scrollToBottom(); 50 | } 51 | 52 | createBotMessages(){ 53 | return this.props.messages.map(message => 54 | 55 | ); 56 | } 57 | 58 | render(){ 59 | 60 | return( 61 |
      62 | {this.createBotMessages()} 63 |
    64 | ); 65 | } 66 | } 67 | 68 | 69 | export class MessageWindow extends Component { 70 | static propTypes = { 71 | getChats: PropTypes.func.isRequired, 72 | messages: PropTypes.array.isRequired, 73 | newMessage: PropTypes.object 74 | }; 75 | 76 | componentDidMount() { 77 | this.props.getChats(); 78 | } 79 | 80 | componentWillReceiveProps(nextProps) { 81 | if(nextProps.newMessage) { 82 | this.props.messages.push(nextProps.newMessage); 83 | } 84 | } 85 | 86 | render() { 87 | return ( 88 |
    89 | 90 |
    91 | ); 92 | } 93 | } 94 | 95 | const mapStateToProps = state => ({ 96 | messages: state.chats.messages, //Now we can use this.props.messages 97 | newMessage: state.chats.current_message 98 | }); 99 | 100 | 101 | export default connect(mapStateToProps, { getChats })(MessageWindow); 102 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/layout/Footer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import '../../../static/css/footer.css'; 3 | 4 | 5 | export class Footer extends Component { 6 | 7 | render() { 8 | return ( 9 |
    10 |
    11 |
    Made with ❤️ in India
    12 |
    13 |
    14 | ) 15 | } 16 | } 17 | 18 | 19 | export default Footer; 20 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/components/layout/Header.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | 4 | export class Header extends Component { 5 | render() { 6 | return ( 7 |
    8 | 18 |
    19 | ) 20 | } 21 | } 22 | 23 | export default Header; 24 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import '../static/css/index.css'; 2 | 3 | 4 | import App from './components/App'; 5 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/reducers/chats.js: -------------------------------------------------------------------------------- 1 | import { GET_CHATS, ADD_CHAT } from "../actions/types"; 2 | 3 | const initialState = { 4 | current_message: {}, 5 | messages: [] 6 | }; 7 | 8 | 9 | export default function(state = initialState, action) { 10 | switch(action.type) { 11 | case GET_CHATS: 12 | return { 13 | ...state, 14 | messages: action.payload 15 | }; 16 | case ADD_CHAT: 17 | return { 18 | messages: [...state.messages, action.payload.usermessage, action.payload.botmessage], 19 | current_message: action.payload.usermessage 20 | }; 21 | default: 22 | return state; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import chats from './chats'; 3 | 4 | 5 | export default combineReducers({ 6 | chats: chats 7 | }); 8 | -------------------------------------------------------------------------------- /django_react_bot/frontend/src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from "redux"; 2 | import { composeWithDevTools } from "redux-devtools-extension"; 3 | import thunk from "redux-thunk"; 4 | import rootReducer from "./reducers"; 5 | 6 | 7 | const initialState = {}; 8 | 9 | const middleware = [thunk]; 10 | 11 | const store = createStore( 12 | rootReducer, 13 | initialState, 14 | composeWithDevTools(applyMiddleware(...middleware)) 15 | ); 16 | 17 | export default store; 18 | -------------------------------------------------------------------------------- /django_react_bot/frontend/static/css/chat_interface.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background-color: #edeff2; 7 | font-family: "Calibri", "Roboto", sans-serif; 8 | } 9 | 10 | .chat_window { 11 | /*position: absolute;*/ 12 | width: calc(100% - 20px); 13 | max-width: 800px; 14 | height: 500px; 15 | border-radius: 10px; 16 | background-color: #fff; 17 | top: 50%; 18 | /*transform: translateX(-50%) translateY(-50%);*/ 19 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15); 20 | background-color: #f8f8f8; 21 | overflow: hidden; 22 | height: calc(100vh - 120px); 23 | } 24 | 25 | .top_menu { 26 | background-color: #fff; 27 | width: 100%; 28 | padding: 13px 0px; 29 | box-shadow: 0 1px 30px rgba(0, 0, 0, 0.1); 30 | } 31 | .top_menu .buttons { 32 | margin: 3px 0 0 20px; 33 | position: absolute; 34 | } 35 | .top_menu .buttons .button { 36 | width: 16px; 37 | height: 16px; 38 | border-radius: 50%; 39 | display: inline-block; 40 | margin-right: 10px; 41 | position: relative; 42 | } 43 | .top_menu .buttons .button.close { 44 | background-color: #f5886e; 45 | } 46 | .top_menu .buttons .button.minimize { 47 | background-color: #fdbf68; 48 | } 49 | .top_menu .buttons .button.maximize { 50 | background-color: #a3d063; 51 | } 52 | .top_menu .title { 53 | text-align: center; 54 | color: #337ab7; 55 | font-size: 20px; 56 | } 57 | 58 | .messages { 59 | position: relative; 60 | list-style: none; 61 | padding: 20px 10px 0 10px; 62 | margin: 0; 63 | height: calc(100vh - 250px); 64 | overflow: scroll; 65 | } 66 | .messages .message { 67 | clear: both; 68 | overflow: hidden; 69 | margin-bottom: 20px; 70 | transition: all 0.5s linear; 71 | opacity: 0; 72 | } 73 | .messages .message.left .avatar { 74 | background-color: #f5886e; 75 | float: left; 76 | } 77 | .messages .message.left .text_wrapper { 78 | background-color: #ffe6cb; 79 | margin-left: 20px; 80 | } 81 | .messages .message.left .text_wrapper::after, .messages .message.left .text_wrapper::before { 82 | right: 100%; 83 | border-right-color: #ffe6cb; 84 | } 85 | .messages .message.left .text { 86 | color: #c48843; 87 | } 88 | .messages .message.right .avatar { 89 | background-color: #fdbf68; 90 | float: right; 91 | } 92 | .messages .message.right .text_wrapper { 93 | background-color: #c7eafc; 94 | margin-right: 20px; 95 | float: right; 96 | } 97 | .messages .message.right .text_wrapper::after, .messages .message.right .text_wrapper::before { 98 | left: 100%; 99 | border-left-color: #c7eafc; 100 | } 101 | .messages .message.right .text { 102 | color: #45829b; 103 | } 104 | 105 | .messages .message.left .text { 106 | color: black; 107 | font-weight: inherit; 108 | } 109 | 110 | .messages .message.appeared { 111 | opacity: 1; 112 | } 113 | .messages .message .avatar { 114 | width: 60px; 115 | height: 60px; 116 | border-radius: 50%; 117 | display: inline-block; 118 | } 119 | .messages .message .text_wrapper { 120 | display: inline-block; 121 | padding: 20px; 122 | border-radius: 6px; 123 | width: calc(100% - 85px); 124 | min-width: 100px; 125 | position: relative; 126 | } 127 | .messages .message .text_wrapper::after, .messages .message .text_wrapper:before { 128 | top: 18px; 129 | border: solid transparent; 130 | content: " "; 131 | height: 0; 132 | width: 0; 133 | position: absolute; 134 | pointer-events: none; 135 | } 136 | .messages .message .text_wrapper::after { 137 | border-width: 13px; 138 | margin-top: 0px; 139 | } 140 | .messages .message .text_wrapper::before { 141 | border-width: 15px; 142 | margin-top: -2px; 143 | } 144 | .messages .message .text_wrapper .text { 145 | font-size: 18px; 146 | font-weight: 300; 147 | } 148 | 149 | .bottom_wrapper { 150 | position: relative; 151 | width: 100%; 152 | background-color: #fff; 153 | padding: 20px 20px; 154 | /*position: absolute;*/ 155 | bottom: 0; 156 | } 157 | .bottom_wrapper .message_input_wrapper { 158 | display: inline-block; 159 | height: 50px; 160 | border-radius: 25px; 161 | border: 1px solid #bcbdc0; 162 | width: calc(100% - 160px); 163 | position: relative; 164 | padding: 0 20px; 165 | } 166 | .bottom_wrapper .message_input_wrapper .message_input { 167 | border: none; 168 | height: 100%; 169 | box-sizing: border-box; 170 | width: calc(100% - 40px); 171 | position: absolute; 172 | outline-width: 0; 173 | color: gray; 174 | } 175 | .bottom_wrapper .send_message { 176 | width: 140px; 177 | height: 50px; 178 | display: inline-block; 179 | border-radius: 50px; 180 | background-color: #a3d063; 181 | border: 2px solid #a3d063; 182 | color: #fff; 183 | cursor: pointer; 184 | transition: all 0.2s linear; 185 | text-align: center; 186 | float: right; 187 | } 188 | .bottom_wrapper .send_message:hover { 189 | color: #a3d063; 190 | background-color: #fff; 191 | } 192 | .bottom_wrapper .send_message .text { 193 | font-size: 18px; 194 | font-weight: 300; 195 | display: inline-block; 196 | line-height: 48px; 197 | } 198 | 199 | .message_template { 200 | display: none; 201 | } 202 | 203 | #msg_input{ 204 | color: black; 205 | } 206 | -------------------------------------------------------------------------------- /django_react_bot/frontend/static/css/footer.css: -------------------------------------------------------------------------------- 1 | .footer_inner { 2 | text-align:center 3 | } 4 | -------------------------------------------------------------------------------- /django_react_bot/frontend/static/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /django_react_bot/frontend/static/css/style.css: -------------------------------------------------------------------------------- 1 | @import url(http://weloveiconfonts.com/api/?family=fontawesome|iconicstroke|typicons); 2 | /* fontawesome */ 3 | [class*="fontawesome-"]:before { 4 | font-family: 'FontAwesome', sans-serif; 5 | } 6 | /* iconicstroke */ 7 | [class*="iconicstroke-"]:before { 8 | font-family: 'IconicStroke', sans-serif; 9 | } 10 | /* typicons */ 11 | [class*="typicons-"]:before { 12 | font-family: 'Typicons', sans-serif; 13 | } 14 | body{ 15 | font-family:arial,sans-serif; 16 | } 17 | .chat-container { 18 | width: 300px; 19 | margin-right: 20px; 20 | float:right; 21 | overflow:hidden; 22 | } 23 | .top-header { 24 | background: #666; 25 | color: white; 26 | padding: 0.2rem; 27 | position: relative; 28 | overflow: hidden; 29 | border-bottom: 4px solid #35ac19; 30 | cursor:pointer; 31 | } 32 | .top-header:hover { 33 | background-color:#35ac19; 34 | } 35 | .top-header-tit { 36 | display: inline; 37 | font-size: 14px; 38 | } 39 | .top-header .typicons-message { 40 | display: inline-block; 41 | padding: 2px 5px 2px 5px; 42 | font-size: 20px; 43 | position: relative; 44 | top: 5px; 45 | } 46 | .top-header .typicons-minus { 47 | position: relative; 48 | top: 3px; 49 | font-size: 15px; 50 | cursor:pointer; 51 | } 52 | .top-header .typicons-plus { 53 | position: relative; 54 | top: 3px; 55 | font-size: 15px; 56 | } 57 | .top-header .typicons-times{ 58 | position: relative; 59 | top: 3px; 60 | font-size: 15px; 61 | } 62 | .top-header .left { 63 | float: left; 64 | } 65 | .top-header .right { 66 | float: right; 67 | padding-top: 5px; 68 | } 69 | .top-header > * { 70 | position: relative; 71 | } 72 | .top-header::before { 73 | content: ''; 74 | position: absolute; 75 | top: -100%; 76 | left: 0; 77 | right: 0; 78 | bottom: -100%; 79 | opacity: 0.25; 80 | background-color: #404040 81 | } 82 | .chat-box { 83 | list-style: none; 84 | background: #e5e5e5; 85 | margin: 0; 86 | padding: 0 0 50px 0; 87 | height: 280px; 88 | overflow-y: auto; 89 | } 90 | .chat-box li { 91 | padding: 0.5rem; 92 | overflow: hidden; 93 | display: flex; 94 | } 95 | .chat-box .avatar-icon { 96 | width: 40px; 97 | position: relative; 98 | } 99 | .chat-box .avatar-icon img { 100 | display: block; 101 | width: 100%; 102 | background-color:#1469A6; 103 | } 104 | .ibo .avatar-icon:after { 105 | content: ''; 106 | position: absolute; 107 | top: 0; 108 | right: 0; 109 | width: 0; 110 | height: 0; 111 | border: 5px solid white; 112 | border-left-color: transparent; 113 | border-bottom-color: transparent; 114 | } 115 | .me { 116 | justify-content: flex-end; 117 | align-items: flex-end; 118 | } 119 | .me .messages { 120 | order: 1; 121 | border-bottom-right-radius: 0; 122 | } 123 | .me .avatar-icon { 124 | order: 2; 125 | } 126 | .me .avatar-icon:after { 127 | content: ''; 128 | position: absolute; 129 | bottom: 0; 130 | left: 0; 131 | width: 0; 132 | height: 0; 133 | border: 5px solid white; 134 | border-right-color: transparent; 135 | border-top-color: transparent; 136 | box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); 137 | } 138 | .messages { 139 | background: white; 140 | padding: 10px; 141 | border-radius: 2px; 142 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); 143 | } 144 | .messages p { 145 | font-size: 0.8rem; 146 | margin: 0 0 0.2rem 0; 147 | } 148 | .messages time { 149 | font-size: 0.7rem; 150 | color: #ccc; 151 | } 152 | .setting{ 153 | background-color: #e5e5e5; 154 | height: 32px; 155 | padding-top: 2px; 156 | border-bottom: 1px solid rgba(0,0,0,.1); 157 | } 158 | .setting .left { 159 | float: left; 160 | } 161 | .setting .right { 162 | float: right; 163 | } 164 | .iconicstroke-user{ 165 | font-size: 22px; 166 | position: relative; 167 | top: 4px; 168 | left: 10px; 169 | color: #414141; 170 | cursor:pointer; 171 | } 172 | .typicons-cog{ 173 | font-size: 23px; 174 | position: relative; 175 | top: 7px; 176 | right: 4px; 177 | color: #414141; 178 | cursor:pointer; 179 | } 180 | .fontawesome-facetime-video{ 181 | font-size: 18px; 182 | position: relative; 183 | top: 3px; 184 | color: #414141; 185 | left: 5px; 186 | cursor:pointer; 187 | } 188 | .iconicstroke-user:hover, .typicons-cog:hover,.fontawesome-facetime-video:hover{ 189 | color:#000000; 190 | } 191 | ::-webkit-scrollbar{height:14px;width:10px;background:#eee;border-left:1px solid #ddd} 192 | ::-webkit-scrollbar-thumb{background:#ddd;border:1px solid #cfcfcf} 193 | ::-webkit-scrollbar-thumb:hover{background:#b2b2b2;border:1px solid #b2b2b2} 194 | ::-webkit-scrollbar-thumb:active{background:#b2b2b2;border:1px solid #b2b2b2} 195 | @-webkit-keyframes pulse { 196 | from { 197 | opacity: 0; 198 | } 199 | to { 200 | opacity: 0.5; 201 | } 202 | } 203 | 204 | /************ 205 | * response * 206 | ************/ 207 | #response { 208 | width:320px; 209 | background-color: rgba(255, 255, 255, 0.8); 210 | } 211 | .say { 212 | width:220px; 213 | padding:8px 15px; 214 | background:rgba(50, 50, 50, 0.2); 215 | border:0px solid #dbdbdb; 216 | } 217 | .saybtn { 218 | position:relative; 219 | padding:6px 15px; 220 | left:-8px; 221 | border:2px solid #207cca; 222 | background-color:#207cca; 223 | color:#fafafa; 224 | } 225 | .saybtn:hover { 226 | background-color:#409cea; 227 | } 228 | 229 | .ace_editor { 230 | border: 1px solid lightgray; 231 | margin: auto; 232 | height: 200px; 233 | width: 80%; 234 | } 235 | .scrollmargin { 236 | height: 80px; 237 | text-align: center; 238 | } 239 | .view{ 240 | border: 1px solid lightgray; 241 | margin: auto; 242 | width: 80%; 243 | } 244 | .view div span{ 245 | margin: 20px; 246 | display: inline-block; 247 | } 248 | .view div span span{ 249 | margin: 0px; 250 | display: inline; 251 | } 252 | .output{ 253 | min-height: 70px; 254 | } 255 | .TitleBar { 256 | margin: auto; 257 | width: 80%; 258 | border: 1px solid lightgray; 259 | height: 30px; 260 | border-bottom: 0px; 261 | background-color: #FCFAFA; 262 | font-size:20px; 263 | } 264 | .TitleBar b{ 265 | margin:15px; 266 | color: #454444; 267 | } 268 | .actionbar{ 269 | margin: auto; 270 | width: 80%; 271 | } 272 | #statusBar { 273 | margin: auto; 274 | width: 80%; 275 | border: 1px solid lightgray; 276 | height: 20px; 277 | border-top: 0px; 278 | } 279 | 280 | .ace_status-indicator { 281 | color: gray; 282 | float:right; 283 | right: 0; 284 | border-left: 1px solid; 285 | } 286 | .submit { 287 | float: right; 288 | border: 1px solid #AAA; 289 | margin-left: 10px; 290 | padding: 4px; 291 | cursor: pointer; 292 | } 293 | 294 | .blinking-cursor { 295 | font-weight: 500; 296 | font-size: 15px; 297 | color: #2E3D48; 298 | -webkit-animation: 1s blink step-end infinite; 299 | -moz-animation: 1s blink step-end infinite; 300 | -ms-animation: 1s blink step-end infinite; 301 | -o-animation: 1s blink step-end infinite; 302 | animation: 1s blink step-end infinite; 303 | } 304 | 305 | @keyframes "blink" { 306 | from, to { 307 | color: transparent; 308 | } 309 | 50% { 310 | color: black; 311 | } 312 | } 313 | 314 | @-moz-keyframes blink { 315 | from, to { 316 | color: transparent; 317 | } 318 | 50% { 319 | color: black; 320 | } 321 | } 322 | 323 | @-webkit-keyframes "blink" { 324 | from, to { 325 | color: transparent; 326 | } 327 | 50% { 328 | color: black; 329 | } 330 | } 331 | 332 | @-ms-keyframes "blink" { 333 | from, to { 334 | color: transparent; 335 | } 336 | 50% { 337 | color: black; 338 | } 339 | } 340 | 341 | @-o-keyframes "blink" { 342 | from, to { 343 | color: transparent; 344 | } 345 | 50% { 346 | color: black; 347 | } 348 | } 349 | #submit:disabled,#SubmitMCQ :disabled { 350 | background-color: white; 351 | } 352 | #submit, #SubmitMCQ { 353 | background: #2cbb0f; 354 | color: white; 355 | } 356 | #submit:hover,#SubmitMCQ:hover{ 357 | background: white; 358 | color: #2cbb0f;} 359 | .submit:hover { 360 | box-shadow: 1px 1px 3px gray; 361 | } 362 | .submit:disabled { 363 | box-shadow: unset; 364 | cursor: unset; 365 | color: lightgrey !important; 366 | background-color: #f6f6f6 !important; 367 | } 368 | #run { 369 | background-color: #4c9ed9; 370 | color: white; 371 | } 372 | #compiler::first-letter { 373 | text-transform: uppercase; 374 | } 375 | @media only screen and (max-height: 480px) { 376 | .chat-box { 377 | height: calc(100vh - 180px); 378 | } 379 | 380 | } 381 | #response{ 382 | width: calc(100% + 20px); 383 | } 384 | @media only screen and (max-Width: 340px) { 385 | .chat-container { 386 | width: calc(100vw - 20px); 387 | max-width: 300px; 388 | margin: auto 10px; 389 | } 390 | .say { 391 | width: calc(100% - 100px); 392 | } 393 | 394 | } 395 | .view { 396 | white-space: pre-wrap; /* Since CSS 2.1 */ 397 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 398 | white-space: -pre-wrap; /* Opera 4-6 */ 399 | white-space: -o-pre-wrap; /* Opera 7 */ 400 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 401 | } 402 | 403 | #QI { 404 | overflow-x: hidden; 405 | } 406 | 407 | .slide { 408 | opacity: 0; 409 | position: relative; 410 | font-family: Arial; 411 | font-size: 14px; 412 | /*line-height: 50px;*/ 413 | right: -100%; 414 | width:100%; 415 | } 416 | 417 | /*.choice { 418 | -webkit-column-count: 2; 419 | -moz-column-count: 2; 420 | column-count: 2; 421 | }*/ 422 | .MCanswer { 423 | display: inline-block; 424 | vertical-align: top; 425 | } 426 | .tab-container{ 427 | background: #f1f1f1; 428 | /* margin: 0; */ 429 | padding: 0; 430 | /* max-height: 35px; */ 431 | /* position: relative; */ 432 | overflow: hidden; 433 | } 434 | 435 | ul.tabs{ 436 | margin: 0; 437 | list-style-type : none; 438 | line-height : 35px; 439 | max-height: 35px; 440 | overflow: hidden; 441 | display: inline-block; 442 | padding: 0; 443 | padding-right: 10px; 444 | padding-left: 10px; 445 | border-bottom: 1px solid #d4d4d4; 446 | width: 100%; 447 | } 448 | 449 | ul.tabs > li.active{ 450 | z-index: 2; 451 | background: white; 452 | } 453 | 454 | ul.tabs > li.active:before{ 455 | border-color : transparent #efefef transparent transparent; 456 | } 457 | 458 | 459 | ul.tabs > li.active:after{ 460 | border-color : transparent transparent transparent #efefef; 461 | } 462 | 463 | ul.tabs > li{ 464 | float: left; 465 | margin : 5px -10px 0; 466 | border-top-right-radius: 25px 170px; 467 | border-top-left-radius: 20px 90px; 468 | padding : 0 30px 0 25px; 469 | height: 170px; 470 | background: #ddd; 471 | position : relative; 472 | box-shadow: 0 10px 20px rgba(0,0,0,.5); 473 | max-width : 200px; 474 | } 475 | 476 | ul.tabs > li > a{ 477 | display: inline-block; 478 | max-width:100%; 479 | overflow: hidden; 480 | text-overflow: ellipsis; 481 | text-decoration: none; 482 | color: #222; 483 | } 484 | 485 | ul.tabs > li:before, ul.tabs > li:after{ 486 | content : ''; 487 | background : transparent; 488 | height: 20px; 489 | width: 20px; 490 | border-radius: 100%; 491 | border-width: 10px; 492 | top: 0px; 493 | border-style : solid; 494 | position : absolute; 495 | } 496 | 497 | ul.tabs > li:before{ 498 | 499 | border-color : transparent #ddd transparent transparent; 500 | left: -23px; 501 | -ms-transform: rotate(48deg); 502 | -webkit-transform : rotate(48deg); 503 | transform: rotate(48deg); 504 | } 505 | 506 | ul.tabs > li:after{ 507 | border-color : transparent transparent transparent #ddd; 508 | -webkit-transform : rotate(-48deg); 509 | -ms-transform: rotate(-48deg); 510 | transform: rotate(-48deg); 511 | right: -17px; 512 | } 513 | 514 | /* Clear Fix took for HTML 5 Boilerlate*/ 515 | .clearfix:after { clear: both; } 516 | .clearfix { zoom: 1; } 517 | .clearfix:after,.clearfix:before{ 518 | -webkit-box-sizing: unset; 519 | -moz-box-sizing: unset; 520 | box-sizing: unset; 521 | } 522 | 523 | *{ 524 | -webkit-box-sizing: unset; 525 | -moz-box-sizing: unset; 526 | box-sizing: unset; 527 | } 528 | body{ 529 | line-height: unset; 530 | } 531 | pre{ 532 | padding: unset; 533 | border-radius:unset; 534 | } 535 | #modal-backdrop{ 536 | height: 100vh; 537 | width: 100vw; 538 | background: rgba(0,0,0,0.53); 539 | z-index: 10000; 540 | position: fixed; 541 | top: 0px; 542 | left: 0px; 543 | } 544 | #modal{ 545 | border-radius: 4px; 546 | background: white; 547 | width: 500px; 548 | margin: auto; 549 | top: 100px; 550 | position: relative; 551 | color: #757575; 552 | overflow: hidden; 553 | 554 | } 555 | #modal-header{ 556 | min-height: 20px; 557 | width: 100%; 558 | font-size: 16px; 559 | font-weight: 100; 560 | border-bottom: 1px solid lightgray; 561 | padding: 12px; 562 | /*text-shadow: 1px 1px 1px rgba(114, 119, 112, 0.8);*/ 563 | } 564 | #modal-body{ 565 | min-height: 20px; 566 | width: 100%; 567 | padding: 5px; 568 | overflow: hidden 569 | } 570 | #modal-footer{ 571 | min-height: 20px; 572 | width: 100%; 573 | border-top: 1px solid lightgray; 574 | padding: 5px; 575 | } 576 | #modal-footer #next{ 577 | cursor: unset; 578 | color: white; 579 | background-color: #4CAF50; 580 | float: right; 581 | margin: 5px; 582 | margin-right: 8px; 583 | border: unset; 584 | padding: 6px; 585 | border-radius: 1px; 586 | } 587 | #modal-footer #next:hover{ 588 | background-color: #ffffff; 589 | color: #4CAF50; 590 | box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); 591 | } 592 | #modal-footer #skip{ 593 | cursor: unset; 594 | color: white; 595 | background-color: #FF622C; 596 | float: right; 597 | margin: 5px; 598 | margin-right: 8px; 599 | border: unset; 600 | padding: 6px; 601 | border-radius: 1px; 602 | } 603 | #modal-footer #skip:hover{ 604 | background-color: white; 605 | color: #FF622C; 606 | box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); 607 | } 608 | .skip:disabled { 609 | box-shadow: unset; 610 | cursor: unset; 611 | color: lightgrey !important; 612 | background-color: #f6f6f6 !important; 613 | } 614 | .test-text { 615 | background-color: white; 616 | margin-left: 40px; 617 | margin-right: 479px; 618 | min-height: 58px; 619 | 620 | } 621 | #modal-body div { 622 | float: left; 623 | width: 166px; 624 | display: inline-block; 625 | /* possibly also height: 300px; */ 626 | } 627 | #modal-body div p span { 628 | font-family: serif;} 629 | -------------------------------------------------------------------------------- /django_react_bot/frontend/static/css/temporary.css: -------------------------------------------------------------------------------- 1 | .chat_window{ 2 | height: calc(100vh - 120px); 3 | } 4 | .messages{ 5 | height: calc(100vh - 250px); 6 | } 7 | 8 | .messages .message.left .text { 9 | color: black !important; 10 | font-weight: inherit; 11 | } 12 | 13 | #msg_input{ 14 | color: black; 15 | } 16 | -------------------------------------------------------------------------------- /django_react_bot/frontend/templates/frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ChatBot 9 | 10 | 11 |
    12 | {% load static %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /django_react_bot/frontend/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django_react_bot/frontend/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | 5 | urlpatterns = [ 6 | path('', views.index), 7 | ] 8 | -------------------------------------------------------------------------------- /django_react_bot/frontend/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | 4 | def index(request): 5 | return render(request, 'frontend/index.html') 6 | -------------------------------------------------------------------------------- /django_react_bot/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_react_bot.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Django-React-ChatBot", 3 | "version": "1.0.0", 4 | "description": "A basic chatbot created using React and Django application", 5 | "main": "webpack.config.js", 6 | "dependencies": { 7 | "axios": "^0.19.2", 8 | "babel-preset-es2015": "^6.24.1", 9 | "prop-types": "^15.7.2", 10 | "react": "^16.13.1", 11 | "react-dom": "^16.13.1", 12 | "react-redux": "^7.2.0", 13 | "react-router-dom": "^5.1.2", 14 | "react-scripts": "^3.4.1", 15 | "redux": "^4.0.5", 16 | "redux-devtools-extension": "^2.13.8", 17 | "redux-thunk": "^2.3.0" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.11.5", 21 | "@babel/preset-env": "^7.11.5", 22 | "@babel/preset-react": "^7.10.4", 23 | "babel-loader": "^8.1.0", 24 | "babel-plugin-transform-class-properties": "^6.24.1", 25 | "webpack": "^4.44.1", 26 | "webpack-cli": "^3.3.12" 27 | }, 28 | "scripts": { 29 | "dev": "webpack --mode development --watch ./django_react_bot/frontend/src/index.js --output ./django_react_bot/frontend/static/frontend/main.js", 30 | "build": "webpack --mode production ./django_react_bot/frontend/src/index.js --output ./django_react_bot/frontend/static/frontend/main.js" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "git+https://github.com/codedak/Django-React-ChatBot.git" 35 | }, 36 | "keywords": [], 37 | "author": "", 38 | "license": "ISC", 39 | "bugs": { 40 | "url": "https://github.com/codedak/Django-React-ChatBot/issues" 41 | }, 42 | "homepage": "https://github.com/codedak/Django-React-ChatBot#readme" 43 | } 44 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cffi==1.14.0 2 | cryptography==2.9.2 3 | Django==2.2 4 | django-rest-knox==4.1.0 5 | djangorestframework==3.11.0 6 | pycparser==2.20 7 | pytz==2020.1 8 | six==1.14.0 9 | sqlparse==0.3.1 10 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | module: { 3 | rules: [ 4 | { 5 | test: /\.js$/, 6 | exclude: /node_modules/, 7 | use: { 8 | loader: "babel-loader" 9 | } 10 | },{ 11 | test: /\.css$/, 12 | use: ['style-loader', 'css-loader'] 13 | } 14 | ] 15 | } 16 | } 17 | --------------------------------------------------------------------------------