Introduces Home component redesign

This commit is contained in:
mashazyu
2020-03-24 20:15:01 +01:00
committed by Sofiya Tepikin
parent b6c0fd0dce
commit 29d76d19b1
11 changed files with 150 additions and 180 deletions
+9 -2
View File
@@ -6,10 +6,16 @@ import Link from './link'
import { Colors, Typography } from '../../styles/redesign'
export default function AppText({ children, onPress, numberOfLines, style}) {
export default function AppText({
children,
linkStyle,
onPress,
numberOfLines,
style
}) {
// we parse for links in case the text contains any
return (
<Link>
<Link style={linkStyle}>
<Text style={[styles.text, style]}
onPress={onPress}
numberOfLines={numberOfLines}
@@ -22,6 +28,7 @@ export default function AppText({ children, onPress, numberOfLines, style}) {
AppText.propTypes = {
children: PropTypes.node,
linkStyle: PropTypes.object,
onPress: PropTypes.func,
numberOfLines: PropTypes.number,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
+21 -10
View File
@@ -7,7 +7,7 @@ import AppText from './app-text'
import { Colors, Fonts, Spacing } from '../../styles/redesign'
const Button = ({ children, isCTA, onPress, testID }) => {
const buttonStyle = isCTA ? styles.orange : {}
const buttonStyle = isCTA ? styles.cta : styles.regular
const textStyle = isCTA ? styles.buttonTextBold : styles.buttonTextRegular
return (
<TouchableOpacity onPress={onPress} style={buttonStyle} testID={testID}>
@@ -23,24 +23,35 @@ Button.propTypes = {
testID: PropTypes.string
}
const button = {
paddingHorizontal: Spacing.large,
paddingVertical: Spacing.base,
const text = {
padding: Spacing.base,
textTransform: 'uppercase'
}
const button = {
alignItems: 'center',
justifyContent: 'center',
margin: Spacing.base
}
const styles = StyleSheet.create({
orange: {
regular: {
...button
},
cta: {
backgroundColor: Colors.orange,
borderRadius: 25
borderRadius: 25,
...button
},
buttonTextBold: {
fontFamily: Fonts.main,
...button
color: 'white',
fontFamily: Fonts.bold,
...text
},
buttonTextRegular: {
fontFamily: Fonts.bold,
...button
color: Colors.greyDark,
fontFamily: Fonts.main,
...text
}
})
+4 -3
View File
@@ -7,10 +7,10 @@ import { Colors, Typography } from '../../styles/redesign'
import links from '../../i18n/en/links'
const Link = ({ children }) => {
const Link = ({ children, style }) => {
return (
<Hyperlink
linkStyle={styles.link}
linkStyle={[styles.link, style]}
linkText={replaceUrlWithText}
linkDefault
>
@@ -20,7 +20,8 @@ const Link = ({ children }) => {
}
Link.propTypes = {
children: PropTypes.node
children: PropTypes.node,
style: PropTypes.object
}
const styles = StyleSheet.create({
+1 -1
View File
@@ -10,7 +10,7 @@ const Icon = createIconSetFromIcoMoon(iconConfig, '', 'Menu')
const MenuIcon = ({ isActive, name }) => {
const color = isActive ? Colors.greyDark : Colors.grey
return <Icon name={name} size={Sizes.icon} color={color} />
return <Icon name={name} size={Sizes.huge} color={color} />
}
MenuIcon.propTypes = {
+7
View File
@@ -62,3 +62,10 @@ export function getBleedingPredictionRange(prediction) {
}
return (daysToEnd === 0 ? '0' : `0 - ${daysToEnd}`)
}
export const dateEnding = {
'1': 'st',
'2': 'nd',
'3': 'rd',
'default': 'th'
}
-40
View File
@@ -1,40 +0,0 @@
import React from 'react'
import { View } from 'react-native'
import PropTypes from 'prop-types'
import Button from './common/button'
import styles from '../styles'
const HomeElement = ({ children, onPress, buttonColor, buttonLabel }) => {
return (
<View
onPress={ onPress }
style={ styles.homeElement }
>
<View style={styles.homeIconAndText}>
{children[0]}
{children[1]}
</View>
<View style={{paddingLeft: 15}}>
{children.slice(2)}
<Button
style={styles.homeButton}
onPress={ onPress }
backgroundColor={ buttonColor }>
{ buttonLabel }
</Button>
</View>
</View>
)
}
HomeElement.propTypes = {
buttonColor: PropTypes.string,
buttonLabel: PropTypes.string,
children: PropTypes.node,
onPress: PropTypes.func,
}
export default HomeElement
+99 -98
View File
@@ -1,54 +1,51 @@
import { LocalDate } from 'js-joda'
import React, { Component } from 'react'
import { ScrollView, View } from 'react-native'
import { connect } from 'react-redux'
import { ScrollView, StyleSheet, View } from 'react-native'
import PropTypes from 'prop-types'
import { LocalDate } from 'js-joda'
import { connect } from 'react-redux'
import { navigate } from '../slices/navigation'
import { getDate, setDate } from '../slices/date'
import DripHomeIcon from '../assets/drip-home-icons'
import AppText from './common/app-text'
import IconText from './icon-text'
import HomeElement from './home-element'
import { home as labels } from '../i18n/en/labels'
import links from '../i18n/en/links'
import Button from './common/button'
import cycleModule from '../lib/cycle'
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
import {
determinePredictionText,
getBleedingPredictionRange
} from './helpers/home'
import { determinePredictionText, dateEnding } from './helpers/home'
import styles, { cycleDayColor, periodColor, secondaryColor } from '../styles'
import { Colors, Fonts, Sizes, Spacing } from '../styles/redesign'
import { homeRedesign as labels, home as cycle } from '../i18n/en/labels'
class Home extends Component {
static propTypes = {
navigate: PropTypes.func,
setDate: PropTypes.func,
// The following are not being used,
// we could see if it's possible to not pass them from the <App />
cycleDay: PropTypes.object,
date: PropTypes.string,
setDate: PropTypes.func
}
constructor(props) {
super(props)
const today = LocalDate.now()
this.todayDateString = today.toString()
const { getCycleDayNumber, getPredictedMenses } = cycleModule()
this.todayDateString = LocalDate.now().toString()
this.cycleDayNumber = getCycleDayNumber(this.todayDateString)
const {status, phase, statusText} =
getFertilityStatusForDay(this.todayDateString)
const prediction = getPredictedMenses()
this.predictionText = determinePredictionText(prediction)
this.bleedingPredictionRange = getBleedingPredictionRange(prediction)
this.fertilityStatus = getFertilityStatusForDay(this.todayDateString)
this.cycleDayText = !this.cycleDayNumber ? cycle.cycleDayNotEnoughInfo
: `${this.cycleDayNumber}${dateEnding[this.cycleDayNumber] || dateEnding['default']}`
this.phase = phase
this.phaseText = !phase ? statusText
: `${phase}${dateEnding[phase] || dateEnding['default']}`
this.prediction = determinePredictionText(prediction)
this.status = status
this.statusText = statusText
this.title = `${today.dayOfMonth()} ${today.month()}`
}
navigateToCycleDayView = () => {
@@ -56,88 +53,92 @@ class Home extends Component {
this.props.navigate('CycleDay')
}
navigateToBleedingEditView = () => {
this.props.setDate(this.todayDateString)
this.props.navigate('BleedingEditView')
}
navigateToChart = () => {
this.props.navigate('Chart')
}
render() {
const {
cycleDayNumber,
predictionText,
bleedingPredictionRange,
cycleDayText,
phase,
phaseText,
prediction,
status,
statusText,
title
} = this
const { phase, status, statusText } = this.fertilityStatus
const cycleDayMoreText = cycleDayNumber ?
labels.cycleDayKnown(cycleDayNumber) :
labels.cycleDayNotEnoughInfo
return (
<View flex={1}>
<ScrollView>
<View style={styles.homeView}>
<HomeElement
onPress={this.navigateToCycleDayView}
buttonColor={ cycleDayColor }
buttonLabel={ labels.editToday }
>
<View>
<DripHomeIcon name="circle" size={80} color={cycleDayColor}/>
</View>
<IconText>{cycleDayNumber || labels.unknown}</IconText>
<AppText style={styles.homeDescriptionText}>
{cycleDayMoreText}
</AppText>
</HomeElement>
<HomeElement
onPress={this.navigateToBleedingEditView}
buttonColor={ periodColor }
buttonLabel={ labels.trackPeriod }
>
<DripHomeIcon name="drop" size={100} color={periodColor} />
<IconText wrapperStyles={{ top: '45%' }}>
{bleedingPredictionRange}
</IconText>
<AppText style={styles.homeDescriptionText}>
{predictionText}
</AppText>
</HomeElement>
<HomeElement
onPress={this.navigateToChart}
buttonColor={ secondaryColor }
buttonLabel={ labels.checkFertility }
>
<View style={styles.homeCircle}/>
<IconText>{ phase ? phase.toString() : labels.unknown }</IconText>
{ phase &&
<AppText style={styles.homeDescriptionText}>
{`${labels.phase(phase)} (${status})`}
</AppText>
}
<AppText style={styles.homeDescriptionText}>
{ `${statusText} Visit ${links.wiki.url}.` }
</AppText>
</HomeElement>
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainer}
>
<AppText style={styles.title}>{title}</AppText>
<View style={styles.line}>
{this.cycleDayNumber && (
<React.Fragment>
<AppText style={styles.whiteText}>{cycleDayText}</AppText>
<AppText>{labels.cycleDay}</AppText>
</React.Fragment>
)}
{!this.cycleDayNumber && <AppText>{cycleDayText}</AppText>}
</View>
<View style={styles.line}>
{!phase && <AppText>{phaseText}</AppText>}
{phase && (
<React.Fragment>
<AppText style={styles.whiteText}>{phaseText}</AppText>
<AppText>{labels.cyclePhase}</AppText>
<AppText>{status}</AppText>
<Asterisk />
</React.Fragment>
)}
</View>
<View style={styles.line}>
<AppText>{prediction}</AppText>
</View>
<Button onPress={this.navigateToCycleDayView} isCTA>
{labels.addData}
</Button>
{phase && (
<View style={styles.line}>
<Asterisk />
<AppText linkStyle={styles.whiteText}>{statusText}</AppText>
</View>
</ScrollView>
</View>
)}
</ScrollView>
)
}
}
const Asterisk = () => {
return <AppText style={styles.asterisk}>*</AppText>
}
const styles = StyleSheet.create({
asterisk: {
color: Colors.orange,
paddingRight: Spacing.base
},
container: {
backgroundColor: Colors.purple,
flex: 1
},
contentContainer: {
padding: Spacing.base
},
line: {
flexDirection: 'row',
justifyContent: 'flex-start',
marginBottom: Spacing.tiny
},
title: {
color: Colors.purpleLight,
fontFamily: Fonts.bold,
fontSize: Sizes.huge,
marginVertical: Spacing.base,
},
whiteText: {
color: 'white'
}
})
const mapStateToProps = (state) => {
return({
date: getDate(state),
-24
View File
@@ -1,24 +0,0 @@
import React from 'react'
import { View } from 'react-native'
import PropTypes from 'prop-types'
import AppText from './common/app-text'
import styles from '../styles'
const IconText = ({ children, wrapperStyles }) => {
return (
<View style={[ styles.homeIconTextWrapper, wrapperStyles ]}>
<AppText style={styles.iconText}>
{ children }
</AppText>
</View>
)
}
IconText.propTypes = {
children: PropTypes.node,
wrapperStyles: PropTypes.object,
}
export default IconText
+7 -1
View File
@@ -1,6 +1,12 @@
import labels from './settings'
const settingsTitles = labels.menuItems
export const homeRedesign = {
cycleDay: ' day of your cycle',
cyclePhase: ' cycle phase - ',
addData: 'add data for today'
}
export const shared = {
cancel: 'Cancel',
save: 'Save',
@@ -113,7 +119,7 @@ export const fertilityStatus = {
fertileUntilEvening: 'Fertile phase ends in the evening',
unknown: 'We cannot show any cycle information because no period data has been added.',
preOvuText: "With NFP rules, you may assume 5 days of infertility at the beginning of your cycle, provided you don't observe any fertile cervical mucus or cervix values.",
periOvuText: "We have not been able to detect both a temperature shift and cervical mucus or cervix shift. Please find more information on NFP rules here:",
periOvuText: "We have not been able to detect both a temperature shift and cervical mucus or cervix shift. Please find more information on NFP rules here: https://gitlab.com/bloodyhealth/drip/wikis/home",
postOvuText: tempRule => {
return (
'We have detected a temperature shift (' + ['regular', '1st exception', '2nd exception'][tempRule] +
+1
View File
@@ -1,4 +1,5 @@
export default {
tiny: 4,
small: 10,
base: 16,
large: 20
+1 -1
View File
@@ -11,7 +11,7 @@ export const sizes = {
base: 18,
subtitle: 22,
title: 24,
icon: 40
huge: 40
}
const title = {