diff --git a/components/bleeding.js b/components/bleeding.js
deleted file mode 100644
index 0472c3c..0000000
--- a/components/bleeding.js
+++ /dev/null
@@ -1,102 +0,0 @@
-import React, { Component } from 'react'
-import {
- View,
- Button,
- Text,
- Switch
-} from 'react-native'
-import RadioForm from 'react-native-simple-radio-button'
-import styles from '../styles/index'
-import { saveBleeding } from '../db'
-import { bleeding as labels } from '../labels/labels'
-
-export default class Bleeding extends Component {
- constructor(props) {
- super(props)
- this.cycleDay = props.cycleDay
- this.showView = props.showView
- let bleedingValue = this.cycleDay.bleeding && this.cycleDay.bleeding.value
- if (! (typeof bleedingValue === 'number') ){
- bleedingValue = -1
- }
- this.state = {
- currentValue: bleedingValue,
- exclude: this.cycleDay.bleeding ? this.cycleDay.bleeding.exclude : false
- }
- }
-
- render() {
- const bleedingRadioProps = [
- {label: labels[0], value: 0 },
- {label: labels[1], value: 1 },
- {label: labels[2], value: 2 },
- {label: labels[3], value: 3 },
- ]
- return (
-
-
-
-
- Bleeding
-
-
- {
- this.setState({currentValue: itemValue})
- }}
- />
-
-
-
-
- Exclude
-
-
- {
- this.setState({exclude: val})
- }}
- value={this.state.exclude}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
- }
-}
\ No newline at end of file
diff --git a/components/cycle-day-overview.js b/components/cycle-day-overview.js
deleted file mode 100644
index 49068fe..0000000
--- a/components/cycle-day-overview.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import React, { Component } from 'react'
-import {
- View,
- Button,
- Text
-} from 'react-native'
-import styles from '../styles/index'
-import { bleeding as labels} from '../labels/labels'
-import cycleModule from '../lib/cycle'
-import { bleedingDaysSortedByDate } from '../db'
-
-const getCycleDayNumber = cycleModule().getCycleDayNumber
-
-export default class DayView extends Component {
- constructor(props) {
- super(props)
- this.cycleDay = props.cycleDay
- this.showView = props.showView
- this.state = {
- cycleDayNumber: getCycleDayNumber(this.cycleDay.date),
- }
-
- this.setStateWithCurrentCycleDayNumber = (function (DayViewComponent) {
- return function () {
- DayViewComponent.setState({
- cycleDayNumber: getCycleDayNumber(DayViewComponent.cycleDay.date)
- })
- }
- })(this)
-
- bleedingDaysSortedByDate.addListener(this.setStateWithCurrentCycleDayNumber)
- }
-
- componentWillUnmount() {
- bleedingDaysSortedByDate.removeListener(this.setStateWithCurrentCycleDayNumber)
- }
-
- render() {
- const bleedingValue = this.cycleDay.bleeding && this.cycleDay.bleeding.value
- let bleedingLabel
- if (typeof bleedingValue === 'number') {
- bleedingLabel = `${labels[bleedingValue]}`
- if (this.cycleDay.bleeding.exclude) bleedingLabel = "( " + bleedingLabel + " )"
- } else {
- bleedingLabel = 'edit'
- }
- const temperatureValue = this.cycleDay.temperature && this.cycleDay.temperature.value
- let temperatureLabel
- if (typeof temperatureValue === 'number') {
- temperatureLabel = `${temperatureValue} °C`
- if (this.cycleDay.temperature.exclude) temperatureLabel = "( " + temperatureLabel + " )"
- } else {
- temperatureLabel = 'edit'
- }
-
- return (
-
-
-
- Bleeding
-
-
-
-
-
-
-
- Temperature
-
-
-
-
-
-
- )
- }
-}
\ No newline at end of file
diff --git a/components/cycle-day/action-buttons.js b/components/cycle-day/action-buttons.js
new file mode 100644
index 0000000..eb33201
--- /dev/null
+++ b/components/cycle-day/action-buttons.js
@@ -0,0 +1,46 @@
+import React from 'react'
+import {
+ View,
+ Button,
+} from 'react-native'
+import { saveSymptom } from '../../db'
+
+export default function (showView) {
+ return function ({ symptom, cycleDay, saveAction, saveDisabled}) {
+ const buttons = [
+ {
+ title: 'Cancel',
+ action: () => showView('dayView')
+ },
+ {
+ title: 'Delete',
+ action: () => {
+ saveSymptom(symptom, cycleDay)
+ showView('dayView')
+ }
+ }, {
+ title: 'Save',
+ action: () => {
+ saveAction()
+ showView('dayView')
+ },
+ disabledCondition: saveDisabled
+ }
+ ]
+
+ return buttons.map(({ title, action, disabledCondition }, i) => {
+ const style = { flex: 1, marginHorizontal: 10 }
+ if (i === 0) style.marginLeft = 0
+ if (i === buttons.length - 1) style.marginRight = 0
+ return (
+
+
+
+ )
+ })
+ }
+}
\ No newline at end of file
diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js
new file mode 100644
index 0000000..d43aab4
--- /dev/null
+++ b/components/cycle-day/cycle-day-overview.js
@@ -0,0 +1,106 @@
+import React, { Component } from 'react'
+import {
+ View,
+ Button,
+ Text
+} from 'react-native'
+import styles from '../../styles'
+import {
+ bleeding as bleedingLabels,
+ mucusFeeling as feelingLabels,
+ mucusTexture as textureLabels,
+ mucusNFP as computeSensiplanMucusLabels,
+} from './labels/labels'
+import cycleDayModule from '../../lib/cycle'
+import { bleedingDaysSortedByDate } from '../../db'
+
+const getCycleDayNumber = cycleDayModule().getCycleDayNumber
+
+export default class DayView extends Component {
+ constructor(props) {
+ super(props)
+ this.cycleDay = props.cycleDay
+ this.showView = props.showView
+ this.state = {
+ cycleDayNumber: getCycleDayNumber(this.cycleDay.date),
+ }
+
+ this.setStateWithCurrentCycleDayNumber = (function (DayViewComponent) {
+ return function () {
+ DayViewComponent.setState({
+ cycleDayNumber: getCycleDayNumber(DayViewComponent.cycleDay.date)
+ })
+ }
+ })(this)
+
+ bleedingDaysSortedByDate.addListener(this.setStateWithCurrentCycleDayNumber)
+ }
+
+ componentWillUnmount() {
+ bleedingDaysSortedByDate.removeListener(this.setStateWithCurrentCycleDayNumber)
+ }
+
+ render() {
+ const bleedingValue = this.cycleDay.bleeding && this.cycleDay.bleeding.value
+ let bleedingLabel
+ if (typeof bleedingValue === 'number') {
+ bleedingLabel = `${bleedingLabels[bleedingValue]}`
+ if (this.cycleDay.bleeding.exclude) bleedingLabel = "( " + bleedingLabel + " )"
+ } else {
+ bleedingLabel = 'edit'
+ }
+ const temperatureValue = this.cycleDay.temperature && this.cycleDay.temperature.value
+ let temperatureLabel
+ if (typeof temperatureValue === 'number') {
+ temperatureLabel = `${temperatureValue} °C - ${this.cycleDay.temperature.time}`
+ if (this.cycleDay.temperature.exclude) {
+ temperatureLabel = "( " + temperatureLabel + " )"
+ }
+ } else {
+ temperatureLabel = 'edit'
+ }
+
+ const mucusFeelingValue = this.cycleDay.mucus && this.cycleDay.mucus.feeling
+ const mucusTextureValue = this.cycleDay.mucus && this.cycleDay.mucus.texture
+ const mucusComputedValue = this.cycleDay.mucus && this.cycleDay.mucus.computedNfp
+ let mucusLabel
+ if (typeof mucusFeelingValue === 'number' && typeof mucusTextureValue === 'number') {
+ mucusLabel = `${feelingLabels[mucusFeelingValue]} + ${textureLabels[mucusTextureValue]} ( ${computeSensiplanMucusLabels[mucusComputedValue]} )`
+ if (this.cycleDay.mucus.exclude) mucusLabel = "( " + mucusLabel + " )"
+ } else {
+ mucusLabel = 'edit'
+ }
+
+ return (
+
+
+ Bleeding
+
+
+
+
+
+ Temperature
+
+
+
+
+
+ Mucus
+
+
+
+
+
+ )
+ }
+}
diff --git a/components/cycle-day.js b/components/cycle-day/index.js
similarity index 66%
rename from components/cycle-day.js
rename to components/cycle-day/index.js
index bc3a674..3eeb983 100644
--- a/components/cycle-day.js
+++ b/components/cycle-day/index.js
@@ -3,13 +3,15 @@ import {
View,
Text
} from 'react-native'
-import cycleModule from '../lib/cycle'
-import getFertilityStatus from '../lib/sympto-adapter'
+import cycleModule from '../../lib/cycle'
+import getFertilityStatus from '../../lib/sympto-adapter'
import DayView from './cycle-day-overview'
-import BleedingEditView from './bleeding'
-import TemperatureEditView from './temperature'
-import { formatDateForViewHeader } from '../labels/format'
-import styles from '../styles/index'
+import BleedingEditView from './symptoms/bleeding'
+import TemperatureEditView from './symptoms/temperature'
+import MucusEditView from './symptoms/mucus'
+import { formatDateForViewHeader } from './labels/format'
+import styles from '../../styles'
+import actionButtonModule from './action-buttons'
const getCycleDayNumber = cycleModule().getCycleDayNumber
@@ -25,13 +27,15 @@ export default class Day extends Component {
this.showView = view => {
this.setState({visibleComponent: view})
}
+
+ this.makeActionButtons = actionButtonModule(this.showView)
}
render() {
const cycleDayNumber = getCycleDayNumber(this.cycleDay.date)
const fertilityStatus = getFertilityStatus(this.cycleDay.date)
return (
-
+
{formatDateForViewHeader(this.cycleDay.date)}
@@ -47,15 +51,16 @@ export default class Day extends Component {
{fertilityStatus}
-
+
{
{ dayView: ,
- bleedingEditView: ,
- temperatureEditView:
+ bleedingEditView: ,
+ temperatureEditView: ,
+ mucusEditView:
}[this.state.visibleComponent]
}
)
}
-}
\ No newline at end of file
+}
diff --git a/labels/format.js b/components/cycle-day/labels/format.js
similarity index 100%
rename from labels/format.js
rename to components/cycle-day/labels/format.js
diff --git a/components/cycle-day/labels/labels.js b/components/cycle-day/labels/labels.js
new file mode 100644
index 0000000..459370b
--- /dev/null
+++ b/components/cycle-day/labels/labels.js
@@ -0,0 +1,11 @@
+const bleeding = ['spotting', 'light', 'medium', 'heavy']
+const mucusFeeling = ['dry', 'nothing', 'wet', 'slippery']
+const mucusTexture = ['nothing', 'creamy', 'egg white']
+const mucusNFP = ['t', 'Ø', 'f', 'S', '+S']
+
+export {
+ bleeding,
+ mucusFeeling,
+ mucusTexture,
+ mucusNFP
+}
diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js
new file mode 100644
index 0000000..7ec0574
--- /dev/null
+++ b/components/cycle-day/symptoms/bleeding.js
@@ -0,0 +1,76 @@
+import React, { Component } from 'react'
+import {
+ View,
+ Text,
+ Switch
+} from 'react-native'
+import RadioForm from 'react-native-simple-radio-button'
+import styles from '../../../styles'
+import { saveSymptom } from '../../../db'
+import { bleeding as labels } from '../labels/labels'
+
+export default class Bleeding extends Component {
+ constructor(props) {
+ super(props)
+ this.cycleDay = props.cycleDay
+ this.makeActionButtons = props.makeActionButtons
+ let bleedingValue = this.cycleDay.bleeding && this.cycleDay.bleeding.value
+ if (!(typeof bleedingValue === 'number')) {
+ bleedingValue = -1
+ }
+ this.state = {
+ currentValue: bleedingValue,
+ exclude: this.cycleDay.bleeding ? this.cycleDay.bleeding.exclude : false
+ }
+ }
+
+ render() {
+ const bleedingRadioProps = [
+ { label: labels[0], value: 0 },
+ { label: labels[1], value: 1 },
+ { label: labels[2], value: 2 },
+ { label: labels[3], value: 3 },
+ ]
+ return (
+
+ Bleeding
+
+ {
+ this.setState({ currentValue: itemValue })
+ }}
+ />
+
+
+ Exclude
+ {
+ this.setState({ exclude: val })
+ }}
+ value={this.state.exclude}
+ />
+
+
+ {this.makeActionButtons(
+ {
+ symptom: 'bleeding',
+ cycleDay: this.cycleDay,
+ saveAction: () => {
+ saveSymptom('bleeding', this.cycleDay, {
+ value: this.state.currentValue,
+ exclude: this.state.exclude
+ })
+ },
+ saveDisabled: this.state.currentValue === -1
+ }
+ )}
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js
new file mode 100644
index 0000000..f94a656
--- /dev/null
+++ b/components/cycle-day/symptoms/mucus.js
@@ -0,0 +1,109 @@
+import React, { Component } from 'react'
+import {
+ View,
+ Text,
+ Switch
+} from 'react-native'
+import RadioForm from 'react-native-simple-radio-button'
+import styles from '../../../styles'
+import { saveSymptom } from '../../../db'
+import {
+ mucusFeeling as feelingLabels,
+ mucusTexture as textureLabels
+} from '../labels/labels'
+import computeSensiplanValue from '../../../lib/sensiplan-mucus'
+
+
+export default class Mucus extends Component {
+ constructor(props) {
+ super(props)
+ this.cycleDay = props.cycleDay
+ this.makeActionButtons = props.makeActionButtons
+ this.state = {
+ exclude: this.cycleDay.mucus ? this.cycleDay.mucus.exclude : false
+ }
+
+ this.state.currentFeelingValue = this.cycleDay.mucus && this.cycleDay.mucus.feeling
+ if (typeof this.state.currentFeelingValue !== 'number') {
+ this.state.currentFeelingValue = -1
+ }
+
+ this.state.currentTextureValue = this.cycleDay.mucus && this.cycleDay.mucus.texture
+ if (typeof this.state.currentTextureValue !== 'number') {
+ this.state.currentTextureValue = -1
+ }
+ }
+
+ render() {
+ const mucusFeelingRadioProps = [
+ {label: feelingLabels[0], value: 0 },
+ {label: feelingLabels[1], value: 1 },
+ {label: feelingLabels[2], value: 2 },
+ {label: feelingLabels[3], value: 3 }
+ ]
+ const mucusTextureRadioProps = [
+ {label: textureLabels[0], value: 0 },
+ {label: textureLabels[1], value: 1 },
+ {label: textureLabels[2], value: 2 }
+ ]
+ return(
+
+ Mucus
+ Feeling
+
+ {
+ this.setState({ currentFeelingValue: itemValue })
+ }}
+ />
+
+ Texture
+
+ {
+ this.setState({ currentTextureValue: itemValue })
+ }}
+ />
+
+
+ Exclude
+ {
+ this.setState({ exclude: val })
+ }}
+ value={this.state.exclude}
+ />
+
+
+
+ {this.makeActionButtons(
+ {
+ symptom: 'mucus',
+ cycleDay: this.cycleDay,
+ saveAction: () => {
+ saveSymptom('mucus', this.cycleDay, {
+ feeling: this.state.currentFeelingValue,
+ texture: this.state.currentTextureValue,
+ computedNfp: computeSensiplanValue(this.state.currentFeelingValue, this.state.currentTextureValue),
+ exclude: this.state.exclude
+ })
+ },
+ saveDisabled: this.state.currentFeelingValue === -1 || this.state.currentTextureValue === -1
+ }
+ )}
+
+
+
+ )
+ }
+}
diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js
new file mode 100644
index 0000000..b9a3d5b
--- /dev/null
+++ b/components/cycle-day/symptoms/temperature.js
@@ -0,0 +1,80 @@
+import React, { Component } from 'react'
+import {
+ View,
+ Text,
+ TextInput,
+ Switch
+} from 'react-native'
+
+import { getPreviousTemperature, saveSymptom } from '../../../db'
+import styles from '../../../styles'
+import { LocalTime, ChronoUnit } from 'js-joda'
+
+export default class Temp extends Component {
+ constructor(props) {
+ super(props)
+ this.cycleDay = props.cycleDay
+ this.makeActionButtons = props.makeActionButtons
+ let initialValue
+
+ if (this.cycleDay.temperature) {
+ initialValue = this.cycleDay.temperature.value.toString()
+ this.time = this.cycleDay.temperature.time
+ } else {
+ const prevTemp = getPreviousTemperature(this.cycleDay)
+ initialValue = prevTemp ? prevTemp.toString() : ''
+ }
+
+ this.state = {
+ currentValue: initialValue,
+ exclude: this.cycleDay.temperature ? this.cycleDay.temperature.exclude : false
+ }
+ }
+
+ render() {
+ const cycleDay = this.cycleDay
+ return (
+
+
+ Temperature (°C)
+ {
+ this.setState({ currentValue: val })
+ }}
+ keyboardType='numeric'
+ value={this.state.currentValue}
+ />
+
+
+ Exclude
+ {
+ this.setState({ exclude: val })
+ }}
+ value={this.state.exclude}
+ />
+
+
+ {this.makeActionButtons({
+ symptom: 'temperature',
+ cycleDay: this.cycleDay,
+ saveAction: () => {
+ const dataToSave = {
+ value: Number(this.state.currentValue),
+ exclude: this.state.exclude
+ }
+ if (!cycleDay.temperature || cycleDay.temperature && !cycleDay.temperature.time) {
+ const now = LocalTime.now().truncatedTo(ChronoUnit.MINUTES).toString()
+ dataToSave.time = now
+ }
+ saveSymptom('temperature', cycleDay, dataToSave)
+ },
+ saveDisabled: this.state.currentValue === ''
+ })}
+
+
+ )
+ }
+}
diff --git a/components/home.js b/components/home.js
index 816a10c..6c3795d 100644
--- a/components/home.js
+++ b/components/home.js
@@ -46,32 +46,28 @@ export default class Home extends Component {
render() {
const navigate = this.props.navigation.navigate
return (
-
-
-
- {this.state.welcomeText}
-
-
-
-
+
+ {this.state.welcomeText}
+
+
-
+
-
+
-
+