diff --git a/admin/src/components/cart/index.js b/admin/src/components/cart/index.js
new file mode 100644
index 0000000..186a2b4
--- /dev/null
+++ b/admin/src/components/cart/index.js
@@ -0,0 +1,39 @@
+import React, { Component } from 'react'
+import { DropTarget } from 'react-dnd'
+import { connect } from 'react-redux'
+import { deleteItemByType } from '../../ducks/cart'
+
+class Cart extends Component {
+ static propTypes = {}
+
+ render() {
+ const { connectDropTarget, canReceive, hovered } = this.props
+ const borderColor = canReceive ? (hovered ? 'green' : 'red') : 'black'
+ return connectDropTarget(
+
+
+
+ π
+
+
+
+ )
+ }
+}
+
+const spec = {
+ drop(props, monitor) {
+ const { deleteItemByType } = props
+ deleteItemByType(monitor.getItem().uid, monitor.getItem().type)
+ }
+}
+
+const collect = (connect, monitor) => ({
+ connectDropTarget: connect.dropTarget(),
+ canReceive: monitor.canDrop(),
+ hovered: monitor.isOver()
+})
+
+export default connect(null, { deleteItemByType })(
+ DropTarget(['person', 'event'], spec, collect)(Cart)
+)
diff --git a/admin/src/components/events/drag-table-row.js b/admin/src/components/events/drag-table-row.js
new file mode 100644
index 0000000..f19008b
--- /dev/null
+++ b/admin/src/components/events/drag-table-row.js
@@ -0,0 +1,30 @@
+import React, { Component } from 'react'
+import { DragSource } from 'react-dnd'
+
+class DragTableCell extends Component {
+ static propTypes = {}
+
+ render() {
+ const { event, connectDragSource } = this.props
+ return (
+
+ {connectDragSource({event.title})}
+
+ )
+ }
+}
+
+const spec = {
+ beginDrag(props) {
+ return {
+ uid: props.event.uid,
+ type: 'events'
+ }
+ }
+}
+
+const collect = (connect, monitor) => ({
+ connectDragSource: connect.dragSource()
+})
+
+export default DragSource('event', spec, collect)(DragTableCell)
diff --git a/admin/src/components/events/virtualized-lazy-table.js b/admin/src/components/events/virtualized-lazy-table.js
index c309a0f..29669b3 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 DragTableCell from './drag-table-row'
import 'react-virtualized/styles.css'
export class EventLazyTable extends Component {
@@ -39,7 +40,12 @@ export class EventLazyTable extends Component {
onRowsRendered={onRowsRendered}
rowClassName="test__event_table_row"
>
-
+
@@ -62,6 +68,10 @@ export class EventLazyTable extends Component {
const { toggleSelection } = this.props
toggleSelection && toggleSelection(rowData.uid)
}
+
+ cellRenderer = (props) => (
+
+ )
}
export default connect(
diff --git a/admin/src/components/people/person-card.js b/admin/src/components/people/person-card.js
index df5bbe8..14abb66 100644
--- a/admin/src/components/people/person-card.js
+++ b/admin/src/components/people/person-card.js
@@ -26,6 +26,7 @@ const spec = {
beginDrag(props) {
return {
uid: props.person.uid,
+ type: 'people',
DragPreview
}
}
diff --git a/admin/src/config.js b/admin/src/config.js
index aa22b3b..8f4a95d 100644
--- a/admin/src/config.js
+++ b/admin/src/config.js
@@ -2,15 +2,15 @@ import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
-export const appName = 'advreact-10-05'
+export const appName = 'advreact-10-05-ee9f5'
export const config = {
- apiKey: 'AIzaSyCbMQM0eQUSQ0SuLVAu9ZNPUcm4rdbiB8U',
+ apiKey: 'AIzaSyA9z4Xmknc0zIAIfvWCfe4XWwhwqiTO9h0',
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: '',
- messagingSenderId: '1094825197832'
+ messagingSenderId: '963790431937'
}
firebase.initializeApp(config)
diff --git a/admin/src/ducks/cart.js b/admin/src/ducks/cart.js
new file mode 100644
index 0000000..21f345f
--- /dev/null
+++ b/admin/src/ducks/cart.js
@@ -0,0 +1,66 @@
+import { appName } from '../config'
+import { Record, OrderedMap } from 'immutable'
+import { put, call, all, takeEvery } from 'redux-saga/effects'
+import firebase from 'firebase/app'
+
+/**
+ * Constants
+ * */
+export const moduleName = 'cart'
+const prefix = `${appName}/${moduleName}`
+export const DELETE_ITEM = `${prefix}/DELETE_ITEM`
+export const DELETE_ITEM_SUCCESS = `${prefix}/DELETE_ITEM_SUCCESS`
+
+/**
+ * Reducer
+ * */
+const ReducerState = Record({
+ elements: new OrderedMap({})
+})
+
+export default function reducer(state = new ReducerState(), action) {
+ const { type } = action
+
+ switch (type) {
+ case DELETE_ITEM_SUCCESS:
+ // ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ ΠΏΡΠΈ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π΅ ΠΏΡΠΎΠΏΠ°ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ events ΠΈΠ»ΠΈ people?
+ return state
+ default:
+ return state
+ }
+}
+
+/**
+ * Selectors
+ * */
+
+/**
+ * Action Creators
+ * */
+
+export function deleteItemByType(itemUid, type) {
+ return {
+ type: DELETE_ITEM,
+ payload: { itemUid, type }
+ }
+}
+
+/**
+ * Sagas
+ */
+
+export function* deleteItemByTypeSaga(action) {
+ const { itemUid, type } = action.payload
+ const itemRef = firebase.database().ref(`${type}/${itemUid}`)
+
+ yield call([itemRef, itemRef.remove], '')
+
+ yield put({
+ type: DELETE_ITEM_SUCCESS,
+ payload: action.payload
+ })
+}
+
+export const saga = function*() {
+ yield all([takeEvery(DELETE_ITEM, deleteItemByTypeSaga)])
+}
diff --git a/admin/src/ducks/people.js b/admin/src/ducks/people.js
index 40562f7..15a0e70 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'
@@ -18,8 +18,8 @@ export const ADD_PERSON_SUCCESS = `${prefix}/ADD_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_TO_PERSON = `${prefix}/ADD_EVENT_TO_PERSON`
+export const ADD_EVENT_TO_PERSON_SUCCESS = `${prefix}/ADD_EVENT_TO_PERSON_SUCCESS`
/**
* Reducer
* */
@@ -42,6 +42,12 @@ export default function reducer(state = new ReducerState(), action) {
case ADD_PERSON_SUCCESS:
return state.setIn(['entities', payload.uid], new PersonRecord(payload))
+ case ADD_EVENT_TO_PERSON_SUCCESS:
+ return state.updateIn(
+ ['entities', payload.personUid, 'events'],
+ (events) => [...new Set([...events, payload.eventUid])]
+ )
+
case FETCH_ALL_SUCCESS:
return state.set('entities', fbToEntities(payload, PersonRecord))
@@ -68,6 +74,11 @@ export const personSelector = createSelector(
(entities, uid) => entities.get(uid)
)
+export const personEventsSelector = createSelector(
+ personSelector,
+ (person) => person.events
+)
+
/**
* Action Creators
* */
@@ -87,7 +98,7 @@ export function fetchAllPeople() {
export function addEventToPerson(eventUid, personUid) {
return {
- type: ADD_EVENT,
+ type: ADD_EVENT_TO_PERSON,
payload: { eventUid, personUid }
}
}
@@ -96,6 +107,20 @@ export function addEventToPerson(eventUid, personUid) {
* Sagas
*/
+export function* addEventToPersonSaga(action) {
+ const { eventUid, personUid } = action.payload
+ const eventsRef = firebase.database().ref(`people/${personUid}/events`)
+ const events = yield select(personEventsSelector, { uid: personUid })
+ const nextPersonEvents = [...new Set([...events, eventUid])]
+
+ yield call([eventsRef, eventsRef.set], nextPersonEvents)
+
+ yield put({
+ type: ADD_EVENT_TO_PERSON_SUCCESS,
+ payload: { eventUid, personUid }
+ })
+}
+
export function* addPersonSaga(action) {
yield put({
type: ADD_PERSON_START,
@@ -128,6 +153,7 @@ export function* fetchAllSaga() {
export const saga = function*() {
yield all([
takeEvery(ADD_PERSON, addPersonSaga),
- takeEvery(FETCH_ALL_REQUEST, fetchAllSaga)
+ takeEvery(FETCH_ALL_REQUEST, fetchAllSaga),
+ takeEvery(ADD_EVENT_TO_PERSON, addEventToPersonSaga)
])
}
diff --git a/admin/src/redux/reducer.js b/admin/src/redux/reducer.js
index 7e88eca..30f86e2 100644
--- a/admin/src/redux/reducer.js
+++ b/admin/src/redux/reducer.js
@@ -4,11 +4,13 @@ import { reducer as form } from 'redux-form'
import authReducer, { moduleName as authModule } from '../ducks/auth'
import peopleReducer, { moduleName as peopleModule } from '../ducks/people'
import eventsReducer, { moduleName as eventsModule } from '../ducks/events'
+import cartReducer, { moduleName as cartModule } from '../ducks/cart'
export default combineReducers({
router,
form,
[authModule]: authReducer,
[peopleModule]: peopleReducer,
- [eventsModule]: eventsReducer
+ [eventsModule]: eventsReducer,
+ [cartModule]: cartReducer
})
diff --git a/admin/src/redux/saga.js b/admin/src/redux/saga.js
index 9d0ed64..07a5d42 100644
--- a/admin/src/redux/saga.js
+++ b/admin/src/redux/saga.js
@@ -2,7 +2,8 @@ import { all } from 'redux-saga/effects'
import { saga as authSaga } from '../ducks/auth'
import { saga as peopleSaga } from '../ducks/people'
import { saga as eventsSaga } from '../ducks/events'
+import { saga as cartSaga } from '../ducks/cart'
export default function*() {
- yield all([authSaga(), peopleSaga(), eventsSaga()])
+ yield all([authSaga(), peopleSaga(), eventsSaga(), cartSaga()])
}
diff --git a/admin/src/routes/events-page.js b/admin/src/routes/events-page.js
index d893d20..15907cd 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 Cart from '../components/cart'
class EventsPage extends Component {
static propTypes = {}
@@ -9,6 +10,7 @@ class EventsPage extends Component {
render() {
return (