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",
|
||||
"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": {
|
||||
"version": "4.2.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"redux-thunk": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.2",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.5.1",
|
||||
"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/timegrid": "^5.3.1",
|
||||
"@loadable/component": "^5.13.2",
|
||||
"@reduxjs/toolkit": "^1.6.1",
|
||||
"attr-accept": "^2.2.2",
|
||||
"bootstrap": "^4.5.3",
|
||||
"chart.js": "^2.9.3",
|
||||
|
|
|
|||
|
|
@ -1,63 +1,16 @@
|
|||
import React from 'react';
|
||||
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-datetime/css/react-datetime.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 = () => {
|
||||
|
||||
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 (
|
||||
<Router basename={process.env.PUBLIC_URL}>
|
||||
<Layout />
|
||||
<JKLayout />
|
||||
</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(
|
||||
<h1>Dashboard</h1>
|
||||
)
|
||||
import NavbarTop from '../navbar/NavbarTop';
|
||||
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;
|
||||
|
|
@ -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 { 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 TimeAgo from 'react-timeago';
|
||||
import JKProfileAvatar from './JKProfileAvatar';
|
||||
|
|
@ -11,31 +11,40 @@ const JKMessageModal = props => {
|
|||
const { show, setShow, user } = props;
|
||||
const LIMIT = 20;
|
||||
|
||||
const [fetching, setFetching] = useState(false);
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [newMessage, setNewMessage] = useState('');
|
||||
const [messagesArrived, setMessagesArrived] = useState(false);
|
||||
|
||||
const toggle = () => setShow(!show);
|
||||
|
||||
const { currentUser } = useAuth();
|
||||
const dispatch = useDispatch();
|
||||
const scrollbar = useRef();
|
||||
const messageTextBox = useRef();
|
||||
const scrolledToBottom = useRef(false);
|
||||
|
||||
const messages = useSelector(state =>
|
||||
state.textMessage.messages
|
||||
.filter(
|
||||
message =>
|
||||
(message.senderId === user.id && message.receiverId === currentUser.id) ||
|
||||
(message.senderId === currentUser.id && message.receiverId === user.id)
|
||||
(message.senderId === user.id && message.receiverId === window.currentUser.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 () => {
|
||||
try {
|
||||
await dispatch(fetchMessagesByReceiverId(user.id)).unwrap();
|
||||
scrollbar.current.scrollToBottom();
|
||||
const options = { userId: user.id, offset: offset, limit: LIMIT };
|
||||
setFetching(true);
|
||||
await dispatch(fetchMessagesByReceiverId(options)).unwrap();
|
||||
} catch (err) {
|
||||
console.log('ERROR', err);
|
||||
} finally {
|
||||
setFetching(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -48,37 +57,102 @@ const JKMessageModal = props => {
|
|||
};
|
||||
setNewMessage('');
|
||||
await dispatch(postNewMessage(msgData)).unwrap();
|
||||
fetchMessages();
|
||||
} catch (err) {
|
||||
console.log('addNewMessage error', err);
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnKeyPress = (event) => {
|
||||
//console.log('event', event.key);
|
||||
if(event.key === 'Enter' || event.key === "NumpadEnter"){
|
||||
sendMessage()
|
||||
const handleOnKeyPress = event => {
|
||||
if (event.key === 'Enter' || event.key === 'NumpadEnter') {
|
||||
event.preventDefault();
|
||||
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(() => {
|
||||
if (show) {
|
||||
//console.log('JKMessageModal User', user.id);
|
||||
if (show && messages.length === 0) {
|
||||
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 (
|
||||
<>
|
||||
<Modal isOpen={show} toggle={toggle}>
|
||||
<ModalHeader toggle={toggle}>Conversation with {user.name}</ModalHeader>
|
||||
<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) => (
|
||||
<div className="d-flex mb-3 mr-1" key={message.id}>
|
||||
<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 className="d-inline-block">
|
||||
<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 === 'hour') return `${value} ${value === 1 ? 'hour' : 'hours'} 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>
|
||||
|
|
@ -103,9 +180,24 @@ const JKMessageModal = props => {
|
|||
</div>
|
||||
))}
|
||||
</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>
|
||||
<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>
|
||||
</Row>
|
||||
</ModalBody>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import JKProfileGenres from './JKProfileGenres';
|
|||
import JKProfilePerformanceSamples from './JKProfilePerformanceSamples';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import JKConnectButton from './JKConnectButton';
|
||||
import JKMessageButton from './JKMessageButton';
|
||||
import JKLatencyBadge from './JKLatencyBadge';
|
||||
import JKLastActiveAgo from './JKLastActiveAgo';
|
||||
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
|
||||
</button>
|
||||
</button> */}
|
||||
|
||||
<JKMessageButton currentUser={currentUser} user={user}>
|
||||
<FontAwesomeIcon icon="comments" transform="shrink-4 down-1" className="mr-1" /> Send Message
|
||||
</JKMessageButton>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect } from 'react';
|
||||
const useScript = (src, onloadHandler) => {
|
||||
const useScript = (src, onloadHandler = () => {}) => {
|
||||
useEffect(() => {
|
||||
const script = document.createElement('script');
|
||||
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 { Route, Switch, Redirect, NavLink } from 'react-router-dom';
|
||||
import { Card, CardBody, Row, Col, Button } from 'reactstrap';
|
||||
import Logo from '../components/navbar/Logo';
|
||||
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 { Route, Switch } from 'react-router-dom';
|
||||
import Dashboard from '../components/dashboard/Dashboard';
|
||||
import DashboardAlt from '../components/dashboard-alt/DashboardAlt';
|
||||
import NavbarTop from '../components/navbar/NavbarTop';
|
||||
import NavbarVertical from '../components/navbar/NavbarVertical';
|
||||
import Footer from '../components/footer/Footer';
|
||||
import loadable from '@loadable/component';
|
||||
import AppContext from '../context/Context';
|
||||
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 { useAuth } from '../context/AuthContext';
|
||||
import { getCurrentUser } from '../helpers/rest';
|
||||
|
||||
|
||||
const AUTH_STAGES = {
|
||||
loading: 1,
|
||||
authenticated: 2,
|
||||
unauthenticated: 3
|
||||
};
|
||||
|
||||
const DashboardRoutes = loadable(() => import('./DashboardRoutes'));
|
||||
|
||||
const DashboardLayout = ({ location }) => {
|
||||
const { isFluid, isVertical, navbarStyle } = useContext(AppContext);
|
||||
|
||||
const { currentUser, setCurrentUser } = useAuth();
|
||||
|
||||
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();
|
||||
}, []);
|
||||
const isKanban = getPageName('kanban');
|
||||
|
||||
useEffect(() => {
|
||||
DashboardRoutes.preload();
|
||||
|
|
@ -65,84 +27,22 @@ const DashboardLayout = ({ location }) => {
|
|||
window.scrollTo(0, 0);
|
||||
}, [location.pathname]);
|
||||
|
||||
switch (stage) {
|
||||
case AUTH_STAGES['authenticated']:
|
||||
return <DashboardSection />;
|
||||
case AUTH_STAGES['unauthenticated']:
|
||||
return <LoginRequestSection />;
|
||||
default:
|
||||
return <DashboardLoadingIndicator />;
|
||||
}
|
||||
};
|
||||
|
||||
const DashboardLoadingIndicator = () => {
|
||||
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'}>
|
||||
{isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />}
|
||||
<ProductProvider>
|
||||
<div className="content">
|
||||
<NavbarTop />
|
||||
<Switch>
|
||||
{/* <Route path="/" exact component={Dashboard} /> */}
|
||||
{/* <Route path="/dashboard-alt" exact component={DashboardAlt} /> */}
|
||||
<Route path="/" exact component={JKDashboard} />
|
||||
<Route path="/" exact component={Dashboard} />
|
||||
<Route path="/dashboard-alt" exact component={DashboardAlt} />
|
||||
<DashboardRoutes />
|
||||
</Switch>
|
||||
{!isKanban && <Footer />}
|
||||
</div>
|
||||
{/* <SidePanelModal path={location.pathname} /> */}
|
||||
<SidePanelModal path={location.pathname} />
|
||||
</ProductProvider>
|
||||
</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 { Redirect, Route, Switch } from 'react-router-dom';
|
||||
// import Alerts from '../components/bootstrap-components/Alerts';
|
||||
// import Avatar from '../components/bootstrap-components/Avatar';
|
||||
// import AutocompleteExample from '../components/bootstrap-components/AutocompleteExample';
|
||||
// import Backgrounds from '../components/bootstrap-components/Backgrounds';
|
||||
// import Badges from '../components/bootstrap-components/Badges';
|
||||
// import Breadcrumbs from '../components/bootstrap-components/Breadcrumb';
|
||||
// import Buttons from '../components/bootstrap-components/Buttons';
|
||||
// import Cards from '../components/bootstrap-components/Cards';
|
||||
// import Carousel from '../components/bootstrap-components/Carousel';
|
||||
// import Collapses from '../components/bootstrap-components/Collapses';
|
||||
// import Combo from '../components/bootstrap-components/Combo';
|
||||
// import CookieNotice from '../components/bootstrap-components/CookieNotice';
|
||||
// import Dropdowns from '../components/bootstrap-components/Dropdowns';
|
||||
// import FalconAccordions from '../components/bootstrap-components/FalconAccordions';
|
||||
// import Forms from '../components/bootstrap-components/Forms';
|
||||
// import ListGroups from '../components/bootstrap-components/ListGroups';
|
||||
// import Modals from '../components/bootstrap-components/Modals';
|
||||
// import Navbars from '../components/bootstrap-components/Navbars';
|
||||
// import NavBarTop from '../components/bootstrap-components/NavBarTop';
|
||||
// import Navs from '../components/bootstrap-components/Navs';
|
||||
// import PageHeaders from '../components/bootstrap-components/PageHeaders';
|
||||
// import Paginations from '../components/bootstrap-components/Paginations';
|
||||
// import Popovers from '../components/bootstrap-components/Popovers';
|
||||
// import ProgressBar from '../components/bootstrap-components/ProgressBar';
|
||||
// import Sidepanel from '../components/bootstrap-components/Sidepanel';
|
||||
// import Spinners from '../components/bootstrap-components/Spinners';
|
||||
// import Tables from '../components/bootstrap-components/Tables';
|
||||
// import Tabs from '../components/bootstrap-components/Tabs';
|
||||
// import Tooltips from '../components/bootstrap-components/Tooltips';
|
||||
// import VerticalNavbar from '../components/bootstrap-components/VerticalNavbar';
|
||||
// import Calendar from '../components/calendar/Calendar';
|
||||
// import ChangeLog from '../components/changelog/ChangeLog';
|
||||
// import Chat from '../components/chat/Chat';
|
||||
// import GettingStarted from '../components/documentation/GettingStarted';
|
||||
// import Checkout from '../components/e-commerce/Checkout';
|
||||
// import Customers from '../components/e-commerce/Customers';
|
||||
// import FavouriteItems from '../components/e-commerce/FavouriteItems';
|
||||
// import OrderDetails from '../components/e-commerce/OrderDetails';
|
||||
// import Orders from '../components/e-commerce/Orders';
|
||||
// import ProductDetails from '../components/e-commerce/ProductDetails';
|
||||
// import Products from '../components/e-commerce/Products';
|
||||
// import ShoppingCart from '../components/e-commerce/ShoppingCart';
|
||||
// import Compose from '../components/email/Compose';
|
||||
// import EmailDetail from '../components/email/EmailDetail';
|
||||
// import Inbox from '../components/email/Inbox';
|
||||
// import InboxProvider from '../components/email/inbox/InboxProvider';
|
||||
// import Starter from '../components/extra/Starter';
|
||||
// import Feed from '../components/feed/Feed';
|
||||
// import Kanban from '../components/kanban/Kanban';
|
||||
// import Activity from '../components/page/Activity';
|
||||
// import Associations from '../components/page/Associations';
|
||||
// import Billing from '../components/page/Billing';
|
||||
// import CustomerDetails from '../components/page/CustomerDetails';
|
||||
// import EventCreate from '../components/page/EventCreate';
|
||||
// import EventDetail from '../components/page/EventDetail';
|
||||
// import Events from '../components/page/Events';
|
||||
// import Faq from '../components/page/Faq';
|
||||
// import InvitePeople from '../components/page/InvitePeople';
|
||||
// import Invoice from '../components/page/Invoice';
|
||||
// import Notifications from '../components/page/Notifications';
|
||||
// import People from '../components/page/People';
|
||||
// import Settings from '../components/page/Settings';
|
||||
// import BulkSelect from '../components/plugins/BulkSelect';
|
||||
// import CalendarExample from '../components/plugins/CalendarExample';
|
||||
// import Chart from '../components/plugins/Chart';
|
||||
// import CodeHighlightDoc from '../components/plugins/CodeHighlightDoc';
|
||||
// import CountUpExample from '../components/plugins/Countup';
|
||||
// import DatetimeExample from '../components/plugins/Datetime';
|
||||
// import Dropzone from '../components/plugins/Dropzone';
|
||||
// import EchartMap from '../components/plugins/EchartMap';
|
||||
// import Echarts from '../components/plugins/Echarts';
|
||||
// import EmojiMart from '../components/plugins/EmojiMart';
|
||||
// import FontAwesome from '../components/plugins/FontAwesome';
|
||||
// import GoogleMapExample from '../components/plugins/GoogleMap';
|
||||
// import ImageLightbox from '../components/plugins/ImageLightbox';
|
||||
// import Leaflet from '../components/plugins/Leaflet';
|
||||
// import Lottie from '../components/plugins/Lottie';
|
||||
// import Plyr from '../components/plugins/Plyr';
|
||||
// import ProgressBarJs from '../components/plugins/ProgressBarJs';
|
||||
// import QuillEditorExample from '../components/plugins/Quill';
|
||||
// import ReactBeautifulDnD from '../components/plugins/ReactBeautifulDnD';
|
||||
// import ReactBootstrapTable2 from '../components/plugins/ReactBootstrapTable2';
|
||||
// import ReactHookFrom from '../components/plugins/ReactHookFrom';
|
||||
// import Scrollbar from '../components/plugins/Scrollbar';
|
||||
// import Select from '../components/plugins/Select';
|
||||
// import SlickCarousel from '../components/plugins/SlickCarousel';
|
||||
// import Toastify from '../components/plugins/Toastify';
|
||||
// import Typed from '../components/plugins/Typed';
|
||||
// import Pricing from '../components/pricing/Pricing';
|
||||
// import PricingAlt from '../components/pricing/PricingAlt';
|
||||
// import Profile from '../components/profile/Profile';
|
||||
// import Borders from '../components/utilities/Borders';
|
||||
// import Clearfix from '../components/utilities/Clearfix';
|
||||
// import CloseIcon from '../components/utilities/CloseIcon';
|
||||
// import Colors from '../components/utilities/Colors';
|
||||
// import Display from '../components/utilities/Display';
|
||||
// import Embed from '../components/utilities/Embed';
|
||||
// import Figures from '../components/utilities/Figures';
|
||||
// import Flex from '../components/utilities/Flex';
|
||||
// import Grid from '../components/utilities/Grid';
|
||||
// import Sizing from '../components/utilities/Sizing';
|
||||
// import Spacing from '../components/utilities/Spacing';
|
||||
// import StretchedLink from '../components/utilities/StretchedLink';
|
||||
// import Typography from '../components/utilities/Typography';
|
||||
// import VerticalAlign from '../components/utilities/VerticalAlign';
|
||||
// import Visibility from '../components/utilities/Visibility';
|
||||
// import Widgets from '../components/widgets/Widgets';
|
||||
import JKPeople from '../components/page/JKPeople';
|
||||
import Alerts from '../components/bootstrap-components/Alerts';
|
||||
import Avatar from '../components/bootstrap-components/Avatar';
|
||||
import AutocompleteExample from '../components/bootstrap-components/AutocompleteExample';
|
||||
import Backgrounds from '../components/bootstrap-components/Backgrounds';
|
||||
import Badges from '../components/bootstrap-components/Badges';
|
||||
import Breadcrumbs from '../components/bootstrap-components/Breadcrumb';
|
||||
import Buttons from '../components/bootstrap-components/Buttons';
|
||||
import Cards from '../components/bootstrap-components/Cards';
|
||||
import Carousel from '../components/bootstrap-components/Carousel';
|
||||
import Collapses from '../components/bootstrap-components/Collapses';
|
||||
import Combo from '../components/bootstrap-components/Combo';
|
||||
import CookieNotice from '../components/bootstrap-components/CookieNotice';
|
||||
import Dropdowns from '../components/bootstrap-components/Dropdowns';
|
||||
import FalconAccordions from '../components/bootstrap-components/FalconAccordions';
|
||||
import Forms from '../components/bootstrap-components/Forms';
|
||||
import ListGroups from '../components/bootstrap-components/ListGroups';
|
||||
import Modals from '../components/bootstrap-components/Modals';
|
||||
import Navbars from '../components/bootstrap-components/Navbars';
|
||||
import NavBarTop from '../components/bootstrap-components/NavBarTop';
|
||||
import Navs from '../components/bootstrap-components/Navs';
|
||||
import PageHeaders from '../components/bootstrap-components/PageHeaders';
|
||||
import Paginations from '../components/bootstrap-components/Paginations';
|
||||
import Popovers from '../components/bootstrap-components/Popovers';
|
||||
import ProgressBar from '../components/bootstrap-components/ProgressBar';
|
||||
import Sidepanel from '../components/bootstrap-components/Sidepanel';
|
||||
import Spinners from '../components/bootstrap-components/Spinners';
|
||||
import Tables from '../components/bootstrap-components/Tables';
|
||||
import Tabs from '../components/bootstrap-components/Tabs';
|
||||
import Tooltips from '../components/bootstrap-components/Tooltips';
|
||||
import VerticalNavbar from '../components/bootstrap-components/VerticalNavbar';
|
||||
import Calendar from '../components/calendar/Calendar';
|
||||
import ChangeLog from '../components/changelog/ChangeLog';
|
||||
import Chat from '../components/chat/Chat';
|
||||
import GettingStarted from '../components/documentation/GettingStarted';
|
||||
import Checkout from '../components/e-commerce/Checkout';
|
||||
import Customers from '../components/e-commerce/Customers';
|
||||
import FavouriteItems from '../components/e-commerce/FavouriteItems';
|
||||
import OrderDetails from '../components/e-commerce/OrderDetails';
|
||||
import Orders from '../components/e-commerce/Orders';
|
||||
import ProductDetails from '../components/e-commerce/ProductDetails';
|
||||
import Products from '../components/e-commerce/Products';
|
||||
import ShoppingCart from '../components/e-commerce/ShoppingCart';
|
||||
import Compose from '../components/email/Compose';
|
||||
import EmailDetail from '../components/email/EmailDetail';
|
||||
import Inbox from '../components/email/Inbox';
|
||||
import InboxProvider from '../components/email/inbox/InboxProvider';
|
||||
import Starter from '../components/extra/Starter';
|
||||
import Feed from '../components/feed/Feed';
|
||||
import Kanban from '../components/kanban/Kanban';
|
||||
import Activity from '../components/page/Activity';
|
||||
import Associations from '../components/page/Associations';
|
||||
import Billing from '../components/page/Billing';
|
||||
import CustomerDetails from '../components/page/CustomerDetails';
|
||||
import EventCreate from '../components/page/EventCreate';
|
||||
import EventDetail from '../components/page/EventDetail';
|
||||
import Events from '../components/page/Events';
|
||||
import Faq from '../components/page/Faq';
|
||||
import InvitePeople from '../components/page/InvitePeople';
|
||||
import Invoice from '../components/page/Invoice';
|
||||
import Notifications from '../components/page/Notifications';
|
||||
import People from '../components/page/People';
|
||||
import Settings from '../components/page/Settings';
|
||||
import BulkSelect from '../components/plugins/BulkSelect';
|
||||
import CalendarExample from '../components/plugins/CalendarExample';
|
||||
import Chart from '../components/plugins/Chart';
|
||||
import CodeHighlightDoc from '../components/plugins/CodeHighlightDoc';
|
||||
import CountUpExample from '../components/plugins/Countup';
|
||||
import DatetimeExample from '../components/plugins/Datetime';
|
||||
import Dropzone from '../components/plugins/Dropzone';
|
||||
import EchartMap from '../components/plugins/EchartMap';
|
||||
import Echarts from '../components/plugins/Echarts';
|
||||
import EmojiMart from '../components/plugins/EmojiMart';
|
||||
import FontAwesome from '../components/plugins/FontAwesome';
|
||||
import GoogleMapExample from '../components/plugins/GoogleMap';
|
||||
import ImageLightbox from '../components/plugins/ImageLightbox';
|
||||
import Leaflet from '../components/plugins/Leaflet';
|
||||
import Lottie from '../components/plugins/Lottie';
|
||||
import Plyr from '../components/plugins/Plyr';
|
||||
import ProgressBarJs from '../components/plugins/ProgressBarJs';
|
||||
import QuillEditorExample from '../components/plugins/Quill';
|
||||
import ReactBeautifulDnD from '../components/plugins/ReactBeautifulDnD';
|
||||
import ReactBootstrapTable2 from '../components/plugins/ReactBootstrapTable2';
|
||||
import ReactHookFrom from '../components/plugins/ReactHookFrom';
|
||||
import Scrollbar from '../components/plugins/Scrollbar';
|
||||
import Select from '../components/plugins/Select';
|
||||
import SlickCarousel from '../components/plugins/SlickCarousel';
|
||||
import Toastify from '../components/plugins/Toastify';
|
||||
import Typed from '../components/plugins/Typed';
|
||||
import Pricing from '../components/pricing/Pricing';
|
||||
import PricingAlt from '../components/pricing/PricingAlt';
|
||||
import Profile from '../components/profile/Profile';
|
||||
import Borders from '../components/utilities/Borders';
|
||||
import Clearfix from '../components/utilities/Clearfix';
|
||||
import CloseIcon from '../components/utilities/CloseIcon';
|
||||
import Colors from '../components/utilities/Colors';
|
||||
import Display from '../components/utilities/Display';
|
||||
import Embed from '../components/utilities/Embed';
|
||||
import Figures from '../components/utilities/Figures';
|
||||
import Flex from '../components/utilities/Flex';
|
||||
import Grid from '../components/utilities/Grid';
|
||||
import Sizing from '../components/utilities/Sizing';
|
||||
import Spacing from '../components/utilities/Spacing';
|
||||
import StretchedLink from '../components/utilities/StretchedLink';
|
||||
import Typography from '../components/utilities/Typography';
|
||||
import VerticalAlign from '../components/utilities/VerticalAlign';
|
||||
import Visibility from '../components/utilities/Visibility';
|
||||
import Widgets from '../components/widgets/Widgets';
|
||||
|
||||
// const InboxRoutes = ({ match: { url } }) => (
|
||||
// <InboxProvider>
|
||||
// <Switch>
|
||||
// <Route path={`${url}/email-detail`} exact component={EmailDetail} />
|
||||
// <Route path={`${url}/inbox`} exact component={Inbox} />
|
||||
// <Route path={`${url}/compose`} exact component={Compose} />
|
||||
const InboxRoutes = ({ match: { url } }) => (
|
||||
<InboxProvider>
|
||||
<Switch>
|
||||
<Route path={`${url}/email-detail`} exact component={EmailDetail} />
|
||||
<Route path={`${url}/inbox`} exact component={Inbox} />
|
||||
<Route path={`${url}/compose`} exact component={Compose} />
|
||||
|
||||
// {/*Redirect*/}
|
||||
// <Redirect to="/errors/404" />
|
||||
// </Switch>
|
||||
// </InboxProvider>
|
||||
// );
|
||||
{/*Redirect*/}
|
||||
<Redirect to="/errors/404" />
|
||||
</Switch>
|
||||
</InboxProvider>
|
||||
);
|
||||
|
||||
// const ProductRoutes = ({ match: { url } }) => (
|
||||
// <Switch>
|
||||
// <Route path={`${url}/products/:productLayout`} exact component={Products} />
|
||||
// <Route path={`${url}/checkout`} exact component={Checkout} />
|
||||
// <Route path={`${url}/product-details/:id`} exact component={ProductDetails} />
|
||||
// <Route path={`${url}/product-details/`} exact component={ProductDetails} />
|
||||
// <Route path={`${url}/shopping-cart`} exact component={ShoppingCart} />
|
||||
// <Route path={`${url}/orders`} exact component={Orders} />
|
||||
// <Route path={`${url}/order-details`} exact component={OrderDetails} />
|
||||
// <Route path={`${url}/customers`} exact component={Customers} />
|
||||
// <Route path={`${url}/favourite-items`} exact component={FavouriteItems} />
|
||||
const ProductRoutes = ({ match: { url } }) => (
|
||||
<Switch>
|
||||
<Route path={`${url}/products/:productLayout`} exact component={Products} />
|
||||
<Route path={`${url}/checkout`} exact component={Checkout} />
|
||||
<Route path={`${url}/product-details/:id`} exact component={ProductDetails} />
|
||||
<Route path={`${url}/product-details/`} exact component={ProductDetails} />
|
||||
<Route path={`${url}/shopping-cart`} exact component={ShoppingCart} />
|
||||
<Route path={`${url}/orders`} exact component={Orders} />
|
||||
<Route path={`${url}/order-details`} exact component={OrderDetails} />
|
||||
<Route path={`${url}/customers`} exact component={Customers} />
|
||||
<Route path={`${url}/favourite-items`} exact component={FavouriteItems} />
|
||||
|
||||
// {/*Redirect*/}
|
||||
// <Redirect to="/errors/404" />
|
||||
// </Switch>
|
||||
// );
|
||||
{/*Redirect*/}
|
||||
<Redirect to="/errors/404" />
|
||||
</Switch>
|
||||
);
|
||||
|
||||
const DashboardRoutes = () => (
|
||||
|
||||
<Switch>
|
||||
<Route path="/friends" component={JKPeople} />
|
||||
|
||||
{/* <Route path="/feed" exact component={Feed} /> */}
|
||||
<Route path="/feed" exact component={Feed} />
|
||||
{/*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/billing" exact component={Billing} />
|
||||
<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/profile" exact component={Profile} />
|
||||
<Route path="/pages/settings" exact component={Settings} />
|
||||
<Route path="/pages/starter" exact component={Starter} /> */}
|
||||
<Route path="/pages/starter" exact component={Starter} />
|
||||
{/*chat*/}
|
||||
{/* <Route path="/chat" exact component={Chat} /> */}
|
||||
<Route path="/chat" exact component={Chat} />
|
||||
{/*calendar*/}
|
||||
{/* <Route path="/calendar" exact component={Calendar} /> */}
|
||||
<Route path="/calendar" exact component={Calendar} />
|
||||
{/*kanban*/}
|
||||
{/* <Route path="/kanban" exact component={Kanban} /> */}
|
||||
<Route path="/kanban" exact component={Kanban} />
|
||||
{/*E commerce*/}
|
||||
{/* <Route path="/e-commerce" component={ProductRoutes} /> */}
|
||||
<Route path="/e-commerce" component={ProductRoutes} />
|
||||
|
||||
{/*Email*/}
|
||||
{/* <Route path="/email" component={InboxRoutes} /> */}
|
||||
<Route path="/email" component={InboxRoutes} />
|
||||
|
||||
{/*widgets*/}
|
||||
{/* <Route path="/widgets" component={Widgets} /> */}
|
||||
<Route path="/widgets" component={Widgets} />
|
||||
|
||||
{/*Documentation*/}
|
||||
{/* <Route path="/documentation" exact component={GettingStarted} /> */}
|
||||
<Route path="/documentation" exact component={GettingStarted} />
|
||||
|
||||
{/*Changelog*/}
|
||||
{/* <Route path="/changelog" exact component={ChangeLog} /> */}
|
||||
<Route path="/changelog" exact component={ChangeLog} />
|
||||
|
||||
{/*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/accordions" exact component={FalconAccordions} />
|
||||
<Route path="/components/avatar" exact component={Avatar} />
|
||||
|
|
@ -215,10 +210,10 @@ const DashboardRoutes = () => (
|
|||
<Route path="/components/tables" exact component={Tables} />
|
||||
<Route path="/components/tooltips" exact component={Tooltips} />
|
||||
<Route path="/components/spinners" exact component={Spinners} />
|
||||
<Route path="/components/carousel" exact component={Carousel} /> */}
|
||||
<Route path="/components/carousel" exact component={Carousel} />
|
||||
|
||||
{/*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/closeIcon" exact component={CloseIcon} />
|
||||
<Route path="/utilities/colors" exact component={Colors} />
|
||||
|
|
@ -232,10 +227,10 @@ const DashboardRoutes = () => (
|
|||
<Route path="/utilities/stretchedLink" exact component={StretchedLink} />
|
||||
<Route path="/utilities/typography" exact component={Typography} />
|
||||
<Route path="/utilities/verticalAlign" exact component={VerticalAlign} />
|
||||
<Route path="/utilities/visibility" exact component={Visibility} /> */}
|
||||
<Route path="/utilities/visibility" exact component={Visibility} />
|
||||
|
||||
{/*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/typed" exact component={Typed} />
|
||||
<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/emoji-mart" exact component={EmojiMart} />
|
||||
<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 to="/errors/404" />
|
||||
</Switch>
|
||||
);
|
||||
|
||||
|
||||
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 { toast, ToastContainer } from 'react-toastify';
|
||||
import { CloseButton, Fade } from '../components/common/Toast';
|
||||
|
|
@ -6,42 +6,33 @@ import { CloseButton, Fade } from '../components/common/Toast';
|
|||
import DashboardLayout from './DashboardLayout';
|
||||
import ErrorLayout from './ErrorLayout';
|
||||
|
||||
|
||||
|
||||
// import loadable from '@loadable/component';
|
||||
|
||||
//const AuthBasicLayout = loadable(() => import('./AuthBasicLayout'));
|
||||
//const Landing = loadable(() => import('../components/landing/Landing'));
|
||||
//const WizardLayout = loadable(() => import('../components/auth/wizard/WizardLayout'));
|
||||
//const AuthCardRoutes = loadable(() => import('../components/auth/card/AuthCardRoutes'));
|
||||
//const AuthSplitRoutes = loadable(() => import('../components/auth/split/AuthSplitRoutes'));
|
||||
import loadable from '@loadable/component';
|
||||
const AuthBasicLayout = loadable(() => import('./AuthBasicLayout'));
|
||||
const Landing = loadable(() => import('../components/landing/Landing'));
|
||||
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 = () => {
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
//AuthBasicLayout.preload();
|
||||
//Landing.preload();
|
||||
//WizardLayout.preload();
|
||||
//AuthCardRoutes.preload();
|
||||
//AuthSplitRoutes.preload();
|
||||
AuthBasicLayout.preload();
|
||||
Landing.preload();
|
||||
WizardLayout.preload();
|
||||
AuthCardRoutes.preload();
|
||||
AuthSplitRoutes.preload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Router fallback={<span />}>
|
||||
<Switch>
|
||||
{/* <Route path="/friends" exact component={PeopleList} /> */}
|
||||
{/* <Route path="/landing" exact component={Landing} /> */}
|
||||
{/* <Route path="/authentication/card" component={AuthCardRoutes} />
|
||||
<Route path="/landing" exact component={Landing} />
|
||||
<Route path="/authentication/card" component={AuthCardRoutes} />
|
||||
<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="/authentication/basic" component={AuthBasicLayout} /> */}
|
||||
|
||||
<Route path="/authentication/basic" component={AuthBasicLayout} />
|
||||
<Route component={DashboardLayout} />
|
||||
</Switch>
|
||||
|
||||
<ToastContainer transition={Fade} closeButton={<CloseButton />} position={toast.POSITION.BOTTOM_LEFT} />
|
||||
</Router>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,37 +4,33 @@ import { getTextMessages, createTextMessage } from '../../helpers/rest';
|
|||
const initialState = {
|
||||
messages: [],
|
||||
status: 'idel',
|
||||
error: null,
|
||||
offset: 0
|
||||
error: null
|
||||
}
|
||||
|
||||
// const [offset, setOffset] = useState(0);
|
||||
// const LIMIT = 20;
|
||||
|
||||
export const fetchMessagesByReceiverId = createAsyncThunk(
|
||||
'textMessage/fetchMessagesByReceiverId',
|
||||
async (userId, thunkAPI) => {
|
||||
async (options, thunkAPI) => {
|
||||
const { userId, offset, limit } = options
|
||||
const response = await getTextMessages({
|
||||
target_user_id: userId
|
||||
// offset: offset,
|
||||
// limit: LIMIT
|
||||
target_user_id: userId,
|
||||
offset: offset,
|
||||
limit: limit
|
||||
})
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
|
||||
export const resturectureTextMessage = (args) => {
|
||||
const { payload, sent } = args
|
||||
//console.log(payload);
|
||||
const messageId = payload.id ? payload.id : nanoid()
|
||||
const createdAt = payload.created_at ? payload.created_at : new Date().toISOString()
|
||||
const { message, sent } = args
|
||||
const messageId = message.id ? message.id : nanoid()
|
||||
const createdAt = message.created_at ? message.created_at : new Date().toISOString()
|
||||
return {
|
||||
id: messageId,
|
||||
message: payload.message,
|
||||
senderId: payload.source_user_id,
|
||||
senderName: payload.source_user['first_name'],
|
||||
receiverId: payload.target_user_id,
|
||||
receiverName: payload.target_user['first_name'],
|
||||
message: message.message,
|
||||
senderId: message.source_user_id,
|
||||
senderName: message.source_user['name'],
|
||||
receiverId: message.target_user_id,
|
||||
receiverName: message.target_user['name'],
|
||||
createdAt: createdAt,
|
||||
sent: sent
|
||||
}
|
||||
|
|
@ -44,7 +40,7 @@ export const postNewMessage = createAsyncThunk(
|
|||
'textMessage/postNewMessage',
|
||||
async (message, thunkAPI) => {
|
||||
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) => {
|
||||
state.status = 'succeeded'
|
||||
console.log(action.payload);
|
||||
state.messages = action.payload.map(message => resturectureTextMessage({ payload: message, sent: true }))
|
||||
const msgs = action.payload.map(message => resturectureTextMessage({ 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) => {
|
||||
state.status = 'failed'
|
||||
|
|
@ -74,6 +73,7 @@ export const textMessageSlice = createSlice({
|
|||
})
|
||||
.addCase(postNewMessage.fulfilled, (state, action) => {
|
||||
console.log("postNewMessage fullfilled", action.payload);
|
||||
state.messages.push(resturectureTextMessage({ message: action.payload, sent: true }))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ target
|
|||
*~
|
||||
bin
|
||||
.bundle
|
||||
.ruby-version
|
||||
|
|
|
|||
|
|
@ -631,6 +631,7 @@ message TextMessage {
|
|||
optional string notification_id = 5;
|
||||
optional string created_at = 6;
|
||||
optional bool clipped_msg = 7;
|
||||
optional string text_message_id = 8;
|
||||
}
|
||||
|
||||
message ChatMessage {
|
||||
|
|
|
|||
|
|
@ -985,7 +985,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# 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(
|
||||
:photo_url => sender_photo_url,
|
||||
:sender_name => sender_name,
|
||||
|
|
@ -993,7 +993,8 @@ module JamRuby
|
|||
:msg => msg,
|
||||
:clipped_msg => clipped_msg,
|
||||
:notification_id => notification_id,
|
||||
:created_at => created_at
|
||||
:created_at => created_at,
|
||||
text_message_id: text_message_id
|
||||
)
|
||||
|
||||
Jampb::ClientMessage.new(
|
||||
|
|
|
|||
|
|
@ -1522,7 +1522,7 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def send_text_message(message, sender, receiver)
|
||||
def send_text_message(message, sender, receiver, text_message_id)
|
||||
|
||||
notification = Notification.new
|
||||
notification.description = NotificationTypes::TEXT_MESSAGE
|
||||
|
|
@ -1542,7 +1542,9 @@ module JamRuby
|
|||
truncated_msg,
|
||||
msg_is_clipped,
|
||||
notification.id,
|
||||
notification.created_date)
|
||||
notification.created_date,
|
||||
text_message_id
|
||||
)
|
||||
logger.debug('-' * 30)
|
||||
logger.debug(msg)
|
||||
logger.debug('-' * 30)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ module JamRuby
|
|||
tm.save
|
||||
|
||||
# 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
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ class ApiTextMessagesController < ApiController
|
|||
|
||||
def create
|
||||
@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
|
||||
|
|
@ -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
|
||||
|
||||
child :source_user => :source_user do |msg|
|
||||
attributes :id, :name, :first_name
|
||||
attributes :id, :name
|
||||
end
|
||||
|
||||
child :target_user => :target_user do |msg|
|
||||
attributes :id, :name, :first_name
|
||||
attributes :id, :name
|
||||
end
|
||||
Loading…
Reference in New Issue