showing incoming text mesages in chat window
This commit is contained in:
parent
7c60153c21
commit
89b3273125
|
|
@ -1736,6 +1736,24 @@
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
|
||||||
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
|
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
|
||||||
},
|
},
|
||||||
|
"@reduxjs/toolkit": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-pa3nqclCJaZPAyBhruQtiRwtTjottRrVJqziVZcWzI73i6L3miLTtUyWfauwv08HWtiXLx1xGyGt+yLFfW/d0A==",
|
||||||
|
"requires": {
|
||||||
|
"immer": "^9.0.1",
|
||||||
|
"redux": "^4.1.0",
|
||||||
|
"redux-thunk": "^2.3.0",
|
||||||
|
"reselect": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"immer": {
|
||||||
|
"version": "9.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.6.tgz",
|
||||||
|
"integrity": "sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@svgr/babel-plugin-add-jsx-attribute": {
|
"@svgr/babel-plugin-add-jsx-attribute": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
|
||||||
|
|
@ -15328,6 +15346,11 @@
|
||||||
"@babel/runtime": "^7.9.2"
|
"@babel/runtime": "^7.9.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"redux-thunk": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
|
||||||
|
},
|
||||||
"regenerate": {
|
"regenerate": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
||||||
|
|
@ -15631,6 +15654,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||||
},
|
},
|
||||||
|
"reselect": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
|
||||||
|
},
|
||||||
"resize-observer-polyfill": {
|
"resize-observer-polyfill": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
"@fullcalendar/react": "^5.3.1",
|
"@fullcalendar/react": "^5.3.1",
|
||||||
"@fullcalendar/timegrid": "^5.3.1",
|
"@fullcalendar/timegrid": "^5.3.1",
|
||||||
"@loadable/component": "^5.13.2",
|
"@loadable/component": "^5.13.2",
|
||||||
|
"@reduxjs/toolkit": "^1.6.1",
|
||||||
"attr-accept": "^2.2.2",
|
"attr-accept": "^2.2.2",
|
||||||
"bootstrap": "^4.5.3",
|
"bootstrap": "^4.5.3",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { BrowserRouter as Router } from 'react-router-dom';
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
import Layout from './layouts/Layout';
|
import JKLayout from './layouts/JKLayout';
|
||||||
|
|
||||||
import 'react-toastify/dist/ReactToastify.min.css';
|
import 'react-toastify/dist/ReactToastify.min.css';
|
||||||
import 'react-datetime/css/react-datetime.css';
|
import 'react-datetime/css/react-datetime.css';
|
||||||
import 'react-image-lightbox/style.css';
|
import 'react-image-lightbox/style.css';
|
||||||
|
|
||||||
import useScript from './hooks/useScript';
|
|
||||||
|
|
||||||
import { useDispatch } from "react-redux";
|
|
||||||
//import { addMessage } from "./store/features/textMessagesSlice"
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
|
||||||
function initJKScripts() {
|
|
||||||
const app = window.JK.JamKazam();
|
|
||||||
const jamServer = new window.JK.JamServer(app, function(event_type) {
|
|
||||||
console.log('---EVENT_TYPE---', event_type);
|
|
||||||
//return app.activeElementEvent(event_type)
|
|
||||||
});
|
|
||||||
jamServer.initialize();
|
|
||||||
window.JK.initJamClient(app);
|
|
||||||
|
|
||||||
const clientInit = new window.JK.ClientInit();
|
|
||||||
clientInit.init();
|
|
||||||
|
|
||||||
window.JK.JamServer.connect() // singleton here defined in JamServer.js
|
|
||||||
.done(function() {
|
|
||||||
console.log('Jamserver connected');
|
|
||||||
//_initAfterConnect(true);
|
|
||||||
})
|
|
||||||
.fail(function() {
|
|
||||||
console.log('Jamserver connection error');
|
|
||||||
//_initAfterConnect(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
registerTextMessageCallback();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerTextMessageCallback(){
|
|
||||||
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.TEXT_MESSAGE, function(header, payload) {
|
|
||||||
console.log('Handling TEXT_MESSAGE ' + JSON.stringify(payload));
|
|
||||||
// chatMessageReceived(payload);
|
|
||||||
// context.ChatActions.msgReceived(payload);
|
|
||||||
// handledNotification(payload);
|
|
||||||
|
|
||||||
//dispatch(addMessage())
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatch = useDispatch()
|
|
||||||
|
|
||||||
useScript(`${process.env.REACT_APP_LEGACY_BASE_URL}/client_scripts`, initJKScripts);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router basename={process.env.PUBLIC_URL}>
|
<Router basename={process.env.PUBLIC_URL}>
|
||||||
<Layout />
|
<JKLayout />
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Card, CardBody, Row, Col } from 'reactstrap';
|
||||||
|
import Logo from '../navbar/Logo';
|
||||||
|
import Section from '../common/Section';
|
||||||
|
|
||||||
|
function JKLoginRequest() {
|
||||||
|
return (
|
||||||
|
<Section className="py-0">
|
||||||
|
<Row className="flex-center min-vh-100 py-6">
|
||||||
|
<Col sm={10} md={8} lg={6} xl={5} className="col-xxl-4">
|
||||||
|
<Logo />
|
||||||
|
<Card>
|
||||||
|
<CardBody className="fs--1 font-weight-normal p-5">
|
||||||
|
<Row className="justify-content-center">
|
||||||
|
<h3 className="mt-3 mt-md-4 font-weight-normal fs-2">Signin to begin</h3>
|
||||||
|
<p>Please login to your jamkazam account before accessing this interface.</p>
|
||||||
|
<a className="btn btn-primary" href="https://www.jamkazam.com/signin">
|
||||||
|
Signin
|
||||||
|
</a>
|
||||||
|
</Row>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JKLoginRequest
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
function JKDashboardLoadingIndicator() {
|
||||||
|
return (
|
||||||
|
<div className="spinner-border" role="status">
|
||||||
|
<span className="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JKDashboardLoadingIndicator
|
||||||
|
|
@ -1,10 +1,93 @@
|
||||||
import React from "react";
|
import React, { useContext, useEffect } from 'react';
|
||||||
|
|
||||||
const JKDashboard = () => {
|
import { Route, Switch } from 'react-router-dom';
|
||||||
|
|
||||||
return(
|
import NavbarTop from '../navbar/NavbarTop';
|
||||||
<h1>Dashboard</h1>
|
import NavbarVertical from '../navbar/NavbarVertical';
|
||||||
)
|
import JKFooter from '../footer/JKFooter';
|
||||||
|
|
||||||
|
import AppContext from '../../context/Context';
|
||||||
|
import { getPageName } from '../../helpers/utils';
|
||||||
|
|
||||||
|
import useScript from '../../hooks/useScript';
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { addMessage } from "../../store/features/textMessagesSlice"
|
||||||
|
|
||||||
|
import JKHome from './JkHome';
|
||||||
|
import loadable from '@loadable/component';
|
||||||
|
const JKDashboardRoutes = loadable(() => import('../../layouts/JKDashboardRoutes'));
|
||||||
|
|
||||||
|
function JKDashboard() {
|
||||||
|
const { isFluid, isVertical, navbarStyle } = useContext(AppContext);
|
||||||
|
const isKanban = getPageName('kanban');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
JKDashboardRoutes.preload();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
const initJKScripts = () => {
|
||||||
|
const app = window.JK.JamKazam();
|
||||||
|
const jamServer = new window.JK.JamServer(app, function(event_type) {
|
||||||
|
console.log('EVENT_TYPE', event_type);
|
||||||
|
});
|
||||||
|
jamServer.initialize();
|
||||||
|
window.JK.initJamClient(app);
|
||||||
|
const clientInit = new window.JK.ClientInit();
|
||||||
|
clientInit.init();
|
||||||
|
|
||||||
|
window.JK.JamServer.connect() // singleton here defined in JamServer.js
|
||||||
|
.done(function() {
|
||||||
|
console.log('Jamserver connected');
|
||||||
|
//_initAfterConnect(true);
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
console.log('Jamserver connection error');
|
||||||
|
//_initAfterConnect(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
registerTextMessageCallback();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const registerTextMessageCallback = () => {
|
||||||
|
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.TEXT_MESSAGE, function(header, payload) {
|
||||||
|
const json = payload
|
||||||
|
const receivedMsg = {
|
||||||
|
id: json.text_message_id,
|
||||||
|
message: json.msg,
|
||||||
|
senderId: json.sender_id,
|
||||||
|
senderName: json.sender_name,
|
||||||
|
receiverId: window.currentUser.id,
|
||||||
|
receiverName: window.currentUser.first_name,
|
||||||
|
createdAt: json.created_at,
|
||||||
|
sent: true
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(addMessage(receivedMsg))
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useScript(`${process.env.REACT_APP_LEGACY_BASE_URL}/client_scripts`, initJKScripts);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={isFluid || isKanban ? 'container-fluid' : 'container'}>
|
||||||
|
{isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />}
|
||||||
|
|
||||||
|
<div className="content">
|
||||||
|
<NavbarTop />
|
||||||
|
<Switch>
|
||||||
|
<Route path="/" exact component={JKHome} />
|
||||||
|
<JKDashboardRoutes />
|
||||||
|
</Switch>
|
||||||
|
{!isKanban && <JKFooter />}
|
||||||
|
</div>
|
||||||
|
{/* <SidePanelModal path={location.pathname} /> */}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default JKDashboard;
|
export default JKDashboard;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const JKHome = () => {
|
||||||
|
|
||||||
|
return(
|
||||||
|
<h1>Dashboard - Home</h1>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JKHome;
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Col, Row } from 'reactstrap';
|
||||||
|
import { version } from '../../config';
|
||||||
|
|
||||||
|
const JKFooter = () => (
|
||||||
|
<footer>
|
||||||
|
<Row noGutters className="justify-content-between text-center fs--1 mt-4 mb-3">
|
||||||
|
<Col sm="auto">
|
||||||
|
<p className="mb-0 text-600">
|
||||||
|
Copyright © {new Date().getFullYear()} JamKazam, Inc. All Rights Reserved
|
||||||
|
</p>
|
||||||
|
</Col>
|
||||||
|
<Col sm="auto">
|
||||||
|
<p className="mb-0 text-600">v{version}</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default JKFooter;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useState, useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { Modal, ModalHeader, ModalBody, Row, Col, Button, ModalFooter } from 'reactstrap';
|
import { Modal, ModalHeader, ModalBody, Row, Col, Button, ModalFooter, Badge } from 'reactstrap';
|
||||||
import { Scrollbar } from 'react-scrollbars-custom';
|
import { Scrollbar } from 'react-scrollbars-custom';
|
||||||
import TimeAgo from 'react-timeago';
|
import TimeAgo from 'react-timeago';
|
||||||
import JKProfileAvatar from './JKProfileAvatar';
|
import JKProfileAvatar from './JKProfileAvatar';
|
||||||
|
|
@ -11,31 +11,40 @@ const JKMessageModal = props => {
|
||||||
const { show, setShow, user } = props;
|
const { show, setShow, user } = props;
|
||||||
const LIMIT = 20;
|
const LIMIT = 20;
|
||||||
|
|
||||||
|
const [fetching, setFetching] = useState(false);
|
||||||
const [offset, setOffset] = useState(0);
|
const [offset, setOffset] = useState(0);
|
||||||
const [newMessage, setNewMessage] = useState('');
|
const [newMessage, setNewMessage] = useState('');
|
||||||
|
const [messagesArrived, setMessagesArrived] = useState(false);
|
||||||
|
|
||||||
const toggle = () => setShow(!show);
|
const toggle = () => setShow(!show);
|
||||||
|
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const scrollbar = useRef();
|
const scrollbar = useRef();
|
||||||
|
const messageTextBox = useRef();
|
||||||
|
const scrolledToBottom = useRef(false);
|
||||||
|
|
||||||
const messages = useSelector(state =>
|
const messages = useSelector(state =>
|
||||||
state.textMessage.messages
|
state.textMessage.messages
|
||||||
.filter(
|
.filter(
|
||||||
message =>
|
message =>
|
||||||
(message.senderId === user.id && message.receiverId === currentUser.id) ||
|
(message.senderId === user.id && message.receiverId === window.currentUser.id) ||
|
||||||
(message.senderId === currentUser.id && message.receiverId === user.id)
|
(message.senderId === window.currentUser.id && message.receiverId === user.id)
|
||||||
)
|
)
|
||||||
.reverse()
|
.sort((a, b) => {
|
||||||
|
return new Date(a.createdAt) - new Date(b.createdAt);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const fetchMessages = async () => {
|
const fetchMessages = async () => {
|
||||||
try {
|
try {
|
||||||
await dispatch(fetchMessagesByReceiverId(user.id)).unwrap();
|
const options = { userId: user.id, offset: offset, limit: LIMIT };
|
||||||
scrollbar.current.scrollToBottom();
|
setFetching(true);
|
||||||
|
await dispatch(fetchMessagesByReceiverId(options)).unwrap();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('ERROR', err);
|
console.log('ERROR', err);
|
||||||
|
} finally {
|
||||||
|
setFetching(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -48,37 +57,102 @@ const JKMessageModal = props => {
|
||||||
};
|
};
|
||||||
setNewMessage('');
|
setNewMessage('');
|
||||||
await dispatch(postNewMessage(msgData)).unwrap();
|
await dispatch(postNewMessage(msgData)).unwrap();
|
||||||
fetchMessages();
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('addNewMessage error', err);
|
console.log('addNewMessage error', err);
|
||||||
} finally {
|
} finally {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnKeyPress = (event) => {
|
const handleOnKeyPress = event => {
|
||||||
//console.log('event', event.key);
|
if (event.key === 'Enter' || event.key === 'NumpadEnter') {
|
||||||
if(event.key === 'Enter' || event.key === "NumpadEnter"){
|
event.preventDefault();
|
||||||
sendMessage()
|
sendMessage();
|
||||||
|
event.target.value = '';
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const scrollAtTop = () => {
|
||||||
|
return scrollbar.current.scrollTop === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollAtMiddle = () => {
|
||||||
|
return scrollbar.current.scrollHeight - scrollbar.current.clientHeight > scrollbar.current.scrollTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollAtBottom = () => {
|
||||||
|
return scrollbar.current.scrollHeight - scrollbar.current.clientHeight === scrollbar.current.scrollTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToBottom = () => {
|
||||||
|
if (scrollbar && scrollbar.current) {
|
||||||
|
scrollbar.current.scrollToBottom();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (show) {
|
if (show && messages.length === 0) {
|
||||||
//console.log('JKMessageModal User', user.id);
|
|
||||||
fetchMessages();
|
fetchMessages();
|
||||||
}
|
}
|
||||||
}, [show, dispatch]);
|
}, [show]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (scrollbar && scrollbar.current) {
|
||||||
|
if (!fetching && !scrollAtTop()) {
|
||||||
|
if (messages[messages.length - 1]['senderId'] !== currentUser.id) {
|
||||||
|
if (!scrolledToBottom.current) {
|
||||||
|
setMessagesArrived(true);
|
||||||
|
} else {
|
||||||
|
goToBottom();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goToBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [messages]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!messagesArrived) {
|
||||||
|
setMessagesArrived(false);
|
||||||
|
goToBottom();
|
||||||
|
}
|
||||||
|
}, [messagesArrived]);
|
||||||
|
|
||||||
|
const handleScrollStop = scrollValues => {
|
||||||
|
scrolledToBottom.current = false;
|
||||||
|
if (scrollValues.scrollTop === 0) {
|
||||||
|
setOffset(prev => prev + 1);
|
||||||
|
} else if (scrollValues.scrollTop === scrollValues.scrollHeight - scrollValues.clientHeight) {
|
||||||
|
scrolledToBottom.current = true;
|
||||||
|
setMessagesArrived(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (offset !== 0) {
|
||||||
|
fetchMessages();
|
||||||
|
}
|
||||||
|
}, [offset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal isOpen={show} toggle={toggle}>
|
<Modal isOpen={show} toggle={toggle}>
|
||||||
<ModalHeader toggle={toggle}>Conversation with {user.name}</ModalHeader>
|
<ModalHeader toggle={toggle}>Conversation with {user.name}</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Scrollbar ref={scrollbar} style={{ width: '100%', height: 200 }}>
|
<Scrollbar
|
||||||
|
ref={scrollbar}
|
||||||
|
onScrollStop={handleScrollStop}
|
||||||
|
style={{ width: '100%', height: 200 }}
|
||||||
|
mobileNative={true}
|
||||||
|
trackClickBehavior="step"
|
||||||
|
>
|
||||||
{messages.map((message, index) => (
|
{messages.map((message, index) => (
|
||||||
<div className="d-flex mb-3 mr-1" key={message.id}>
|
<div className="d-flex mb-3 mr-1" key={message.id}>
|
||||||
<div className="avatar avatar-2xl d-inline-block">
|
<div className="avatar avatar-2xl d-inline-block">
|
||||||
<JKProfileAvatar url={ message.receiverId === currentUser.id ? currentUser.photo_url : user.photo_url} />
|
<JKProfileAvatar
|
||||||
|
url={message.receiverId === currentUser.id ? currentUser.photo_url : user.photo_url}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-inline-block">
|
<div className="d-inline-block">
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
|
|
@ -93,6 +167,9 @@ const JKMessageModal = props => {
|
||||||
if (unit === 'minute') return `${value} ${value === 1 ? 'minute' : 'minutes'} ago`;
|
if (unit === 'minute') return `${value} ${value === 1 ? 'minute' : 'minutes'} ago`;
|
||||||
if (unit === 'hour') return `${value} ${value === 1 ? 'hour' : 'hours'} ago`;
|
if (unit === 'hour') return `${value} ${value === 1 ? 'hour' : 'hours'} ago`;
|
||||||
if (unit === 'day') return `${value} ${value === 1 ? 'day' : 'days'} ago`;
|
if (unit === 'day') return `${value} ${value === 1 ? 'day' : 'days'} ago`;
|
||||||
|
if (unit === 'week') return `${value} ${value === 1 ? 'week' : 'weeks'} ago`;
|
||||||
|
if (unit === 'month') return `${value} ${value === 1 ? 'month' : 'months'} ago`;
|
||||||
|
if (unit === 'year') return `${value} ${value === 1 ? 'year' : 'years'} ago`;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</time>
|
</time>
|
||||||
|
|
@ -103,9 +180,24 @@ const JKMessageModal = props => {
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</Scrollbar>
|
</Scrollbar>
|
||||||
|
{messagesArrived && (
|
||||||
|
<Row>
|
||||||
|
<Col className="d-flex justify-content-center">
|
||||||
|
<Button color="info" size="sm" onClick={() => setMessagesArrived(prev => !prev)}>
|
||||||
|
New messages
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<textarea style={{ width: '100%' }} value={newMessage} onChange={e => setNewMessage(e.target.value)} onKeyPress={handleOnKeyPress} />
|
<textarea
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
value={newMessage}
|
||||||
|
onChange={e => setNewMessage(e.target.value)}
|
||||||
|
onKeyPress={handleOnKeyPress}
|
||||||
|
ref={messageTextBox}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import JKProfileGenres from './JKProfileGenres';
|
||||||
import JKProfilePerformanceSamples from './JKProfilePerformanceSamples';
|
import JKProfilePerformanceSamples from './JKProfilePerformanceSamples';
|
||||||
import { useAuth } from '../../context/AuthContext';
|
import { useAuth } from '../../context/AuthContext';
|
||||||
import JKConnectButton from './JKConnectButton';
|
import JKConnectButton from './JKConnectButton';
|
||||||
|
import JKMessageButton from './JKMessageButton';
|
||||||
import JKLatencyBadge from './JKLatencyBadge';
|
import JKLatencyBadge from './JKLatencyBadge';
|
||||||
import JKLastActiveAgo from './JKLastActiveAgo';
|
import JKLastActiveAgo from './JKLastActiveAgo';
|
||||||
import JKProfileSkillLevel from './JKProfileSkillLevel';
|
import JKProfileSkillLevel from './JKProfileSkillLevel';
|
||||||
|
|
@ -139,9 +140,13 @@ const JKProfileSidePanel = props => {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>{' '}
|
/>{' '}
|
||||||
<button className="btn btn-outline-primary" data-testid="message">
|
{/* <button className="btn btn-outline-primary" data-testid="message">
|
||||||
<span className="fas fa-comment" /> Send Message
|
<span className="fas fa-comment" /> Send Message
|
||||||
</button>
|
</button> */}
|
||||||
|
|
||||||
|
<JKMessageButton currentUser={currentUser} user={user}>
|
||||||
|
<FontAwesomeIcon icon="comments" transform="shrink-4 down-1" className="mr-1" /> Send Message
|
||||||
|
</JKMessageButton>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
const useScript = (src, onloadHandler) => {
|
const useScript = (src, onloadHandler = () => {}) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = src;
|
script.src = src;
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,23 @@
|
||||||
import React, { useState, useContext, useEffect } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Route, Switch, Redirect, NavLink } from 'react-router-dom';
|
import { Route, Switch } from 'react-router-dom';
|
||||||
import { Card, CardBody, Row, Col, Button } from 'reactstrap';
|
import Dashboard from '../components/dashboard/Dashboard';
|
||||||
import Logo from '../components/navbar/Logo';
|
import DashboardAlt from '../components/dashboard-alt/DashboardAlt';
|
||||||
import Section from '../components/common/Section';
|
|
||||||
//import Dashboard from '../components/dashboard/Dashboard';
|
|
||||||
import JKDashboard from '../components/dashboard/JkDashboard';
|
|
||||||
//import DashboardAlt from '../components/dashboard-alt/DashboardAlt';
|
|
||||||
|
|
||||||
import NavbarTop from '../components/navbar/NavbarTop';
|
import NavbarTop from '../components/navbar/NavbarTop';
|
||||||
import NavbarVertical from '../components/navbar/NavbarVertical';
|
import NavbarVertical from '../components/navbar/NavbarVertical';
|
||||||
import Footer from '../components/footer/Footer';
|
import Footer from '../components/footer/Footer';
|
||||||
import loadable from '@loadable/component';
|
import loadable from '@loadable/component';
|
||||||
import AppContext from '../context/Context';
|
import AppContext from '../context/Context';
|
||||||
import ProductProvider from '../components/e-commerce/ProductProvider';
|
import ProductProvider from '../components/e-commerce/ProductProvider';
|
||||||
// import SidePanelModal from '../components/side-panel/SidePanelModal';
|
import SidePanelModal from '../components/side-panel/SidePanelModal';
|
||||||
import { getPageName } from '../helpers/utils';
|
import { getPageName } from '../helpers/utils';
|
||||||
|
|
||||||
import { useAuth } from '../context/AuthContext';
|
|
||||||
import { getCurrentUser } from '../helpers/rest';
|
|
||||||
|
|
||||||
|
|
||||||
const AUTH_STAGES = {
|
|
||||||
loading: 1,
|
|
||||||
authenticated: 2,
|
|
||||||
unauthenticated: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
const DashboardRoutes = loadable(() => import('./DashboardRoutes'));
|
const DashboardRoutes = loadable(() => import('./DashboardRoutes'));
|
||||||
|
|
||||||
const DashboardLayout = ({ location }) => {
|
const DashboardLayout = ({ location }) => {
|
||||||
|
const { isFluid, isVertical, navbarStyle } = useContext(AppContext);
|
||||||
|
|
||||||
const { currentUser, setCurrentUser } = useAuth();
|
const isKanban = getPageName('kanban');
|
||||||
|
|
||||||
const [stage, setStage] = useState(AUTH_STAGES['loading']);
|
|
||||||
|
|
||||||
const fetchCurrentUser = () => {
|
|
||||||
getCurrentUser()
|
|
||||||
.then(resp => {
|
|
||||||
if (resp.ok) {
|
|
||||||
return resp.json();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log('layout CURRENT_USER', data);
|
|
||||||
setCurrentUser(data);
|
|
||||||
setStage(AUTH_STAGES['authenticated']);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
setStage(AUTH_STAGES['unauthenticated']);
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchCurrentUser();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
DashboardRoutes.preload();
|
DashboardRoutes.preload();
|
||||||
|
|
@ -65,84 +27,22 @@ const DashboardLayout = ({ location }) => {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
||||||
switch (stage) {
|
|
||||||
case AUTH_STAGES['authenticated']:
|
|
||||||
return <DashboardSection />;
|
|
||||||
case AUTH_STAGES['unauthenticated']:
|
|
||||||
return <LoginRequestSection />;
|
|
||||||
default:
|
|
||||||
return <DashboardLoadingIndicator />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const DashboardLoadingIndicator = () => {
|
|
||||||
return (
|
return (
|
||||||
<div className="spinner-border" role="status">
|
|
||||||
<span className="sr-only">Loading...</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LoginRequestSection = () => {
|
|
||||||
return (
|
|
||||||
<Section className="py-0">
|
|
||||||
<Row className="flex-center min-vh-100 py-6">
|
|
||||||
<Col sm={10} md={8} lg={6} xl={5} className="col-xxl-4">
|
|
||||||
<Logo />
|
|
||||||
<Card>
|
|
||||||
<CardBody className="fs--1 font-weight-normal p-5">
|
|
||||||
<Row className="justify-content-center">
|
|
||||||
<h3 className="mt-3 mt-md-4 font-weight-normal fs-2">Signin to begin</h3>
|
|
||||||
<p>Please login to your jamkazam account before accessing this interface.</p>
|
|
||||||
<a className="btn btn-primary" href="https://www.jamkazam.com/signin">
|
|
||||||
Signin
|
|
||||||
</a>
|
|
||||||
</Row>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const DashboardSection = () => {
|
|
||||||
const { isFluid, isVertical, navbarStyle } = useContext(AppContext);
|
|
||||||
const isKanban = getPageName('kanban');
|
|
||||||
|
|
||||||
return (
|
|
||||||
|
|
||||||
<div className={isFluid || isKanban ? 'container-fluid' : 'container'}>
|
<div className={isFluid || isKanban ? 'container-fluid' : 'container'}>
|
||||||
{isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />}
|
{isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />}
|
||||||
<ProductProvider>
|
<ProductProvider>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<NavbarTop />
|
<NavbarTop />
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* <Route path="/" exact component={Dashboard} /> */}
|
<Route path="/" exact component={Dashboard} />
|
||||||
{/* <Route path="/dashboard-alt" exact component={DashboardAlt} /> */}
|
<Route path="/dashboard-alt" exact component={DashboardAlt} />
|
||||||
<Route path="/" exact component={JKDashboard} />
|
|
||||||
<DashboardRoutes />
|
<DashboardRoutes />
|
||||||
</Switch>
|
</Switch>
|
||||||
{!isKanban && <Footer />}
|
{!isKanban && <Footer />}
|
||||||
</div>
|
</div>
|
||||||
{/* <SidePanelModal path={location.pathname} /> */}
|
<SidePanelModal path={location.pathname} />
|
||||||
</ProductProvider>
|
</ProductProvider>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ProtectedRoute = ({ component: Component, ...rest }) => {
|
|
||||||
const { currentUser } = useAuth();
|
|
||||||
return (
|
|
||||||
// Show the component only when the user is logged in
|
|
||||||
// Otherwise, redirect the user to /login page
|
|
||||||
<Route
|
|
||||||
{...rest}
|
|
||||||
render={props =>
|
|
||||||
currentUser ? <Component {...props} /> : <Redirect to={{ pathname: '/authentication/basic/start' }} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,153 +1,148 @@
|
||||||
import { fn } from 'moment';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||||
// import Alerts from '../components/bootstrap-components/Alerts';
|
import Alerts from '../components/bootstrap-components/Alerts';
|
||||||
// import Avatar from '../components/bootstrap-components/Avatar';
|
import Avatar from '../components/bootstrap-components/Avatar';
|
||||||
// import AutocompleteExample from '../components/bootstrap-components/AutocompleteExample';
|
import AutocompleteExample from '../components/bootstrap-components/AutocompleteExample';
|
||||||
// import Backgrounds from '../components/bootstrap-components/Backgrounds';
|
import Backgrounds from '../components/bootstrap-components/Backgrounds';
|
||||||
// import Badges from '../components/bootstrap-components/Badges';
|
import Badges from '../components/bootstrap-components/Badges';
|
||||||
// import Breadcrumbs from '../components/bootstrap-components/Breadcrumb';
|
import Breadcrumbs from '../components/bootstrap-components/Breadcrumb';
|
||||||
// import Buttons from '../components/bootstrap-components/Buttons';
|
import Buttons from '../components/bootstrap-components/Buttons';
|
||||||
// import Cards from '../components/bootstrap-components/Cards';
|
import Cards from '../components/bootstrap-components/Cards';
|
||||||
// import Carousel from '../components/bootstrap-components/Carousel';
|
import Carousel from '../components/bootstrap-components/Carousel';
|
||||||
// import Collapses from '../components/bootstrap-components/Collapses';
|
import Collapses from '../components/bootstrap-components/Collapses';
|
||||||
// import Combo from '../components/bootstrap-components/Combo';
|
import Combo from '../components/bootstrap-components/Combo';
|
||||||
// import CookieNotice from '../components/bootstrap-components/CookieNotice';
|
import CookieNotice from '../components/bootstrap-components/CookieNotice';
|
||||||
// import Dropdowns from '../components/bootstrap-components/Dropdowns';
|
import Dropdowns from '../components/bootstrap-components/Dropdowns';
|
||||||
// import FalconAccordions from '../components/bootstrap-components/FalconAccordions';
|
import FalconAccordions from '../components/bootstrap-components/FalconAccordions';
|
||||||
// import Forms from '../components/bootstrap-components/Forms';
|
import Forms from '../components/bootstrap-components/Forms';
|
||||||
// import ListGroups from '../components/bootstrap-components/ListGroups';
|
import ListGroups from '../components/bootstrap-components/ListGroups';
|
||||||
// import Modals from '../components/bootstrap-components/Modals';
|
import Modals from '../components/bootstrap-components/Modals';
|
||||||
// import Navbars from '../components/bootstrap-components/Navbars';
|
import Navbars from '../components/bootstrap-components/Navbars';
|
||||||
// import NavBarTop from '../components/bootstrap-components/NavBarTop';
|
import NavBarTop from '../components/bootstrap-components/NavBarTop';
|
||||||
// import Navs from '../components/bootstrap-components/Navs';
|
import Navs from '../components/bootstrap-components/Navs';
|
||||||
// import PageHeaders from '../components/bootstrap-components/PageHeaders';
|
import PageHeaders from '../components/bootstrap-components/PageHeaders';
|
||||||
// import Paginations from '../components/bootstrap-components/Paginations';
|
import Paginations from '../components/bootstrap-components/Paginations';
|
||||||
// import Popovers from '../components/bootstrap-components/Popovers';
|
import Popovers from '../components/bootstrap-components/Popovers';
|
||||||
// import ProgressBar from '../components/bootstrap-components/ProgressBar';
|
import ProgressBar from '../components/bootstrap-components/ProgressBar';
|
||||||
// import Sidepanel from '../components/bootstrap-components/Sidepanel';
|
import Sidepanel from '../components/bootstrap-components/Sidepanel';
|
||||||
// import Spinners from '../components/bootstrap-components/Spinners';
|
import Spinners from '../components/bootstrap-components/Spinners';
|
||||||
// import Tables from '../components/bootstrap-components/Tables';
|
import Tables from '../components/bootstrap-components/Tables';
|
||||||
// import Tabs from '../components/bootstrap-components/Tabs';
|
import Tabs from '../components/bootstrap-components/Tabs';
|
||||||
// import Tooltips from '../components/bootstrap-components/Tooltips';
|
import Tooltips from '../components/bootstrap-components/Tooltips';
|
||||||
// import VerticalNavbar from '../components/bootstrap-components/VerticalNavbar';
|
import VerticalNavbar from '../components/bootstrap-components/VerticalNavbar';
|
||||||
// import Calendar from '../components/calendar/Calendar';
|
import Calendar from '../components/calendar/Calendar';
|
||||||
// import ChangeLog from '../components/changelog/ChangeLog';
|
import ChangeLog from '../components/changelog/ChangeLog';
|
||||||
// import Chat from '../components/chat/Chat';
|
import Chat from '../components/chat/Chat';
|
||||||
// import GettingStarted from '../components/documentation/GettingStarted';
|
import GettingStarted from '../components/documentation/GettingStarted';
|
||||||
// import Checkout from '../components/e-commerce/Checkout';
|
import Checkout from '../components/e-commerce/Checkout';
|
||||||
// import Customers from '../components/e-commerce/Customers';
|
import Customers from '../components/e-commerce/Customers';
|
||||||
// import FavouriteItems from '../components/e-commerce/FavouriteItems';
|
import FavouriteItems from '../components/e-commerce/FavouriteItems';
|
||||||
// import OrderDetails from '../components/e-commerce/OrderDetails';
|
import OrderDetails from '../components/e-commerce/OrderDetails';
|
||||||
// import Orders from '../components/e-commerce/Orders';
|
import Orders from '../components/e-commerce/Orders';
|
||||||
// import ProductDetails from '../components/e-commerce/ProductDetails';
|
import ProductDetails from '../components/e-commerce/ProductDetails';
|
||||||
// import Products from '../components/e-commerce/Products';
|
import Products from '../components/e-commerce/Products';
|
||||||
// import ShoppingCart from '../components/e-commerce/ShoppingCart';
|
import ShoppingCart from '../components/e-commerce/ShoppingCart';
|
||||||
// import Compose from '../components/email/Compose';
|
import Compose from '../components/email/Compose';
|
||||||
// import EmailDetail from '../components/email/EmailDetail';
|
import EmailDetail from '../components/email/EmailDetail';
|
||||||
// import Inbox from '../components/email/Inbox';
|
import Inbox from '../components/email/Inbox';
|
||||||
// import InboxProvider from '../components/email/inbox/InboxProvider';
|
import InboxProvider from '../components/email/inbox/InboxProvider';
|
||||||
// import Starter from '../components/extra/Starter';
|
import Starter from '../components/extra/Starter';
|
||||||
// import Feed from '../components/feed/Feed';
|
import Feed from '../components/feed/Feed';
|
||||||
// import Kanban from '../components/kanban/Kanban';
|
import Kanban from '../components/kanban/Kanban';
|
||||||
// import Activity from '../components/page/Activity';
|
import Activity from '../components/page/Activity';
|
||||||
// import Associations from '../components/page/Associations';
|
import Associations from '../components/page/Associations';
|
||||||
// import Billing from '../components/page/Billing';
|
import Billing from '../components/page/Billing';
|
||||||
// import CustomerDetails from '../components/page/CustomerDetails';
|
import CustomerDetails from '../components/page/CustomerDetails';
|
||||||
// import EventCreate from '../components/page/EventCreate';
|
import EventCreate from '../components/page/EventCreate';
|
||||||
// import EventDetail from '../components/page/EventDetail';
|
import EventDetail from '../components/page/EventDetail';
|
||||||
// import Events from '../components/page/Events';
|
import Events from '../components/page/Events';
|
||||||
// import Faq from '../components/page/Faq';
|
import Faq from '../components/page/Faq';
|
||||||
// import InvitePeople from '../components/page/InvitePeople';
|
import InvitePeople from '../components/page/InvitePeople';
|
||||||
// import Invoice from '../components/page/Invoice';
|
import Invoice from '../components/page/Invoice';
|
||||||
// import Notifications from '../components/page/Notifications';
|
import Notifications from '../components/page/Notifications';
|
||||||
// import People from '../components/page/People';
|
import People from '../components/page/People';
|
||||||
// import Settings from '../components/page/Settings';
|
import Settings from '../components/page/Settings';
|
||||||
// import BulkSelect from '../components/plugins/BulkSelect';
|
import BulkSelect from '../components/plugins/BulkSelect';
|
||||||
// import CalendarExample from '../components/plugins/CalendarExample';
|
import CalendarExample from '../components/plugins/CalendarExample';
|
||||||
// import Chart from '../components/plugins/Chart';
|
import Chart from '../components/plugins/Chart';
|
||||||
// import CodeHighlightDoc from '../components/plugins/CodeHighlightDoc';
|
import CodeHighlightDoc from '../components/plugins/CodeHighlightDoc';
|
||||||
// import CountUpExample from '../components/plugins/Countup';
|
import CountUpExample from '../components/plugins/Countup';
|
||||||
// import DatetimeExample from '../components/plugins/Datetime';
|
import DatetimeExample from '../components/plugins/Datetime';
|
||||||
// import Dropzone from '../components/plugins/Dropzone';
|
import Dropzone from '../components/plugins/Dropzone';
|
||||||
// import EchartMap from '../components/plugins/EchartMap';
|
import EchartMap from '../components/plugins/EchartMap';
|
||||||
// import Echarts from '../components/plugins/Echarts';
|
import Echarts from '../components/plugins/Echarts';
|
||||||
// import EmojiMart from '../components/plugins/EmojiMart';
|
import EmojiMart from '../components/plugins/EmojiMart';
|
||||||
// import FontAwesome from '../components/plugins/FontAwesome';
|
import FontAwesome from '../components/plugins/FontAwesome';
|
||||||
// import GoogleMapExample from '../components/plugins/GoogleMap';
|
import GoogleMapExample from '../components/plugins/GoogleMap';
|
||||||
// import ImageLightbox from '../components/plugins/ImageLightbox';
|
import ImageLightbox from '../components/plugins/ImageLightbox';
|
||||||
// import Leaflet from '../components/plugins/Leaflet';
|
import Leaflet from '../components/plugins/Leaflet';
|
||||||
// import Lottie from '../components/plugins/Lottie';
|
import Lottie from '../components/plugins/Lottie';
|
||||||
// import Plyr from '../components/plugins/Plyr';
|
import Plyr from '../components/plugins/Plyr';
|
||||||
// import ProgressBarJs from '../components/plugins/ProgressBarJs';
|
import ProgressBarJs from '../components/plugins/ProgressBarJs';
|
||||||
// import QuillEditorExample from '../components/plugins/Quill';
|
import QuillEditorExample from '../components/plugins/Quill';
|
||||||
// import ReactBeautifulDnD from '../components/plugins/ReactBeautifulDnD';
|
import ReactBeautifulDnD from '../components/plugins/ReactBeautifulDnD';
|
||||||
// import ReactBootstrapTable2 from '../components/plugins/ReactBootstrapTable2';
|
import ReactBootstrapTable2 from '../components/plugins/ReactBootstrapTable2';
|
||||||
// import ReactHookFrom from '../components/plugins/ReactHookFrom';
|
import ReactHookFrom from '../components/plugins/ReactHookFrom';
|
||||||
// import Scrollbar from '../components/plugins/Scrollbar';
|
import Scrollbar from '../components/plugins/Scrollbar';
|
||||||
// import Select from '../components/plugins/Select';
|
import Select from '../components/plugins/Select';
|
||||||
// import SlickCarousel from '../components/plugins/SlickCarousel';
|
import SlickCarousel from '../components/plugins/SlickCarousel';
|
||||||
// import Toastify from '../components/plugins/Toastify';
|
import Toastify from '../components/plugins/Toastify';
|
||||||
// import Typed from '../components/plugins/Typed';
|
import Typed from '../components/plugins/Typed';
|
||||||
// import Pricing from '../components/pricing/Pricing';
|
import Pricing from '../components/pricing/Pricing';
|
||||||
// import PricingAlt from '../components/pricing/PricingAlt';
|
import PricingAlt from '../components/pricing/PricingAlt';
|
||||||
// import Profile from '../components/profile/Profile';
|
import Profile from '../components/profile/Profile';
|
||||||
// import Borders from '../components/utilities/Borders';
|
import Borders from '../components/utilities/Borders';
|
||||||
// import Clearfix from '../components/utilities/Clearfix';
|
import Clearfix from '../components/utilities/Clearfix';
|
||||||
// import CloseIcon from '../components/utilities/CloseIcon';
|
import CloseIcon from '../components/utilities/CloseIcon';
|
||||||
// import Colors from '../components/utilities/Colors';
|
import Colors from '../components/utilities/Colors';
|
||||||
// import Display from '../components/utilities/Display';
|
import Display from '../components/utilities/Display';
|
||||||
// import Embed from '../components/utilities/Embed';
|
import Embed from '../components/utilities/Embed';
|
||||||
// import Figures from '../components/utilities/Figures';
|
import Figures from '../components/utilities/Figures';
|
||||||
// import Flex from '../components/utilities/Flex';
|
import Flex from '../components/utilities/Flex';
|
||||||
// import Grid from '../components/utilities/Grid';
|
import Grid from '../components/utilities/Grid';
|
||||||
// import Sizing from '../components/utilities/Sizing';
|
import Sizing from '../components/utilities/Sizing';
|
||||||
// import Spacing from '../components/utilities/Spacing';
|
import Spacing from '../components/utilities/Spacing';
|
||||||
// import StretchedLink from '../components/utilities/StretchedLink';
|
import StretchedLink from '../components/utilities/StretchedLink';
|
||||||
// import Typography from '../components/utilities/Typography';
|
import Typography from '../components/utilities/Typography';
|
||||||
// import VerticalAlign from '../components/utilities/VerticalAlign';
|
import VerticalAlign from '../components/utilities/VerticalAlign';
|
||||||
// import Visibility from '../components/utilities/Visibility';
|
import Visibility from '../components/utilities/Visibility';
|
||||||
// import Widgets from '../components/widgets/Widgets';
|
import Widgets from '../components/widgets/Widgets';
|
||||||
import JKPeople from '../components/page/JKPeople';
|
|
||||||
|
|
||||||
// const InboxRoutes = ({ match: { url } }) => (
|
const InboxRoutes = ({ match: { url } }) => (
|
||||||
// <InboxProvider>
|
<InboxProvider>
|
||||||
// <Switch>
|
<Switch>
|
||||||
// <Route path={`${url}/email-detail`} exact component={EmailDetail} />
|
<Route path={`${url}/email-detail`} exact component={EmailDetail} />
|
||||||
// <Route path={`${url}/inbox`} exact component={Inbox} />
|
<Route path={`${url}/inbox`} exact component={Inbox} />
|
||||||
// <Route path={`${url}/compose`} exact component={Compose} />
|
<Route path={`${url}/compose`} exact component={Compose} />
|
||||||
|
|
||||||
// {/*Redirect*/}
|
{/*Redirect*/}
|
||||||
// <Redirect to="/errors/404" />
|
<Redirect to="/errors/404" />
|
||||||
// </Switch>
|
</Switch>
|
||||||
// </InboxProvider>
|
</InboxProvider>
|
||||||
// );
|
);
|
||||||
|
|
||||||
// const ProductRoutes = ({ match: { url } }) => (
|
const ProductRoutes = ({ match: { url } }) => (
|
||||||
// <Switch>
|
<Switch>
|
||||||
// <Route path={`${url}/products/:productLayout`} exact component={Products} />
|
<Route path={`${url}/products/:productLayout`} exact component={Products} />
|
||||||
// <Route path={`${url}/checkout`} exact component={Checkout} />
|
<Route path={`${url}/checkout`} exact component={Checkout} />
|
||||||
// <Route path={`${url}/product-details/:id`} exact component={ProductDetails} />
|
<Route path={`${url}/product-details/:id`} exact component={ProductDetails} />
|
||||||
// <Route path={`${url}/product-details/`} exact component={ProductDetails} />
|
<Route path={`${url}/product-details/`} exact component={ProductDetails} />
|
||||||
// <Route path={`${url}/shopping-cart`} exact component={ShoppingCart} />
|
<Route path={`${url}/shopping-cart`} exact component={ShoppingCart} />
|
||||||
// <Route path={`${url}/orders`} exact component={Orders} />
|
<Route path={`${url}/orders`} exact component={Orders} />
|
||||||
// <Route path={`${url}/order-details`} exact component={OrderDetails} />
|
<Route path={`${url}/order-details`} exact component={OrderDetails} />
|
||||||
// <Route path={`${url}/customers`} exact component={Customers} />
|
<Route path={`${url}/customers`} exact component={Customers} />
|
||||||
// <Route path={`${url}/favourite-items`} exact component={FavouriteItems} />
|
<Route path={`${url}/favourite-items`} exact component={FavouriteItems} />
|
||||||
|
|
||||||
// {/*Redirect*/}
|
{/*Redirect*/}
|
||||||
// <Redirect to="/errors/404" />
|
<Redirect to="/errors/404" />
|
||||||
// </Switch>
|
</Switch>
|
||||||
// );
|
);
|
||||||
|
|
||||||
const DashboardRoutes = () => (
|
const DashboardRoutes = () => (
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/friends" component={JKPeople} />
|
<Route path="/feed" exact component={Feed} />
|
||||||
|
|
||||||
{/* <Route path="/feed" exact component={Feed} /> */}
|
|
||||||
{/*Pages*/}
|
{/*Pages*/}
|
||||||
{/* <Route path="/pages/activity" exact component={Activity} />
|
<Route path="/pages/activity" exact component={Activity} />
|
||||||
<Route path="/pages/associations" exact component={Associations} />
|
<Route path="/pages/associations" exact component={Associations} />
|
||||||
<Route path="/pages/billing" exact component={Billing} />
|
<Route path="/pages/billing" exact component={Billing} />
|
||||||
<Route path="/pages/customer-details" exact component={CustomerDetails} />
|
<Route path="/pages/customer-details" exact component={CustomerDetails} />
|
||||||
|
|
@ -163,30 +158,30 @@ const DashboardRoutes = () => (
|
||||||
<Route path="/pages/pricing-alt" exact component={PricingAlt} />
|
<Route path="/pages/pricing-alt" exact component={PricingAlt} />
|
||||||
<Route path="/pages/profile" exact component={Profile} />
|
<Route path="/pages/profile" exact component={Profile} />
|
||||||
<Route path="/pages/settings" exact component={Settings} />
|
<Route path="/pages/settings" exact component={Settings} />
|
||||||
<Route path="/pages/starter" exact component={Starter} /> */}
|
<Route path="/pages/starter" exact component={Starter} />
|
||||||
{/*chat*/}
|
{/*chat*/}
|
||||||
{/* <Route path="/chat" exact component={Chat} /> */}
|
<Route path="/chat" exact component={Chat} />
|
||||||
{/*calendar*/}
|
{/*calendar*/}
|
||||||
{/* <Route path="/calendar" exact component={Calendar} /> */}
|
<Route path="/calendar" exact component={Calendar} />
|
||||||
{/*kanban*/}
|
{/*kanban*/}
|
||||||
{/* <Route path="/kanban" exact component={Kanban} /> */}
|
<Route path="/kanban" exact component={Kanban} />
|
||||||
{/*E commerce*/}
|
{/*E commerce*/}
|
||||||
{/* <Route path="/e-commerce" component={ProductRoutes} /> */}
|
<Route path="/e-commerce" component={ProductRoutes} />
|
||||||
|
|
||||||
{/*Email*/}
|
{/*Email*/}
|
||||||
{/* <Route path="/email" component={InboxRoutes} /> */}
|
<Route path="/email" component={InboxRoutes} />
|
||||||
|
|
||||||
{/*widgets*/}
|
{/*widgets*/}
|
||||||
{/* <Route path="/widgets" component={Widgets} /> */}
|
<Route path="/widgets" component={Widgets} />
|
||||||
|
|
||||||
{/*Documentation*/}
|
{/*Documentation*/}
|
||||||
{/* <Route path="/documentation" exact component={GettingStarted} /> */}
|
<Route path="/documentation" exact component={GettingStarted} />
|
||||||
|
|
||||||
{/*Changelog*/}
|
{/*Changelog*/}
|
||||||
{/* <Route path="/changelog" exact component={ChangeLog} /> */}
|
<Route path="/changelog" exact component={ChangeLog} />
|
||||||
|
|
||||||
{/*Components*/}
|
{/*Components*/}
|
||||||
{/* <Route path="/components/alerts" exact component={Alerts} />
|
<Route path="/components/alerts" exact component={Alerts} />
|
||||||
<Route path="/components/autocomplete" exact component={AutocompleteExample} />
|
<Route path="/components/autocomplete" exact component={AutocompleteExample} />
|
||||||
<Route path="/components/accordions" exact component={FalconAccordions} />
|
<Route path="/components/accordions" exact component={FalconAccordions} />
|
||||||
<Route path="/components/avatar" exact component={Avatar} />
|
<Route path="/components/avatar" exact component={Avatar} />
|
||||||
|
|
@ -215,10 +210,10 @@ const DashboardRoutes = () => (
|
||||||
<Route path="/components/tables" exact component={Tables} />
|
<Route path="/components/tables" exact component={Tables} />
|
||||||
<Route path="/components/tooltips" exact component={Tooltips} />
|
<Route path="/components/tooltips" exact component={Tooltips} />
|
||||||
<Route path="/components/spinners" exact component={Spinners} />
|
<Route path="/components/spinners" exact component={Spinners} />
|
||||||
<Route path="/components/carousel" exact component={Carousel} /> */}
|
<Route path="/components/carousel" exact component={Carousel} />
|
||||||
|
|
||||||
{/*Utilities*/}
|
{/*Utilities*/}
|
||||||
{/* <Route path="/utilities/borders" exact component={Borders} />
|
<Route path="/utilities/borders" exact component={Borders} />
|
||||||
<Route path="/utilities/clearfix" exact component={Clearfix} />
|
<Route path="/utilities/clearfix" exact component={Clearfix} />
|
||||||
<Route path="/utilities/closeIcon" exact component={CloseIcon} />
|
<Route path="/utilities/closeIcon" exact component={CloseIcon} />
|
||||||
<Route path="/utilities/colors" exact component={Colors} />
|
<Route path="/utilities/colors" exact component={Colors} />
|
||||||
|
|
@ -232,10 +227,10 @@ const DashboardRoutes = () => (
|
||||||
<Route path="/utilities/stretchedLink" exact component={StretchedLink} />
|
<Route path="/utilities/stretchedLink" exact component={StretchedLink} />
|
||||||
<Route path="/utilities/typography" exact component={Typography} />
|
<Route path="/utilities/typography" exact component={Typography} />
|
||||||
<Route path="/utilities/verticalAlign" exact component={VerticalAlign} />
|
<Route path="/utilities/verticalAlign" exact component={VerticalAlign} />
|
||||||
<Route path="/utilities/visibility" exact component={Visibility} /> */}
|
<Route path="/utilities/visibility" exact component={Visibility} />
|
||||||
|
|
||||||
{/*Plugins*/}
|
{/*Plugins*/}
|
||||||
{/* <Route path="/plugins/calendar-example" exact component={CalendarExample} />
|
<Route path="/plugins/calendar-example" exact component={CalendarExample} />
|
||||||
<Route path="/plugins/bulk-select" exact component={BulkSelect} />
|
<Route path="/plugins/bulk-select" exact component={BulkSelect} />
|
||||||
<Route path="/plugins/typed" exact component={Typed} />
|
<Route path="/plugins/typed" exact component={Typed} />
|
||||||
<Route path="/plugins/image-lightbox" exact component={ImageLightbox} />
|
<Route path="/plugins/image-lightbox" exact component={ImageLightbox} />
|
||||||
|
|
@ -260,12 +255,11 @@ const DashboardRoutes = () => (
|
||||||
<Route path="/plugins/code-highlight" exact component={CodeHighlightDoc} />
|
<Route path="/plugins/code-highlight" exact component={CodeHighlightDoc} />
|
||||||
<Route path="/plugins/emoji-mart" exact component={EmojiMart} />
|
<Route path="/plugins/emoji-mart" exact component={EmojiMart} />
|
||||||
<Route path="/plugins/react-bootstrap-table2" exact component={ReactBootstrapTable2} />
|
<Route path="/plugins/react-bootstrap-table2" exact component={ReactBootstrapTable2} />
|
||||||
<Route path="/plugins/react-beautiful-dnd" exact component={ReactBeautifulDnD} /> */}
|
<Route path="/plugins/react-beautiful-dnd" exact component={ReactBeautifulDnD} />
|
||||||
|
|
||||||
{/*Redirect*/}
|
{/*Redirect*/}
|
||||||
<Redirect to="/errors/404" />
|
<Redirect to="/errors/404" />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
export default DashboardRoutes;
|
export default DashboardRoutes;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Route, Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
import JKDashboardLoadingIndicator from '../components/dashboard/JKDashboardLoadingIndicator';
|
||||||
|
import JKLoginRequest from '../components/auth/JKLoginRequest';
|
||||||
|
import JKDashboard from '../components/dashboard/JKDashboard';
|
||||||
|
|
||||||
|
import { useAuth } from '../context/AuthContext';
|
||||||
|
import { getCurrentUser } from '../helpers/rest';
|
||||||
|
|
||||||
|
const AUTH_STAGES = {
|
||||||
|
loading: 1,
|
||||||
|
authenticated: 2,
|
||||||
|
unauthenticated: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const JKDashboardLayout = ({ location }) => {
|
||||||
|
|
||||||
|
const { setCurrentUser } = useAuth();
|
||||||
|
const [stage, setStage] = useState(AUTH_STAGES['loading']);
|
||||||
|
|
||||||
|
const fetchCurrentUser = () => {
|
||||||
|
getCurrentUser()
|
||||||
|
.then(resp => {
|
||||||
|
if (resp.ok) {
|
||||||
|
return resp.json();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(user => {
|
||||||
|
setCurrentUser(user);
|
||||||
|
window.currentUser = user;
|
||||||
|
setStage(AUTH_STAGES['authenticated']);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
setStage(AUTH_STAGES['unauthenticated']);
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchCurrentUser();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
switch (stage) {
|
||||||
|
case AUTH_STAGES['authenticated']:
|
||||||
|
return <JKDashboard />;
|
||||||
|
case AUTH_STAGES['unauthenticated']:
|
||||||
|
return <JKLoginRequest />;
|
||||||
|
default:
|
||||||
|
return <JKDashboardLoadingIndicator />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const ProtectedRoute = ({ component: Component, ...rest }) => {
|
||||||
|
const { currentUser } = useAuth();
|
||||||
|
return (
|
||||||
|
// Show the component only when the user is logged in
|
||||||
|
// Otherwise, redirect the user to /login page
|
||||||
|
<Route
|
||||||
|
{...rest}
|
||||||
|
render={props =>
|
||||||
|
currentUser ? <Component {...props} /> : <Redirect to={{ pathname: '/authentication/basic/start' }} />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
JKDashboardLayout.propTypes = { location: PropTypes.object.isRequired };
|
||||||
|
|
||||||
|
export default JKDashboardLayout;
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||||
|
import JKPeople from '../components/page/JKPeople';
|
||||||
|
|
||||||
|
const JKDashboardRoutes = () => (
|
||||||
|
|
||||||
|
<Switch>
|
||||||
|
<Route path="/friends" component={JKPeople} />
|
||||||
|
{/*Redirect*/}
|
||||||
|
<Redirect to="/errors/404" />
|
||||||
|
</Switch>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
export default JKDashboardRoutes;
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||||
|
import { toast, ToastContainer } from 'react-toastify';
|
||||||
|
import { CloseButton, Fade } from '../components/common/Toast';
|
||||||
|
|
||||||
|
import JKDashboardLayout from './JKDashboardLayout';
|
||||||
|
import ErrorLayout from './ErrorLayout';
|
||||||
|
|
||||||
|
|
||||||
|
const JKLayout = () => {
|
||||||
|
return (
|
||||||
|
<Router fallback={<span />}>
|
||||||
|
<Switch>
|
||||||
|
<Route path="/errors" component={ErrorLayout} />
|
||||||
|
<Route component={JKDashboardLayout} />
|
||||||
|
</Switch>
|
||||||
|
<ToastContainer transition={Fade} closeButton={<CloseButton />} position={toast.POSITION.BOTTOM_LEFT} />
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JKLayout;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||||
import { toast, ToastContainer } from 'react-toastify';
|
import { toast, ToastContainer } from 'react-toastify';
|
||||||
import { CloseButton, Fade } from '../components/common/Toast';
|
import { CloseButton, Fade } from '../components/common/Toast';
|
||||||
|
|
@ -6,42 +6,33 @@ import { CloseButton, Fade } from '../components/common/Toast';
|
||||||
import DashboardLayout from './DashboardLayout';
|
import DashboardLayout from './DashboardLayout';
|
||||||
import ErrorLayout from './ErrorLayout';
|
import ErrorLayout from './ErrorLayout';
|
||||||
|
|
||||||
|
import loadable from '@loadable/component';
|
||||||
|
const AuthBasicLayout = loadable(() => import('./AuthBasicLayout'));
|
||||||
// import loadable from '@loadable/component';
|
const Landing = loadable(() => import('../components/landing/Landing'));
|
||||||
|
const WizardLayout = loadable(() => import('../components/auth/wizard/WizardLayout'));
|
||||||
//const AuthBasicLayout = loadable(() => import('./AuthBasicLayout'));
|
const AuthCardRoutes = loadable(() => import('../components/auth/card/AuthCardRoutes'));
|
||||||
//const Landing = loadable(() => import('../components/landing/Landing'));
|
const AuthSplitRoutes = loadable(() => import('../components/auth/split/AuthSplitRoutes'));
|
||||||
//const WizardLayout = loadable(() => import('../components/auth/wizard/WizardLayout'));
|
|
||||||
//const AuthCardRoutes = loadable(() => import('../components/auth/card/AuthCardRoutes'));
|
|
||||||
//const AuthSplitRoutes = loadable(() => import('../components/auth/split/AuthSplitRoutes'));
|
|
||||||
|
|
||||||
const Layout = () => {
|
const Layout = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//AuthBasicLayout.preload();
|
AuthBasicLayout.preload();
|
||||||
//Landing.preload();
|
Landing.preload();
|
||||||
//WizardLayout.preload();
|
WizardLayout.preload();
|
||||||
//AuthCardRoutes.preload();
|
AuthCardRoutes.preload();
|
||||||
//AuthSplitRoutes.preload();
|
AuthSplitRoutes.preload();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router fallback={<span />}>
|
<Router fallback={<span />}>
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* <Route path="/friends" exact component={PeopleList} /> */}
|
<Route path="/landing" exact component={Landing} />
|
||||||
{/* <Route path="/landing" exact component={Landing} /> */}
|
<Route path="/authentication/card" component={AuthCardRoutes} />
|
||||||
{/* <Route path="/authentication/card" component={AuthCardRoutes} />
|
<Route path="/authentication/split" component={AuthSplitRoutes} />
|
||||||
<Route path="/authentication/split" component={AuthSplitRoutes} />
|
<Route path="/authentication/wizard" component={WizardLayout} />
|
||||||
<Route path="/authentication/wizard" component={WizardLayout} /> */}
|
|
||||||
<Route path="/errors" component={ErrorLayout} />
|
<Route path="/errors" component={ErrorLayout} />
|
||||||
{/* <Route path="/authentication/basic" component={AuthBasicLayout} /> */}
|
<Route path="/authentication/basic" component={AuthBasicLayout} />
|
||||||
|
|
||||||
<Route component={DashboardLayout} />
|
<Route component={DashboardLayout} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
<ToastContainer transition={Fade} closeButton={<CloseButton />} position={toast.POSITION.BOTTOM_LEFT} />
|
<ToastContainer transition={Fade} closeButton={<CloseButton />} position={toast.POSITION.BOTTOM_LEFT} />
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,37 +4,33 @@ import { getTextMessages, createTextMessage } from '../../helpers/rest';
|
||||||
const initialState = {
|
const initialState = {
|
||||||
messages: [],
|
messages: [],
|
||||||
status: 'idel',
|
status: 'idel',
|
||||||
error: null,
|
error: null
|
||||||
offset: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const [offset, setOffset] = useState(0);
|
|
||||||
// const LIMIT = 20;
|
|
||||||
|
|
||||||
export const fetchMessagesByReceiverId = createAsyncThunk(
|
export const fetchMessagesByReceiverId = createAsyncThunk(
|
||||||
'textMessage/fetchMessagesByReceiverId',
|
'textMessage/fetchMessagesByReceiverId',
|
||||||
async (userId, thunkAPI) => {
|
async (options, thunkAPI) => {
|
||||||
|
const { userId, offset, limit } = options
|
||||||
const response = await getTextMessages({
|
const response = await getTextMessages({
|
||||||
target_user_id: userId
|
target_user_id: userId,
|
||||||
// offset: offset,
|
offset: offset,
|
||||||
// limit: LIMIT
|
limit: limit
|
||||||
})
|
})
|
||||||
return response.json()
|
return response.json()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const resturectureTextMessage = (args) => {
|
export const resturectureTextMessage = (args) => {
|
||||||
const { payload, sent } = args
|
const { message, sent } = args
|
||||||
//console.log(payload);
|
const messageId = message.id ? message.id : nanoid()
|
||||||
const messageId = payload.id ? payload.id : nanoid()
|
const createdAt = message.created_at ? message.created_at : new Date().toISOString()
|
||||||
const createdAt = payload.created_at ? payload.created_at : new Date().toISOString()
|
|
||||||
return {
|
return {
|
||||||
id: messageId,
|
id: messageId,
|
||||||
message: payload.message,
|
message: message.message,
|
||||||
senderId: payload.source_user_id,
|
senderId: message.source_user_id,
|
||||||
senderName: payload.source_user['first_name'],
|
senderName: message.source_user['name'],
|
||||||
receiverId: payload.target_user_id,
|
receiverId: message.target_user_id,
|
||||||
receiverName: payload.target_user['first_name'],
|
receiverName: message.target_user['name'],
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
sent: sent
|
sent: sent
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +40,7 @@ export const postNewMessage = createAsyncThunk(
|
||||||
'textMessage/postNewMessage',
|
'textMessage/postNewMessage',
|
||||||
async (message, thunkAPI) => {
|
async (message, thunkAPI) => {
|
||||||
const response = await createTextMessage(message)
|
const response = await createTextMessage(message)
|
||||||
return { status: response.status, payload: message }
|
return response.json()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -65,8 +61,11 @@ export const textMessageSlice = createSlice({
|
||||||
})
|
})
|
||||||
.addCase(fetchMessagesByReceiverId.fulfilled, (state, action) => {
|
.addCase(fetchMessagesByReceiverId.fulfilled, (state, action) => {
|
||||||
state.status = 'succeeded'
|
state.status = 'succeeded'
|
||||||
console.log(action.payload);
|
const msgs = action.payload.map(message => resturectureTextMessage({ message, sent: true }))
|
||||||
state.messages = action.payload.map(message => resturectureTextMessage({ payload: message, sent: true }))
|
const mergedMsgs = [...state.messages, ...msgs]
|
||||||
|
const unique = [];
|
||||||
|
mergedMsgs.map(x => unique.filter(a => a.id == x.id).length > 0 ? null : unique.push(x));
|
||||||
|
state.messages = unique
|
||||||
})
|
})
|
||||||
.addCase(fetchMessagesByReceiverId.rejected, (state, action) => {
|
.addCase(fetchMessagesByReceiverId.rejected, (state, action) => {
|
||||||
state.status = 'failed'
|
state.status = 'failed'
|
||||||
|
|
@ -74,6 +73,7 @@ export const textMessageSlice = createSlice({
|
||||||
})
|
})
|
||||||
.addCase(postNewMessage.fulfilled, (state, action) => {
|
.addCase(postNewMessage.fulfilled, (state, action) => {
|
||||||
console.log("postNewMessage fullfilled", action.payload);
|
console.log("postNewMessage fullfilled", action.payload);
|
||||||
|
state.messages.push(resturectureTextMessage({ message: action.payload, sent: true }))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ target
|
||||||
*~
|
*~
|
||||||
bin
|
bin
|
||||||
.bundle
|
.bundle
|
||||||
|
.ruby-version
|
||||||
|
|
|
||||||
|
|
@ -631,6 +631,7 @@ message TextMessage {
|
||||||
optional string notification_id = 5;
|
optional string notification_id = 5;
|
||||||
optional string created_at = 6;
|
optional string created_at = 6;
|
||||||
optional bool clipped_msg = 7;
|
optional bool clipped_msg = 7;
|
||||||
|
optional string text_message_id = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ChatMessage {
|
message ChatMessage {
|
||||||
|
|
|
||||||
|
|
@ -985,7 +985,7 @@ module JamRuby
|
||||||
end
|
end
|
||||||
|
|
||||||
# creates the general purpose text message
|
# creates the general purpose text message
|
||||||
def text_message(receiver_id, sender_photo_url, sender_name, sender_id, msg, clipped_msg, notification_id, created_at)
|
def text_message(receiver_id, sender_photo_url, sender_name, sender_id, msg, clipped_msg, notification_id, created_at, text_message_id)
|
||||||
text_message = Jampb::TextMessage.new(
|
text_message = Jampb::TextMessage.new(
|
||||||
:photo_url => sender_photo_url,
|
:photo_url => sender_photo_url,
|
||||||
:sender_name => sender_name,
|
:sender_name => sender_name,
|
||||||
|
|
@ -993,7 +993,8 @@ module JamRuby
|
||||||
:msg => msg,
|
:msg => msg,
|
||||||
:clipped_msg => clipped_msg,
|
:clipped_msg => clipped_msg,
|
||||||
:notification_id => notification_id,
|
:notification_id => notification_id,
|
||||||
:created_at => created_at
|
:created_at => created_at,
|
||||||
|
text_message_id: text_message_id
|
||||||
)
|
)
|
||||||
|
|
||||||
Jampb::ClientMessage.new(
|
Jampb::ClientMessage.new(
|
||||||
|
|
|
||||||
|
|
@ -1522,7 +1522,7 @@ module JamRuby
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_text_message(message, sender, receiver)
|
def send_text_message(message, sender, receiver, text_message_id)
|
||||||
|
|
||||||
notification = Notification.new
|
notification = Notification.new
|
||||||
notification.description = NotificationTypes::TEXT_MESSAGE
|
notification.description = NotificationTypes::TEXT_MESSAGE
|
||||||
|
|
@ -1542,7 +1542,9 @@ module JamRuby
|
||||||
truncated_msg,
|
truncated_msg,
|
||||||
msg_is_clipped,
|
msg_is_clipped,
|
||||||
notification.id,
|
notification.id,
|
||||||
notification.created_date)
|
notification.created_date,
|
||||||
|
text_message_id
|
||||||
|
)
|
||||||
logger.debug('-' * 30)
|
logger.debug('-' * 30)
|
||||||
logger.debug(msg)
|
logger.debug(msg)
|
||||||
logger.debug('-' * 30)
|
logger.debug('-' * 30)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ module JamRuby
|
||||||
tm.save
|
tm.save
|
||||||
|
|
||||||
# send notification
|
# send notification
|
||||||
@notification = Notification.send_text_message(sanitized_text, User.find(source_user_id), User.find(target_user_id))
|
@notification = Notification.send_text_message(sanitized_text, User.find(source_user_id), User.find(target_user_id), tm.id)
|
||||||
|
|
||||||
tm
|
tm
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ class ApiTextMessagesController < ApiController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@text_message = TextMessage.create(params[:message], params[:target_user_id], current_user.id)
|
@text_message = TextMessage.create(params[:message], params[:target_user_id], current_user.id)
|
||||||
respond_with_model(@text_message, new: true)
|
#respond_with_model(@text_message, new: true)
|
||||||
|
respond_with @text_message
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
object @text_message
|
||||||
|
|
||||||
|
attributes :id, :source_user_id, :target_user_id, :message, :created_at
|
||||||
|
|
||||||
|
child :source_user => :source_user do |msg|
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
||||||
|
child :target_user => :target_user do |msg|
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
@ -3,9 +3,9 @@ collection @text_messages
|
||||||
attributes :id, :source_user_id, :target_user_id, :message, :created_at
|
attributes :id, :source_user_id, :target_user_id, :message, :created_at
|
||||||
|
|
||||||
child :source_user => :source_user do |msg|
|
child :source_user => :source_user do |msg|
|
||||||
attributes :id, :name, :first_name
|
attributes :id, :name
|
||||||
end
|
end
|
||||||
|
|
||||||
child :target_user => :target_user do |msg|
|
child :target_user => :target_user do |msg|
|
||||||
attributes :id, :name, :first_name
|
attributes :id, :name
|
||||||
end
|
end
|
||||||
Loading…
Reference in New Issue