Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bee6b145ed | |||
| 57c8e31a9a | |||
| 726b65914b | |||
| 82b6a6b603 | |||
| 5f61f37d2f | |||
| 1b6d21f730 | |||
| be0c11abfe | |||
| e2e320927b | |||
| 5c2a80c5c2 | |||
| 2e060d3261 | |||
| c267e80424 | |||
| c95e25a9b2 | |||
| 6c1ee3e5e2 | |||
| 499e2d0628 | |||
| 951fb778d4 | |||
| 6d6473ca78 | |||
| 5a0321c5e5 | |||
| 0c6c706274 |
+30
-6
@@ -4,9 +4,7 @@ import PropTypes from 'prop-types'
|
|||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
import AppText from './common/app-text'
|
import AppText from './common/app-text'
|
||||||
import Asterisk from './common/Asterisk'
|
|
||||||
import Button from './common/button'
|
import Button from './common/button'
|
||||||
import Footnote from './common/Footnote'
|
|
||||||
|
|
||||||
import cycleModule from '../lib/cycle'
|
import cycleModule from '../lib/cycle'
|
||||||
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
|
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
|
||||||
@@ -18,11 +16,9 @@ import {
|
|||||||
import { Colors, Fonts, Sizes, Spacing } from '../styles'
|
import { Colors, Fonts, Sizes, Spacing } from '../styles'
|
||||||
import { LocalDate } from '@js-joda/core'
|
import { LocalDate } from '@js-joda/core'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useDate } from '../hooks/useDate'
|
|
||||||
|
|
||||||
const Home = ({ navigate }) => {
|
const Home = ({ navigate, setDate }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { setDate } = useDate()
|
|
||||||
|
|
||||||
function navigateToCycleDayView() {
|
function navigateToCycleDayView() {
|
||||||
setDate(todayDateString)
|
setDate(todayDateString)
|
||||||
@@ -73,12 +69,26 @@ const Home = ({ navigate }) => {
|
|||||||
<Button isCTA isSmall={false} onPress={navigateToCycleDayView}>
|
<Button isCTA isSmall={false} onPress={navigateToCycleDayView}>
|
||||||
{t('labels.home.addDataForToday')}
|
{t('labels.home.addDataForToday')}
|
||||||
</Button>
|
</Button>
|
||||||
{phase && <Footnote>{statusText}</Footnote>}
|
{phase && (
|
||||||
|
<View style={styles.asteriskLine}>
|
||||||
|
<Asterisk />
|
||||||
|
<AppText linkStyle={styles.whiteText} style={styles.greyText}>
|
||||||
|
{statusText}
|
||||||
|
</AppText>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Asterisk = () => {
|
||||||
|
return <AppText style={styles.asterisk}>*</AppText>
|
||||||
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
asterisk: {
|
||||||
|
color: Colors.orange,
|
||||||
|
},
|
||||||
container: {
|
container: {
|
||||||
backgroundColor: Colors.purple,
|
backgroundColor: Colors.purple,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -94,6 +104,12 @@ const styles = StyleSheet.create({
|
|||||||
marginBottom: Spacing.tiny,
|
marginBottom: Spacing.tiny,
|
||||||
marginTop: Spacing.small,
|
marginTop: Spacing.small,
|
||||||
},
|
},
|
||||||
|
asteriskLine: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignContent: 'flex-start',
|
||||||
|
marginBottom: Spacing.tiny,
|
||||||
|
marginTop: Spacing.small,
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
color: Colors.purpleLight,
|
color: Colors.purpleLight,
|
||||||
fontFamily: Fonts.bold,
|
fontFamily: Fonts.bold,
|
||||||
@@ -108,10 +124,18 @@ const styles = StyleSheet.create({
|
|||||||
color: 'white',
|
color: 'white',
|
||||||
fontSize: Sizes.subtitle,
|
fontSize: Sizes.subtitle,
|
||||||
},
|
},
|
||||||
|
whiteText: {
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
greyText: {
|
||||||
|
color: Colors.greyLight,
|
||||||
|
paddingLeft: Spacing.base,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
Home.propTypes = {
|
Home.propTypes = {
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
|
setDate: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Home
|
export default Home
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import AppStatusBar from './common/app-status-bar'
|
|||||||
import AcceptLicense from './AcceptLicense'
|
import AcceptLicense from './AcceptLicense'
|
||||||
import PasswordPrompt from './password-prompt'
|
import PasswordPrompt from './password-prompt'
|
||||||
|
|
||||||
import { DateProvider } from '../hooks/useDate'
|
|
||||||
|
|
||||||
export default function AppWrapper() {
|
export default function AppWrapper() {
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const [isLicenseAccepted, setIsLicenseAccepted] = useState(false)
|
const [isLicenseAccepted, setIsLicenseAccepted] = useState(false)
|
||||||
@@ -49,9 +47,7 @@ export default function AppWrapper() {
|
|||||||
{isDbEncrypted ? (
|
{isDbEncrypted ? (
|
||||||
<PasswordPrompt enableShowApp={() => setIsDbEncrypted(false)} />
|
<PasswordPrompt enableShowApp={() => setIsDbEncrypted(false)} />
|
||||||
) : (
|
) : (
|
||||||
<DateProvider>
|
<App restartApp={() => checkIsDbEncrypted()} />
|
||||||
<App restartApp={() => checkIsDbEncrypted()} />
|
|
||||||
</DateProvider>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-3
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
|
|||||||
import { BackHandler, StyleSheet, View } from 'react-native'
|
import { BackHandler, StyleSheet, View } from 'react-native'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import { useDate } from '../hooks/useDate'
|
import { LocalDate } from '@js-joda/core'
|
||||||
|
|
||||||
import Header from './header'
|
import Header from './header'
|
||||||
import Menu from './menu'
|
import Menu from './menu'
|
||||||
@@ -13,8 +13,7 @@ import setupNotifications from '../lib/notifications'
|
|||||||
import { closeDb } from '../db'
|
import { closeDb } from '../db'
|
||||||
|
|
||||||
const App = ({ restartApp }) => {
|
const App = ({ restartApp }) => {
|
||||||
const { setDate } = useDate()
|
const [date, setDate] = useState(LocalDate.now().toString())
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState('Home')
|
const [currentPage, setCurrentPage] = useState('Home')
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
if (currentPage === 'Home') {
|
if (currentPage === 'Home') {
|
||||||
@@ -44,6 +43,8 @@ const App = ({ restartApp }) => {
|
|||||||
const isTemperatureEditView = currentPage === 'TemperatureEditView'
|
const isTemperatureEditView = currentPage === 'TemperatureEditView'
|
||||||
const headerProps = { navigate: setCurrentPage }
|
const headerProps = { navigate: setCurrentPage }
|
||||||
const pageProps = {
|
const pageProps = {
|
||||||
|
date,
|
||||||
|
setDate,
|
||||||
isTemperatureEditView,
|
isTemperatureEditView,
|
||||||
navigate: setCurrentPage,
|
navigate: setCurrentPage,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import PropTypes from 'prop-types'
|
|||||||
import { StyleSheet, View } from 'react-native'
|
import { StyleSheet, View } from 'react-native'
|
||||||
import { CalendarList } from 'react-native-calendars'
|
import { CalendarList } from 'react-native-calendars'
|
||||||
|
|
||||||
import { useDate } from '../hooks/useDate'
|
|
||||||
|
|
||||||
import { getBleedingDaysSortedByDate } from '../db'
|
import { getBleedingDaysSortedByDate } from '../db'
|
||||||
import cycleModule from '../lib/cycle'
|
import cycleModule from '../lib/cycle'
|
||||||
import {
|
import {
|
||||||
@@ -14,8 +12,7 @@ import {
|
|||||||
todayToCalFormat,
|
todayToCalFormat,
|
||||||
} from './helpers/calendar'
|
} from './helpers/calendar'
|
||||||
|
|
||||||
const CalendarView = ({ navigate }) => {
|
const CalendarView = ({ setDate, navigate }) => {
|
||||||
const { setDate } = useDate()
|
|
||||||
const bleedingDays = getBleedingDaysSortedByDate()
|
const bleedingDays = getBleedingDaysSortedByDate()
|
||||||
const predictedMenses = cycleModule().getPredictedMenses()
|
const predictedMenses = cycleModule().getPredictedMenses()
|
||||||
|
|
||||||
@@ -52,6 +49,7 @@ const styles = StyleSheet.create({
|
|||||||
})
|
})
|
||||||
|
|
||||||
CalendarView.propTypes = {
|
CalendarView.propTypes = {
|
||||||
|
setDate: PropTypes.func.isRequired,
|
||||||
navigate: PropTypes.func.isRequired,
|
navigate: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,24 +28,12 @@ import { Spacing } from '../../styles'
|
|||||||
const getSymptomsFromCycleDays = (cycleDays) =>
|
const getSymptomsFromCycleDays = (cycleDays) =>
|
||||||
SYMPTOMS.filter((symptom) => cycleDays.some((cycleDay) => cycleDay[symptom]))
|
SYMPTOMS.filter((symptom) => cycleDays.some((cycleDay) => cycleDay[symptom]))
|
||||||
|
|
||||||
const CycleChart = ({ navigate }) => {
|
const CycleChart = ({ navigate, setDate }) => {
|
||||||
const [shouldShowHint, setShouldShowHint] = useState(true)
|
const [shouldShowHint, setShouldShowHint] = useState(true)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(async () => {
|
||||||
let isMounted = true
|
const flag = await getChartFlag()
|
||||||
|
setShouldShowHint(flag === 'true')
|
||||||
async function checkShouldShowHint() {
|
|
||||||
const flag = await getChartFlag()
|
|
||||||
if (isMounted) {
|
|
||||||
setShouldShowHint(flag === 'true')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkShouldShowHint()
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
isMounted = false
|
|
||||||
}
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const hideHint = () => {
|
const hideHint = () => {
|
||||||
@@ -84,6 +72,7 @@ const CycleChart = ({ navigate }) => {
|
|||||||
const renderColumn = ({ item }) => {
|
const renderColumn = ({ item }) => {
|
||||||
return (
|
return (
|
||||||
<DayColumn
|
<DayColumn
|
||||||
|
setDate={setDate}
|
||||||
dateString={item}
|
dateString={item}
|
||||||
navigate={navigate}
|
navigate={navigate}
|
||||||
symptomHeight={symptomHeight}
|
symptomHeight={symptomHeight}
|
||||||
@@ -135,6 +124,7 @@ const CycleChart = ({ navigate }) => {
|
|||||||
|
|
||||||
CycleChart.propTypes = {
|
CycleChart.propTypes = {
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
|
setDate: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import SymptomCell from './symptom-cell'
|
|||||||
import TemperatureColumn from './temperature-column'
|
import TemperatureColumn from './temperature-column'
|
||||||
import CycleDayLabel from './cycle-day-label'
|
import CycleDayLabel from './cycle-day-label'
|
||||||
|
|
||||||
import { useDate } from '../../hooks/useDate'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
symptomColorMethods,
|
symptomColorMethods,
|
||||||
getTemperatureProps,
|
getTemperatureProps,
|
||||||
@@ -21,13 +19,13 @@ const DayColumn = ({
|
|||||||
dateString,
|
dateString,
|
||||||
chartSymptoms,
|
chartSymptoms,
|
||||||
columnHeight,
|
columnHeight,
|
||||||
|
setDate,
|
||||||
navigate,
|
navigate,
|
||||||
shouldShowTemperatureColumn,
|
shouldShowTemperatureColumn,
|
||||||
symptomHeight,
|
symptomHeight,
|
||||||
symptomRowSymptoms,
|
symptomRowSymptoms,
|
||||||
xAxisHeight,
|
xAxisHeight,
|
||||||
}) => {
|
}) => {
|
||||||
const { setDate } = useDate()
|
|
||||||
const cycleDayData = getCycleDay(dateString)
|
const cycleDayData = getCycleDay(dateString)
|
||||||
let data = {}
|
let data = {}
|
||||||
|
|
||||||
@@ -107,6 +105,7 @@ DayColumn.propTypes = {
|
|||||||
chartSymptoms: PropTypes.array,
|
chartSymptoms: PropTypes.array,
|
||||||
columnHeight: PropTypes.number.isRequired,
|
columnHeight: PropTypes.number.isRequired,
|
||||||
navigate: PropTypes.func.isRequired,
|
navigate: PropTypes.func.isRequired,
|
||||||
|
setDate: PropTypes.func.isRequired,
|
||||||
shouldShowTemperatureColumn: PropTypes.bool,
|
shouldShowTemperatureColumn: PropTypes.bool,
|
||||||
symptomHeight: PropTypes.number.isRequired,
|
symptomHeight: PropTypes.number.isRequired,
|
||||||
symptomRowSymptoms: PropTypes.array,
|
symptomRowSymptoms: PropTypes.array,
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { StyleSheet, View } from 'react-native'
|
||||||
|
|
||||||
|
import AppText from '../common/app-text'
|
||||||
|
|
||||||
|
import { Containers, Spacing, Typography } from '../../styles'
|
||||||
|
|
||||||
|
const AppHelp = ({ text }) => (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<AppText style={styles.accentPurple}>*</AppText>
|
||||||
|
<AppText>{text}</AppText>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
|
||||||
|
AppHelp.propTypes = {
|
||||||
|
text: PropTypes.string.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
accentPurple: {
|
||||||
|
...Typography.accentPurple,
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
paddingRight: Spacing.base,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
...Containers.rowContainer,
|
||||||
|
padding: Spacing.base,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default AppHelp
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { StyleSheet } from 'react-native'
|
|
||||||
|
|
||||||
import AppText from './app-text'
|
|
||||||
|
|
||||||
import { Colors } from '../../styles'
|
|
||||||
|
|
||||||
const Asterisk = () => <AppText style={styles.asterisk}>*</AppText>
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
asterisk: {
|
|
||||||
color: Colors.orange,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default Asterisk
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { StyleSheet, View } from 'react-native'
|
|
||||||
|
|
||||||
import AppText from '../common/app-text'
|
|
||||||
import Asterisk from '../common/Asterisk'
|
|
||||||
|
|
||||||
import { Colors, Spacing } from '../../styles'
|
|
||||||
|
|
||||||
const Footnote = ({ children }) => {
|
|
||||||
if (!children) return false
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Asterisk />
|
|
||||||
<AppText linkStyle={styles.link} style={styles.text}>
|
|
||||||
{children}
|
|
||||||
</AppText>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Footnote.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignContent: 'flex-start',
|
|
||||||
marginBottom: Spacing.tiny,
|
|
||||||
marginTop: Spacing.small,
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
color: Colors.greyLight,
|
|
||||||
paddingLeft: Spacing.base,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default Footnote
|
|
||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import { StyleSheet, View } from 'react-native'
|
import { StyleSheet, View } from 'react-native'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import AppText from '../common/app-text'
|
import AppText from './app-text'
|
||||||
|
|
||||||
import { Sizes, Spacing, Typography } from '../../styles'
|
import { Sizes, Spacing, Typography } from '../../styles'
|
||||||
|
|
||||||
@@ -15,10 +15,12 @@ StatsOverview.propTypes = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Row = ({ rowContent }) => {
|
const Row = ({ rowContent }) => {
|
||||||
|
const showHelp = rowContent[1].includes('deviation') ? true : false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Cell content={rowContent[0]} isLeft />
|
<Cell content={rowContent[0]} isLeft />
|
||||||
<Cell content={rowContent[1]} />
|
<Cell content={rowContent[1]} showHelp={showHelp} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -27,7 +29,7 @@ Row.propTypes = {
|
|||||||
rowContent: PropTypes.array.isRequired,
|
rowContent: PropTypes.array.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Cell = ({ content, isLeft }) => {
|
const Cell = ({ content, isLeft, showHelp }) => {
|
||||||
const styleContainer = isLeft ? styles.cellLeft : styles.cellRight
|
const styleContainer = isLeft ? styles.cellLeft : styles.cellRight
|
||||||
const styleText = isLeft ? styles.accentPurpleBig : styles.accentOrange
|
const styleText = isLeft ? styles.accentPurpleBig : styles.accentOrange
|
||||||
const numberOfLines = isLeft ? 1 : 2
|
const numberOfLines = isLeft ? 1 : 2
|
||||||
@@ -42,6 +44,7 @@ const Cell = ({ content, isLeft }) => {
|
|||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</AppText>
|
</AppText>
|
||||||
|
{showHelp && <AppText style={styles.accentPurpleBig}>*</AppText>}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -49,6 +52,7 @@ const Cell = ({ content, isLeft }) => {
|
|||||||
Cell.propTypes = {
|
Cell.propTypes = {
|
||||||
content: PropTypes.node.isRequired,
|
content: PropTypes.node.isRequired,
|
||||||
isLeft: PropTypes.bool,
|
isLeft: PropTypes.bool,
|
||||||
|
showHelp: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
@@ -66,7 +70,10 @@ const styles = StyleSheet.create({
|
|||||||
flex: 3,
|
flex: 3,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
cellRight: { flex: 5 },
|
cellRight: {
|
||||||
|
flex: 5,
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
row: { flexDirection: 'row' },
|
row: { flexDirection: 'row' },
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { FlatList, StyleSheet, View } from 'react-native'
|
import { Dimensions, FlatList, StyleSheet, View } from 'react-native'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import AppText from '../common/app-text'
|
import AppText from './app-text'
|
||||||
|
import CloseIcon from './close-icon'
|
||||||
|
|
||||||
import cycleModule from '../../lib/cycle'
|
import cycleModule from '../../lib/cycle'
|
||||||
import { Spacing, Typography, Colors } from '../../styles'
|
import { Sizes, Spacing, Typography, Colors } from '../../styles'
|
||||||
import { humanizeDate } from '../helpers/format-date'
|
import { humanizeDate } from '../helpers/format-date'
|
||||||
|
|
||||||
const Item = ({ data }) => {
|
const Item = ({ data }) => {
|
||||||
@@ -35,43 +36,67 @@ Item.propTypes = {
|
|||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
const StatsTable = () => {
|
const StatsTable = ({ onClose }) => {
|
||||||
const renderItem = ({ item }) => <Item data={item} />
|
const renderItem = ({ item }) => <Item data={item} />
|
||||||
const data = cycleModule().getStats()
|
const data = cycleModule().getStats()
|
||||||
|
|
||||||
if (!data || data.length === 0) return false
|
if (!data || data.length === 0) return false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<View style={styles.modalContainer}>
|
||||||
data={data}
|
<View style={styles.headerContainer}>
|
||||||
renderItem={renderItem}
|
<CloseIcon onClose={onClose} />
|
||||||
keyExtractor={(item) => item.date}
|
</View>
|
||||||
ItemSeparatorComponent={ItemDivider}
|
<FlatList
|
||||||
ListHeaderComponent={FlatListHeader}
|
data={data}
|
||||||
ListHeaderComponentStyle={styles.headerDivider}
|
renderItem={renderItem}
|
||||||
stickyHeaderIndices={[0]}
|
keyExtractor={(item) => item.date}
|
||||||
contentContainerStyle={styles.container}
|
ItemSeparatorComponent={ItemDivider}
|
||||||
/>
|
ListHeaderComponent={FlatListHeader}
|
||||||
|
ListHeaderComponentStyle={styles.headerDivider}
|
||||||
|
stickyHeaderIndices={[0]}
|
||||||
|
contentContainerStyle={styles.container}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatsTable.propTypes = {
|
||||||
|
onClose: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
const ItemDivider = () => <View style={styles.divider} />
|
const ItemDivider = () => <View style={styles.divider} />
|
||||||
|
|
||||||
const FlatListHeader = () => (
|
const FlatListHeader = () => {
|
||||||
<View style={styles.row}>
|
const { t } = useTranslation(null, { keyPrefix: 'stats' })
|
||||||
<View style={styles.accentCell}>
|
|
||||||
<AppText style={styles.header}>{'Cycle Start'}</AppText>
|
return (
|
||||||
|
<View style={styles.row}>
|
||||||
|
<View style={styles.accentCell}>
|
||||||
|
<AppText style={styles.header}>{t('cycle_start')}</AppText>
|
||||||
|
</View>
|
||||||
|
<View style={styles.cell}>
|
||||||
|
<AppText style={styles.header}>{t('cycle_length')}</AppText>
|
||||||
|
</View>
|
||||||
|
<View style={styles.cell}>
|
||||||
|
<AppText style={styles.header}>{t('bleeding')}</AppText>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.cell}>
|
)
|
||||||
<AppText style={styles.header}>{'Cycle Length'}</AppText>
|
}
|
||||||
</View>
|
|
||||||
<View style={styles.cell}>
|
|
||||||
<AppText style={styles.header}>{'Bleeding'}</AppText>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
accentCell: {
|
||||||
|
flex: 3,
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
cell: {
|
||||||
|
flex: 2,
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
paddingHorizontal: Spacing.base,
|
||||||
|
},
|
||||||
divider: {
|
divider: {
|
||||||
height: 1,
|
height: 1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -81,27 +106,31 @@ const styles = StyleSheet.create({
|
|||||||
...Typography.accentOrange,
|
...Typography.accentOrange,
|
||||||
paddingVertical: Spacing.small,
|
paddingVertical: Spacing.small,
|
||||||
},
|
},
|
||||||
|
headerContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
paddingTop: Spacing.base,
|
||||||
|
paddingRight: Spacing.base,
|
||||||
|
},
|
||||||
headerDivider: {
|
headerDivider: {
|
||||||
borderBottomColor: Colors.purple,
|
borderBottomColor: Colors.purple,
|
||||||
borderBottomWidth: 2,
|
borderBottomWidth: 2,
|
||||||
},
|
},
|
||||||
|
modalContainer: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
backgroundColor: Colors.turquoiseLight,
|
||||||
|
marginTop: Sizes.huge * 2,
|
||||||
|
maxHeight: Dimensions.get('window').height * 0.7,
|
||||||
|
minHeight: '40%',
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
row: {
|
row: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
paddingVertical: Spacing.tiny,
|
paddingVertical: Spacing.tiny,
|
||||||
backgroundColor: Colors.turquoiseLight,
|
backgroundColor: Colors.turquoiseLight,
|
||||||
},
|
},
|
||||||
cell: {
|
|
||||||
flex: 2,
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
accentCell: {
|
|
||||||
flex: 3,
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
container: {
|
|
||||||
paddingHorizontal: Spacing.base,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default StatsTable
|
export default StatsTable
|
||||||
@@ -9,13 +9,10 @@ import SymptomPageTitle from './symptom-page-title'
|
|||||||
import { getCycleDay } from '../../db'
|
import { getCycleDay } from '../../db'
|
||||||
import { getData, nextDate, prevDate } from '../helpers/cycle-day'
|
import { getData, nextDate, prevDate } from '../helpers/cycle-day'
|
||||||
|
|
||||||
import { useDate } from '../../hooks/useDate'
|
|
||||||
|
|
||||||
import { Spacing } from '../../styles'
|
import { Spacing } from '../../styles'
|
||||||
import { SYMPTOMS } from '../../config'
|
import { SYMPTOMS } from '../../config'
|
||||||
|
|
||||||
const CycleDayOverView = ({ isTemperatureEditView }) => {
|
const CycleDayOverView = ({ date, setDate, isTemperatureEditView }) => {
|
||||||
const { date, setDate } = useDate()
|
|
||||||
const cycleDay = getCycleDay(date)
|
const cycleDay = getCycleDay(date)
|
||||||
|
|
||||||
const [editedSymptom, setEditedSymptom] = useState(
|
const [editedSymptom, setEditedSymptom] = useState(
|
||||||
@@ -61,6 +58,8 @@ const CycleDayOverView = ({ isTemperatureEditView }) => {
|
|||||||
|
|
||||||
CycleDayOverView.propTypes = {
|
CycleDayOverView.propTypes = {
|
||||||
cycleDay: PropTypes.object,
|
cycleDay: PropTypes.object,
|
||||||
|
date: PropTypes.string,
|
||||||
|
setDate: PropTypes.func,
|
||||||
isTemperatureEditView: PropTypes.bool,
|
isTemperatureEditView: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { ImageBackground, SafeAreaView, ScrollView, View } from 'react-native'
|
||||||
|
import { ScaledSheet } from 'react-native-size-matters'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
import Button from './common/button'
|
||||||
|
import AppHelp from './common/AppHelp'
|
||||||
|
import AppModal from './common/app-modal'
|
||||||
|
import AppText from './common/app-text'
|
||||||
|
import StatsOverview from './common/StatsOverview'
|
||||||
|
import StatsTable from './common/StatsTable'
|
||||||
|
|
||||||
|
import cycleModule from '../lib/cycle'
|
||||||
|
import { getCycleLengthStats as getCycleInfo } from '../lib/cycle-length'
|
||||||
|
|
||||||
|
import { Containers, Sizes, Spacing, Typography } from '../styles'
|
||||||
|
|
||||||
|
const image = require('../assets/cycle-icon.png')
|
||||||
|
|
||||||
|
const Stats = () => {
|
||||||
|
const [isStatsVisible, setIsStatsVisible] = useState(false)
|
||||||
|
|
||||||
|
const { t } = useTranslation(null, { keyPrefix: 'stats' })
|
||||||
|
|
||||||
|
const cycleLengths = cycleModule().getAllCycleLengths()
|
||||||
|
const numberOfCycles = cycleLengths?.length
|
||||||
|
const hasAtLeastOneCycle = numberOfCycles >= 1
|
||||||
|
const cycleData = hasAtLeastOneCycle
|
||||||
|
? getCycleInfo(cycleLengths)
|
||||||
|
: { minimum: '—', maximum: '—', stdDeviation: '—' }
|
||||||
|
const statsData = [
|
||||||
|
[cycleData.minimum, t('min')],
|
||||||
|
[cycleData.maximum, t('max')],
|
||||||
|
[
|
||||||
|
cycleData.stdDeviation ? cycleData.stdDeviation : '—',
|
||||||
|
t('standard_deviation'),
|
||||||
|
],
|
||||||
|
[numberOfCycles, t('completed_cycles')],
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={styles.pageContainer}>
|
||||||
|
<ScrollView contentContainerStyle={styles.overviewContainer}>
|
||||||
|
<AppText>{t('cycle_length_explainer')}</AppText>
|
||||||
|
{!hasAtLeastOneCycle && <AppText>{t('no_data')}</AppText>}
|
||||||
|
{hasAtLeastOneCycle && (
|
||||||
|
<>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.columnLeft}>
|
||||||
|
<ImageBackground
|
||||||
|
source={image}
|
||||||
|
imageStyle={styles.image}
|
||||||
|
style={styles.imageContainter}
|
||||||
|
>
|
||||||
|
<AppText
|
||||||
|
numberOfLines={1}
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
style={styles.accentPurpleGiant}
|
||||||
|
>
|
||||||
|
{cycleData.mean}
|
||||||
|
</AppText>
|
||||||
|
<AppText style={styles.accentPurpleHuge}>{t('days')}</AppText>
|
||||||
|
</ImageBackground>
|
||||||
|
<AppText style={styles.accentOrange}>{t('average')}</AppText>
|
||||||
|
</View>
|
||||||
|
<View style={styles.columnRight}>
|
||||||
|
<StatsOverview data={statsData} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Button isCTA onPress={() => setIsStatsVisible(true)}>
|
||||||
|
{t('show_stats')}
|
||||||
|
</Button>
|
||||||
|
<AppHelp text={t('standard_deviation_help')} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{isStatsVisible && (
|
||||||
|
<AppModal onClose={() => setIsStatsVisible(false)}>
|
||||||
|
<StatsTable
|
||||||
|
onClose={() => setIsStatsVisible(false)}
|
||||||
|
testID="statsTable"
|
||||||
|
/>
|
||||||
|
</AppModal>
|
||||||
|
)}
|
||||||
|
</SafeAreaView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const column = {
|
||||||
|
flexDirection: 'column',
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = ScaledSheet.create({
|
||||||
|
accentOrange: {
|
||||||
|
...Typography.accentOrange,
|
||||||
|
fontSize: Sizes.small,
|
||||||
|
},
|
||||||
|
accentPurpleGiant: {
|
||||||
|
...Typography.accentPurpleGiant,
|
||||||
|
marginTop: Spacing.base * -2,
|
||||||
|
},
|
||||||
|
accentPurpleHuge: {
|
||||||
|
...Typography.accentPurpleHuge,
|
||||||
|
marginTop: Spacing.base * -1,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
alignItems: 'center',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
|
columnLeft: {
|
||||||
|
...column,
|
||||||
|
flex: 3,
|
||||||
|
},
|
||||||
|
columnRight: {
|
||||||
|
...column,
|
||||||
|
flex: 5,
|
||||||
|
paddingTop: Spacing.small,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
resizeMode: 'contain',
|
||||||
|
},
|
||||||
|
imageContainter: {
|
||||||
|
paddingTop: Spacing.large * 2.5,
|
||||||
|
marginBottom: Spacing.large,
|
||||||
|
},
|
||||||
|
overviewContainer: {
|
||||||
|
paddingHorizontal: Spacing.base,
|
||||||
|
paddingTop: Spacing.base,
|
||||||
|
},
|
||||||
|
pageContainer: {
|
||||||
|
...Containers.pageContainer,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default Stats
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { ImageBackground, View } from 'react-native'
|
|
||||||
import { ScaledSheet } from 'react-native-size-matters'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
|
|
||||||
import AppText from '../common/app-text'
|
|
||||||
import StatsOverview from './StatsOverview'
|
|
||||||
import StatsTable from './StatsTable'
|
|
||||||
|
|
||||||
import cycleModule from '../../lib/cycle'
|
|
||||||
import { getCycleLengthStats as getCycleInfo } from '../../lib/cycle-length'
|
|
||||||
|
|
||||||
import { Containers, Sizes, Spacing, Typography } from '../../styles'
|
|
||||||
|
|
||||||
const image = require('../../assets/cycle-icon.png')
|
|
||||||
|
|
||||||
const Stats = () => {
|
|
||||||
const { t } = useTranslation(null, { keyPrefix: 'stats' })
|
|
||||||
|
|
||||||
const cycleLengths = cycleModule().getAllCycleLengths()
|
|
||||||
const numberOfCycles = cycleLengths.length
|
|
||||||
const cycleData =
|
|
||||||
numberOfCycles > 0
|
|
||||||
? getCycleInfo(cycleLengths)
|
|
||||||
: { minimum: '—', maximum: '—', stdDeviation: '—' }
|
|
||||||
const standardDeviation = cycleData.stdDeviation
|
|
||||||
? cycleData.stdDeviation
|
|
||||||
: '—'
|
|
||||||
const statsData = [
|
|
||||||
[cycleData.minimum, t('overview.min')],
|
|
||||||
[cycleData.maximum, t('overview.max')],
|
|
||||||
[standardDeviation, t('overview.standardDeviation')],
|
|
||||||
[numberOfCycles, t('overview.completedCycles')],
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={styles.pageContainer}>
|
|
||||||
<View style={styles.overviewContainer}>
|
|
||||||
<AppText>{t('intro')}</AppText>
|
|
||||||
{numberOfCycles === 0 ? (
|
|
||||||
<AppText>{t('noData')}</AppText>
|
|
||||||
) : (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<View style={styles.columnLeft}>
|
|
||||||
<ImageBackground
|
|
||||||
source={image}
|
|
||||||
imageStyle={styles.image}
|
|
||||||
style={styles.imageContainter}
|
|
||||||
>
|
|
||||||
<AppText
|
|
||||||
numberOfLines={1}
|
|
||||||
ellipsizeMode="clip"
|
|
||||||
style={styles.accentPurpleGiant}
|
|
||||||
>
|
|
||||||
{cycleData.mean}
|
|
||||||
</AppText>
|
|
||||||
<AppText style={styles.accentPurpleHuge}>
|
|
||||||
{t('overview.days')}
|
|
||||||
</AppText>
|
|
||||||
</ImageBackground>
|
|
||||||
<AppText style={styles.accentOrange}>
|
|
||||||
{t('overview.average')}
|
|
||||||
</AppText>
|
|
||||||
</View>
|
|
||||||
<View style={styles.columnRight}>
|
|
||||||
<StatsOverview data={statsData} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<StatsTable />
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const column = {
|
|
||||||
flexDirection: 'column',
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = ScaledSheet.create({
|
|
||||||
accentOrange: {
|
|
||||||
...Typography.accentOrange,
|
|
||||||
fontSize: Sizes.small,
|
|
||||||
},
|
|
||||||
accentPurpleGiant: {
|
|
||||||
...Typography.accentPurpleGiant,
|
|
||||||
marginTop: Spacing.base * -2,
|
|
||||||
},
|
|
||||||
accentPurpleHuge: {
|
|
||||||
...Typography.accentPurpleHuge,
|
|
||||||
marginTop: Spacing.base * -1,
|
|
||||||
},
|
|
||||||
container: {
|
|
||||||
alignItems: 'center',
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
columnLeft: {
|
|
||||||
...column,
|
|
||||||
flex: 3,
|
|
||||||
},
|
|
||||||
columnRight: {
|
|
||||||
...column,
|
|
||||||
flex: 5,
|
|
||||||
paddingTop: Spacing.small,
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
resizeMode: 'contain',
|
|
||||||
},
|
|
||||||
imageContainter: {
|
|
||||||
paddingTop: Spacing.large * 2.5,
|
|
||||||
marginBottom: Spacing.large,
|
|
||||||
},
|
|
||||||
overviewContainer: {
|
|
||||||
paddingHorizontal: Spacing.base,
|
|
||||||
paddingTop: Spacing.base,
|
|
||||||
},
|
|
||||||
pageContainer: {
|
|
||||||
...Containers.pageContainer,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default Stats
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import React, { createContext, useContext, useState } from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { LocalDate } from '@js-joda/core'
|
|
||||||
|
|
||||||
const DateContext = createContext()
|
|
||||||
|
|
||||||
export const DateProvider = ({ children }) => {
|
|
||||||
const [date, setDate] = useState(LocalDate.now().toString())
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DateContext.Provider value={{ date, setDate }}>
|
|
||||||
{children}
|
|
||||||
</DateContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DateProvider.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useDate = () => {
|
|
||||||
const { date, setDate } = useContext(DateContext)
|
|
||||||
return { date, setDate }
|
|
||||||
}
|
|
||||||
+15
-19
@@ -61,27 +61,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stats": {
|
|
||||||
"noData": "At least one completed cycle is needed to display stats.",
|
|
||||||
"intro": "Basic statistics about the length of your cycles.",
|
|
||||||
"overview": {
|
|
||||||
"average": "Average cycle",
|
|
||||||
"days": "days",
|
|
||||||
"min": "Shortest",
|
|
||||||
"max": "Longest",
|
|
||||||
"standardDeviation": "Standard\ndeviation",
|
|
||||||
"completedCycles": "completed\ncycles"
|
|
||||||
},
|
|
||||||
"showStats": "Show period details",
|
|
||||||
"details": {
|
|
||||||
"cycleStart": "Cycle start",
|
|
||||||
"cycleLength": "Cycle length",
|
|
||||||
"bleedingDays": "Bleeding"
|
|
||||||
},
|
|
||||||
"footnote": "Based on the standard deviation of all your tracked periods drip. calculates a range for the starting day of the upcoming 3 periods. The range will be 3 days if your standard deviation is smaller than 1.5 and 5 days if the value is bigger.\n\nThe standard deviation tells you how much the length of your periods vary, 0 means all your periods are exactly the same length and the bigger the value the more the period length varies."
|
|
||||||
},
|
|
||||||
"plurals": {
|
"plurals": {
|
||||||
"day": "{{count}} day",
|
"day": "{{count}} day",
|
||||||
"day_plural": "{{count}} days"
|
"day_plural": "{{count}} days"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"show_stats": "Show period details",
|
||||||
|
"cycle_start": "Cycle start",
|
||||||
|
"cycle_length": "Cycle length",
|
||||||
|
"bleeding": "Bleeding",
|
||||||
|
"cycle_length_explainer": "Basic statistics about the length of your cycles.",
|
||||||
|
"no_data": "At least one completed cycle is needed to display stats.",
|
||||||
|
"days": "days",
|
||||||
|
"completed_cycles": "completed\ncycles",
|
||||||
|
"average": "Average cycle",
|
||||||
|
"min": "Shortest",
|
||||||
|
"max": "Longest",
|
||||||
|
"standard_deviation": "Standard\ndeviation",
|
||||||
|
"standard_deviation_help": "Based on the standard deviation of all your tracked periods drip. calculates a range for the starting day of the upcoming 3 periods. The range will be 3 days if your standard deviation is smaller than 1.5 and 5 days if the value is bigger.\n\nThe standard deviation tells you how much the length of your periods vary, 0 means all your periods are exactly the same length and the bigger the value the more the period length varies."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
// Import Jest Native matchers
|
|
||||||
import '@testing-library/jest-native/extend-expect'
|
|
||||||
+4
-1
@@ -1,7 +1,10 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
preset: '@testing-library/react-native',
|
preset: '@testing-library/react-native',
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
||||||
setupFilesAfterEnv: ['./jest-setup.js'],
|
moduleNameMapper: {
|
||||||
|
'\\.(png)$': require.resolve('./test/file-mock.js'),
|
||||||
|
},
|
||||||
|
setupFilesAfterEnv: ['./test/jest-setup.js'],
|
||||||
transformIgnorePatterns: [
|
transformIgnorePatterns: [
|
||||||
'node_modules/(?!((jest-)?react-native(-.*)?|@react-native(-community)?)/)',
|
'node_modules/(?!((jest-)?react-native(-.*)?|@react-native(-community)?)/)',
|
||||||
],
|
],
|
||||||
|
|||||||
+19
-15
@@ -6,7 +6,7 @@ import Spacing from './spacing'
|
|||||||
|
|
||||||
export const fonts = {
|
export const fonts = {
|
||||||
main: Platform.OS === 'ios' ? 'Jost-Book' : 'Jost-400-Book',
|
main: Platform.OS === 'ios' ? 'Jost-Book' : 'Jost-400-Book',
|
||||||
bold : Platform.OS === 'ios' ? 'Jost-Bold' : 'Jost-700-Bold',
|
bold: Platform.OS === 'ios' ? 'Jost-Bold' : 'Jost-700-Bold',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sizes = {
|
export const sizes = {
|
||||||
@@ -23,7 +23,7 @@ export const sizes = {
|
|||||||
const accentText = {
|
const accentText = {
|
||||||
fontFamily: fonts.bold,
|
fontFamily: fonts.bold,
|
||||||
textAlignVertical: 'center',
|
textAlignVertical: 'center',
|
||||||
textTransform: 'uppercase'
|
textTransform: 'uppercase',
|
||||||
}
|
}
|
||||||
|
|
||||||
const accentTextBig = {
|
const accentTextBig = {
|
||||||
@@ -43,47 +43,51 @@ const accentTextHuge = {
|
|||||||
|
|
||||||
const accentTextSmall = {
|
const accentTextSmall = {
|
||||||
...accentText,
|
...accentText,
|
||||||
fontSize: sizes.small
|
fontSize: sizes.small,
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = {
|
const title = {
|
||||||
color: Colors.purple,
|
color: Colors.purple,
|
||||||
marginVertical: Spacing.large
|
marginVertical: Spacing.large,
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = {
|
const label = {
|
||||||
fontSize: sizes.small,
|
fontSize: sizes.small,
|
||||||
textTransform: 'uppercase'
|
textTransform: 'uppercase',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
accentOrange: {
|
accentOrange: {
|
||||||
...accentTextSmall,
|
...accentTextSmall,
|
||||||
color: Colors.orange
|
color: Colors.orange,
|
||||||
|
},
|
||||||
|
accentPurple: {
|
||||||
|
...accentTextSmall,
|
||||||
|
color: Colors.purple,
|
||||||
},
|
},
|
||||||
accentPurpleBig: {
|
accentPurpleBig: {
|
||||||
...accentTextBig,
|
...accentTextBig,
|
||||||
color: Colors.purple
|
color: Colors.purple,
|
||||||
},
|
},
|
||||||
accentPurpleGiant: {
|
accentPurpleGiant: {
|
||||||
...accentTextGiant,
|
...accentTextGiant,
|
||||||
color: Colors.purple
|
color: Colors.purple,
|
||||||
},
|
},
|
||||||
accentPurpleHuge: {
|
accentPurpleHuge: {
|
||||||
...accentTextHuge,
|
...accentTextHuge,
|
||||||
color: Colors.purple
|
color: Colors.purple,
|
||||||
},
|
},
|
||||||
mainText: {
|
mainText: {
|
||||||
fontFamily: fonts.main,
|
fontFamily: fonts.main,
|
||||||
fontSize: sizes.base
|
fontSize: sizes.base,
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
...label
|
...label,
|
||||||
},
|
},
|
||||||
labelBold: {
|
labelBold: {
|
||||||
color: Colors.greyDark,
|
color: Colors.greyDark,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
...label
|
...label,
|
||||||
},
|
},
|
||||||
labelLight: {
|
labelLight: {
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@@ -91,7 +95,7 @@ export default {
|
|||||||
},
|
},
|
||||||
subtitle: {
|
subtitle: {
|
||||||
fontSize: sizes.subtitle,
|
fontSize: sizes.subtitle,
|
||||||
...title
|
...title,
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
@@ -99,7 +103,7 @@ export default {
|
|||||||
fontWeight: '700',
|
fontWeight: '700',
|
||||||
fontSize: sizes.title,
|
fontSize: sizes.title,
|
||||||
marginHorizontal: Spacing.base,
|
marginHorizontal: Spacing.base,
|
||||||
...title
|
...title,
|
||||||
},
|
},
|
||||||
titleWithoutMargin: {
|
titleWithoutMargin: {
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
@@ -107,5 +111,5 @@ export default {
|
|||||||
fontFamily: fonts.bold,
|
fontFamily: fonts.bold,
|
||||||
fontWeight: '700',
|
fontWeight: '700',
|
||||||
fontSize: sizes.title,
|
fontSize: sizes.title,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { render, screen, fireEvent } from '@testing-library/react-native'
|
import { render, screen, fireEvent } from '@testing-library/react-native'
|
||||||
import AcceptLicense from '../components/AcceptLicense'
|
|
||||||
|
|
||||||
import { saveLicenseFlag } from '../local-storage'
|
import AcceptLicense from '../../components/AcceptLicense'
|
||||||
|
|
||||||
jest.mock('../local-storage', () => ({
|
import { saveLicenseFlag } from '../../local-storage'
|
||||||
|
|
||||||
|
jest.mock('../../local-storage', () => ({
|
||||||
saveLicenseFlag: jest.fn(() => Promise.resolve()),
|
saveLicenseFlag: jest.fn(() => Promise.resolve()),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock('react-i18next', () => ({
|
|
||||||
useTranslation: () => ({
|
|
||||||
t: (str, options) => {
|
|
||||||
return str + (options ? JSON.stringify(options) : '')
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
describe('AcceptLicense', () => {
|
describe('AcceptLicense', () => {
|
||||||
test('On clicking OK button, the license is accepted', async () => {
|
test('On clicking OK button, the license is accepted', async () => {
|
||||||
const mockedSetLicense = jest.fn()
|
const mockedSetLicense = jest.fn()
|
||||||
@@ -0,0 +1,395 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Stats screen when provided data, renders stats 1`] = `
|
||||||
|
<RCTSafeAreaView
|
||||||
|
emulateUnlessSupported={true}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<RCTScrollView
|
||||||
|
contentContainerStyle={
|
||||||
|
Object {
|
||||||
|
"paddingHorizontal": 34.285714285714285,
|
||||||
|
"paddingTop": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_length_explainer
|
||||||
|
</Text>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "space-between",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 3,
|
||||||
|
"flexDirection": "column",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
accessibilityIgnoresInvertColors={true}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": 42.857142857142854,
|
||||||
|
"paddingTop": 107.14285714285714,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
source={123}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"bottom": 0,
|
||||||
|
"left": 0,
|
||||||
|
"position": "absolute",
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"height": undefined,
|
||||||
|
"width": undefined,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"resizeMode": "contain",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 85.71428571428571,
|
||||||
|
"marginTop": -68.57142857142857,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
30.33
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 68.57142857142857,
|
||||||
|
"marginTop": -34.285714285714285,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
days
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
average
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 5,
|
||||||
|
"flexDirection": "column",
|
||||||
|
"paddingTop": 21.428571428571427,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StatsOverview
|
||||||
|
data={
|
||||||
|
Array [
|
||||||
|
Array [
|
||||||
|
30,
|
||||||
|
"min",
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
31,
|
||||||
|
"max",
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.58,
|
||||||
|
"standard_deviation",
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3,
|
||||||
|
"completed_cycles",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
collapsable={false}
|
||||||
|
focusable={true}
|
||||||
|
onClick={[Function]}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"alignSelf": "center",
|
||||||
|
"backgroundColor": "#F38337",
|
||||||
|
"borderRadius": 25,
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "center",
|
||||||
|
"marginTop": 34.285714285714285,
|
||||||
|
"minWidth": "15%",
|
||||||
|
"opacity": 1,
|
||||||
|
"paddingHorizontal": 8.571428571428571,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "white",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"padding": 21.428571428571427,
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
show_stats
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<AppHelp
|
||||||
|
text="standard_deviation_help"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</RCTScrollView>
|
||||||
|
</RCTSafeAreaView>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Stats screen when provided no data, renders no_data text 1`] = `
|
||||||
|
<RCTSafeAreaView
|
||||||
|
emulateUnlessSupported={true}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<RCTScrollView
|
||||||
|
contentContainerStyle={
|
||||||
|
Object {
|
||||||
|
"paddingHorizontal": 34.285714285714285,
|
||||||
|
"paddingTop": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_length_explainer
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
no_data
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</RCTScrollView>
|
||||||
|
</RCTSafeAreaView>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Stats screen when provided null, renders no_data text 1`] = `
|
||||||
|
<RCTSafeAreaView
|
||||||
|
emulateUnlessSupported={true}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<RCTScrollView
|
||||||
|
contentContainerStyle={
|
||||||
|
Object {
|
||||||
|
"paddingHorizontal": 34.285714285714285,
|
||||||
|
"paddingTop": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_length_explainer
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
no_data
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</RCTScrollView>
|
||||||
|
</RCTSafeAreaView>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Stats screen when provided undefined, renders no_data text 1`] = `
|
||||||
|
<RCTSafeAreaView
|
||||||
|
emulateUnlessSupported={true}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<RCTScrollView
|
||||||
|
contentContainerStyle={
|
||||||
|
Object {
|
||||||
|
"paddingHorizontal": 34.285714285714285,
|
||||||
|
"paddingTop": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_length_explainer
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
no_data
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</RCTScrollView>
|
||||||
|
</RCTSafeAreaView>
|
||||||
|
`;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render } from '@testing-library/react-native'
|
||||||
|
|
||||||
|
import AppHelp from '../../../components/common/AppHelp'
|
||||||
|
|
||||||
|
describe('AppHelp screen', () => {
|
||||||
|
test('when provided text, should render it', async () => {
|
||||||
|
const text = 'Some help test'
|
||||||
|
const { toJSON } = render(<AppHelp text={text} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { render } from '@testing-library/react-native'
|
|
||||||
|
|
||||||
import Footnote from '../../../components/common/Footnote'
|
|
||||||
|
|
||||||
describe('Footnote component', () => {
|
|
||||||
test('when children are present, renders them', () => {
|
|
||||||
const text = 'Some footnote text'
|
|
||||||
const { toJSON } = render(<Footnote>{text}</Footnote>)
|
|
||||||
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('when no children, renders nothing', () => {
|
|
||||||
const { toJSON } = render(<Footnote></Footnote>)
|
|
||||||
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render } from '@testing-library/react-native'
|
||||||
|
|
||||||
|
import StatsOverview from '../../../components/common/StatsOverview'
|
||||||
|
|
||||||
|
describe('StatsOverview screen', () => {
|
||||||
|
test('when provided correct, renders it', async () => {
|
||||||
|
const data = [
|
||||||
|
[21, 'shortest'],
|
||||||
|
[21, 'longest'],
|
||||||
|
[0, 'standard deviation'],
|
||||||
|
[2, 'completed cycles'],
|
||||||
|
]
|
||||||
|
const { toJSON } = render(<StatsOverview data={data} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided empty data, renders nothing (does not break)', async () => {
|
||||||
|
const data = []
|
||||||
|
const { toJSON } = render(<StatsOverview data={data} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render } from '@testing-library/react-native'
|
||||||
|
|
||||||
|
import StatsTable from '../../../components/common/StatsTable'
|
||||||
|
|
||||||
|
const mockGetStats = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{ date: '2022-07-01', cycleLength: 31, bleedingLength: 5 },
|
||||||
|
{ date: '2022-06-01', cycleLength: 31, bleedingLength: 5 },
|
||||||
|
])
|
||||||
|
.mockImplementationOnce(() => [])
|
||||||
|
.mockImplementationOnce(() => null)
|
||||||
|
.mockImplementationOnce(() => undefined)
|
||||||
|
|
||||||
|
jest.mock('../../../lib/cycle', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: () => ({
|
||||||
|
getStats: mockGetStats,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('StatsTable screen', () => {
|
||||||
|
test('when provided correct data set, renders it', async () => {
|
||||||
|
const { toJSON } = render(<StatsTable onClose={jest.fn()} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided no data, renders nothing', async () => {
|
||||||
|
const { toJSON } = render(<StatsTable onClose={jest.fn()} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided null, renders nothing', async () => {
|
||||||
|
const { toJSON } = render(<StatsTable onClose={jest.fn()} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided undefined, renders nothing', async () => {
|
||||||
|
const { toJSON } = render(<StatsTable onClose={jest.fn()} />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
+13
-17
@@ -1,13 +1,13 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Footnote component when children are present, renders them 1`] = `
|
exports[`AppHelp screen when provided text, should render it 1`] = `
|
||||||
<View
|
<View
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignContent": "flex-start",
|
"alignItems": "center",
|
||||||
"flexDirection": "row",
|
"flexDirection": "row",
|
||||||
"marginBottom": 8.571428571428571,
|
"justifyContent": "space-between",
|
||||||
"marginTop": 21.428571428571427,
|
"padding": 34.285714285714285,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -20,7 +20,13 @@ exports[`Footnote component when children are present, renders them 1`] = `
|
|||||||
"fontSize": 34.285714285714285,
|
"fontSize": 34.285714285714285,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": "#F38337",
|
"alignSelf": "flex-start",
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"paddingRight": 34.285714285714285,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -28,11 +34,6 @@ exports[`Footnote component when children are present, renders them 1`] = `
|
|||||||
*
|
*
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
linkStyle={
|
|
||||||
Object {
|
|
||||||
"color": "white",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
style={
|
style={
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -40,16 +41,11 @@ exports[`Footnote component when children are present, renders them 1`] = `
|
|||||||
"fontFamily": "Jost-Book",
|
"fontFamily": "Jost-Book",
|
||||||
"fontSize": 34.285714285714285,
|
"fontSize": 34.285714285714285,
|
||||||
},
|
},
|
||||||
Object {
|
undefined,
|
||||||
"color": "#CCC",
|
|
||||||
"paddingLeft": 34.285714285714285,
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Some footnote text
|
Some help test
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Footnote component when no children, renders nothing 1`] = `null`;
|
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`StatsOverview screen when provided correct, renders it 1`] = `
|
||||||
|
Array [
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-end",
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 64.28571428571428,
|
||||||
|
"marginRight": 8.571428571428571,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
21
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 5,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="tail"
|
||||||
|
numberOfLines={2}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"margin": 15,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
shortest
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>,
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-end",
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 64.28571428571428,
|
||||||
|
"marginRight": 8.571428571428571,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
21
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 5,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="tail"
|
||||||
|
numberOfLines={2}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"margin": 15,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
longest
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>,
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-end",
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 64.28571428571428,
|
||||||
|
"marginRight": 8.571428571428571,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 5,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="tail"
|
||||||
|
numberOfLines={2}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"margin": 15,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
standard deviation
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 64.28571428571428,
|
||||||
|
"marginRight": 8.571428571428571,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
*
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>,
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-end",
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="clip"
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#3A2671",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 64.28571428571428,
|
||||||
|
"marginRight": 8.571428571428571,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
2
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 5,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
ellipsizeMode="tail"
|
||||||
|
numberOfLines={2}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"margin": 15,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
completed cycles
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>,
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`StatsOverview screen when provided empty data, renders nothing (does not break) 1`] = `null`;
|
||||||
@@ -0,0 +1,433 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`StatsTable screen when provided correct data set, renders it 1`] = `
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignSelf": "center",
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"marginTop": 137.14285714285714,
|
||||||
|
"maxHeight": 933.8,
|
||||||
|
"minHeight": "40%",
|
||||||
|
"position": "absolute",
|
||||||
|
"width": "100%",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "flex-end",
|
||||||
|
"paddingRight": 34.285714285714285,
|
||||||
|
"paddingTop": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
collapsable={false}
|
||||||
|
focusable={true}
|
||||||
|
hitSlop={
|
||||||
|
Object {
|
||||||
|
"bottom": 39.23529411764706,
|
||||||
|
"left": 42.857142857142854,
|
||||||
|
"right": 42.857142857142854,
|
||||||
|
"top": 39.23529411764706,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={[Function]}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignSelf": "flex-start",
|
||||||
|
"marginBottom": 34.285714285714285,
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
allowFontScaling={false}
|
||||||
|
selectable={false}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": undefined,
|
||||||
|
"fontSize": 12,
|
||||||
|
},
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"fontSize": 47.14285714285714,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
Object {
|
||||||
|
"fontFamily": "Entypo",
|
||||||
|
"fontStyle": "normal",
|
||||||
|
"fontWeight": "normal",
|
||||||
|
},
|
||||||
|
Object {},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<RCTScrollView
|
||||||
|
ItemSeparatorComponent={[Function]}
|
||||||
|
ListHeaderComponent={[Function]}
|
||||||
|
ListHeaderComponentStyle={
|
||||||
|
Object {
|
||||||
|
"borderBottomColor": "#3A2671",
|
||||||
|
"borderBottomWidth": 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentContainerStyle={
|
||||||
|
Object {
|
||||||
|
"paddingHorizontal": 34.285714285714285,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"bleedingLength": 5,
|
||||||
|
"cycleLength": 31,
|
||||||
|
"date": "2022-07-01",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"bleedingLength": 5,
|
||||||
|
"cycleLength": 31,
|
||||||
|
"date": "2022-06-01",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
getItem={[Function]}
|
||||||
|
getItemCount={[Function]}
|
||||||
|
keyExtractor={[Function]}
|
||||||
|
onContentSizeChange={[Function]}
|
||||||
|
onLayout={[Function]}
|
||||||
|
onMomentumScrollBegin={[Function]}
|
||||||
|
onMomentumScrollEnd={[Function]}
|
||||||
|
onScroll={[Function]}
|
||||||
|
onScrollBeginDrag={[Function]}
|
||||||
|
onScrollEndDrag={[Function]}
|
||||||
|
removeClippedSubviews={false}
|
||||||
|
renderItem={[Function]}
|
||||||
|
scrollEventThrottle={50}
|
||||||
|
stickyHeaderIndices={
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
viewabilityConfigCallbackPairs={Array []}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<View
|
||||||
|
onLayout={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderBottomColor": "#3A2671",
|
||||||
|
"borderBottomWidth": 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "space-between",
|
||||||
|
"paddingVertical": 8.571428571428571,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"paddingVertical": 21.428571428571427,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_start
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"paddingVertical": 21.428571428571427,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
cycle_length
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"color": "#F38337",
|
||||||
|
"fontFamily": "Jost-Bold",
|
||||||
|
"fontSize": 27.857142857142858,
|
||||||
|
"paddingVertical": 21.428571428571427,
|
||||||
|
"textAlignVertical": "center",
|
||||||
|
"textTransform": "uppercase",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
bleeding
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
onLayout={[Function]}
|
||||||
|
style={null}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "space-between",
|
||||||
|
"paddingVertical": 8.571428571428571,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
01. Jul 22
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
day{"count":31}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
day{"count":5}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#888",
|
||||||
|
"height": 1,
|
||||||
|
"width": "100%",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
onLayout={[Function]}
|
||||||
|
style={null}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "#E9F2ED",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "space-between",
|
||||||
|
"paddingVertical": 8.571428571428571,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 3,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
01. Jun 22
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
day{"count":31}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 2,
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#555",
|
||||||
|
"fontFamily": "Jost-Book",
|
||||||
|
"fontSize": 34.285714285714285,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
day{"count":5}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</RCTScrollView>
|
||||||
|
</View>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`StatsTable screen when provided no data, renders nothing 1`] = `null`;
|
||||||
|
|
||||||
|
exports[`StatsTable screen when provided null, renders nothing 1`] = `null`;
|
||||||
|
|
||||||
|
exports[`StatsTable screen when provided undefined, renders nothing 1`] = `null`;
|
||||||
@@ -1,14 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { render, screen } from '@testing-library/react-native'
|
import { render, screen } from '@testing-library/react-native'
|
||||||
import License from '../components/settings/License'
|
|
||||||
|
|
||||||
jest.mock('react-i18next', () => ({
|
import License from '../../../components/settings/License'
|
||||||
useTranslation: () => ({
|
|
||||||
t: (str, options) => {
|
|
||||||
return str + (options ? JSON.stringify(options) : '')
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
describe('License screen', () => {
|
describe('License screen', () => {
|
||||||
test('It should have a correct year', async () => {
|
test('It should have a correct year', async () => {
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { fireEvent, render } from '@testing-library/react-native'
|
||||||
|
|
||||||
|
import Stats from '../../components/stats'
|
||||||
|
|
||||||
|
jest.mock('../../components/common/AppHelp', () => 'AppHelp')
|
||||||
|
jest.mock('../../components/common/StatsOverview', () => 'StatsOverview')
|
||||||
|
jest.mock('../../components/common/StatsTable', () => 'StatsTable')
|
||||||
|
|
||||||
|
const mockGetAllCycleLengths = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(() => [])
|
||||||
|
.mockImplementationOnce(() => [30, 31, 30])
|
||||||
|
.mockImplementationOnce(() => null)
|
||||||
|
.mockImplementationOnce(() => undefined)
|
||||||
|
.mockImplementationOnce(() => [30, 31, 30])
|
||||||
|
|
||||||
|
jest.mock('../../lib/cycle', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: () => ({
|
||||||
|
getAllCycleLengths: mockGetAllCycleLengths,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('Stats screen', () => {
|
||||||
|
test('when provided no data, renders no_data text', async () => {
|
||||||
|
const { toJSON } = render(<Stats />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided data, renders stats', async () => {
|
||||||
|
const { toJSON } = render(<Stats />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided null, renders no_data text', async () => {
|
||||||
|
const { toJSON } = render(<Stats />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when provided undefined, renders no_data text', async () => {
|
||||||
|
const { toJSON } = render(<Stats />)
|
||||||
|
|
||||||
|
expect(toJSON()).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('when button is clicked, StatsTable is rendered', async () => {
|
||||||
|
const { getByText, findByTestId } = render(<Stats />)
|
||||||
|
const button = getByText('show_stats')
|
||||||
|
|
||||||
|
fireEvent(button, 'click')
|
||||||
|
|
||||||
|
await expect(findByTestId('statsTable')).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
module.exports = 123
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Import Jest Native matchers
|
||||||
|
import '@testing-library/jest-native/extend-expect'
|
||||||
|
|
||||||
|
jest.mock('react-i18next', () => ({
|
||||||
|
useTranslation: () => ({
|
||||||
|
t: (str, options) => str + (options ? JSON.stringify(options) : ''),
|
||||||
|
}),
|
||||||
|
}))
|
||||||
Reference in New Issue
Block a user