diff --git a/src/components/CustomDragLayer.js b/src/components/CustomDragLayer.js index 3138896..c19aa07 100644 --- a/src/components/CustomDragLayer.js +++ b/src/components/CustomDragLayer.js @@ -17,7 +17,7 @@ class CustomDragLayer extends Component { const {offset, item} = this.props const DragPreview = item.DragPreview - if (!DragPreview) return null + if (!DragPreview || !offset) return null const style = { transform: `translate(${offset.x}px, ${offset.y}px)` diff --git a/src/components/basket/Basket.js b/src/components/basket/Basket.js new file mode 100644 index 0000000..18bd92e --- /dev/null +++ b/src/components/basket/Basket.js @@ -0,0 +1,41 @@ +import React, {Component} from 'react' +import {DropTarget} from 'react-dnd' +import {deleteEvent} from '../../ducks/events' +import {connect} from 'react-redux' + +class Basket extends Component { + render() { + const {connectDropTarget, hovered} = this.props; + const basketColor = hovered ? 'red': '#888'; + const style = { + width: '300px', + height: '100px', + border: `1px solid ${basketColor}`, + textAlign: 'center', + lineHeight: '100px', + color: basketColor + }; + return connectDropTarget(
Basket
); + } +} + +const spec = { + drop(props, monitor) { + const item = monitor.getItem(); + const {deleteEvent} = props; + deleteEvent(item.id); + } +}; + +const collect = (connect, monitor) => ({ + connectDropTarget: connect.dropTarget(), + canDrop: monitor.canDrop(), + hovered: monitor.isOver() +}); + +export default connect( + null, + { + deleteEvent + }) +(DropTarget(['event'], spec, collect)(Basket)) diff --git a/src/components/events/EventDragPreview.js b/src/components/events/EventDragPreview.js new file mode 100644 index 0000000..7672809 --- /dev/null +++ b/src/components/events/EventDragPreview.js @@ -0,0 +1,28 @@ +import React, { Component } from 'react' +import {connect} from 'react-redux' +import {eventSelector} from '../../ducks/events' + +class EventDragPreview extends Component { + static propTypes = { + + }; + + render() { + return ( +
+

+ {this.props.event.title} +

+
+ ) + } +} + +export default connect((state, props) => ({ + event: eventSelector(state, props) +}))(EventDragPreview) \ No newline at end of file diff --git a/src/components/events/EventRow.js b/src/components/events/EventRow.js new file mode 100644 index 0000000..3e140e4 --- /dev/null +++ b/src/components/events/EventRow.js @@ -0,0 +1,53 @@ +import React, { Component } from 'react' +import {DragSource} from 'react-dnd' +import {getEmptyImage} from 'react-dnd-html5-backend' +import DragPreview from './EventDragPreview' + +class EventRow extends Component { + static propTypes = { + + }; + + componentDidMount() { + this.props.connectPreview(getEmptyImage()) + } + + handleClick = (data) => () => { + this.props.onRowClick(data.uid); + }; + + render() { + const cellStyle = { + display: 'inline-block', + marginRight: '15px', + width: '200px' + }; + const {style, event, connectDragSource} = this.props; + return connectDragSource(
+ {event.title} + {event.where} + {event.when} +
) + } +} + +const spec = { + beginDrag(props) { + return { + id: props.event.uid, + DragPreview + } + }, + + endDrag() { + console.log('---', 'endDrag') + } +}; + +const collect = (connect, monitor) => ({ + connectDragSource: connect.dragSource(), + connectPreview: connect.dragPreview(), + isDragging: monitor.isDragging() +}); + +export default DragSource('event', spec, collect)(EventRow) \ No newline at end of file diff --git a/src/components/events/EventTableVirtualized.js b/src/components/events/EventTableVirtualized.js index 8fb544c..1ddb06d 100644 --- a/src/components/events/EventTableVirtualized.js +++ b/src/components/events/EventTableVirtualized.js @@ -3,6 +3,7 @@ import {Table, Column} from 'react-virtualized' import {connect} from 'react-redux' import {fetchAllEvents, selectEvent, selectedEventsSelector, eventListSelector, loadedSelector, loadingSelector} from '../../ducks/events' import Loader from '../common/Loader' +import EventRow from './EventRow' import 'react-virtualized/styles.css' class EventTableVirtualized extends Component { @@ -19,13 +20,14 @@ class EventTableVirtualized extends Component { return ( this.props.selectEvent(rowData.uid)} + onRowClick={this.props.selectEvent} + rowRenderer={this.rowRenderer} > ; + rowGetter = ({ index }) => this.props.events[index] } diff --git a/src/components/routes/Admin.js b/src/components/routes/Admin.js index 2d09350..d142bea 100644 --- a/src/components/routes/Admin.js +++ b/src/components/routes/Admin.js @@ -2,6 +2,7 @@ import React, { Component } from 'react' import PeopleList from '../people/PeopleList' import EventList from '../events/EventTableVirtualized' import SelectedEvents from '../events/SelectedEvents' +import Basket from '../basket/Basket' class Admin extends Component { static propTypes = { @@ -12,6 +13,7 @@ class Admin extends Component { return (

Admin Page

+ diff --git a/src/config.js b/src/config.js index 2782a0b..161087f 100644 --- a/src/config.js +++ b/src/config.js @@ -1,12 +1,12 @@ import firebase from 'firebase' -export const appName = 'advreact-1610' +export const appName = 'react-course-f262b' firebase.initializeApp({ - apiKey: "AIzaSyB31xpTtp4Jln_hb2kAbE4PGf6Mi8EgLyA", authDomain: `${appName}.firebaseapp.com`, databaseURL: `https://${appName}.firebaseio.com`, projectId: appName, - storageBucket: "", - messagingSenderId: "397157634637" + apiKey: "AIzaSyAt-smU_1tqNdkj9pmSpVLxqaOjhDwf4dk", + storageBucket: "react-course-f262b.appspot.com", + messagingSenderId: "447165438476" }) \ No newline at end of file diff --git a/src/ducks/events.js b/src/ducks/events.js index dd75bae..f3e2af7 100644 --- a/src/ducks/events.js +++ b/src/ducks/events.js @@ -18,6 +18,10 @@ export const FETCH_LAZY_REQUEST = `${prefix}/FETCH_LAZY_REQUEST` export const FETCH_LAZY_START = `${prefix}/FETCH_LAZY_START` export const FETCH_LAZY_SUCCESS = `${prefix}/FETCH_LAZY_SUCCESS` +export const DELETE_EVENT_REQUEST = `${prefix}/DELETE_EVENT_REQUEST` +export const DELETE_EVENT_START = `${prefix}/DELETE_EVENT_START` +export const DELETE_EVENT_SUCCESS = `${prefix}/DELETE_EVENT_SUCCESS` + export const SELECT_EVENT = `${prefix}/SELECT_EVENT` @@ -63,6 +67,9 @@ export default function reducer(state = new ReducerRecord(), action) { case SELECT_EVENT: return state.update('selected', selected => selected.add(payload.uid)) + case DELETE_EVENT_SUCCESS: + return state + .deleteIn(['entities', action.payload.uid]); default: return state @@ -82,6 +89,8 @@ export const eventListSelector = createSelector(entitiesSelector, entities => en export const selectedEventsSelector = createSelector(entitiesSelector, selectionSelector, (entities, selection) => selection.map(uid => entities.get(uid)) ) +export const idSelector = (state, props) => props.id +export const eventSelector = createSelector(entitiesSelector, idSelector, (entities, id) => entities.get(id)) /** * Action Creators @@ -106,6 +115,13 @@ export function fetchLazy() { } } +export function deleteEvent(uid) { + return { + type: DELETE_EVENT_REQUEST, + payload: { uid } + } +} + /** * Sagas * */ @@ -154,6 +170,21 @@ export const fetchLazySaga = function * () { } } +export const deleteEventSaga = function * ({payload}) { + const ref = firebase.database().ref(`events/${payload.uid}`); + + yield put({ + type: DELETE_EVENT_START + }); + + yield call([ref, ref.remove]); + + yield put({ + type: DELETE_EVENT_SUCCESS, + payload + }) +}; + //lazy fetch FB /* firebase.database().ref('events') @@ -165,6 +196,7 @@ firebase.database().ref('events') export function* saga() { yield all([ takeEvery(FETCH_ALL_REQUEST, fetchAllSaga), + takeEvery(DELETE_EVENT_REQUEST, deleteEventSaga), fetchLazySaga() ]) } \ No newline at end of file