Skip to content
Open

HT 2 #14

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions admin/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ 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() {
return (
<div>
<Route path="/auth" component={Auth} />
<ProtectedRoute path="/admin" component={Admin} />
<Route path="/events" component={Events} />
</div>
)
}
Expand Down
43 changes: 43 additions & 0 deletions admin/src/components/event/event-list.js
Original file line number Diff line number Diff line change
@@ -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 <div>Loading...</div>

return (
<div>
{this.props.events.map((event) => (
<li key={event.id}>
{event.title}
<p>{event.url}</p>
<p>{event.where}</p>
<p>{event.when}</p>
<p>{event.month}</p>
<p>{event.submissionDeadline}</p>
</li>
))}
</div>
)
}
}

export default connect(
(state) => {
return {
events: eventsSelector(state),
loading: state.events.loading,
loaded: state.events.loaded
}
},
{ loadEvents }
)(EventList)
6 changes: 3 additions & 3 deletions admin/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
101 changes: 101 additions & 0 deletions admin/src/ducks/events.js
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

можно .map, а еще лучше так объектом и хранить

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)
}
4 changes: 3 additions & 1 deletion admin/src/redux/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
3 changes: 2 additions & 1 deletion admin/src/redux/saga.js
Original file line number Diff line number Diff line change
@@ -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()])
}
21 changes: 21 additions & 0 deletions admin/src/routes/events.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>Events page</h1>
<button onClick={this.props.loadEvents}>Load events</button>
<EventList />
</div>
)
}
}

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