diff --git a/admin/src/components/common/trash.js b/admin/src/components/common/trash.js
new file mode 100644
index 0000000..2f9624f
--- /dev/null
+++ b/admin/src/components/common/trash.js
@@ -0,0 +1,43 @@
+import React, { Component } from 'react'
+import { DropTarget } from 'react-dnd'
+import { connect } from 'react-redux'
+import { deletePerson } from '../../ducks/people'
+import { deleteEvent } from '../../ducks/events'
+
+const style = {
+ position: 'fixed',
+ top: 0,
+ right: 0,
+ fontSize: '10em'
+}
+
+class Trash extends Component {
+ render() {
+ const { connectDropTarget } = this.props
+ return connectDropTarget(
🗑
)
+ }
+}
+
+const spec = {
+ drop(props, monitor) {
+ const { deletePerson, deleteEvent } = props
+ const itemType = monitor.getItemType()
+ const uid = monitor.getItem().uid
+
+ if (itemType === 'person') {
+ deletePerson(uid)
+ }
+
+ if (itemType === 'event') {
+ deleteEvent(uid)
+ }
+ }
+}
+
+const collect = (connect) => ({
+ connectDropTarget: connect.dropTarget()
+})
+
+export default connect(null, { deletePerson, deleteEvent })(
+ DropTarget(['person', 'event'], spec, collect)(Trash)
+)
diff --git a/admin/src/components/events/draggable-table-row.js b/admin/src/components/events/draggable-table-row.js
new file mode 100644
index 0000000..4435368
--- /dev/null
+++ b/admin/src/components/events/draggable-table-row.js
@@ -0,0 +1,19 @@
+import { DragSource } from 'react-dnd'
+import { defaultTableRowRenderer } from 'react-virtualized'
+
+const DraggableTableRow = ({ connectDragSource, ...props }) =>
+ connectDragSource(defaultTableRowRenderer(props))
+
+const spec = {
+ beginDrag(props) {
+ return {
+ uid: props.rowData.uid
+ }
+ }
+}
+
+const collect = (connect, monitor) => ({
+ connectDragSource: connect.dragSource()
+})
+
+export default DragSource('event', spec, collect)(DraggableTableRow)
diff --git a/admin/src/components/events/virtualized-lazy-table.js b/admin/src/components/events/virtualized-lazy-table.js
index c309a0f..818a0bd 100644
--- a/admin/src/components/events/virtualized-lazy-table.js
+++ b/admin/src/components/events/virtualized-lazy-table.js
@@ -8,6 +8,7 @@ import {
eventListSelector
} from '../../ducks/events'
import { Table, Column, InfiniteLoader } from 'react-virtualized'
+import DraggableTableRow from './draggable-table-row'
import 'react-virtualized/styles.css'
export class EventLazyTable extends Component {
@@ -38,6 +39,7 @@ export class EventLazyTable extends Component {
onRowClick={this.handleRowClick}
onRowsRendered={onRowsRendered}
rowClassName="test__event_table_row"
+ rowRenderer={this.rowRenderer}
>
@@ -48,6 +50,8 @@ export class EventLazyTable extends Component {
)
}
+ rowRenderer = (props) =>
+
isRowLoaded = ({ index }) => index < this.props.events.length
loadMoreRows = () => {
diff --git a/admin/src/ducks/events.js b/admin/src/ducks/events.js
index 0fd43e7..72984ca 100644
--- a/admin/src/ducks/events.js
+++ b/admin/src/ducks/events.js
@@ -21,6 +21,10 @@ export const FETCH_LAZY_SUCCESS = `${prefix}/FETCH_LAZY_SUCCESS`
export const TOGGLE_SELECTION = `${prefix}/TOGGLE_SELECTION`
+export const DELETE_EVENT = `${prefix}/DELETE_EVENT`
+export const DELETE_EVENT_START = `${prefix}/DELETE_EVENT_START`
+export const DELETE_EVENT_SUCCESS = `${prefix}/DELETE_EVENT_SUCCESS`
+
/**
* Reducer
* */
@@ -70,6 +74,9 @@ export default function reducer(state = new ReducerRecord(), action) {
: selected.add(payload.uid)
)
+ case DELETE_EVENT_SUCCESS:
+ return state.deleteIn(['entities', payload.uid])
+
default:
return state
}
@@ -129,6 +136,13 @@ export function fetchLazy() {
}
}
+export function deleteEvent(uid) {
+ return {
+ type: DELETE_EVENT,
+ payload: { uid }
+ }
+}
+
/**
* Sagas
* */
@@ -179,6 +193,26 @@ export const fetchLazySaga = function*() {
}
}
+export function* deleteEventSaga({ payload: { uid } }) {
+ yield put({
+ type: DELETE_EVENT_START,
+ payload: { uid }
+ })
+
+ const eventRef = firebase.database().ref(`events/${uid}`)
+
+ yield call([eventRef, eventRef.remove])
+
+ yield put({
+ type: DELETE_EVENT_SUCCESS,
+ payload: { uid }
+ })
+}
+
export function* saga() {
- yield all([takeEvery(FETCH_ALL_REQUEST, fetchAllSaga), fetchLazySaga()])
+ yield all([
+ takeEvery(FETCH_ALL_REQUEST, fetchAllSaga),
+ fetchLazySaga(),
+ takeEvery(DELETE_EVENT, deleteEventSaga)
+ ])
}
diff --git a/admin/src/ducks/people.js b/admin/src/ducks/people.js
index 40562f7..b3d3dc7 100644
--- a/admin/src/ducks/people.js
+++ b/admin/src/ducks/people.js
@@ -1,7 +1,7 @@
import { appName } from '../config'
import { Record, OrderedMap } from 'immutable'
import { createSelector } from 'reselect'
-import { put, call, all, takeEvery } from 'redux-saga/effects'
+import { put, call, all, takeEvery, select } from 'redux-saga/effects'
import { reset } from 'redux-form'
import firebase from 'firebase/app'
import { fbToEntities } from './utils'
@@ -15,10 +15,16 @@ export const ADD_PERSON = `${prefix}/ADD_PERSON`
export const ADD_PERSON_START = `${prefix}/ADD_PERSON_START`
export const ADD_PERSON_SUCCESS = `${prefix}/ADD_PERSON_SUCCESS`
+export const DELETE_PERSON = `${prefix}/DELETE_PERSON`
+export const DELETE_PERSON_START = `${prefix}/DELETE_PERSON_START`
+export const DELETE_PERSON_SUCCESS = `${prefix}/DELETE_PERSON_SUCCESS`
+
export const FETCH_ALL_REQUEST = `${prefix}/FETCH_ALL_REQUEST`
export const FETCH_ALL_SUCCESS = `${prefix}/FETCH_ALL_SUCCESS`
export const ADD_EVENT = `${prefix}/ADD_EVENT`
+export const ADD_EVENT_START = `${prefix}/ADD_EVENT_START`
+export const ADD_EVENT_SUCCESS = `${prefix}/ADD_EVENT_SUCCESS`
/**
* Reducer
@@ -42,6 +48,15 @@ export default function reducer(state = new ReducerState(), action) {
case ADD_PERSON_SUCCESS:
return state.setIn(['entities', payload.uid], new PersonRecord(payload))
+ case DELETE_PERSON_SUCCESS:
+ return state.deleteIn(['entities', payload.uid])
+
+ case ADD_EVENT_SUCCESS:
+ return state.updateIn(
+ ['entities', payload.personUid, 'events'],
+ (events) => [...events, payload.eventUid]
+ )
+
case FETCH_ALL_SUCCESS:
return state.set('entities', fbToEntities(payload, PersonRecord))
@@ -67,6 +82,10 @@ export const personSelector = createSelector(
idSelector,
(entities, uid) => entities.get(uid)
)
+export const personEventsSelector = createSelector(
+ personSelector,
+ (person) => person.events
+)
/**
* Action Creators
@@ -79,6 +98,13 @@ export function addPerson(person) {
}
}
+export function deletePerson(uid) {
+ return {
+ type: DELETE_PERSON,
+ payload: { uid }
+ }
+}
+
export function fetchAllPeople() {
return {
type: FETCH_ALL_REQUEST
@@ -114,6 +140,22 @@ export function* addPersonSaga(action) {
yield put(reset('person'))
}
+export function* deletePersonSaga({ payload: { uid } }) {
+ yield put({
+ type: DELETE_PERSON_START,
+ payload: { uid }
+ })
+
+ const personRef = firebase.database().ref(`people/${uid}`)
+
+ yield call([personRef, personRef.remove])
+
+ yield put({
+ type: DELETE_PERSON_SUCCESS,
+ payload: { uid }
+ })
+}
+
export function* fetchAllSaga() {
const peopleRef = firebase.database().ref('people')
@@ -125,9 +167,29 @@ export function* fetchAllSaga() {
})
}
+export function* addEventToPersonSaga({ payload: { eventUid, personUid } }) {
+ yield put({
+ type: ADD_EVENT_START,
+ payload: { eventUid, personUid }
+ })
+
+ const eventsRef = firebase.database().ref(`people/${personUid}/events`)
+
+ const events = yield select(personEventsSelector, { uid: personUid })
+
+ yield call([eventsRef, eventsRef.set], [...events, eventUid])
+
+ yield put({
+ type: ADD_EVENT_SUCCESS,
+ payload: { eventUid, personUid }
+ })
+}
+
export const saga = function*() {
yield all([
takeEvery(ADD_PERSON, addPersonSaga),
- takeEvery(FETCH_ALL_REQUEST, fetchAllSaga)
+ takeEvery(DELETE_PERSON, deletePersonSaga),
+ takeEvery(FETCH_ALL_REQUEST, fetchAllSaga),
+ takeEvery(ADD_EVENT, addEventToPersonSaga)
])
}
diff --git a/admin/src/routes/events-page.js b/admin/src/routes/events-page.js
index d893d20..d9373b4 100644
--- a/admin/src/routes/events-page.js
+++ b/admin/src/routes/events-page.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
import EventsTable from '../components/events/virtualized-lazy-table'
import SelectedEvents from '../components/events/selected-events'
import PeopleList from '../components/people/people-list'
+import Trash from '../components/common/trash'
class EventsPage extends Component {
static propTypes = {}
@@ -12,6 +13,7 @@ class EventsPage extends Component {
+
)
}