diff --git a/admin-panel/package.json b/admin-panel/package.json
index 1ada3cf..2dcbe74 100644
--- a/admin-panel/package.json
+++ b/admin-panel/package.json
@@ -19,7 +19,8 @@
"redux-logger": "^3.0.6",
"redux-saga": "^0.16.0",
"redux-thunk": "^2.2.0",
- "reselect": "^3.0.1"
+ "reselect": "^3.0.1",
+ "styled-components": "^2.2.4"
},
"scripts": {
"start": "react-scripts start",
diff --git a/admin-panel/src/App.js b/admin-panel/src/App.js
new file mode 100644
index 0000000..fd110f7
--- /dev/null
+++ b/admin-panel/src/App.js
@@ -0,0 +1,23 @@
+import React, { Component } from 'react'
+import {Route} from 'react-router-dom'
+import Auth from './components/routes/auth'
+import Admin from './components/routes/Admin'
+import ProtectedRoute from './components/common/ProtectedRoute'
+
+class App extends Component {
+ static propTypes = {
+
+ };
+
+ render() {
+ return (
+
+ )
+ }
+}
+
+export default App
\ No newline at end of file
diff --git a/admin-panel/src/components/App.js b/admin-panel/src/components/App.js
index 6abd045..d8cc8a3 100644
--- a/admin-panel/src/components/App.js
+++ b/admin-panel/src/components/App.js
@@ -1,29 +1,23 @@
-import React, { Component } from 'react'
+import React from 'react'
import {Route, NavLink} from 'react-router-dom'
import AuthPage from './routes/auth'
import AdminPage from './routes/Admin'
import ProtectedRoute from './common/ProtectedRoute'
import PersonPage from './routes/PersonPage'
+import EventsPage from './routes/EventsPage';
-class App extends Component {
- static propTypes = {
+const App = () =>
+
+
Hello world
+
+ admin
+ people
+ events
+
+
+
+
+
+
- };
-
- render() {
- return (
-
- )
- }
-}
-
-export default App
\ No newline at end of file
+export default App;
\ No newline at end of file
diff --git a/admin-panel/src/components/people/PeopleList.js b/admin-panel/src/components/people/PeopleList.js
new file mode 100644
index 0000000..0a1a4a6
--- /dev/null
+++ b/admin-panel/src/components/people/PeopleList.js
@@ -0,0 +1,14 @@
+import React from 'react'
+
+export default ({list}) =>
+
+
People
+
+
Id. Email Имя Фамилия
+ {list.map((p, idx) => (
+
+ {idx}. {p.email} {p.firstName} {p.lastName}
+
+ ))}
+
+
diff --git a/admin-panel/src/components/routes/Admin.js b/admin-panel/src/components/routes/Admin.js
index 952248e..91dbb03 100644
--- a/admin-panel/src/components/routes/Admin.js
+++ b/admin-panel/src/components/routes/Admin.js
@@ -1,17 +1,6 @@
-import React, { Component } from 'react'
+import React from 'react'
-class Admin extends Component {
- static propTypes = {
-
- };
-
- render() {
- return (
-
-
Admin Page
-
- )
- }
-}
-
-export default Admin
\ No newline at end of file
+export default () =>
+
+
Admin Page
+
\ No newline at end of file
diff --git a/admin-panel/src/components/routes/EventsPage.js b/admin-panel/src/components/routes/EventsPage.js
new file mode 100644
index 0000000..80e4a3b
--- /dev/null
+++ b/admin-panel/src/components/routes/EventsPage.js
@@ -0,0 +1,44 @@
+import React from 'react'
+import {connect} from 'react-redux'
+import {saveEventsToDb, eventsSelector, loaderSelector} from '../../ducks/event'
+
+const EventsPage = ({saveEventsToDb,eventList, loading }) =>
+
+
Events Page
+
Upload Events
+
+
Events List
+
+
+
+ month
+ submissionDeadline
+ title
+ url
+ when
+ where
+
+
+
+
+ {!loading && eventList.map(value =>
+ value.map((prop,key) =>
+
+ {prop.month}
+ {prop.submissionDeadline}
+ {prop.title}
+ {prop.url}
+ {prop.when}
+ {prop.where}
+
+ )
+ )}
+ {loading && Loading... }
+
+
+
+
+export default connect(state => ({
+ eventList: eventsSelector(state),
+ loading:loaderSelector(state)
+}), {saveEventsToDb})(EventsPage)
\ No newline at end of file
diff --git a/admin-panel/src/components/routes/PersonPage.js b/admin-panel/src/components/routes/PersonPage.js
index fd69263..a1708ae 100644
--- a/admin-panel/src/components/routes/PersonPage.js
+++ b/admin-panel/src/components/routes/PersonPage.js
@@ -1,21 +1,18 @@
-import React, { Component } from 'react'
+import React from 'react'
import {connect} from 'react-redux'
-import {addPerson} from '../../ducks/people'
+import {addPerson, peopleSelector} from '../../ducks/people'
import NewPersonForm from '../people/NewPersonForm'
+import PeopleList from '../people/PeopleList';
-class PersonPage extends Component {
- static propTypes = {
+const PersonPage =
+ ({addPerson, peopleList}) =>
+
- };
- render() {
- return (
-
-
Add new person
-
-
- )
- }
-}
-
-export default connect(null, {addPerson})(PersonPage)
\ No newline at end of file
+export default connect(state => ({
+ peopleList: peopleSelector(state)
+}), {addPerson})(PersonPage)
\ No newline at end of file
diff --git a/admin-panel/src/components/routes/auth/index.js b/admin-panel/src/components/routes/auth/index.js
index 91c9bab..9114b86 100644
--- a/admin-panel/src/components/routes/auth/index.js
+++ b/admin-panel/src/components/routes/auth/index.js
@@ -1,7 +1,8 @@
import React, { Component } from 'react'
import {Route, NavLink} from 'react-router-dom'
import {connect} from 'react-redux'
-import {signIn, signUp} from '../../../ducks/auth'
+
+import {signIn, signUp, errorSelector, loadingSelector} from '../../../ducks/auth'
import SignInForm from '../../auth/SignInForm'
import SignUpForm from '../../auth/SignUpForm'
@@ -11,6 +12,7 @@ class Auth extends Component {
};
render() {
+ const {loading, error} = this.props;
return (
Auth page
@@ -20,6 +22,12 @@ class Auth extends Component {
} />
} />
+ {error !== null &&
+ {error}
+ }
+ {loading &&
+ Loading...
+ }
)
}
@@ -29,4 +37,7 @@ class Auth extends Component {
}
-export default connect(null, { signIn, signUp })(Auth)
\ No newline at end of file
+export default connect(state => ({
+ error: errorSelector(state),
+ loading: loadingSelector(state)
+}), { signIn, signUp })(Auth)
\ No newline at end of file
diff --git a/admin-panel/src/components/user/UserForm.js b/admin-panel/src/components/user/UserForm.js
new file mode 100644
index 0000000..36541c8
--- /dev/null
+++ b/admin-panel/src/components/user/UserForm.js
@@ -0,0 +1,46 @@
+import React, { Component } from 'react'
+import {reduxForm, Field} from 'redux-form'
+import validator from 'email-validator'
+
+import ErrorField from '../common/ErrorField'
+
+class UserForm extends Component {
+ static propTypes = {
+
+ };
+
+ render() {
+ const {mode} = this.props;
+ return (
+
+
{mode === 'add' ? 'Add user' : 'Edit User' }
+
+
+
+ )
+ }
+}
+const validate = ({ email }) => {
+ const errors = {}
+
+ if (!email) errors.email = 'email is a required field'
+ if (email && !validator.validate(email)) errors.email = 'incorrect email format'
+
+ return errors
+}
+
+export default reduxForm({
+ form: 'user',
+ validate
+})(UserForm)
\ No newline at end of file
diff --git a/admin-panel/src/config.js b/admin-panel/src/config.js
index 65bba00..8bb4843 100644
--- a/admin-panel/src/config.js
+++ b/admin-panel/src/config.js
@@ -1,14 +1,15 @@
import firebase from 'firebase'
-export const appName = 'advreact-04-12'
+export const appName = 'advreact-04-12-vesna'
const config = {
- apiKey: "AIzaSyCmDWlgYIhtEr1pWjgKYds3iXKWBl9wbjE",
+ appName: appName,
+ apiKey: "AIzaSyAkBB770P-MOKox9k6DjFRKi9J-bIoMnJs",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: "",
- messagingSenderId: "95255462276"
+ messagingSenderId: "786443944884"
}
firebase.initializeApp(config)
\ No newline at end of file
diff --git a/admin-panel/src/ducks/auth.test.js b/admin-panel/src/ducks/auth.test.js
new file mode 100644
index 0000000..c89ddb7
--- /dev/null
+++ b/admin-panel/src/ducks/auth.test.js
@@ -0,0 +1,191 @@
+import {call, put, take} from 'redux-saga/effects'
+import {
+ signInSaga,
+ SIGN_IN_REQUEST,
+ SIGN_IN_START,
+ SIGN_IN_SUCCESS,
+ SIGN_IN_ERROR,
+
+ signUpSaga,
+ SIGN_UP_REQUEST,
+ SIGN_UP_START,
+ SIGN_UP_SUCCESS,
+ SIGN_UP_ERROR
+} from './auth';
+import firebase from 'firebase'
+
+describe('auth saga', () => {
+
+ /**
+ * Sign in tests
+ */
+
+ it('should sign in person', () => {
+ const user = {
+ password: '123456',
+ email: 'ivanovasvetlana1991@gmail.com'
+ }
+
+ const action = {
+ type: SIGN_IN_REQUEST,
+ payload: { user }
+ }
+
+ const generator = signInSaga(action)
+
+ expect(generator.next().value).toEqual(put({
+ type: SIGN_IN_START
+ }))
+
+ const auth = firebase.auth()
+
+ expect(JSON.stringify(generator.next().value)).toEqual(JSON.stringify(
+ call(
+ [auth, auth.createUserWithEmailAndPassword],
+ action.payload.email,
+ action.payload.password
+ )
+ )
+ )
+
+ expect(generator.next(user).value).toEqual(
+ put({
+ type: SIGN_IN_SUCCESS,
+ payload: { user }
+ })
+ )
+
+ expect(generator.next().done).toBe(true)
+
+ });
+
+ it('should be error in sign in request', () => {
+ const user = {
+ password: '1236',
+ email: 'ivanovasvetlana1991@gmail.com'
+ }
+
+ const action = {
+ type: SIGN_IN_REQUEST,
+ payload: { user }
+ }
+
+ const generator = signInSaga(action)
+
+ expect(generator.next().value).toEqual(put({
+ type: SIGN_IN_START
+ }))
+
+ const auth = firebase.auth()
+
+ expect(JSON.stringify(generator.next().value)).toEqual(JSON.stringify(
+ call(
+ [auth, auth.createUserWithEmailAndPassword],
+ action.payload.email,
+ action.payload.password
+ )
+ )
+ )
+
+ const error = new Error('something went wrong')
+
+ expect(generator.throw(error).value).toEqual(
+ put({
+ type: SIGN_IN_ERROR,
+ payload: { error }
+ })
+ )
+
+ expect(generator.next().done).toBe(true)
+
+ });
+
+ /**
+ * Sign up tests
+ */
+
+ it('should sign up person', () => {
+ const user = {
+ password: '123456',
+ email: 'ivanovasvetlana1991@gmail.com'
+ }
+
+ const action = {
+ type: SIGN_UP_REQUEST,
+ payload: { user }
+ }
+
+ const generator = signUpSaga()
+
+ expect(generator.next().value).toEqual(take(SIGN_UP_REQUEST))
+
+ expect(generator.next(action).value).toEqual(put({
+ type: SIGN_UP_START
+ }))
+
+ const auth = firebase.auth()
+
+ expect(JSON.stringify(generator.next().value)).toEqual(JSON.stringify(
+ call(
+ [auth, auth.createUserWithEmailAndPassword],
+ action.payload.email,
+ action.payload.password
+ )
+ )
+ )
+
+ expect(generator.next(user).value).toEqual(
+ put({
+ type: SIGN_UP_SUCCESS,
+ payload: { user }
+ })
+ )
+
+ expect(generator.next().value).toEqual(take(SIGN_UP_REQUEST))
+
+ });
+
+ it('should throw error in sign up ', () => {
+ const user = {
+ password: '123456',
+ email: 'ivanovasvetlana1991@gmail.com'
+ }
+
+ const action = {
+ type: SIGN_UP_REQUEST,
+ payload: { user }
+ }
+
+ const generator = signUpSaga()
+
+ expect(generator.next().value).toEqual(take(SIGN_UP_REQUEST))
+
+ expect(generator.next(action).value).toEqual(put({
+ type: SIGN_UP_START
+ }))
+
+ const auth = firebase.auth()
+
+ expect(JSON.stringify(generator.next().value)).toEqual(JSON.stringify(
+ call(
+ [auth, auth.createUserWithEmailAndPassword],
+ action.payload.email,
+ action.payload.password
+ )
+ )
+ )
+
+ const error = new Error('something went wrong')
+
+ expect(generator.throw(error).value).toEqual(
+ put({
+ type: SIGN_UP_ERROR,
+ payload: { error }
+ })
+ )
+
+ expect(generator.next().value).toEqual(take(SIGN_UP_REQUEST))
+
+ });
+
+});
\ No newline at end of file
diff --git a/admin-panel/src/ducks/event.js b/admin-panel/src/ducks/event.js
new file mode 100644
index 0000000..e3e69d7
--- /dev/null
+++ b/admin-panel/src/ducks/event.js
@@ -0,0 +1,130 @@
+import {appName} from '../config'
+import {Record, List} from 'immutable'
+import {put, call, all, takeEvery} from 'redux-saga/effects'
+import {createSelector} from 'reselect'
+
+import {saveEventsToFB, getEventsFromFB} from '../mocks/index';
+
+/**
+ * Constants
+ * */
+
+export const moduleName = 'event'
+const prefix = `${appName}/${moduleName}`
+
+export const ADD_EVENTS_REQUEST = `${prefix}/ADD_EVENTS_REQUEST`
+export const ADD_EVENTS_START = `${prefix}/ADD_EVENTS_START`
+export const ADD_EVENTS_SUCCESS = `${prefix}/ADD_EVENTS_SUCCESS`
+export const ADD_EVENTS_ERROR = `${prefix}/ADD_EVENTS_ERROR`
+
+export const GET_EVENTS_REQUEST = `${prefix}/GET_EVENTS_REQUEST`
+export const GET_EVENTS_START = `${prefix}/GET_EVENTS_START`
+export const GET_EVENTS_SUCCESS = `${prefix}/GET_EVENTS_SUCCESS`
+export const GET_EVENTS_ERROR = `${prefix}/GET_EVENTS_ERROR`
+
+/**
+ * Reducer
+ * */
+const ReducerState = Record({
+ entities: new List([]),
+ loading: false,
+ error: null
+})
+
+
+export default function reducer(state = new ReducerState(), action) {
+ const {type, payload} = action
+
+ switch (type) {
+ case ADD_EVENTS_START:
+ return state
+ .set('error', null)
+ .set('loading', true)
+
+ case GET_EVENTS_SUCCESS:
+ return state
+ .update('entities', entities => entities.push(Object.values(payload.events)))
+ .set('loading', false)
+
+ case ADD_EVENTS_ERROR:
+ case GET_EVENTS_ERROR:
+ return state
+ .set('loading', false)
+ .set('error', payload.error.message)
+ default:
+ return state
+ }
+}
+
+/**
+ * Selectors
+ * */
+export const stateSelector = state => state[moduleName]
+export const eventsSelector = createSelector(stateSelector, state => state.entities)
+export const loaderSelector = createSelector(stateSelector, state => state.loading)
+
+/**
+ * Action Creators
+ * */
+
+export function saveEventsToDb() {
+ return {
+ type: ADD_EVENTS_REQUEST
+ }
+}
+
+/**
+ * Sagas
+ */
+
+export const saveEventsSaga = function * (action) {
+ try {
+ yield put({
+ type: ADD_EVENTS_START
+ })
+ let events = yield call(getEventsFromFB);
+
+ if(events === null){
+ events = yield call(saveEventsToFB)
+ }
+
+ yield put({
+ type: ADD_EVENTS_SUCCESS,
+ payload: { events }
+ })
+ }catch(error){
+ yield put({
+ type: ADD_EVENTS_ERROR,
+ payload: { error }
+ })
+ }
+}
+
+export const fetchEventsSaga = function * (action){
+ try{
+ yield put({
+ type: GET_EVENTS_START
+ })
+ const events = yield call(getEventsFromFB)
+
+ yield put({
+ type: GET_EVENTS_SUCCESS,
+ payload: { events }
+ })
+
+ }
+ catch(error){
+ yield put({
+ type: GET_EVENTS_ERROR,
+ payload: { error }
+ })
+ }
+}
+
+
+export const saga = function * () {
+ yield all([
+ takeEvery(ADD_EVENTS_REQUEST, saveEventsSaga),
+ takeEvery(ADD_EVENTS_SUCCESS,fetchEventsSaga)
+ ])
+}
\ No newline at end of file
diff --git a/admin-panel/src/ducks/people.js b/admin-panel/src/ducks/people.js
index 52bce70..e7063cb 100644
--- a/admin-panel/src/ducks/people.js
+++ b/admin-panel/src/ducks/people.js
@@ -1,6 +1,8 @@
import {appName} from '../config'
import {Record, List} from 'immutable'
import {put, call, all, takeEvery} from 'redux-saga/effects'
+import {createSelector} from 'reselect'
+import {reset} from 'redux-form';
import {generateId} from './utils'
/**
@@ -10,6 +12,7 @@ export const moduleName = 'people'
const prefix = `${appName}/${moduleName}`
export const ADD_PERSON = `${prefix}/ADD_PERSON`
export const ADD_PERSON_SUCCESS = `${prefix}/ADD_PERSON_SUCCESS`
+export const ADD_PERSON_ERROR = `${prefix}/ADD_PERSON_ERROR`
/**
* Reducer
@@ -30,7 +33,7 @@ export default function reducer(state = new ReducerState(), action) {
switch (type) {
case ADD_PERSON_SUCCESS:
- return state.update('entities', entities => entities.push(new PersonRecord(payload.person)))
+ return state.update('entities', entities => entities.push(new PersonRecord(payload)))
default:
return state
@@ -40,6 +43,8 @@ export default function reducer(state = new ReducerState(), action) {
/**
* Selectors
* */
+export const stateSelector = state => state[moduleName]
+export const peopleSelector = createSelector(stateSelector, state => state.entities)
/**
* Action Creators
@@ -59,12 +64,20 @@ export function addPerson(person) {
export const addPersonSaga = function * (action) {
const { person } = action.payload
- const id = yield call(generateId)
+ try {
+ const id = yield call(generateId)
- yield put({
- type: ADD_PERSON_SUCCESS,
- payload: {id, ...person}
- })
+ yield put({
+ type: ADD_PERSON_SUCCESS,
+ payload: { id, ...person }
+ })
+ yield put(reset('person'))
+ }catch(error){
+ yield put({
+ type: ADD_PERSON_ERROR,
+ payload: { error }
+ })
+ }
}
export const saga = function * () {
diff --git a/admin-panel/src/ducks/user.js b/admin-panel/src/ducks/user.js
new file mode 100644
index 0000000..675a121
--- /dev/null
+++ b/admin-panel/src/ducks/user.js
@@ -0,0 +1,75 @@
+import {appName} from '../config'
+import {Record} from 'immutable'
+import firebase from 'firebase'
+
+/**
+ * Constants
+ * */
+export const moduleName = 'user'
+const prefix = `${appName}/${moduleName}`
+
+export const ADD_USER_START = `${prefix}/ADD_USER_START`
+export const ADD_USER_SUCCESS = `${prefix}/ADD_USER_SUCCESS`
+export const ADD_USER_FAIL = `${prefix}/ADD_USER_FAIL`
+
+/**
+ * Reducer
+ * */
+export const ReducerRecord = Record({
+ //users: null,
+ loading: false,
+ error: null
+})
+
+export default function reducer(state = new ReducerRecord(), action) {
+ const {type, payload} = action
+
+ switch (type) {
+ case ADD_USER_START:
+ return state.set('loading', true)
+
+ case ADD_USER_SUCCESS:
+ return state
+ .set('loading', false)
+
+ case ADD_USER_FAIL:
+ return state
+ .set('loading', false)
+ .set('error', payload.error.message)
+
+ default:
+ return state
+ }
+}
+
+/**
+ * Selectors
+ * */
+
+//export const userListSelector = state => state[moduleName].users
+export const userLoaderSelector = state => state[moduleName].loading
+export const userErrorSelector = state => state[moduleName].error
+
+/**
+ * Action Creators
+ * */
+
+export function addUser(firstName, lastName, email) {
+ return (dispatch) => {
+ dispatch({
+ type: ADD_USER_START
+ })
+
+ const db = firebase.database();
+ const users = db.ref().child('users');
+
+ users.push({firstName, lastName, email})
+ .then(answer => dispatch({
+ type: ADD_USER_SUCCESS
+ }))
+ .catch(error => dispatch({
+ type: ADD_USER_FAIL,
+ payload: { error }
+ }))
+ }
+}
diff --git a/admin-panel/src/mocks/index.js b/admin-panel/src/mocks/index.js
index d1a851f..57c2d98 100644
--- a/admin-panel/src/mocks/index.js
+++ b/admin-panel/src/mocks/index.js
@@ -6,4 +6,11 @@ export function saveEventsToFB() {
conferences.forEach(conference => eventsRef.push(conference))
}
+export function getEventsFromFB() {
+ const db = firebase.database()
+ const eventsRef = db.ref(`/events`)
+ return eventsRef.once('value').then(result => result.val()
+ );
+}
+
window.saveEventsToFB = saveEventsToFB
\ No newline at end of file
diff --git a/admin-panel/src/redux/reducer.js b/admin-panel/src/redux/reducer.js
index cc6e0aa..0eb750b 100644
--- a/admin-panel/src/redux/reducer.js
+++ b/admin-panel/src/redux/reducer.js
@@ -3,9 +3,11 @@ import {routerReducer as router} from 'react-router-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 eventReducer, {moduleName as eventModule} from '../ducks/event'
export default combineReducers({
router, form,
[authModule]: authReducer,
- [peopleModule]: peopleReducer
+ [peopleModule]: peopleReducer,
+ [eventModule]: eventReducer
})
\ No newline at end of file
diff --git a/admin-panel/src/redux/saga.js b/admin-panel/src/redux/saga.js
index 4a6c841..c431ce8 100644
--- a/admin-panel/src/redux/saga.js
+++ b/admin-panel/src/redux/saga.js
@@ -1,10 +1,12 @@
import {all} from 'redux-saga/effects'
import {saga as peopleSaga} from '../ducks/people'
import {saga as authSaga} from '../ducks/auth'
+import {saga as eventSaga} from '../ducks/event'
export default function * rootSaga() {
yield all([
peopleSaga(),
- authSaga()
+ authSaga(),
+ eventSaga()
])
}
\ No newline at end of file
diff --git a/admin-panel/yarn.lock b/admin-panel/yarn.lock
index 5e59e02..653af0e 100644
--- a/admin-panel/yarn.lock
+++ b/admin-panel/yarn.lock
@@ -1232,6 +1232,13 @@ buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
+buffer@^5.0.3:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.8.tgz#84daa52e7cf2fa8ce4195bc5cf0f7809e0930b24"
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+
builtin-modules@^1.0.0, builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
@@ -1679,6 +1686,10 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
+css-color-keywords@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
+
css-color-names@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
@@ -1719,6 +1730,14 @@ css-selector-tokenizer@^0.7.0:
fastparse "^1.1.1"
regexpu-core "^1.0.0"
+css-to-react-native@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.0.4.tgz#cf4cc407558b3474d4ba8be1a2cd3b6ce713101b"
+ dependencies:
+ css-color-keywords "^1.0.0"
+ fbjs "^0.8.5"
+ postcss-value-parser "^3.3.0"
+
css-what@2.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
@@ -2555,7 +2574,7 @@ fb-watchman@^2.0.0:
dependencies:
bser "^2.0.0"
-fbjs@^0.8.16:
+fbjs@^0.8.16, fbjs@^0.8.5, fbjs@^0.8.9:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
@@ -3057,6 +3076,10 @@ hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+hoist-non-react-statics@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
+
hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -3384,6 +3407,10 @@ is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+is-function@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
+
is-glob@^2.0.0, is-glob@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
@@ -3436,6 +3463,12 @@ is-plain-obj@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
+is-plain-object@^2.0.1:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
+ dependencies:
+ isobject "^3.0.1"
+
is-posix-bracket@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
@@ -3520,6 +3553,10 @@ isobject@^2.0.0:
dependencies:
isarray "1.0.0"
+isobject@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
+
isomorphic-fetch@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
@@ -6144,6 +6181,24 @@ style-loader@0.19.0:
loader-utils "^1.0.2"
schema-utils "^0.3.0"
+styled-components@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.2.4.tgz#dd87fd3dafd359e7a0d570aec1bd07d691c0b5a2"
+ dependencies:
+ buffer "^5.0.3"
+ css-to-react-native "^2.0.3"
+ fbjs "^0.8.9"
+ hoist-non-react-statics "^1.2.0"
+ is-function "^1.0.1"
+ is-plain-object "^2.0.1"
+ prop-types "^15.5.4"
+ stylis "^3.4.0"
+ supports-color "^3.2.3"
+
+stylis@^3.4.0:
+ version "3.4.5"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.5.tgz#d7b9595fc18e7b9c8775eca8270a9a1d3e59806e"
+
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"