Skip to content
Snippets Groups Projects
temperature.js 5.85 KiB
Newer Older
import React, { Component } from 'react'
import {
  View,
  TextInput,
  Switch,
  Alert,
  ScrollView
import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
import padWithZeros from '../../helpers/pad-time-with-zeros'

import { getPreviousTemperature, saveSymptom } from '../../../db'
import styles from '../../../styles'
import { LocalTime, ChronoUnit } from 'js-joda'
Julia Friesel's avatar
Julia Friesel committed
import { temperature as labels } from '../labels'
import { scaleObservable } from '../../../local-storage'
import { shared } from '../../labels'
import ActionButtonFooter from './action-button-footer'
import config from '../../../config'
import SymptomSection from './symptom-section'
const minutes = ChronoUnit.MINUTES
export default class Temp extends Component {
  constructor(props) {
    super(props)
    this.cycleDay = props.cycleDay
    this.makeActionButtons = props.makeActionButtons

    const temp = this.cycleDay.temperature

    this.state = {
      exclude: temp ? temp.exclude : false,
      time: temp ? temp.time : LocalTime.now().truncatedTo(minutes).toString(),
      isTimePickerVisible: false,
tina's avatar
tina committed
      outOfRange: null,
      note: temp ? temp.note : null
Julia Friesel's avatar
Julia Friesel committed
      this.state.temperature = temp.value.toString()
      if (temp.value === Math.floor(temp.value)) {
        this.state.temperature = `${this.state.temperature}.0`
      }
    } else {
      const prevTemp = getPreviousTemperature(this.cycleDay)
Julia Friesel's avatar
Julia Friesel committed
        this.state.temperature = prevTemp.toString()
        this.state.isSuggestion = true
  saveTemperature = () => {
    const dataToSave = {
      value: Number(this.state.temperature),
      exclude: this.state.exclude,
tina's avatar
tina committed
      time: this.state.time,
      note: this.state.note
    }
    saveSymptom('temperature', this.cycleDay, dataToSave)
    this.props.navigate('CycleDay', {cycleDay: this.cycleDay})
  }

  checkRangeAndSave = () => {
    const value = Number(this.state.temperature)

    const absolute = {
      min: config.temperatureScale.min,
      max: config.temperatureScale.max
    }
    const scale = scaleObservable.value
    let warningMsg
    if (value < absolute.min || value > absolute.max) {
      warningMsg = labels.outOfAbsoluteRangeWarning
    } else if (value < scale.min || value > scale.max) {
      warningMsg = labels.outOfRangeWarning
    }

    if (warningMsg) {
      Alert.alert(
        shared.warning,
        warningMsg,
        [
          { text: shared.cancel },
          { text: shared.save, onPress: this.saveTemperature}
        ]
      )
    } else {
      this.saveTemperature()
    }

  }


      <View style={{ flex: 1 }}>
        <ScrollView style={styles.page}>
          <View>
            <SymptomSection
              header="Temperature (°C)"
              explainer={labels.temperature.explainer}
              inline={true}
            >
              <TempInput
                value={this.state.temperature}
                setState={(val) => this.setState(val)}
                isSuggestion={this.state.isSuggestion}
            </SymptomSection>
            <SymptomSection
              header="Time"
              inline={true}
            >
              <TextInput
                style={styles.temperatureTextInput}
                onFocus={() => {
                  Keyboard.dismiss()
                  this.setState({ isTimePickerVisible: true })
                }}
                value={this.state.time}
              />
              <DateTimePicker
                mode="time"
                isVisible={this.state.isTimePickerVisible}
                onConfirm={jsDate => {
                  this.setState({
                    time: padWithZeros(jsDate),
                    isTimePickerVisible: false
                  })
                }}
                onCancel={() => this.setState({ isTimePickerVisible: false })}
              />
            </SymptomSection>
            <SymptomSection
              header="Note"
              explainer={labels.note.explainer}
            >
tina's avatar
tina committed
              <TextInput
                multiline={true}
tina's avatar
tina committed
                autoFocus={this.state.focusTextArea}
                placeholder="Enter"
tina's avatar
tina committed
                value={this.state.note}
                onChangeText={(val) => {
                  this.setState({ note: val })
                }}
              />
            </SymptomSection>
            <SymptomSection
              header="Exclude"
              explainer={labels.excludeExplainer}
              inline={true}
            >
              <Switch
                onValueChange={(val) => {
                  this.setState({ exclude: val })
                }}
                value={this.state.exclude}
              />
            </SymptomSection>
        </ScrollView>
        <ActionButtonFooter
          symptom='temperature'
          cycleDay={this.cycleDay}
          saveAction={() => this.checkRangeAndSave()}
          saveDisabled={
            this.state.temperature === '' ||
            isNaN(Number(this.state.temperature)) ||
            isInvalidTime(this.state.time)
          }
          navigate={this.props.navigate}
          autoShowDayView={false}
class TempInput extends Component {
  render() {
    const style = [styles.temperatureTextInput]
    if (this.props.isSuggestion) {
      style.push(styles.temperatureTextInputSuggestion)
    }
    return (
      <TextInput
        style={style}
        onChangeText={(val) => {
          if (isNaN(Number(val))) return
Julia Friesel's avatar
Julia Friesel committed
          this.props.setState({ temperature: val, isSuggestion: false })
        }}
        keyboardType='numeric'
Julia Friesel's avatar
Julia Friesel committed
        value={this.props.value}
        onBlur={this.checkRange}
Julia Friesel's avatar
Julia Friesel committed
        autoFocus={true}
function isInvalidTime(timeString) {
  try {
    LocalTime.parse(timeString)
  } catch (err) {
    return true
  }
  return false
}