diff --git a/assets/cycle-icon.png b/assets/cycle-icon.png
new file mode 100644
index 0000000..aa225b3
Binary files /dev/null and b/assets/cycle-icon.png differ
diff --git a/components/common/table.js b/components/common/table.js
new file mode 100644
index 0000000..f1e024f
--- /dev/null
+++ b/components/common/table.js
@@ -0,0 +1,79 @@
+import React from 'react'
+import { StyleSheet, View } from 'react-native'
+import PropTypes from 'prop-types'
+
+import AppText from './app-text'
+
+import { Spacing, Typography } from '../../styles/redesign'
+
+const Table = ({ tableContent }) => {
+ return (
+ tableContent.map((rowContent, i) =>
)
+ )
+}
+
+Table.propTypes = {
+ tableContent: PropTypes.array.isRequired
+}
+
+const Row = ({ rowContent }) => {
+ return(
+
+ |
+ |
+
+ )
+}
+
+Row.propTypes = {
+ rowContent: PropTypes.array.isRequired
+}
+
+const Cell = ({ content, isLeft }) => {
+ const styleContainer = isLeft ? styles.cellLeft : styles.cellRight
+ const styleText = isLeft ? styles.accentPurpleBig : styles.accentOrange
+ const numberOfLines = isLeft ? 1 : 2
+ const ellipsizeMode = isLeft ? 'clip' : 'tail'
+
+ return(
+
+
+ {content}
+
+
+ )
+}
+
+Cell.propTypes = {
+ content: PropTypes.node.isRequired,
+ isLeft: PropTypes.bool
+}
+
+const styles = StyleSheet.create({
+ accentOrange: {
+ ...Typography.accentOrange
+ },
+ accentPurpleBig: {
+ ...Typography.accentPurpleBig,
+ marginRight: Spacing.base
+ },
+ cellLeft: {
+ alignItems: 'flex-end',
+ flex: 5,
+ justifyContent: 'center'
+ },
+ cellRight: {
+ flex: 6,
+ justifyContent: 'center'
+ },
+ row: {
+ flexDirection: 'row',
+ marginBottom: Spacing.tiny
+ }
+})
+
+export default Table
\ No newline at end of file
diff --git a/components/stats.js b/components/stats.js
index a89ddcc..213ae7d 100644
--- a/components/stats.js
+++ b/components/stats.js
@@ -1,77 +1,114 @@
-import React, { Component } from 'react'
-import {
- View,
- ScrollView
-} from 'react-native'
+import React from 'react'
+import { ImageBackground, StyleSheet, View } from 'react-native'
+
+import AppPage from './common/app-page'
+import AppText from './common/app-text'
+import Segment from './common/segment'
+import Table from './common/table'
-import styles from '../styles/index'
import cycleModule from '../lib/cycle'
import {getCycleLengthStats as getCycleInfo} from '../lib/cycle-length'
import {stats as labels} from '../i18n/en/labels'
-import AppText from './common/app-text'
-import Segment from './common/segment'
-export default class Stats extends Component {
- render() {
- const cycleLengths = cycleModule().getAllCycleLengths()
- const atLeastOneCycle = cycleLengths.length >= 1
- let numberOfCycles
- let cycleInfo
- if (atLeastOneCycle) {
- numberOfCycles = cycleLengths.length
- if (numberOfCycles > 1) {
- cycleInfo = getCycleInfo(cycleLengths)
- }
- }
- return (
-
-
-
- {labels.cycleLengthExplainer}
-
+import { Sizes, Spacing, Typography } from '../styles/redesign'
- {!atLeastOneCycle &&
- {labels.emptyStats}
- }
- {atLeastOneCycle && numberOfCycles === 1 &&
-
- {labels.oneCycleStats}
- {cycleLengths[0]}
- {labels.daysLabel}.
-
- }
- {atLeastOneCycle && numberOfCycles > 1 &&
-
-
- {labels.averageLabel}: {cycleInfo.mean} {labels.daysLabel}
-
-
-
-
- {labels.minLabel}: {cycleInfo.minimum} {labels.daysLabel}
-
-
-
-
- {labels.maxLabel}: {cycleInfo.maximum} {labels.daysLabel}
-
-
-
-
- {labels.stdLabel}: {cycleInfo.stdDeviation} {labels.daysLabel}
-
-
-
- {labels.basisOfStatsBeginning}
- {numberOfCycles}
- {labels.basisOfStatsEnd}
-
- }
-
-
- )
+const image = require('../assets/cycle-icon.png')
+
+const Stats = () => {
+ const cycleLengths = cycleModule().getAllCycleLengths()
+ const atLeastOneCycle = cycleLengths.length >= 1
+ const numberOfCycles = cycleLengths.length
+ let cycleData
+ if (atLeastOneCycle) {
+ cycleData = getCycleInfo(cycleLengths)
}
+
+ const statsData = [
+ [atLeastOneCycle ? cycleData.minimum : 0, labels.minLabel],
+ [atLeastOneCycle ? cycleData.maximum : 0, labels.maxLabel],
+ [atLeastOneCycle && cycleData.stdDeviation ? cycleData.stdDeviation : '—', labels.stdLabel],
+ [numberOfCycles, labels.basisOfStatsEnd]
+ ]
+ return (
+
+
+ {labels.cycleLengthExplainer}
+ {!atLeastOneCycle && {labels.emptyStats}}
+ {atLeastOneCycle &&
+
+
+
+
+ {cycleData.mean}
+
+
+ {labels.daysLabel}
+
+
+
+ {labels.averageLabel}
+
+
+
+
+
+
+ }
+
+
+ )
}
+
+const column = {
+ flexDirection: 'column'
+}
+
+const styles = StyleSheet.create({
+ accentOrange: {
+ ...Typography.accentOrange
+ },
+ accentPurpleGiant: {
+ ...Typography.accentPurpleGiant,
+ marginVertical: Sizes.giant * (-0.5)
+ },
+ accentPurpleHuge: {
+ ...Typography.accentPurpleHuge,
+ marginRight: Spacing.base
+ },
+ container: {
+ alignItems: 'center',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ },
+ columnLeft: {
+ ...column,
+ flex: 4
+ },
+ columnRight: {
+ ...column,
+ flex: 5
+ },
+ image: {
+ height: Sizes.huge * 3,
+ marginLeft: Sizes.huge / 2,
+ resizeMode: 'contain',
+ width: Sizes.huge * 3
+ },
+ imageContainter: {
+ paddingTop: Sizes.huge,
+ marginBottom: Sizes.huge / 4
+ },
+ pageContainer: {
+ marginVertical: Spacing.large
+ }
+})
+
+export default Stats
\ No newline at end of file
diff --git a/i18n/en/labels.js b/i18n/en/labels.js
index 4dd59fe..3b5e8df 100644
--- a/i18n/en/labels.js
+++ b/i18n/en/labels.js
@@ -61,19 +61,14 @@ export const menuTitles = {
}
export const stats = {
- cycleLengthTitle: 'Cycle length',
cycleLengthExplainer: 'Basic statistics about the length of your cycles.',
emptyStats: 'At least one completed cycle is needed to display stats.',
- //oneCycleStats: (number) => `You have documented one cycle of ${number} days.`,
- oneCycleStats: 'You have documented one cycle of',
daysLabel: 'days',
- //getBasisOfStats: (numberOfCycles) => `Stats are based on ${numberOfCycles} completed cycles.`,
- basisOfStatsBeginning: 'Stats are based on',
- basisOfStatsEnd: 'completed cycles.',
- averageLabel: 'Average cycle length',
- minLabel: 'Shortest cycle',
- maxLabel: 'Longest cycle',
- stdLabel: 'Standard deviation'
+ basisOfStatsEnd: 'completed\ncycles',
+ averageLabel: 'Average cycle',
+ minLabel: `Shortest`,
+ maxLabel: `Longest`,
+ stdLabel: `Standard\ndeviation`
}
export const bleedingPrediction = {
diff --git a/styles/typography.js b/styles/typography.js
index 59892e8..bfc5173 100644
--- a/styles/typography.js
+++ b/styles/typography.js
@@ -12,7 +12,9 @@ export const sizes = {
base: 18,
subtitle: 22,
title: 24,
- huge: 40
+ big: 30,
+ huge: 40,
+ giant: 50
}
const title = {
@@ -20,7 +22,49 @@ const title = {
marginVertical: Spacing.large
}
+const accentText = {
+ fontFamily: fonts.bold,
+ textAlignVertical: 'center',
+ textTransform: 'uppercase'
+}
+
+const accentTextBig = {
+ ...accentText,
+ fontSize: sizes.big,
+}
+
+const accentTextGiant = {
+ ...accentText,
+ fontSize: sizes.giant,
+}
+
+const accentTextHuge = {
+ ...accentText,
+ fontSize: sizes.huge,
+}
+
+const accentTextSmall = {
+ ...accentText,
+ fontSize: sizes.small
+}
+
export default {
+ accentOrange: {
+ ...accentTextSmall,
+ color: Colors.orange
+ },
+ accentPurpleBig: {
+ ...accentTextBig,
+ color: Colors.purple
+ },
+ accentPurpleGiant: {
+ ...accentTextGiant,
+ color: Colors.purple
+ },
+ accentPurpleHuge: {
+ ...accentTextHuge,
+ color: Colors.purple
+ },
mainText: {
fontFamily: fonts.main,
fontSize: sizes.base