From 5589b3a5895cc2338edca9dae33d2a9edacc770d Mon Sep 17 00:00:00 2001 From: Kevin Dave Date: Thu, 3 Aug 2017 18:00:07 +0700 Subject: [PATCH] Admin Menu --- package.json | 1 + src/actions/ProfileActions.js | 19 ++-- src/actions/ProjectListActions.js | 40 ++++++++ src/actions/RegisterActions.js | 4 +- src/actions/RewardActions.js | 16 ++-- src/actions/index.js | 2 +- src/actions/types.js | 5 + src/component/admin/ProjectList.js | 124 +++++++++++++++++++++++++ src/component/commons/MyDrawer.js | 47 ++++++++-- src/component/main_app/CategoryList.js | 1 - src/component/main_app/Profile.js | 8 +- src/component/styles.js | 8 ++ src/config/routes.js | 4 +- src/reducers/ProjectListReducer.js | 20 ++++ src/reducers/index.js | 4 +- 15 files changed, 266 insertions(+), 37 deletions(-) create mode 100644 src/actions/ProjectListActions.js create mode 100644 src/component/admin/ProjectList.js create mode 100644 src/reducers/ProjectListReducer.js diff --git a/package.json b/package.json index 7bbd6db..743f76b 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react-native-animatable": "^1.2.3", "react-native-easy-grid": "^0.1.14", "react-native-router-flux": "^3.35.0", + "react-native-swipeable": "^0.6.0", "react-native-vector-icons": "^4.2.0", "react-redux": "^5.0.5", "redux": "^3.7.2", diff --git a/src/actions/ProfileActions.js b/src/actions/ProfileActions.js index 6e80e49..e7f7bf8 100644 --- a/src/actions/ProfileActions.js +++ b/src/actions/ProfileActions.js @@ -1,4 +1,3 @@ -import _ from 'lodash'; import firebase from 'firebase'; import { PROFILE_FULLNAME_CHANGE, PROFILE_COMPANY_CHANGE, INITIAL_PROFILE, FETCH_PROFILE, PROFILE_SAVE_CHANGES, @@ -9,16 +8,10 @@ export const initialProfile = () => { return (dispatch) => { dispatch({ type: FETCH_PROFILE }); - firebase.database().ref('/profiles/').orderByChild('uid').equalTo(currentUser.uid) + firebase.database().ref(`/profiles/${currentUser.uid}`) .on('value', snapshot => { - const email = currentUser.email; - const profile = _.map(snapshot.val(), (val, uid) => { - return { ...val, uid }; - }); - const fullName = profile[0].fullName; - const company = profile[0].company; - const uid = profile[0].uid; - const payload = { email, fullName, company, uid }; + const { fullName, company } = snapshot.val(); + const payload = { email: currentUser.email, fullName, company }; dispatch({ type: INITIAL_PROFILE, payload }); }); }; @@ -38,11 +31,13 @@ export const profileCompanyChange = (text) => { }; }; -export const profileSaveChanges = ({ fullName, company, uid }) => { +export const profileSaveChanges = ({ fullName, company }) => { + const { currentUser } = firebase.auth(); + return (dispatch) => { dispatch({ type: PROFILE_SAVE_CHANGES }); - firebase.database().ref(`/profiles/${uid}/`) + firebase.database().ref(`/profiles/${currentUser.uid}`) .update({ fullName, company }) .then(() => { dispatch({ type: PROFILE_CHANGES_SUCCESS }); diff --git a/src/actions/ProjectListActions.js b/src/actions/ProjectListActions.js new file mode 100644 index 0000000..960a5de --- /dev/null +++ b/src/actions/ProjectListActions.js @@ -0,0 +1,40 @@ +import _ from 'lodash'; +import firebase from 'firebase'; +import { PROJECT_LIST_FETCH_SUCCESS, PROJECT_LIST_VALIDATING, + PROJECT_LIST_VALIDATED } from './types'; + +export const projectListFetch = () => { + return (dispatch) => { + firebase.database().ref('/projects/') + .on('value', snapshot => { + const projects = _.map(snapshot.val(), (val, projectId) => { + return { ...val, projectId }; + }); + + _.remove(projects, (item) => { + if ('isValid' in item) { + return item; + } + }); + + dispatch({ type: PROJECT_LIST_FETCH_SUCCESS, payload: projects }); + }); + }; +}; + +export const projectListValidating = (isValid, id) => { + return (dispatch) => { + dispatch({ type: PROJECT_LIST_VALIDATING }); + + firebase.database().ref(`/projects/${id}/`) + .update({ isValid }) + .then(() => { + projectValidated(dispatch); + }); + }; +}; + +const projectValidated = (dispatch) => { + dispatch({ type: PROJECT_LIST_VALIDATED }); +}; + diff --git a/src/actions/RegisterActions.js b/src/actions/RegisterActions.js index 519c389..9c00401 100644 --- a/src/actions/RegisterActions.js +++ b/src/actions/RegisterActions.js @@ -40,8 +40,8 @@ export const registerUser = ({ email, password, company, fullName }) => { firebase.auth().createUserWithEmailAndPassword(email, password) .then((user) => { const dbRoot = firebase.database().ref(); - dbRoot.child('profiles') - .push({ fullName, company, uid: user.uid }) + dbRoot.child(`/profiles/${user.uid}`) + .set({ fullName, company }) .then(() => { Alert.alert('Success', 'Berhasil mendaftar ! Silahkan cek email anda untuk email verifikasi'); const { currentUser } = firebase.auth(); diff --git a/src/actions/RewardActions.js b/src/actions/RewardActions.js index e6c1c43..7a4627d 100644 --- a/src/actions/RewardActions.js +++ b/src/actions/RewardActions.js @@ -13,16 +13,20 @@ export const projectInputChange = (text) => { export const projectSubmit = ({ project }) => { console.log('project submitted'); const { currentUser } = firebase.auth(); - const currentDate = new Date().toLocaleDateString(); + const currentDate = new Date().toLocaleDateString(); return (dispatch) => { dispatch({ type: PROJECT_SUBMIT }); - firebase.database().ref().child('projects') - .push({ project, date: currentDate, uid: currentUser.uid }) - .then(() => { - dispatch({ type: PROJECT_SUBMIT_SUCCESS }); - Alert.alert('Berhasil', 'Project anda berhasil di daftar kan !'); + firebase.database().ref(`/profiles/${currentUser.uid}/`) + .on('value', snapshot => { + const { fullName, company } = snapshot.val(); + firebase.database().ref().child('projects') + .push({ project, date: currentDate, uid: currentUser.uid, fullName, company }) + .then(() => { + dispatch({ type: PROJECT_SUBMIT_SUCCESS }); + Alert.alert('Berhasil', 'Project anda berhasil di daftar kan !'); + }); }); }; }; diff --git a/src/actions/index.js b/src/actions/index.js index e05e797..5767eac 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -5,4 +5,4 @@ export * from './ProductActions'; export * from './RewardActions'; export * from './ProfileActions'; export * from './ChangePasswordActions'; - +export * from './ProjectListActions'; diff --git a/src/actions/types.js b/src/actions/types.js index 8f76b90..cb5e581 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -35,3 +35,8 @@ export const UPDATE_PASSWORD = 'update_password'; export const CHANGE_PASSWORD_SUCCESS = 'change_password_success'; export const CHANGE_PASSWORD_FAIL = 'change_password_fail'; export const PASSWORD_INITIAL_SCREEN = 'password_initial_screen'; + +export const PROJECT_LIST_FETCH_SUCCESS = 'project_list_fetch_success'; +export const PROJECT_LIST_VALIDATED = 'project_list_validated'; +export const PROJECT_LIST_VALIDATING = 'project_list_validating'; +export const PROJECT_LIST_VALIDATING_ERROR = 'project_list_validating_error'; diff --git a/src/component/admin/ProjectList.js b/src/component/admin/ProjectList.js new file mode 100644 index 0000000..307fa31 --- /dev/null +++ b/src/component/admin/ProjectList.js @@ -0,0 +1,124 @@ +import React, { Component } from 'react'; +import { DrawerLayoutAndroid, ScrollView, RefreshControl, Alert } from 'react-native'; +import { Container, List, Content, Button, Text, ListItem } from 'native-base'; +import Swipeable from 'react-native-swipeable'; +import { connect } from 'react-redux'; +import { CustomHeader, MyDrawer } from '../commons/'; +import { projectListFetch, projectListValidating } from '../../actions'; +import { DRAWER_MENU } from '../commons/ButtonConst'; + + +class ProjectList extends Component { + componentWillMount() { + this.props.projectListFetch(); + } + + onRefresh() { + this.props.projectListFetch(); + } + + openDrawer() { + this.refs['.DRAWER'].openDrawer(); + } + + renderContent() { + if (!this.props.loading) { + return ( + + ); + } + } + + renderRow(project) { + const rightButtons = [ + , + + ]; + + return ( + + + {project.project} + + + ); + } + + render() { + const navigationView = (); + + return ( + + navigationView} + ref={'.DRAWER'} + > + + this.openDrawer.bind(this)} + /> + + } + > + + {this.renderContent()} + + + + + ); + } +} + +const mapStateToProps = ({ projectList }) => { + const project = projectList.projects; + const loading = projectList.loading; + + return { project, loading }; +}; + +export default connect(mapStateToProps, { projectListFetch, projectListValidating })(ProjectList); diff --git a/src/component/commons/MyDrawer.js b/src/component/commons/MyDrawer.js index c4a6a88..4eaca50 100644 --- a/src/component/commons/MyDrawer.js +++ b/src/component/commons/MyDrawer.js @@ -1,33 +1,62 @@ import React, { Component } from 'react'; +import firebase from 'firebase'; import { Container, Content, List, CardItem, - Left, Icon, Text } from 'native-base'; + Left, Icon, Text, View } from 'native-base'; import { Actions } from 'react-native-router-flux'; +import styles from '../styles'; class MyDrawer extends Component { + state = { isAdmin: false }; + + componentWillMount() { + const { currentUser } = firebase.auth(); + + firebase.database().ref(`/admins/${currentUser.uid}`) + .once('value', snapshot => { + this.setState({ isAdmin: snapshot.val() }); + }); + } + + renderAdminMenu() { + if (this.state.isAdmin) { + return ( + + Actions.projectlist()}> + + + Project List + + + + ); + } + } + render() { - const { containerStyle } = styles; + const { containerStyle } = thisStyles; return ( Actions.product()}> - - Products + + Products Actions.reward()}> - - Rewards + + Rewards Actions.profile()}> - - Profile + + Profile + {this.renderAdminMenu()} @@ -35,7 +64,7 @@ class MyDrawer extends Component { } } -const styles = { +const thisStyles = { containerStyle: { flex: 1, backgroundColor: '#fff' diff --git a/src/component/main_app/CategoryList.js b/src/component/main_app/CategoryList.js index 04ae359..becaee6 100644 --- a/src/component/main_app/CategoryList.js +++ b/src/component/main_app/CategoryList.js @@ -34,7 +34,6 @@ class CategoryList extends Component { ); } diff --git a/src/component/main_app/Profile.js b/src/component/main_app/Profile.js index 3ae0301..eaaaa12 100644 --- a/src/component/main_app/Profile.js +++ b/src/component/main_app/Profile.js @@ -33,8 +33,8 @@ class Profile extends Component { } onChangeProfile() { - const { fullName, company, uid } = this.props; - this.props.profileSaveChanges({ fullName, company, uid }); + const { fullName, company } = this.props; + this.props.profileSaveChanges({ fullName, company }); } onLogOut() { @@ -147,9 +147,9 @@ class Profile extends Component { } const mapStateToProps = ({ profile }) => { - const { fullName, company, loading, email, loadingSubmit, uid } = profile; + const { fullName, company, loading, email, loadingSubmit } = profile; - return { fullName, company, loading, email, loadingSubmit, uid }; + return { fullName, company, loading, email, loadingSubmit }; }; export default connect(mapStateToProps, diff --git a/src/component/styles.js b/src/component/styles.js index 6ca0134..5d2ce75 100644 --- a/src/component/styles.js +++ b/src/component/styles.js @@ -30,6 +30,14 @@ const styles = { inputLabelStyle: { fontSize: 13, flex: 1 + }, + drawerIconStyle: { + flexDirection: 'column', + flex: 2 + }, + drawerTextStyle: { + flexDirection: 'column', + flex: 8 } }; diff --git a/src/config/routes.js b/src/config/routes.js index 371f4ee..917de6f 100644 --- a/src/config/routes.js +++ b/src/config/routes.js @@ -10,6 +10,7 @@ import FormReward from '../component/main_app/FormReward'; import ProjectHistory from '../component/main_app/ProjectHistory'; import Profile from '../component/main_app/Profile'; import ChangePassword from '../component/main_app/ChangePassword'; +import ProjectList from '../component/admin/ProjectList'; const Routes = (props) => { return ( @@ -31,7 +32,8 @@ const Routes = (props) => { - + + ); diff --git a/src/reducers/ProjectListReducer.js b/src/reducers/ProjectListReducer.js new file mode 100644 index 0000000..61bab40 --- /dev/null +++ b/src/reducers/ProjectListReducer.js @@ -0,0 +1,20 @@ +import { PROJECT_LIST_FETCH_SUCCESS, PROJECT_LIST_VALIDATING, + PROJECT_LIST_VALIDATED } from '../actions/types'; + +const INITIAL_STATE = { + projects: [], + loading: true +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case PROJECT_LIST_FETCH_SUCCESS: + return { ...state, projects: action.payload, loading: false }; + case PROJECT_LIST_VALIDATING: + return { ...state, loading: true }; + case PROJECT_LIST_VALIDATED: + return { ...state, loading: false }; + default: + return state; + } +}; diff --git a/src/reducers/index.js b/src/reducers/index.js index b11fd26..b9ba807 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,6 +7,7 @@ import ProjectHistoryReducer from './ProjectHistoryReducer'; import RegisterReducer from './RegisterReducer'; import ProfileReducer from './ProfileReducer'; import ChangePasswordReducer from './ChangePasswordReducer'; +import ProjectListReducer from './ProjectListReducer'; export default combineReducers({ login: LoginReducer, @@ -16,5 +17,6 @@ export default combineReducers({ rewardsForm: RewardFormReducer, projectHistory: ProjectHistoryReducer, profile: ProfileReducer, - changePassword: ChangePasswordReducer + changePassword: ChangePasswordReducer, + projectList: ProjectListReducer });