Skip to content
Snippets Groups Projects
cycle-day-overview.js 8.04 KiB
Newer Older
import React, { Component } from 'react'
import {
  ScrollView,
  View,
Julia Friesel's avatar
Julia Friesel committed
  TouchableOpacity,
  Dimensions
} from 'react-native'
import { LocalDate } from 'js-joda'
import Header from '../header'
import { getOrCreateCycleDay } from '../../db'
import cycleModule from '../../lib/cycle'
import Icon from 'react-native-vector-icons/FontAwesome'
import styles, { iconStyles } from '../../styles'
import {
  bleeding as bleedingLabels,
  mucusFeeling as feelingLabels,
  mucusTexture as textureLabels,
  mucusNFP as computeSensiplanMucusLabels,
emelko's avatar
emelko committed
  cervixOpening as openingLabels,
  cervixFirmness as firmnessLabels,
  cervixPosition as positionLabels,
  pain as painLabels,
  sex as sexLabels
emelko's avatar
emelko committed
} from './labels/labels'
import { AppText } from '../app-text'
export default class CycleDayOverView extends Component {
  constructor(props) {
    super(props)
    this.state = {
      cycleDay: props.cycleDay
  goToCycleDay = (target) => {
    const localDate = LocalDate.parse(this.state.cycleDay.date)
    const targetDate = target === 'before' ?
      localDate.minusDays(1).toString() :
      localDate.plusDays(1).toString()
    this.setState({ cycleDay: getOrCreateCycleDay(targetDate) })
  }

  navigate(symptom) {
    this.props.navigate(symptom, {
      cycleDay: this.state.cycleDay,
  render() {
    const cycleDay = this.state.cycleDay
    const getCycleDayNumber = cycleModule().getCycleDayNumber
    const cycleDayNumber = getCycleDayNumber(cycleDay.date)
    const dateInFuture = LocalDate.now().isBefore(LocalDate.parse(this.state.cycleDay.date))
    return (
      <View style={{ flex: 1 }}>
        <Header
          isCycleDayOverView={true}
          cycleDayNumber={cycleDayNumber}
          date={cycleDay.date}
          goToCycleDay={this.goToCycleDay}
        <ScrollView>
          <View style={styles.symptomBoxesView}>
            <SymptomBox
              title='Bleeding'
              onPress={() => this.navigate('BleedingEditView')}
              data={getLabel('bleeding', cycleDay.bleeding)}
            />
            <SymptomBox
              title='Temperature'
              onPress={() => this.navigate('TemperatureEditView')}
              data={getLabel('temperature', cycleDay.temperature)}
            />
            <SymptomBox
              title='Mucus'
              onPress={() => this.navigate('MucusEditView')}
              data={getLabel('mucus', cycleDay.mucus)}
            />
            <SymptomBox
              title='Cervix'
              onPress={() => this.navigate('CervixEditView')}
              data={getLabel('cervix', cycleDay.cervix)}
            />
            <SymptomBox
              title='Desire'
              onPress={() => this.navigate('DesireEditView')}
              data={getLabel('desire', cycleDay.desire)}
            />
            <SymptomBox
              title='Sex'
              onPress={() => this.navigate('SexEditView')}
              data={getLabel('sex', cycleDay.sex)}
            <SymptomBox
              title='Pain'
              onPress={() => this.navigate('PainEditView')}
              data={getLabel('pain', cycleDay.pain)}
            <SymptomBox
              title='Note'
              onPress={() => this.navigate('NoteEditView')}
              data={getLabel('note', cycleDay.note)}
            />
            {/*  this is just to make the last row adhere to the grid
Julia Friesel's avatar
Julia Friesel committed
        (and) because there are no pseudo properties in RN */}
            <FillerBoxes />
          </View >
        </ScrollView >
      </View >
Julia Friesel's avatar
Julia Friesel committed

function getLabel(symptomName, symptom) {
  const labels = {
    bleeding: bleeding => {
      if (typeof bleeding.value === 'number') {
        let bleedingLabel = `${bleedingLabels[bleeding.value]}`
        if (bleeding.exclude) bleedingLabel = "( " + bleedingLabel + " )"
        return bleedingLabel
      }
    },
    temperature: temperature => {
      if (typeof temperature.value === 'number') {
        let temperatureLabel = `${temperature.value} °C - ${temperature.time}`
        if (temperature.exclude) {
          temperatureLabel = "( " + temperatureLabel + " )"
        }
        return temperatureLabel
      }
    },
    mucus: mucus => {
      const categories = ['feeling', 'texture', 'value']
      if (categories.every(c => typeof mucus[c] === 'number')) {
        let mucusLabel = [feelingLabels[mucus.feeling], textureLabels[mucus.texture]].join(', ')
        mucusLabel += `\n${computeSensiplanMucusLabels[mucus.value]}`
        if (mucus.exclude) mucusLabel = `(${mucusLabel})`
Julia Friesel's avatar
Julia Friesel committed
        return mucusLabel
      }
    },
    cervix: cervix => {
      let cervixLabel = []
Julia Friesel's avatar
Julia Friesel committed
      if (cervix.opening > -1 && cervix.firmness > -1) {
        cervixLabel.push(
          openingLabels[cervix.opening],
          firmnessLabels[cervix.firmness]
        )
Bl00dyMarie's avatar
Bl00dyMarie committed
        if (cervix.position > -1) {
          cervixLabel.push(positionLabels[cervix.position])
Bl00dyMarie's avatar
Bl00dyMarie committed
        }
        cervixLabel = cervixLabel.join(', ')
        if (cervix.exclude) cervixLabel = `(${cervixLabel})`
Julia Friesel's avatar
Julia Friesel committed
        return cervixLabel
      }
    },
    note: note => {
      return note.value
    },
    desire: desire => {
      if (typeof desire.value === 'number') {
        const desireLabel = `${intensityLabels[desire.value]}`
        return desireLabel
      }
Bl00dyMarie's avatar
Bl00dyMarie committed
    },
    sex: sex => {
      let sexLabel = []
      if (sex && Object.values(sex).some(val => val)){
        Object.keys(sex).forEach(key => {
          if(sex[key] && key !== 'other' && key !== 'note') {
            sexLabel.push(sexLabels[key])
          }
          if(key === 'other' && sex.other) {
            let label = sexLabels[key]
            if(sex.note) {
              label = `${label} (${sex.note})`
            }
            sexLabel.push(label)
          }
        })
        sexLabel = sexLabel.join(', ')
Bl00dyMarie's avatar
Bl00dyMarie committed
      }
      let painLabel = []
      if (pain && Object.values(pain).some(val => val)){
        Object.keys(pain).forEach(key => {
          if(pain[key] && key !== 'other' && key !== 'note') {
          if(key === 'other' && pain.other) {
            let label = painLabels[key]
            if(pain.note) {
              label = `${label} (${pain.note})`
            }
            painLabel.push(label)
Bl00dyMarie's avatar
Bl00dyMarie committed
      }
Julia Friesel's avatar
Julia Friesel committed
  if (!symptom) return
  const label = labels[symptomName](symptom)
Julia Friesel's avatar
Julia Friesel committed
  if (label.length < 45) return label
  return label.slice(0, 42) + '...'
class SymptomBox extends Component {
  render() {
    const d = this.props.data
    const boxActive = d ? styles.symptomBoxActive : {}
    const iconActive = d ? iconStyles.symptomBoxActive : {}
Julia Friesel's avatar
Julia Friesel committed
    const iconStyle = Object.assign({}, iconStyles.symptomBox, iconActive, disabledStyle)
    const textActive = d ? styles.symptomTextActive : {}
    const disabledStyle = this.props.disabled ? styles.symptomInFuture : {}
    return (
      <TouchableOpacity onPress={this.props.onPress} disabled={this.props.disabled}>
Julia Friesel's avatar
Julia Friesel committed
        <View style={[styles.symptomBox, boxActive, disabledStyle]}>
          <Icon
            name='thermometer'
            {...iconStyle}
          <AppText style={[textActive, disabledStyle]}>{this.props.title}</AppText>
        </View>
Julia Friesel's avatar
Julia Friesel committed
        <View style={[styles.symptomDataBox, disabledStyle]}>
          <AppText style={styles.symptomDataText}>{this.props.data}</AppText>
        </View>
      </TouchableOpacity>
    )
  }
Julia Friesel's avatar
Julia Friesel committed
}

class FillerBoxes extends Component {
  render() {
    const n = Dimensions.get('window').width / styles.symptomBox.width
Julia Friesel's avatar
Julia Friesel committed
    const fillerBoxes = []
    for (let i = 0; i < Math.ceil(n); i++) {
      fillerBoxes.push(
        <View
          width={styles.symptomBox.width}
Julia Friesel's avatar
Julia Friesel committed
          height={0}
          key={i.toString()}
        />
      )
    }
    return fillerBoxes
Julia Friesel's avatar
Julia Friesel committed
  }