diff --git a/admin/src/App.js b/admin/src/App.js index c54f214..b921363 100644 --- a/admin/src/App.js +++ b/admin/src/App.js @@ -3,6 +3,7 @@ import { Route } from 'react-router-dom' import ProtectedRoute from './components/common/protected-route' import Auth from './routes/auth' import Admin from './routes/admin' +import Events from './routes/events' class App extends Component { render() { @@ -10,6 +11,7 @@ class App extends Component {
+
) } diff --git a/admin/src/components/event/event-list.js b/admin/src/components/event/event-list.js new file mode 100644 index 0000000..f51143e --- /dev/null +++ b/admin/src/components/event/event-list.js @@ -0,0 +1,43 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { eventsSelector } from '../../ducks/events' +import { loadEvents } from '../../ducks/events' + +class EventList extends Component { + static propTypes = {} + + componentDidMount() { + const { loading, loaded, loadEvents } = this.props + if (!loaded && !loading) loadEvents() + } + + render() { + if (this.props.loading) return
Loading...
+ + return ( +
+ {this.props.events.map((event) => ( +
  • + {event.title} +

    {event.url}

    +

    {event.where}

    +

    {event.when}

    +

    {event.month}

    +

    {event.submissionDeadline}

    +
  • + ))} +
    + ) + } +} + +export default connect( + (state) => { + return { + events: eventsSelector(state), + loading: state.events.loading, + loaded: state.events.loaded + } + }, + { loadEvents } +)(EventList) diff --git a/admin/src/config.js b/admin/src/config.js index a6889dc..718d7af 100644 --- a/admin/src/config.js +++ b/admin/src/config.js @@ -2,15 +2,15 @@ import { initializeApp } from 'firebase/app' import 'firebase/auth' import 'firebase/database' -export const appName = 'adv-react-25-06' +export const appName = 'adv-react-au-0307' const config = { - apiKey: 'AIzaSyDzqwnZ_39QyqhxYZVPjVH8eBww7DUBmVc', + apiKey: 'AIzaSyDj6YDOCSRPFbUGtUwwtyPrA-koT2uKCxg', authDomain: `${appName}.firebaseapp.com`, databaseURL: `https://${appName}.firebaseio.com`, projectId: appName, storageBucket: '', - messagingSenderId: '874599443389' + messagingSenderId: '650330669903' } initializeApp(config) diff --git a/admin/src/ducks/events.js b/admin/src/ducks/events.js new file mode 100644 index 0000000..18abd48 --- /dev/null +++ b/admin/src/ducks/events.js @@ -0,0 +1,101 @@ +import { appName } from '../config' +import { Record, List } from 'immutable' +import firebase from 'firebase/app' +import { takeEvery, put, call } from 'redux-saga/effects' +import { createSelector } from 'reselect' + +/** + * Constants + * */ +export const moduleName = 'events' +const prefix = `${appName}/${moduleName}` + +export const LOAD_EVENTS_REQUEST = `${prefix}/LOAD_EVENTS_REQUEST` +export const LOAD_EVENTS_SUCCESS = `${prefix}/LOAD_EVENTS_SUCCESS` +export const LOAD_EVENTS_ERROR = `${prefix}/LOAD_EVENTS_ERROR` + +/** + * Reducer + * */ +export const ReducerRecord = Record({ + entities: new List([]), + loading: false, + loaded: false +}) +const EventRecord = Record({ + id: null, + title: null, + url: null, + where: null, + when: null, + month: null, + submissionDeadline: null +}) + +export default function reducer(state = new ReducerRecord(), action) { + const { type, payload } = action + + switch (type) { + case LOAD_EVENTS_REQUEST: + return state.set('loading', true) + + case LOAD_EVENTS_SUCCESS: + return state + .update('entities', (entities) => { + let newEntities = [] + for (let id in payload) + newEntities.push(new EventRecord({ ...payload[id], id })) + return new List(newEntities) + }) + .set('loading', false) + .set('loaded', true) + + case LOAD_EVENTS_ERROR: + return state + + default: + return state + } +} + +/** + * Selectors + * */ + +export const stateSelector = (state) => state[moduleName] +export const eventsSelector = createSelector(stateSelector, (state) => + state.entities.valueSeq().toArray() +) + +/** + * Action Creators + * */ + +export function loadEvents() { + return { + type: LOAD_EVENTS_REQUEST, + payload: {} + } +} + +export function* loadEventsSaga(action) { + const databaseEvents = firebase.database().ref('/events/') + + try { + const snapshot = yield call([databaseEvents, databaseEvents.once], 'value') + + yield put({ + type: LOAD_EVENTS_SUCCESS, + payload: snapshot.val() + }) + } catch (error) { + yield put({ + type: LOAD_EVENTS_ERROR, + error + }) + } +} + +export function* saga() { + yield takeEvery(LOAD_EVENTS_REQUEST, loadEventsSaga) +} diff --git a/admin/src/redux/reducer.js b/admin/src/redux/reducer.js index 60ea924..dbac96d 100644 --- a/admin/src/redux/reducer.js +++ b/admin/src/redux/reducer.js @@ -2,9 +2,11 @@ import { combineReducers } from 'redux' 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 eventModule } from '../ducks/events' export default combineReducers({ form, [authModule]: authReducer, - [peopleModule]: peopleReducer + [peopleModule]: peopleReducer, + [eventModule]: eventsReducer }) diff --git a/admin/src/redux/saga.js b/admin/src/redux/saga.js index ca88652..71a1ad8 100644 --- a/admin/src/redux/saga.js +++ b/admin/src/redux/saga.js @@ -1,7 +1,8 @@ import { all } from 'redux-saga/effects' import { saga as peopleSaga } from '../ducks/people' import { saga as authSaga } from '../ducks/auth' +import { saga as eventsSaga } from '../ducks/events' export default function*() { - yield all([authSaga(), peopleSaga()]) + yield all([authSaga(), peopleSaga(), eventsSaga()]) } diff --git a/admin/src/routes/events.js b/admin/src/routes/events.js new file mode 100644 index 0000000..ea9fabd --- /dev/null +++ b/admin/src/routes/events.js @@ -0,0 +1,21 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { loadEvents } from '../ducks/events' +import EventList from '../components/event/event-list' + +class EventsRoute extends Component { + render() { + return ( +
    +

    Events page

    + + +
    + ) + } +} + +export default connect( + null, + { loadEvents } +)(EventsRoute)