diff --git a/components/app.js b/components/app.js index 73403d6..fc8f7e3 100644 --- a/components/app.js +++ b/components/app.js @@ -20,20 +20,17 @@ const headerTitlesLowerCase = Object.keys(headerTitles).reduce((acc, curr) => { acc[curr] = headerTitles[curr].toLowerCase() return acc }, {}) -const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => { - acc[curr] = menuTitles[curr].toLowerCase() - return acc -}, {}) -const isSymptomView = name => Object.keys(symptomViews).includes(name) -const isSettingsView = name => Object.keys(settingsViews).includes(name) -const isMenuItem = name => Object.keys(menuTitles).includes(name) +const HOME_PAGE = 'Home' +const INFO_SYMPTOM_PAGE = 'InfoSymptom' +const CYCLE_DAY_PAGE = 'CycleDay' +const SETTINGS_MENU_PAGE = 'SettingsMenu' export default class App extends Component { constructor(props) { super(props) this.state = { - currentPage: 'Home' + currentPage: HOME_PAGE } this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonPress) setupNotifications(this.navigate) @@ -44,91 +41,107 @@ export default class App extends Component { } navigate = (pageName, props) => { + const { currentPage } = this.state // for the back button to work properly, we want to // remember two origins: which menu item we came from // and from where we navigated to the symptom view (day // view or home page) - if (isMenuItem(this.state.currentPage)) { - this.menuOrigin = this.state.currentPage + if (this.isMenuItem()) { + this.menuOrigin = currentPage } - if (!isSymptomView(this.state.currentPage) && - this.state.currentPage !== 'InfoSymptom') { - this.originForSymptomView = this.state.currentPage + if (!this.isSymptomView() && !this.isInfoSymptomView()) { + this.originForSymptomView = currentPage } - this.setState({currentPage: pageName, currentProps: props}) + this.setState({ currentPage: pageName, currentProps: props }) } handleBackButtonPress = () => { - if (this.state.currentPage === 'Home') return false - if (isSymptomView(this.state.currentPage)) { + const { currentPage, currentProps } = this.state + if (currentPage === HOME_PAGE) return false + if (this.isSymptomView()) { this.navigate( - this.originForSymptomView, { date: this.state.currentProps.date } + this.originForSymptomView, { date: currentProps.date } ) - } else if (isSettingsView(this.state.currentPage)) { - this.navigate('SettingsMenu') - } else if (this.state.currentPage === 'CycleDay') { + } else if (this.isSettingsView()) { + this.navigate(SETTINGS_MENU_PAGE) + } else if (currentPage === CYCLE_DAY_PAGE) { this.navigate(this.menuOrigin) - } else if (this.state.currentPage === 'InfoSymptom') { + } else if (this.isInfoSymptomView()) { + const { date, cycleDay, symptomView } = currentProps this.navigate( - this.state.currentProps.symptomView, { - date: this.state.currentProps.date, - cycleDay: this.state.currentProps.cycleDay - }) + symptomView, { date, cycleDay }) } else { - this.navigate('Home') + this.navigate(HOME_PAGE) } return true } + isMenuItem() { + return Object.keys(menuTitles).includes(this.state.currentPage) + } + + isSymptomView() { + return Object.keys(symptomViews).includes(this.state.currentPage) + } + + isInfoSymptomView() { + return this.state.currentPage === INFO_SYMPTOM_PAGE + } + + isSettingsView() { + return Object.keys(settingsViews).includes(this.state.currentPage) + } + isDefaultView() { - return this.state.currentPage !== 'CycleDay' && - !isSymptomView(this.state.currentPage) && - this.state.currentPage !== 'InfoSymptom' + const { currentPage } = this.state + return currentPage !== CYCLE_DAY_PAGE && + !this.isSymptomView() && + !this.isInfoSymptomView() } render() { - const page = { - Home, Calendar, CycleDay, Chart, InfoSymptom, - SettingsMenu, ...settingsViews, Stats, ...symptomViews - }[this.state.currentPage] + const { currentPage, currentProps } = this.state + const pages = { + Home, + Calendar, + CycleDay, + Chart, + InfoSymptom, + SettingsMenu, + ...settingsViews, + Stats, + ...symptomViews + } + const page = pages[currentPage] + const title = headerTitlesLowerCase[currentPage] + const isSymptomView = this.isSymptomView() return ( {this.isDefaultView() && -
+
} - {this.state.currentPage === 'InfoSymptom' && -
+ {this.isInfoSymptomView() && +
} - {isSymptomView(this.state.currentPage) && + {isSymptomView &&
this.navigate('InfoSymptom', { - date: this.state.currentProps.date, - symptomView: this.state.currentPage, - cycleDay: this.state.currentProps.cycleDay + date={currentProps.date} + goToSymptomInfo={() => this.navigate(INFO_SYMPTOM_PAGE, { + symptomView: currentPage, + ...currentProps })} />} - {React.createElement(page, { navigate: this.navigate, - ...this.state.currentProps + ...currentProps })} - {!isSymptomView(this.state.currentPage) && - + {!isSymptomView && + } ) diff --git a/components/menu.js b/components/menu.js index 7a692e0..26a752d 100644 --- a/components/menu.js +++ b/components/menu.js @@ -1,46 +1,84 @@ -import React, { Component } from 'react' +import React from 'react' import { View, Text, TouchableOpacity } from 'react-native' + +import settingsViews from './settings' + +import { menuTitles } from '../i18n/en/labels' + import styles, { iconStyles, secondaryColor } from '../styles' import Icon from 'react-native-vector-icons/MaterialCommunityIcons' -export default class Menu extends Component { - makeMenuItem = ({ title, icon, onPress}, i) => { - const styleActive = (this.props.currentPage.toLowerCase() === title) ? - {color: secondaryColor} : {} - return ( - - - - {title} - - - ) - } +const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => { + acc[curr] = menuTitles[curr].toLowerCase() + return acc +}, {}) - goTo(componentName) { - this.props.navigate(componentName) +const menuItems = [ + { + labelKey: 'Home', + icon: 'home', + component: 'Home', + }, + { + labelKey: 'Calendar', + icon: 'calendar-range', + component: 'Calendar', + }, + { + labelKey: 'Chart', + icon: 'chart-line', + component: 'Chart', + }, + { + labelKey: 'Stats', + icon: 'chart-pie', + component: 'Stats', + }, + { + labelKey: 'Settings', + icon: 'settings', + component: 'SettingsMenu', + children: Object.keys(settingsViews), } +] - render() { - const t = this.props.titles - return ( - - {[ - { title: t.Home, icon: 'home', onPress: () => this.goTo('Home') }, - { title: t.Calendar, icon: 'calendar-range', onPress: () => this.goTo('Calendar') }, - { title: t.Chart, icon: 'chart-line', onPress: () => this.goTo('Chart') }, - { title: t.Stats, icon: 'chart-pie', onPress: () => this.goTo('Stats') }, - { title: t.Settings, icon: 'settings', onPress: () => this.goTo('SettingsMenu') }, - ].map(this.makeMenuItem)} - - ) - } +const MenuItem = ({ icon, labelKey, active, onPress }) => { + const styleActive = active ? { color: secondaryColor } : null + return ( + + + + {menuTitlesLowerCase[labelKey]} + + + ) } + +const Menu = ({ currentPage, navigate }) => { + return ( + + { menuItems.map(({ icon, labelKey, component, children }) => { + const isActive = (component === currentPage) || + (children && children.indexOf(currentPage) !== -1) + return ( + navigate(component)} + /> + )} + )} + + ) +} + +export default Menu \ No newline at end of file