diff --git a/.eslintrc b/.eslintrc
index 761d707..7fb97d8 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -44,7 +44,7 @@
"no-var": "error",
"prefer-const": "error",
"no-trailing-spaces": "error",
- "react/prop-types": 0,
+ "react/prop-types": 2,
"max-len": [
1,
{
diff --git a/components/app-text-input.js b/components/app-text-input.js
index 50bf3f1..54e4a19 100644
--- a/components/app-text-input.js
+++ b/components/app-text-input.js
@@ -18,7 +18,11 @@ export default function AppTextInput({ style, ...props }) {
}
AppTextInput.propTypes = {
- secureTextEntry: PropTypes.bool
+ autoFocus: PropTypes.bool,
+ onChangeText: PropTypes.func,
+ placeholder: PropTypes.string,
+ style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
+ value: PropTypes.string,
}
AppTextInput.defaultProps = {
diff --git a/components/app-text.js b/components/app-text.js
index 83e8781..e2c6210 100644
--- a/components/app-text.js
+++ b/components/app-text.js
@@ -1,27 +1,26 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { Text } from 'react-native'
import styles from "../styles"
import Link from './link'
-export default function AppText(props) {
+export default function AppText({ children, onPress, numberOfLines, style}) {
// we parse for links in case the text contains any
return (
-
- {props.children}
+ {children}
)
}
-export function SymptomSectionHeader(props) {
- return (
-
- {props.children}
-
- )
-}
\ No newline at end of file
+AppText.propTypes = {
+ children: PropTypes.node,
+ onPress: PropTypes.func,
+ numberOfLines: PropTypes.number,
+ style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
+}
diff --git a/components/button.js b/components/button.js
index 41d5344..be06408 100644
--- a/components/button.js
+++ b/components/button.js
@@ -1,22 +1,31 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { TouchableOpacity } from 'react-native'
import AppText from './app-text'
import styles from '../styles'
-export default function Button(props) {
+export default function Button({
+ backgroundColor,
+ children,
+ onPress,
+ style,
+ testID
+}) {
return (
-
- {props.children}
-
+ {children}
)
-}
\ No newline at end of file
+}
+
+Button.propTypes = {
+ backgroundColor: PropTypes.string,
+ children: PropTypes.node,
+ onPress: PropTypes.func,
+ style: PropTypes.object,
+ testID: PropTypes.string
+}
diff --git a/components/calendar.js b/components/calendar.js
index 9387e0c..2340168 100644
--- a/components/calendar.js
+++ b/components/calendar.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { CalendarList } from 'react-native-calendars'
import { connect } from 'react-redux'
@@ -13,6 +14,11 @@ import styles from '../styles/index'
import nothingChanged from '../db/db-unchanged'
class CalendarView extends Component {
+ static propTypes = {
+ setDate: PropTypes.func.isRequired,
+ navigate: PropTypes.func.isRequired
+ }
+
constructor(props) {
super(props)
this.bleedingDays = getBleedingDaysSortedByDate()
diff --git a/components/chart/chart.js b/components/chart/chart.js
index 9598552..d11131a 100644
--- a/components/chart/chart.js
+++ b/components/chart/chart.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { View, FlatList, ActivityIndicator } from 'react-native'
import AppLoadingView from '../app-loading'
@@ -17,6 +18,11 @@ import config from '../../config'
import styles from './styles'
export default class CycleChart extends Component {
+ static propTypes = {
+ navigate: PropTypes.func,
+ end: PropTypes.bool
+ }
+
constructor(props) {
super(props)
this.state = {}
@@ -147,12 +153,14 @@ export default class CycleChart extends Component {
}
}
-function LoadingMoreView(props) {
+function LoadingMoreView({ end }) {
return (
- {!props.end &&
-
- }
+ {!end && }
)
}
+
+LoadingMoreView.propTypes = {
+ end: PropTypes.bool
+}
diff --git a/components/chart/day-column.js b/components/chart/day-column.js
index fffc1fc..687b993 100644
--- a/components/chart/day-column.js
+++ b/components/chart/day-column.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { TouchableOpacity } from 'react-native'
import { connect } from 'react-redux'
@@ -18,6 +19,18 @@ import {
} from '../helpers/chart'
class DayColumn extends Component {
+ static propTypes = {
+ dateString: PropTypes.string.isRequired,
+ chartSymptoms: PropTypes.array,
+ columnHeight: PropTypes.number.isRequired,
+ getFhmAndLtlInfo: PropTypes.func.isRequired,
+ navigate: PropTypes.func.isRequired,
+ setDate: PropTypes.func.isRequired,
+ symptomHeight: PropTypes.number.isRequired,
+ symptomRowSymptoms: PropTypes.array,
+ xAxisHeight: PropTypes.number
+ }
+
constructor(props) {
super()
diff --git a/components/chart/dot-and-line.js b/components/chart/dot-and-line.js
index 21e9eeb..be5be85 100644
--- a/components/chart/dot-and-line.js
+++ b/components/chart/dot-and-line.js
@@ -1,10 +1,20 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { Path, Shape } from 'react-native/Libraries/ART/ReactNativeART'
import styles from './styles'
import config from '../../config'
export default class DotAndLine extends Component {
+ static propTypes = {
+ exclude: PropTypes.bool,
+ leftY: PropTypes.number,
+ leftTemperatureExclude: PropTypes.bool,
+ rightY: PropTypes.number,
+ rightTemperatureExclude: PropTypes.bool,
+ y: PropTypes.number.isRequired
+ }
+
shouldComponentUpdate(newProps) {
return Object.keys(newProps).some(key => newProps[key] != this.props[key])
}
diff --git a/components/cycle-day/SymptomBox.js b/components/cycle-day/SymptomBox.js
index b4af7c3..62f5df0 100644
--- a/components/cycle-day/SymptomBox.js
+++ b/components/cycle-day/SymptomBox.js
@@ -1,4 +1,5 @@
-import React, { Component } from 'react'
+import React from 'react'
+import PropTypes from 'prop-types'
import { View, TouchableOpacity } from 'react-native'
import AppText from '../app-text'
@@ -124,47 +125,50 @@ const l = {
}
}
-export default class SymptomBox extends Component {
- getLabel = () => {
- const { symptom, symptomData } = this.props
- return symptomData && l[symptom](symptomData)
- }
-
- render() {
- const { symptom, onPress, disabled } = this.props
- const data = this.getLabel()
- const iconName = `drip-icon-${symptom}`
-
- const disabledStyle = disabled ? styles.symptomInFuture : null
- const containerStyle = [
- styles.symptomBox,
- data && styles.symptomBoxActive,
- disabledStyle
- ]
- const titleStyle = [
- data && styles.symptomTextActive,
- disabledStyle,
- {fontSize: 15}
- ]
- const dataBoxStyle = [styles.symptomDataBox, disabledStyle]
-
- return (
-
-
-
-
- {symptomTitles[symptom].toLowerCase()}
-
-
-
-
- {data}
-
-
-
- )
- }
+const getLabel = (symptom, symptomData) => {
+ return symptomData && l[symptom](symptomData)
}
-const Icon = ({name, isActive}) =>
-
\ No newline at end of file
+export default function SymptomBox(
+ { disabled, onPress, symptom, symptomData }) {
+
+ const data = getLabel(symptom, symptomData)
+ const iconName = `drip-icon-${symptom}`
+
+ const disabledStyle = disabled ? styles.symptomInFuture : null
+ const containerStyle = [
+ styles.symptomBox,
+ data && styles.symptomBoxActive,
+ disabledStyle
+ ]
+ const titleStyle = [
+ data && styles.symptomTextActive,
+ disabledStyle,
+ {fontSize: 15}
+ ]
+ const dataBoxStyle = [styles.symptomDataBox, disabledStyle]
+ const iconColor = data ? 'white' : 'black'
+
+ return (
+
+
+
+
+ {symptomTitles[symptom].toLowerCase()}
+
+
+
+
+ {data}
+
+
+
+ )
+}
+
+SymptomBox.propTypes = {
+ disabled: PropTypes.bool.isRequired,
+ onPress: PropTypes.func.isRequired,
+ symptom: PropTypes.string.isRequired,
+ symptomData: PropTypes.object
+}
\ No newline at end of file
diff --git a/components/cycle-day/select-box-group.js b/components/cycle-day/select-box-group.js
index 3ff1f58..ee64d00 100644
--- a/components/cycle-day/select-box-group.js
+++ b/components/cycle-day/select-box-group.js
@@ -1,34 +1,38 @@
-import React, { Component } from 'react'
-import {
- View,
- TouchableOpacity,
-} from 'react-native'
-import styles from '../../styles'
+import React from 'react'
+import PropTypes from 'prop-types'
+import { View, TouchableOpacity } from 'react-native'
+
import AppText from '../app-text'
-export default class SelectBoxGroup extends Component {
- render() {
- return (
-
- {Object.keys(this.props.labels).map(key => {
- const style = [styles.selectBox]
- const textStyle = []
- if (this.props.optionsState[key]) {
- style.push(styles.selectBoxActive)
- textStyle.push(styles.selectBoxTextActive)
- }
- return (
- this.props.onSelect(key)}
- key={key}
- >
-
- {this.props.labels[key]}
-
-
- )
- })}
-
- )
- }
-}
\ No newline at end of file
+import styles from '../../styles'
+
+export default function SelectBoxGroup({ labels, onSelect, optionsState }) {
+ return (
+
+ {Object.keys(labels).map(key => {
+ const style = [styles.selectBox]
+ const textStyle = []
+ if (optionsState[key]) {
+ style.push(styles.selectBoxActive)
+ textStyle.push(styles.selectBoxTextActive)
+ }
+ return (
+ onSelect(key)}
+ key={key}
+ >
+
+ {labels[key]}
+
+
+ )
+ })}
+
+ )
+}
+
+SelectBoxGroup.propTypes = {
+ labels: PropTypes.object.isRequired,
+ onSelect: PropTypes.func.isRequired,
+ optionsState: PropTypes.object.isRequired
+}
diff --git a/components/cycle-day/select-tab-group.js b/components/cycle-day/select-tab-group.js
index 63c0536..a8fffc6 100644
--- a/components/cycle-day/select-tab-group.js
+++ b/components/cycle-day/select-tab-group.js
@@ -1,47 +1,50 @@
-import React, { Component } from 'react'
-import {
- View,
- TouchableOpacity,
-} from 'react-native'
-import styles from '../../styles'
+import React from 'react'
+import PropTypes from 'prop-types'
+import { View, TouchableOpacity } from 'react-native'
+
import AppText from '../app-text'
-export default class SelectTabGroup extends Component {
- render() {
- const { buttons, onSelect } = this.props
- return (
-
- {
- buttons.map(({ label, value }, i) => {
- let firstOrLastStyle
- if (i === buttons.length - 1) {
- firstOrLastStyle = styles.selectTabLast
- } else if (i === 0) {
- firstOrLastStyle = styles.selectTabFirst
- }
- let activeStyle
- const isActive = value === this.props.active
- if (isActive) activeStyle = styles.selectTabActive
- return (
- onSelect(isActive ? null : value)}
- key={i}
- activeOpacity={1}
- >
-
-
- {label}
-
+import styles from '../../styles'
+
+export default function SelectTabGroup({ active, buttons, onSelect }) {
+ return (
+
+ {
+ buttons.map(({ label, value }, i) => {
+ let firstOrLastStyle
+ if (i === buttons.length - 1) {
+ firstOrLastStyle = styles.selectTabLast
+ } else if (i === 0) {
+ firstOrLastStyle = styles.selectTabFirst
+ }
+ let activeStyle
+ const isActive = value === active
+ if (isActive) activeStyle = styles.selectTabActive
+ return (
+ onSelect(isActive ? null : value)}
+ key={i}
+ activeOpacity={1}
+ >
+
+
+ {label}
-
- )
- })
- }
-
- )
- }
+
+
+ )
+ })
+ }
+
+ )
+}
+
+SelectTabGroup.propTypes = {
+ active: PropTypes.number,
+ buttons: PropTypes.array.isRequired,
+ onSelect: PropTypes.func.isRequired
}
\ No newline at end of file
diff --git a/components/cycle-day/symptoms/desire.js b/components/cycle-day/symptoms/desire.js
index 1898366..de05f52 100644
--- a/components/cycle-day/symptoms/desire.js
+++ b/components/cycle-day/symptoms/desire.js
@@ -21,7 +21,7 @@ class Desire extends Component {
const symptom = 'desire'
const { cycleDay } = props
- const defaultSymptomData = { value: '' }
+ const defaultSymptomData = { value: null }
const symptomData =
cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData
diff --git a/components/cycle-day/symptoms/info-symptom.js b/components/cycle-day/symptoms/info-symptom.js
index 887b229..93820e2 100644
--- a/components/cycle-day/symptoms/info-symptom.js
+++ b/components/cycle-day/symptoms/info-symptom.js
@@ -1,22 +1,28 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { ScrollView, View, TouchableOpacity } from 'react-native'
import Icon from 'react-native-vector-icons/SimpleLineIcons'
import AppText from '../../app-text'
import labels from '../../../i18n/en/symptom-info.js'
import styles, {iconStyles} from '../../../styles/index'
-export default function InfoSymptom(props) {
+export default function InfoSymptom({ close, symptom }) {
return (
-
+
- {labels[props.symptom].text}
+ {labels[symptom].text}
)
}
+
+InfoSymptom.propTypes = {
+ close: PropTypes.func.isRequired,
+ symptom: PropTypes.string.isRequired
+}
diff --git a/components/cycle-day/symptoms/note.js b/components/cycle-day/symptoms/note.js
index 17cfef1..4dd7866 100644
--- a/components/cycle-day/symptoms/note.js
+++ b/components/cycle-day/symptoms/note.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { TextInput } from 'react-native'
import SymptomSection from './symptom-section'
@@ -9,6 +10,11 @@ import SymptomView from './symptom-view'
import { saveSymptom } from '../../../db'
class Note extends Component {
+ static propTypes = {
+ cycleDay: PropTypes.object.isRequired,
+ date: PropTypes.string.isRequired
+ }
+
constructor(props) {
super(props)
const symptom = 'note'
@@ -41,16 +47,12 @@ class Note extends Component {
values={this.state}
date={this.props.date}
>
-
+
{
- this.setState({ value: val })
- }}
+ onChangeText={(val) => { this.setState({ value: val })}}
value={this.state.value}
testID='noteInput'
/>
diff --git a/components/cycle-day/symptoms/symptom-section.js b/components/cycle-day/symptoms/symptom-section.js
index 0728454..92192df 100644
--- a/components/cycle-day/symptoms/symptom-section.js
+++ b/components/cycle-day/symptoms/symptom-section.js
@@ -1,6 +1,6 @@
import React, { Component } from 'react'
import { View } from 'react-native'
-import AppText, { SymptomSectionHeader } from '../../app-text'
+import AppText from '../../app-text'
import styles from '../../../styles'
export default class SymptomSection extends Component {
@@ -16,7 +16,7 @@ export default class SymptomSection extends Component {
return (
{ p.header &&
- {p.header}
+ {p.header}
}
diff --git a/components/cycle-day/symptoms/temperature-input.js b/components/cycle-day/symptoms/temperature-input.js
index 2bcc39e..cc0dbd9 100644
--- a/components/cycle-day/symptoms/temperature-input.js
+++ b/components/cycle-day/symptoms/temperature-input.js
@@ -102,3 +102,7 @@ const OutOfRangeWarning = ({ temperature }) => {
return {warningMsg}
}
+
+OutOfRangeWarning.propTypes = {
+ temperature: PropTypes.string.isRequired
+}
diff --git a/components/framed-segment.js b/components/framed-segment.js
index 800c564..49bce23 100644
--- a/components/framed-segment.js
+++ b/components/framed-segment.js
@@ -5,21 +5,24 @@ import { View } from 'react-native'
import AppText from './app-text'
import styles from '../styles'
-const FramedSegment = ({children, ...props}) => {
- const style = [styles.framedSegment, props.style]
- if (props.last) style.push(styles.framedSegmentLast)
+const FramedSegment = ({ children, last, style, title }) => {
+ const viewStyle = [styles.framedSegment, style]
+ if (last) viewStyle.push(styles.framedSegmentLast)
return (
-
- {
- props.title
- && {props.title}
- }
+
+ {title && {title}}
{children}
)
}
FramedSegment.propTypes = {
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node
+ ]),
+ last: PropTypes.bool,
+ style: PropTypes.object,
title: PropTypes.string
}
diff --git a/components/header/index.js b/components/header/index.js
index d96856a..885eec3 100644
--- a/components/header/index.js
+++ b/components/header/index.js
@@ -29,7 +29,8 @@ export default function Header({
Header.propTypes = {
handleBack: PropTypes.func,
+ handleDelete: PropTypes.func,
handleNext: PropTypes.func,
- title: PropTypes.string,
subtitle: PropTypes.string,
+ title: PropTypes.string.isRequired
}
diff --git a/components/license.js b/components/license.js
index 5a95ad1..b433063 100644
--- a/components/license.js
+++ b/components/license.js
@@ -1,4 +1,5 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { ScrollView, View, BackHandler } from 'react-native'
import AppText from './app-text'
import { shared } from '../i18n/en/labels'
@@ -36,4 +37,8 @@ export default function License({setLicense}) {
)
-}
\ No newline at end of file
+}
+
+License.propTypes = {
+ setLicense: PropTypes.func.isRequired
+}
diff --git a/components/link.js b/components/link.js
index d0b9a83..caea792 100644
--- a/components/link.js
+++ b/components/link.js
@@ -1,4 +1,5 @@
import React from 'react'
+import PropTypes from 'prop-types'
import Hyperlink from 'react-native-hyperlink'
import styles from '../styles'
import links from '../i18n/en/links'
@@ -15,6 +16,13 @@ export default function Link(props) {
)
}
+Link.propTypes = {
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node
+ ])
+}
+
function replaceUrlWithText(url) {
const link = Object.values(links).find(l => l.url === url)
return (link && link.text) || url
diff --git a/components/menu/menu-item.js b/components/menu/menu-item.js
index cf59c0e..8dc1bcd 100644
--- a/components/menu/menu-item.js
+++ b/components/menu/menu-item.js
@@ -1,4 +1,5 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { Text, TouchableOpacity } from 'react-native'
import styles, { iconStyles, secondaryColor } from '../../styles'
@@ -11,13 +12,11 @@ const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => {
return acc
}, {})
-const MenuItem = ({ icon, label, active, onPress }) => {
+export default function MenuItem({ active, icon, label, onPress }) {
const styleActive = active ? { color: secondaryColor } : null
+
return (
-
+
{
)
}
-export default MenuItem
\ No newline at end of file
+MenuItem.propTypes = {
+ active: PropTypes.bool,
+ icon: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ onPress: PropTypes.func.isRequired
+}
\ No newline at end of file
diff --git a/components/password-prompt.js b/components/password-prompt.js
index 356a699..b2b7af4 100644
--- a/components/password-prompt.js
+++ b/components/password-prompt.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import { View, TextInput, TouchableOpacity, Alert } from 'react-native'
import nodejs from 'nodejs-mobile-react-native'
import { saveEncryptionFlag } from '../local-storage'
@@ -9,6 +10,10 @@ import { passwordPrompt as labels, shared, menuTitles } from '../i18n/en/labels'
import { requestHash, deleteDbAndOpenNew, openDb } from '../db'
export default class PasswordPrompt extends Component {
+ static propTypes = {
+ enableShowApp: PropTypes.func.isRequired
+ }
+
constructor(props) {
super(props)
this.state = {
diff --git a/components/settings/settings-menu.js b/components/settings/settings-menu.js
index a622a1d..f6b6bc2 100644
--- a/components/settings/settings-menu.js
+++ b/components/settings/settings-menu.js
@@ -1,4 +1,5 @@
import React from 'react'
+import PropTypes from 'prop-types'
import { TouchableOpacity, ScrollView } from 'react-native'
import { connect } from 'react-redux'
@@ -21,7 +22,7 @@ const menu = [
{title: labels.license, component: 'License'}
]
-const SettingsMenu = (props) => {
+const SettingsMenu = ({ navigate }) => {
return (
{ menu.map(menuItem)}
@@ -33,7 +34,7 @@ const SettingsMenu = (props) => {
props.navigate(item.component)}
+ onPress={() => navigate(item.component)}
>
{item.title.toLowerCase()}
@@ -41,6 +42,10 @@ const SettingsMenu = (props) => {
}
}
+SettingsMenu.propTypes = {
+ navigate: PropTypes.func.isRequired
+}
+
const mapDispatchToProps = (dispatch) => {
return({
navigate: (page) => dispatch(navigate(page)),
diff --git a/components/settings/shared/settings-button.js b/components/settings/shared/settings-button.js
index 00bc8ed..94aa210 100644
--- a/components/settings/shared/settings-button.js
+++ b/components/settings/shared/settings-button.js
@@ -28,8 +28,11 @@ const SettingsButton = ({ children, style, secondary, ...props }) => {
}
SettingsButton.propTypes = {
+ children: PropTypes.node,
+ disabled: PropTypes.bool,
onPress: PropTypes.func.isRequired,
- disabled: PropTypes.bool
+ secondary: PropTypes.bool,
+ style: PropTypes.object
}
export default SettingsButton
\ No newline at end of file
diff --git a/styles/index.js b/styles/index.js
index 1b9bb4f..e54b8bb 100644
--- a/styles/index.js
+++ b/styles/index.js
@@ -157,7 +157,8 @@ export default StyleSheet.create({
},
symptomViewHeading: {
fontWeight: 'bold',
- fontFamily: textFontBold
+ fontFamily: textFontBold,
+ flex: 1
},
symptomSection: {
marginBottom: 10