list notifications
This commit is contained in:
parent
1a3a81508d
commit
3d428d52fc
8 changed files with 1257 additions and 351 deletions
1358
package-lock.json
generated
1358
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -47,6 +47,7 @@
|
|||
"json-loader": "0.5.7",
|
||||
"lodash": "4.17.4",
|
||||
"node-uuid": "1.4.8",
|
||||
"nodemon": "^1.17.1",
|
||||
"outdent": "0.3.0",
|
||||
"prop-types": "15.5.10",
|
||||
"react": "15.6.1",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Link } from 'react-router'
|
||||
|
||||
import onClickOutsideAddon from 'react-onclickoutside'
|
||||
import Notification from './Notification'
|
||||
|
@ -53,9 +54,9 @@ class NotificationBox extends Component {
|
|||
key={`notification-${n.id}`} />
|
||||
).concat([
|
||||
<li key='notification-see-all'>
|
||||
<a href='/notifications' className='notificationsBoxSeeAll'>
|
||||
<Link to='/notifications' className='notificationsBoxSeeAll'>
|
||||
See all
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
])
|
||||
}
|
||||
|
|
13
src/routes/Notifications/NotificationPage.js
Normal file
13
src/routes/Notifications/NotificationPage.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Link } from 'react-router'
|
||||
|
||||
import NotificationsHeader from './NotificationsHeader'
|
||||
|
||||
class NotificationPage extends Component {
|
||||
render = () => {
|
||||
return <NotificationsHeader />
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default NotificationPage
|
132
src/routes/Notifications/Notifications.js
Normal file
132
src/routes/Notifications/Notifications.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Link } from 'react-router'
|
||||
|
||||
import NotificationsHeader from './NotificationsHeader'
|
||||
|
||||
// these come from mailboxer.rb in the api repo
|
||||
const BLACKLIST = ['ACCESS_REQUEST', 'ACCESS_APPROVED', 'INVITE_TO_EDIT']
|
||||
|
||||
function getNotificationText (notification) {
|
||||
let map, topic, topic1, topic2
|
||||
switch (notification.type) {
|
||||
case 'ACCESS_APPROVED':
|
||||
map = notification.data.map
|
||||
return (
|
||||
<span>granted your request to edit map <span className="in-bold">{map.name}</span></span>
|
||||
)
|
||||
case 'ACCESS_REQUEST':
|
||||
map = notification.data.map
|
||||
return (
|
||||
<span>
|
||||
wants permission to map with you on <span className="in-bold">{map.name}</span>
|
||||
{!notification.data.object.answered && <span> <div className="action">Offer a response</div></span>}
|
||||
</span>
|
||||
)
|
||||
case 'INVITE_TO_EDIT':
|
||||
map = notification.data.map
|
||||
return (
|
||||
<span>
|
||||
gave you edit access to map <span className="in-bold">{map.name}</span>
|
||||
</span>
|
||||
)
|
||||
case 'TOPIC_ADDED_TO_MAP':
|
||||
topic = notification.data.topic
|
||||
map = notification.data.map
|
||||
return (
|
||||
<span>
|
||||
added topic <span className="in-bold">{topic.name}</span> to map <span className="in-bold">{map.name}</span>
|
||||
</span>
|
||||
)
|
||||
case 'TOPIC_CONNECTED_1':
|
||||
topic1 = notification.data.topic1
|
||||
topic2 = notification.data.topic2
|
||||
return (
|
||||
<span>
|
||||
connected <span className="in-bold">{topic1.name}</span> to <span className="in-bold">{topic2.name}</span>
|
||||
</span>
|
||||
)
|
||||
case 'TOPIC_CONNECTED_2':
|
||||
topic1 = notification.data.topic1
|
||||
topic2 = notification.data.topic2
|
||||
return (
|
||||
<span>
|
||||
connected <span className="in-bold">{topic2.name}</span> to <span className="in-bold">{topic1.name}</span>
|
||||
</span>
|
||||
)
|
||||
case 'MESSAGE_FROM_DEVS':
|
||||
return (
|
||||
<span>
|
||||
{notification.subject}
|
||||
</span>
|
||||
)
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class Notifications extends Component {
|
||||
render = () => {
|
||||
const notifications = (this.props.notifications || []).filter(n => !(BLACKLIST.indexOf(n.type) > -1 && (!n.data.object || !n.data.map)))
|
||||
return (
|
||||
<div>
|
||||
<div id="yield">
|
||||
<div className="centerContent notificationsPage">
|
||||
<header className="page-header">
|
||||
<h2 className="title">Notifications</h2>
|
||||
</header>
|
||||
<ul className="notifications">
|
||||
{notifications.map(n => {
|
||||
//const receipt = this.props.receipts.find(n => n.notification_id === notification.id)
|
||||
const receipt = {
|
||||
is_read: false
|
||||
}
|
||||
return <Notification key={n.id} notification={n} receipt={receipt} />
|
||||
})}
|
||||
{notifications.length === 0 && <div className="emptyInbox">
|
||||
You have no notifications. More time for dancing.
|
||||
</div>}
|
||||
</ul>
|
||||
</div>
|
||||
{notifications.total_pages > 1 && <div className="centerContent withPadding pagination">
|
||||
<Paginate notifications={notifications} />
|
||||
</div>}
|
||||
</div>
|
||||
<NotificationsHeader />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Paginate extends Component {
|
||||
render = () => {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class Notification extends Component {
|
||||
render = () => {
|
||||
const { notification, receipt } = this.props
|
||||
return (
|
||||
<li className={`notification ${receipt.is_read ? 'read' : 'unread' }`} id={`notification-${ notification.id }`}>
|
||||
<Link to={`/notifications/${notification.id}`}>
|
||||
<div className="notification-actor">
|
||||
<img src={notification.actor.image} />
|
||||
</div>
|
||||
<div className="notification-body">
|
||||
<div className="in-bold">{notification.actor.name}</div>
|
||||
{getNotificationText(notification)}
|
||||
</div>
|
||||
</Link>
|
||||
<div className="notification-read-unread">
|
||||
<a data-remote="true" rel="nofollow" data-method="put" href={`/notifications/${notification.id}/mark_${receipt.is_read ? 'un' : ''}read`}>mark as {receipt.is_read ? 'un' : ''}read</a>
|
||||
</div>
|
||||
<div className="notification-date">
|
||||
{notification.created_at}
|
||||
</div>
|
||||
<div className="clearfloat"></div>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Notifications
|
|
@ -1,8 +1,9 @@
|
|||
import React, { Component } from 'react'
|
||||
import NavBar from '../components/NavBar'
|
||||
import NavBarLink from '../components/NavBarLink'
|
||||
|
||||
class Notifications extends Component {
|
||||
import NavBar from '../../components/NavBar'
|
||||
import NavBarLink from '../../components/NavBarLink'
|
||||
|
||||
class NotificationsHeader extends Component {
|
||||
render = () => {
|
||||
return (
|
||||
<NavBar>
|
||||
|
@ -14,4 +15,4 @@ class Notifications extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default Notifications
|
||||
export default NotificationsHeader
|
|
@ -5,7 +5,8 @@ import App from './App'
|
|||
import Apps from './Apps'
|
||||
import Maps from './Maps'
|
||||
import MapView from './MapView'
|
||||
import Notifications from './Notifications'
|
||||
import Notifications from './Notifications/Notifications'
|
||||
import NotificationPage from './Notifications/NotificationPage'
|
||||
import TopicView from './TopicView'
|
||||
import LoggedOutHome from './LoggedOutHome'
|
||||
import RequestAccess from './RequestAccess'
|
||||
|
@ -40,7 +41,7 @@ export default function makeRoutes (currentUser) {
|
|||
<Route path="request" component={RequestInvite} />
|
||||
<Route path="notifications">
|
||||
<IndexRoute component={Notifications} />
|
||||
<Route path=":id" component={Notifications} />
|
||||
<Route path=":id" component={NotificationPage} />
|
||||
</Route>
|
||||
<Route path="users">
|
||||
<Route path=":id/edit" component={UserSettings} />
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
import React, { Component } from react
|
||||
|
||||
class MyComponent extends Component {
|
||||
render = () => {
|
||||
return (
|
||||
<div id="yield">
|
||||
<div className="centerContent notificationsPage">
|
||||
<header className="page-header">
|
||||
<h2 className="title">Notifications</h4>
|
||||
</header>
|
||||
<ul className="notifications">
|
||||
{ blacklist = [MAP_ACCESS_REQUEST, MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT] }
|
||||
{ notifications = @notifications.to_a.delete_if{|n| blacklist.include?(n.notification_code) && (n.notified_object.nil? || n.notified_object.map.nil?) }}
|
||||
{ notifications.each do |notification| }
|
||||
{ receipt = @receipts.find_by(notification_id: notification.id) }
|
||||
<li className="notification { receipt.is_read? ? 'read' : 'unread' }" id="notification-{ notification.id }">
|
||||
{ link_to notification_path(notification.id) do }
|
||||
<div className="notification-actor">
|
||||
{ image_tag notification.sender.image(:thirtytwo) }
|
||||
</div>
|
||||
<div className="notification-body">
|
||||
<div className="in-bold">{ notification.sender.name }</div>
|
||||
{
|
||||
case notification.notification_code
|
||||
when MAP_ACCESS_APPROVED }
|
||||
{ map = notification.notified_object.map }
|
||||
granted your request to edit map <span className="in-bold">{ map.name }</span>
|
||||
{ when MAP_ACCESS_REQUEST }
|
||||
{ map = notification.notified_object.map }
|
||||
wants permission to map with you on <span className="in-bold">{ map.name }</span>
|
||||
{ if !notification.notified_object.answered }
|
||||
<div className="action">Offer a response</div>
|
||||
{ end }
|
||||
{ when MAP_INVITE_TO_EDIT }
|
||||
{ map = notification.notified_object.map }
|
||||
gave you edit access to map <span className="in-bold">{ map.name }</span>
|
||||
{ when TOPIC_ADDED_TO_MAP }
|
||||
{ topic = notification.notified_object.eventable
|
||||
map = notification.notified_object.map }
|
||||
added topic <span className="in-bold">{ topic.name }</span> to map <span className="in-bold">{ map.name }</span>
|
||||
{ when TOPIC_CONNECTED_1 }
|
||||
{ topic1 = notification.notified_object&.topic1 }
|
||||
{ topic2 = notification.notified_object&.topic2 }
|
||||
connected <span className="in-bold">{ topic1&.name }</span> to <span className="in-bold">{ topic2&.name }</span>
|
||||
{ when TOPIC_CONNECTED_2 }
|
||||
{ topic1 = notification.notified_object&.topic1 }
|
||||
{ topic2 = notification.notified_object&.topic2 }
|
||||
connected <span className="in-bold">{ topic2&.name }</span> to <span className="in-bold">{ topic1&.name }</span>
|
||||
{ when MESSAGE_FROM_DEVS }
|
||||
{ notification.subject }
|
||||
{ end }
|
||||
</div>
|
||||
{ end }
|
||||
<div className="notification-read-unread">
|
||||
{ if receipt.is_read? }
|
||||
{ link_to 'mark as unread', mark_unread_notification_path(notification.id), remote: true, method: :put }
|
||||
{ else }
|
||||
{ link_to 'mark as read', mark_read_notification_path(notification.id), remote: true, method: :put }
|
||||
{ end }
|
||||
</div>
|
||||
<div className="notification-date">
|
||||
{ notification.created_at.strftime("%b %d") }
|
||||
</div>
|
||||
<div className="clearfloat"></div>
|
||||
</li>
|
||||
{ end }
|
||||
{ if notifications.count == 0 }
|
||||
<div className="emptyInbox">
|
||||
You have no notifications. More time for dancing.
|
||||
</div>
|
||||
{ end }
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{ if @notifications.total_pages > 1 }
|
||||
<div className="centerContent withPadding pagination">
|
||||
{ paginate @notifications }
|
||||
</div>
|
||||
{ end }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MyComponent
|
Loading…
Reference in a new issue