Skip to content

Commit

Permalink
ft(real-time-notifs): show live motifications
Browse files Browse the repository at this point in the history
- fix notification number show issue for  mark one as read
- add dockerfile
- set up live notifications for apdate, create and approve/reject for relelvant users
- set up and filter real time comment notifications
[Finishes #168049961]
  • Loading branch information
didasmbalanya committed Dec 5, 2019
1 parent 582ab5b commit 09b7ad3
Show file tree
Hide file tree
Showing 18 changed files with 179 additions and 47 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ storybook-static/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Image to build from
FROM node:latest

# Create app directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
ADD package*.json ./
RUN yarn import --silent
RUN yarn add react-scripts -g

# add app
ADD . /usr/src/app

# Map port to the Docker daemon
EXPOSE 3000

# Run the start script
CMD [ "npm", "start" ]
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@
"moxios": "^0.4.0",
"react-test-renderer": "^16.11.0",
"redux-mock-store": "^1.5.3",
"sinon": "^7.5.0"
"sinon": "^7.5.0",
"socket.io-mock": "^1.2.3"
},
"quokka": {
"babel": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const state = {
notId: 3,
markThisRead: jest.fn(),
toggleNotDisplay: jest.fn(),
getUser: jest.fn(),
notPaneDisplay: false,
isAuthenticated: false,
notifications: [
Expand Down Expand Up @@ -55,6 +56,8 @@ const props = {
notifications: state.notifications,
markRead: jest.fn(),
displayNots: false,
getUser: jest.fn(),
setAutoFill: jest.fn(),
};

const findByAttr = (wrapper, dataTest) => wrapper.find(`[data-test="${dataTest}"]`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Initialprops = {
markThisRead: jest.fn(),
toggleNotDisplay: jest.fn(),
notPaneDisplay: false,
loadNotifications: jest.fn(),
};

const store = mockStore(Initialprops);
Expand Down
1 change: 1 addition & 0 deletions src/__tests__/components/tripStat/tripStats.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Provider } from "react-redux";
import TripStatsComponent, {
TripStats,
} from "../../../components/tripStats/tripStats";

const mockStore = configureStore([thunk]);
const data = {
createdAt: "2019-11-13T10:07:21.401Z",
Expand Down
45 changes: 24 additions & 21 deletions src/__tests__/redux/reducers/notificationReducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@ import {
TOOGLE_NOTIFICATION_PANE,
GET_ALL_NOTIFICATIONS,
MARK_ONE_NOTIFICATION_SEEN,
MARK_ALL_NOTIFICATIONS_SEEN,
MARK_ALL_NOTIFICATIONS_SEEN
} from "../../../redux/actions/actionType";
import initialState from "../../../redux/reducers/initialState";

const data = {
createdAt: "2019-11-13T10:07:21.401Z",
id: 8,
message: "visit nairobi",
request_id: 12,
seen: "false",
type: "ReturnTrip",
updatedAt: "2019-11-15T13:13:44.347Z",
user_id: 49,
notPaneDisplay: false,
data: {
createdAt: "2019-11-13T10:07:21.401Z",
id: 8,
message: "visit nairobi",
request_id: 12,
seen: "false",
type: "ReturnTrip",
updatedAt: "2019-11-15T13:13:44.347Z",
user_id: 49,
notPaneDisplay: false
}
};


const state = {
...initialState,
profile: { user: data },
notifications: [
{
id: 8,
Expand All @@ -30,7 +32,7 @@ const state = {
seen: "false",
type: "ReturnTrip",
updatedAt: "2019-11-15T13:13:44.347Z",
user_id: 49,
user_id: 49
},
{
id: 9,
Expand All @@ -39,7 +41,7 @@ const state = {
seen: "false",
type: "ReturnTrip",
updatedAt: "2019-11-15T13:13:44.347Z",
user_id: 49,
user_id: 49
},
{
id: 10,
Expand All @@ -48,15 +50,16 @@ const state = {
seen: "false",
type: "ReturnTrip",
updatedAt: "2019-11-15T13:13:44.347Z",
user_id: 49,
},
],
user_id: 49
}
]
};
test("should mark one notification as read", () => {
const action = {
type: MARK_ONE_NOTIFICATION_SEEN,
payload: data,
payload: data
};

const response = notificationReducer(state, action);
expect(response.notificationCount).toBe(-1);
expect(response.notifications.length).toBe(2);
Expand All @@ -65,24 +68,24 @@ test("should mark one notification as read", () => {
test("should get all notifications for a user", () => {
const action = {
type: MARK_ALL_NOTIFICATIONS_SEEN,
payload: data,
payload: data
};
const response = notificationReducer(state, action);
expect(response.notifications.length).toBe(0);
});
test("should get all notifications for a user", () => {
const action = {
type: GET_ALL_NOTIFICATIONS,
notifications: state.notifications,
notifications: state.notifications
};
const response = notificationReducer(state, action);
expect(response.notifications.length).toBe(6);
expect(response.notifications.length).toBe(3);
});

test("should toggle notification display", () => {
const action = {
type: TOOGLE_NOTIFICATION_PANE,
notPanedisplay: true,
notPanedisplay: true
};
const response = notificationReducer(state, action);
expect(response.notPaneDisplay).toBe(true);
Expand Down
8 changes: 7 additions & 1 deletion src/components/dashboard/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import MostTravelled from "../tripStats/mostTravelled";
import SideBar from "../side-bar";
import SingleTrip from "../tripStats/singleTrip";
import TripStats from "../tripStats/tripStats";
import { retrieveProfile } from '../../redux/actions/profileAction';

class Dashboard extends Component {
async componentDidMount() {
await retrieveProfile();
}

render() {
const { total, trips } = this.props;
return (
Expand Down Expand Up @@ -59,6 +64,7 @@ Total trips:
const mapStateToProps = (state) => ({
trips: state.Requests.trips,
total: state.Requests.totalTrips,
user: state.profile.user,
});

export default connect(mapStateToProps, null)(Dashboard);
export default connect(mapStateToProps, { retrieveProfile })(Dashboard);
82 changes: 68 additions & 14 deletions src/components/notification/notificationPane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,77 @@ import { toast } from "react-toastify";
import SingleNotification from "./singleNotification";
import CloseIconButton from "../common/close-icon-button";
import { socket } from "../../config/sockets";
import { retrieveProfile } from "../../redux/actions/profileAction";
import {
getNotifications,
markAllRead,
toggleNotPane,
toggleNotPane
} from "../../redux/actions/notificationActions";

export class NotificationPane extends Component {
componentDidMount() {
const { loadNotifications } = this.props;
loadNotifications();
async componentDidMount() {
const { loadNotifications, getUser } = this.props;
await getUser();
await loadNotifications();

if (socket) {
socket.on("request_update", (data) => {
const { id } = this.props.user;
if (id === data.user_id) {
const { user } = this.props;
socket.on("new_user", data => {
toast.success(`${data.from} is now online`, {
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
});

socket.on("travel_request_response", data => {
const { id } = user;
if (id === data.request_owner) {
toast.success(`Trip request ${data.status}`, {
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
}
});

socket.on("request_update", data => {
const { id } = user;
if (id === data.user_id){
toast.success(data.message, {
position: toast.POSITION.TOP_RIGHT,
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
}
});

socket.on("new_travel_request", data => {
const { id } = user;
if (id !== data.request_owner) {
if (data.status === undefined && id === data.user_id) {
toast.success(data.message, {
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
}
}
});

socket.on("new_comment", data => {
const { id } = user;
if (id !== data.from && ( id === data.reqOwner || id === data.manager)) {
toast.success(data.message, {
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
}
});

socket.on("send_message", data => {
const { id } = user;
if (id === data.user_id) {
toast.success(data.notMessage, {
position: toast.POSITION.TOP_RIGHT
});
loadNotifications();
}
});
}
Expand All @@ -43,7 +96,7 @@ export class NotificationPane extends Component {
notifications,
displayNots,
toggleNotDisplay,
markRead,
markRead
} = this.props;
return (
<div>
Expand All @@ -63,8 +116,8 @@ export class NotificationPane extends Component {
<div className="modal-body">
<div className="notificationsList">
<ul>
{notifications
&& notifications.map((not) => (
{notifications &&
notifications.map(not => (
<SingleNotification
type={not.type}
message={not.message}
Expand Down Expand Up @@ -107,17 +160,18 @@ export class NotificationPane extends Component {
}
}

const mapStateToProps = (state) => ({
const mapStateToProps = state => ({
notifications: state.notifications.notifications,
displayNots: state.notifications.notPaneDisplay,
isAuthenticated: state.loginState.isAuthenticated,
user: state.profile.user,
user: state.profile.user
});

const mapDispatchToProps = {
loadNotifications: getNotifications,
markRead: markAllRead,
toggleNotDisplay: toggleNotPane,
getUser: retrieveProfile
};

NotificationPane.propTypes = {
Expand All @@ -126,7 +180,7 @@ NotificationPane.propTypes = {
loadNotifications: PropTypes.func.isRequired,
markRead: PropTypes.func.isRequired,
displayNots: PropTypes.bool.isRequired,
toggleNotDisplay: PropTypes.func.isRequired,
toggleNotDisplay: PropTypes.func.isRequired
};

export default connect(mapStateToProps, mapDispatchToProps)(NotificationPane);
Loading

0 comments on commit 09b7ad3

Please sign in to comment.