diff --git a/MobileApp/App.js b/MobileApp/App.js index cca2cba..80a01d3 100644 --- a/MobileApp/App.js +++ b/MobileApp/App.js @@ -1,46 +1,24 @@ -import {configure} from 'mobx' -import {Provider} from 'mobx-react' +import { configure } from 'mobx' +import { Provider } from 'mobx-react' -configure({enforceActions: true}) +configure({ enforceActions: true }) + +import React from 'react' +import { View, Image } from 'react-native' -import React from 'react'; -import {StyleSheet, View, Image} from 'react-native'; -//import SignIn from './src/components/sign-in' -//import HelloWorld from './src/hello-world' -import EventList from './src/components/events/event-list' -import EventScreen from './src/components/events/event-screen' -import fixtures from './fixtures.json' -import img from './assets/images/logo.png' import AppNavigator from './src/components/app-navigator' import stores from './src/stores' - -const events = Object.entries(fixtures.events).map(([uid, event]) => ({...event, uid})) - export default class App extends React.Component { - render() { - return - - - } - - setNavRef = (ref) => { - stores.navigation.setRef(ref) - } + render() { + return ( + + + + ) + } + + setNavRef = (ref) => { + stores.navigation.setRef(ref) + } } - -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', - paddingTop: 30, - paddingBottom: 30, - }, - image: { - width: '100%', - height: 100 - } -}); - diff --git a/MobileApp/src/components/app-navigator.js b/MobileApp/src/components/app-navigator.js index 5beec7a..a30bdb4 100644 --- a/MobileApp/src/components/app-navigator.js +++ b/MobileApp/src/components/app-navigator.js @@ -1,16 +1,16 @@ -import {createStackNavigator} from 'react-navigation' +import { createStackNavigator } from 'react-navigation' import AuthScreen from './screens/auth' -import EventListScreen from './screens/event-list' +import MainScreen from './screens/main' import EventScreen from './screens/event' export default createStackNavigator({ - auth: { - screen: AuthScreen - }, - eventList: { - screen: EventListScreen - }, - event: { - screen: EventScreen - } -}) \ No newline at end of file + auth: { + screen: AuthScreen + }, + main: { + screen: MainScreen + }, + 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..a11594d --- /dev/null +++ b/MobileApp/src/components/common/loader.js @@ -0,0 +1,24 @@ +import React, { Component } from 'react' +import { ActivityIndicator, StyleSheet, View } from 'react-native' + +export default class Loader extends Component { + render() { + return ( + + + + ) + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center' + }, + horizontal: { + flexDirection: 'row', + justifyContent: 'space-around', + padding: 10 + } +}) diff --git a/MobileApp/src/components/event-list.js b/MobileApp/src/components/event-list.js deleted file mode 100644 index 7156d55..0000000 --- a/MobileApp/src/components/event-list.js +++ /dev/null @@ -1,26 +0,0 @@ -import React, { Component } from 'react' -import {ScrollView, StyleSheet, Text} from 'react-native' -import Card from './common/card' - -class EventList extends Component { - static propTypes = { - - }; - - render() { - return ( - - {this.props.events.map(event => - - {event.title} - - )} - - ) - } -} - -const styles = StyleSheet.create({ -}) - -export default EventList \ No newline at end of file diff --git a/MobileApp/src/components/events/event-list.js b/MobileApp/src/components/events/event-list.js index 47b9786..104ad5f 100644 --- a/MobileApp/src/components/events/event-list.js +++ b/MobileApp/src/components/events/event-list.js @@ -1,39 +1,49 @@ import React, { Component } from 'react' -import {Text, StyleSheet, SectionList} from 'react-native' +import { Text, StyleSheet, SectionList } from 'react-native' import EventCard from './event-card' import groupBy from 'lodash/groupBy' class EventList extends Component { - static propTypes = { + static propTypes = {} - }; - - render() { - const grouped = groupBy(this.props.events, event => event.title.charAt(0)) - const sections = Object.entries(grouped).map(([letter, list]) => ({ - title: `${letter}, ${list.length} events`, - data: list.map(event => ({key: event.uid, event})) - })) - return {section.title}} - renderItem = {({item}) => } - /> - } + render() { + const grouped = groupBy(this.props.events, (event) => event.title.charAt(0)) + const sections = Object.entries(grouped).map(([letter, list]) => ({ + title: `${letter}, ${list.length} events`, + data: list.map((event) => ({ key: event.uid, event })) + })) + 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 - } + sectionList: { + paddingLeft: 20, + paddingRight: 20 + }, + header: { + backgroundColor: '#F0F0F0', + height: 40, + lineHeight: 40, + marginBottom: 5, + shadowOffset: { + height: 2, + width: 0 + }, + shadowOpacity: 0.3, + elevation: 3 + } }) -export default EventList \ No newline at end of file +export default EventList diff --git a/MobileApp/src/components/people/people-list.js b/MobileApp/src/components/people/people-list.js new file mode 100644 index 0000000..a118e17 --- /dev/null +++ b/MobileApp/src/components/people/people-list.js @@ -0,0 +1,51 @@ +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 { + static propTypes = {} + + render() { + const grouped = groupBy(this.props.people, (person) => + person.firstName.charAt(0) + ) + const sections = Object.entries(grouped).map(([letter, list]) => ({ + title: `${letter}, ${list.length} people`, + data: list.map((person) => ({ key: person.uid, person })) + })) + return ( + ( + {section.title} + )} + renderItem={({ item }) => ( + + )} + /> + ) + } +} + +const styles = StyleSheet.create({ + sectionList: { + paddingLeft: 20, + paddingRight: 20 + }, + 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..fdbb635 --- /dev/null +++ b/MobileApp/src/components/people/person-card.js @@ -0,0 +1,20 @@ +import React, { Component } from 'react' +import { Text, StyleSheet } from 'react-native' +import Card from '../common/card' + +class PersonCard extends Component { + static propTypes = {} + + render() { + const { person } = this.props + return ( + + {person.firstName} + + ) + } +} + +const styles = StyleSheet.create({}) + +export default PersonCard diff --git a/MobileApp/src/components/screens/auth.js b/MobileApp/src/components/screens/auth.js index 4cf7d91..5dbf283 100644 --- a/MobileApp/src/components/screens/auth.js +++ b/MobileApp/src/components/screens/auth.js @@ -1,22 +1,19 @@ import React, { Component } from 'react' -import {View, StyleSheet} from 'react-native' +import { View, StyleSheet } from 'react-native' import SignIn from '../sign-in' class AuthScreen extends Component { - static propTypes = { + static propTypes = {} - }; + render() { + return + } - render() { - return - } - - handleSignIn = () => { - this.props.navigation.navigate('eventList') - } + handleSignIn = () => { + this.props.navigation.navigate('eventList') + } } -const styles = StyleSheet.create({ -}) +const styles = StyleSheet.create({}) -export default AuthScreen \ No newline at end of file +export default AuthScreen diff --git a/MobileApp/src/components/screens/event-list.js b/MobileApp/src/components/screens/event-list.js index 1b4240f..2f1a6b0 100644 --- a/MobileApp/src/components/screens/event-list.js +++ b/MobileApp/src/components/screens/event-list.js @@ -1,18 +1,38 @@ import React, { Component } from 'react' -import {View, StyleSheet} from 'react-native' +import { View, Text, StyleSheet } from 'react-native' +import { observer, inject } from 'mobx-react' 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.getAllEvents() + } + } - render() { - return + render() { + if (this.props.events.loading) { + return } + return ( + + Events list + + + ) + } } const styles = StyleSheet.create({ + header: { + fontSize: 30, + padding: 20 + } }) -export default EventListScreen \ No newline at end of file +export default EventListScreen diff --git a/MobileApp/src/components/screens/main.js b/MobileApp/src/components/screens/main.js new file mode 100644 index 0000000..fa1a946 --- /dev/null +++ b/MobileApp/src/components/screens/main.js @@ -0,0 +1,18 @@ +import { createMaterialTopTabNavigator } from 'react-navigation' +import EventListScreen from './event-list' +import PeopleListScreen from './people-list' + +export default createMaterialTopTabNavigator({ + eventList: { + screen: EventListScreen, + navigationOptions: { + title: 'Event List' + } + }, + peopleList: { + screen: PeopleListScreen, + navigationOptions: { + title: 'People List' + } + } +}) diff --git a/MobileApp/src/components/screens/people-list.js b/MobileApp/src/components/screens/people-list.js new file mode 100644 index 0000000..8af1118 --- /dev/null +++ b/MobileApp/src/components/screens/people-list.js @@ -0,0 +1,38 @@ +import React, { Component } from 'react' +import { View, Text, StyleSheet } from 'react-native' +import { observer, inject } from 'mobx-react' +import PeopleList from '../people/people-list' +import Loader from '../common/loader' + +@inject('people') +@observer +class PeopleListScreen extends Component { + static propTypes = {} + + componentDidMount() { + if (!this.props.people.loading && !this.props.people.loaded) { + this.props.people.getAllPeople() + } + } + + render() { + if (this.props.people.loading) { + return + } + return ( + + People list + + + ) + } +} + +const styles = StyleSheet.create({ + header: { + fontSize: 30, + padding: 20 + } +}) + +export default PeopleListScreen diff --git a/MobileApp/src/components/sign-in.js b/MobileApp/src/components/sign-in.js index d451ace..6f43639 100644 --- a/MobileApp/src/components/sign-in.js +++ b/MobileApp/src/components/sign-in.js @@ -1,62 +1,60 @@ import React, { Component } from 'react' -import {View, Text, TextInput, TouchableOpacity, Platform} from 'react-native' -import {observer, inject} from 'mobx-react' +import { View, Text, TextInput, TouchableOpacity, Platform } from 'react-native' +import { observer, inject } from 'mobx-react' @inject('user') @observer class SignIn extends Component { - render() { - return ( - - Please Sign In: - - Email: - - - - Password: - isValidPassowrd: {this.props.user.isValidPassword} - - - - Submit - - - ) - } + render() { + return ( + + Please Sign In: + + Email: + + + + Password: + isValidPassowrd: {this.props.user.isValidPassword} + + + + Submit + + + ) + } - handleEmailChange = this.props.user.setEmail - handlePasswordChange = this.props.user.setPassword + handleEmailChange = this.props.user.setEmail + handlePasswordChange = this.props.user.setPassword - handleSubmit = this.props.user.signIn + handleSubmit = this.props.user.signIn } const styles = { - container: { - flex: 1, - flexDirection: 'column', - justifyContent: 'space-around' - }, - input: { - ...Platform.select({ - ios: { - borderBottomWidth: 1 - }, - android: { - - } - }) - } + container: { + flex: 1, + flexDirection: 'column', + justifyContent: 'space-around' + }, + input: { + ...Platform.select({ + ios: { + borderBottomWidth: 1 + }, + android: {} + }) + } } -export default SignIn \ No newline at end of file +export default SignIn diff --git a/MobileApp/src/config.js b/MobileApp/src/config.js index aa22b3b..8f4a95d 100644 --- a/MobileApp/src/config.js +++ b/MobileApp/src/config.js @@ -2,15 +2,15 @@ import firebase from 'firebase/app' import 'firebase/auth' import 'firebase/database' -export const appName = 'advreact-10-05' +export const appName = 'advreact-10-05-ee9f5' export const config = { - apiKey: 'AIzaSyCbMQM0eQUSQ0SuLVAu9ZNPUcm4rdbiB8U', + apiKey: 'AIzaSyA9z4Xmknc0zIAIfvWCfe4XWwhwqiTO9h0', authDomain: `${appName}.firebaseapp.com`, databaseURL: `https://${appName}.firebaseio.com`, projectId: appName, storageBucket: '', - messagingSenderId: '1094825197832' + messagingSenderId: '963790431937' } firebase.initializeApp(config) diff --git a/MobileApp/src/stores/events.js b/MobileApp/src/stores/events.js new file mode 100644 index 0000000..90f2a52 --- /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 = null + + getAllEvents = 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..2f6fd39 100644 --- a/MobileApp/src/stores/index.js +++ b/MobileApp/src/stores/index.js @@ -1,12 +1,18 @@ 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 navigationStore = new NavigationStore() export const userStore = new UserStore(navigationStore) +export const eventsStore = new EventsStore() +export const peopleStore = new PeopleStore() export default { - user: userStore, - navigation: navigationStore -} \ No newline at end of file + user: userStore, + events: eventsStore, + people: peopleStore, + navigation: navigationStore +} diff --git a/MobileApp/src/stores/people.js b/MobileApp/src/stores/people.js new file mode 100644 index 0000000..76437c7 --- /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 = null + + getAllPeople = 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..632dd87 100644 --- a/MobileApp/src/stores/user.js +++ b/MobileApp/src/stores/user.js @@ -1,30 +1,32 @@ -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(navigationStore) { + this.navigationStore = navigationStore + } - @observable email = '' - @observable password = '' - @observable user = null + @observable email = 'test@test.ru' + @observable password = '12345678' + @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 + this.navigationStore.navigate('main') + }) + .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 }))