diff --git a/MobileApp/src/components/app-navigator.js b/MobileApp/src/components/app-navigator.js index 5beec7a..8b2af14 100644 --- a/MobileApp/src/components/app-navigator.js +++ b/MobileApp/src/components/app-navigator.js @@ -1,16 +1,29 @@ -import {createStackNavigator} from 'react-navigation' +import { + createStackNavigator, + createBottomTabNavigator +} from 'react-navigation' import AuthScreen from './screens/auth' import EventListScreen from './screens/event-list' import EventScreen from './screens/event' +import PeopleListScreen from './screens/people-list' + +const TabNavigator = createBottomTabNavigator({ + eventList: { + screen: EventListScreen + }, + peopletList: { + screen: PeopleListScreen + } +}) export default createStackNavigator({ - auth: { - screen: AuthScreen - }, - eventList: { - screen: EventListScreen - }, - event: { - screen: EventScreen - } -}) \ No newline at end of file + auth: { + screen: AuthScreen + }, + eventList: { + screen: TabNavigator + }, + event: { + screen: EventScreen + } +}) diff --git a/MobileApp/src/components/common/loader.js b/MobileApp/src/components/common/loader.js new file mode 100644 index 0000000..5b504fa --- /dev/null +++ b/MobileApp/src/components/common/loader.js @@ -0,0 +1,10 @@ +import React from 'react' +import { ActivityIndicator, View } from 'react-native' + +Loader = () => ( + + + +) + +export default Loader diff --git a/MobileApp/src/components/people/people-list.js b/MobileApp/src/components/people/people-list.js new file mode 100644 index 0000000..3f01f3b --- /dev/null +++ b/MobileApp/src/components/people/people-list.js @@ -0,0 +1,44 @@ +import React, { Component } from 'react' +import { Text, StyleSheet, SectionList } from 'react-native' +import PersonCard from './person-card' +import groupBy from 'lodash/groupBy' + +class PeopleList extends Component { + render() { + const grouped = groupBy(this.props.people, (person) => + person.firstName.charAt(0) + ) + const sections = Object.entries(grouped).map(([letter, list]) => ({ + title: letter, + data: list.map((person) => ({ key: person.uid, person })) + })) + return ( + ( + {section.title} + )} + renderItem={({ item }) => ( + + )} + /> + ) + } +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: '#F0F0F0', + height: 40, + lineHeight: 40, + marginBottom: 5, + shadowOffset: { + height: 2, + width: 0 + }, + shadowOpacity: 0.3, + elevation: 3 + } +}) + +export default PeopleList diff --git a/MobileApp/src/components/people/person-card.js b/MobileApp/src/components/people/person-card.js new file mode 100644 index 0000000..55eb260 --- /dev/null +++ b/MobileApp/src/components/people/person-card.js @@ -0,0 +1,20 @@ +import React, { Component } from 'react' +import { Text } from 'react-native' +import Card from '../common/card' + +class PeopleCard extends Component { + render() { + const { + person: { firstName, lastName } + } = this.props + return ( + + + {firstName} {lastName} + + + ) + } +} + +export default PeopleCard diff --git a/MobileApp/src/components/screens/event-list.js b/MobileApp/src/components/screens/event-list.js index 1b4240f..13fcd45 100644 --- a/MobileApp/src/components/screens/event-list.js +++ b/MobileApp/src/components/screens/event-list.js @@ -1,18 +1,29 @@ import React, { Component } from 'react' -import {View, StyleSheet} from 'react-native' +import { observer, inject } from 'mobx-react' +import { StyleSheet } from 'react-native' import EventList from '../events/event-list' +import Loader from '../common/loader' +@inject('events') +@observer class EventListScreen extends Component { - static propTypes = { + static propTypes = {} - }; + componentDidMount() { + if (!this.props.events.loading && !this.props.events.loaded) { + this.props.events.fetchAll() + } + } - render() { - return + render() { + if (this.props.events.loading) { + return } + + return + } } -const styles = StyleSheet.create({ -}) +const styles = StyleSheet.create({}) -export default EventListScreen \ No newline at end of file +export default EventListScreen diff --git a/MobileApp/src/components/screens/people-list.js b/MobileApp/src/components/screens/people-list.js new file mode 100644 index 0000000..aed1334 --- /dev/null +++ b/MobileApp/src/components/screens/people-list.js @@ -0,0 +1,24 @@ +import React, { Component } from 'react' +import { observer, inject } from 'mobx-react' +import PeopleList from '../people/people-list' +import Loader from '../common/loader' + +@inject('people') +@observer +class PeopleListScreen extends Component { + componentDidMount() { + if (!this.props.people.loading && !this.props.people.loaded) { + this.props.people.fetchAll() + } + } + + render() { + if (this.props.people.loading) { + return + } + + return + } +} + +export default PeopleListScreen diff --git a/MobileApp/src/stores/events.js b/MobileApp/src/stores/events.js new file mode 100644 index 0000000..0893dc4 --- /dev/null +++ b/MobileApp/src/stores/events.js @@ -0,0 +1,25 @@ +import { observable, action } from 'mobx' +import firebase from 'firebase/app' +import { fbToEntities } from './utils' + +export default class EventsStore { + @observable loading = false + @observable loaded = false + @observable entities = [] + + fetchAll = action(() => { + this.loading = true + + firebase + .database() + .ref('events') + .once( + 'value', + action((data) => { + this.loading = false + this.entities = fbToEntities(data.val()) + this.loaded = true + }) + ) + }) +} diff --git a/MobileApp/src/stores/index.js b/MobileApp/src/stores/index.js index 35339d8..bbe15be 100644 --- a/MobileApp/src/stores/index.js +++ b/MobileApp/src/stores/index.js @@ -1,12 +1,19 @@ import '../config' import UserStore from './user' +import EventsStore from './events' +import PeopleStore from './people' import NavigationStore from './navigation' -export const navigationStore = new NavigationStore -export const userStore = new UserStore(navigationStore) +class Stores { + constructor() { + this.navigation = new NavigationStore(this) + this.user = new UserStore(this) + this.events = new EventsStore(this) + this.people = new PeopleStore(this) + } +} -export default { - user: userStore, - navigation: navigationStore -} \ No newline at end of file +const stores = new Stores() + +export default stores diff --git a/MobileApp/src/stores/people.js b/MobileApp/src/stores/people.js new file mode 100644 index 0000000..7939dba --- /dev/null +++ b/MobileApp/src/stores/people.js @@ -0,0 +1,25 @@ +import { observable, action } from 'mobx' +import firebase from 'firebase/app' +import { fbToEntities } from './utils' + +export default class PeopleStore { + @observable loading = false + @observable loaded = false + @observable entities = [] + + fetchAll = action(() => { + this.loading = true + + firebase + .database() + .ref('people') + .once( + 'value', + action((data) => { + this.loading = false + this.entities = fbToEntities(data.val()) + this.loaded = true + }) + ) + }) +} diff --git a/MobileApp/src/stores/user.js b/MobileApp/src/stores/user.js index a156033..cf0668d 100644 --- a/MobileApp/src/stores/user.js +++ b/MobileApp/src/stores/user.js @@ -1,30 +1,33 @@ -import {observable, computed, action} from 'mobx' +import { observable, computed, action } from 'mobx' import firebase from 'firebase/app' export default class UserStore { - constructor(navigationStore) { - this.navigationStore = navigationStore - } + constructor(stores) { + this.navigationStore = stores.navigation + } - @observable email = '' - @observable password = '' - @observable user = null + @observable email = '' + @observable password = '' + @observable user = null - @computed get isValidPassword() { - return this.password.length >= 8 - } + @computed + get isValidPassword() { + return this.password.length >= 8 + } - @action setEmail = (email) => this.email = email - @action setPassword = (password) => this.password = password + @action setEmail = (email) => (this.email = email) + @action setPassword = (password) => (this.password = password) - signIn = () => { - firebase.auth().signInWithEmailAndPassword(this.email, this.password) - .then(user => { - this.user = user - console.log('---', 123) - this.navigationStore.navigate('eventList') - }) - .catch(error => console.error(error)) - this.user = {} - } -} \ No newline at end of file + signIn = () => { + firebase + .auth() + .signInWithEmailAndPassword(this.email, this.password) + .then((user) => { + this.user = user + console.log('---', 123) + this.navigationStore.navigate('eventList') + }) + .catch((error) => console.error(error)) + this.user = {} + } +} diff --git a/MobileApp/src/stores/utils.js b/MobileApp/src/stores/utils.js new file mode 100644 index 0000000..2f7d527 --- /dev/null +++ b/MobileApp/src/stores/utils.js @@ -0,0 +1,2 @@ +export const fbToEntities = (data) => + Object.entries(data).map(([uid, entity]) => ({ uid, ...entity }))