Massive/ViewBest.tsx

114 lines
4.0 KiB
TypeScript
Raw Normal View History

import {Picker} from '@react-native-picker/picker';
import {RouteProp, useRoute} from '@react-navigation/native';
import {useEffect, useState} from 'react';
import {View} from 'react-native';
2022-07-11 01:00:17 +00:00
import {BestPageParams} from './BestPage';
2022-09-02 00:24:28 +00:00
import Chart from './Chart';
import {PADDING} from './constants';
import {setRepo} from './db';
import GymSet from './gym-set';
import {Metrics} from './metrics';
import {Periods} from './periods';
import StackHeader from './StackHeader';
2022-07-11 01:00:17 +00:00
import {formatMonth} from './time';
import useDark from './use-dark';
import Volume from './volume';
2022-09-02 00:24:28 +00:00
2022-07-11 01:00:17 +00:00
export default function ViewBest() {
const {params} = useRoute<RouteProp<BestPageParams, 'ViewBest'>>();
const dark = useDark();
const [weights, setWeights] = useState<GymSet[]>([]);
2022-08-24 00:32:57 +00:00
const [volumes, setVolumes] = useState<Volume[]>([]);
2022-09-02 00:24:28 +00:00
const [metric, setMetric] = useState(Metrics.Weight);
const [period, setPeriod] = useState(Periods.Monthly);
2022-07-08 12:11:10 +00:00
2022-09-02 00:24:28 +00:00
useEffect(() => {
2022-09-20 00:35:44 +00:00
console.log(`${ViewBest.name}.useEffect`, {metric});
console.log(`${ViewBest.name}.useEffect`, {period});
let difference = '-7 days';
if (period === Periods.Monthly) difference = '-1 months';
else if (period === Periods.Yearly) difference = '-1 years';
let group = '%Y-%m-%d';
if (period === Periods.Yearly) group = '%Y-%m';
const builder = setRepo
.createQueryBuilder()
.select("STRFTIME('%Y-%m-%d', created)", 'created')
.addSelect('unit')
.where('name = :name', {name: params.best.name})
.andWhere('NOT hidden')
.andWhere("DATE(created) >= DATE('now', 'weekday 0', :difference)", {
difference,
})
.groupBy('name')
.addGroupBy(`STRFTIME('${group}', created)`);
switch (metric) {
case Metrics.Weight:
builder
.addSelect('MAX(weight)', 'weight')
.getRawMany()
.then(setWeights);
break;
case Metrics.Volume:
builder
.addSelect('SUM(weight * reps)', 'value')
.getRawMany()
.then(setVolumes);
break;
default:
2022-10-31 04:05:31 +00:00
// Brzycki formula https://en.wikipedia.org/wiki/One-repetition_maximum#Brzycki
builder
.addSelect('MAX(weight / (1.0278 - 0.0278 * reps))', 'weight')
.getRawMany()
.then(weights => {
console.log({weights});
setWeights(weights);
});
}
}, [params.best.name, metric, period]);
2022-07-12 03:54:04 +00:00
2022-07-08 12:11:10 +00:00
return (
<>
<StackHeader title={params.best.name} />
<View style={{padding: PADDING}}>
<Picker
style={{color: dark ? 'white' : 'black'}}
dropdownIconColor={dark ? 'white' : 'black'}
selectedValue={metric}
onValueChange={value => setMetric(value)}>
<Picker.Item value={Metrics.Volume} label={Metrics.Volume} />
<Picker.Item value={Metrics.Weight} label={Metrics.Weight} />
<Picker.Item value={Metrics.OneRepMax} label={Metrics.OneRepMax} />
</Picker>
<Picker
style={{color: dark ? 'white' : 'black'}}
dropdownIconColor={dark ? 'white' : 'black'}
selectedValue={period}
onValueChange={value => setPeriod(value)}>
<Picker.Item value={Periods.Weekly} label={Periods.Weekly} />
<Picker.Item value={Periods.Monthly} label={Periods.Monthly} />
<Picker.Item value={Periods.Yearly} label={Periods.Yearly} />
</Picker>
{metric === Metrics.Volume ? (
<Chart
yData={volumes.map(v => v.value)}
yFormat={(value: number) =>
`${value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}${
volumes[0].unit || 'kg'
}`
}
xData={weights}
xFormat={(_value, index) => formatMonth(weights[index].created!)}
/>
) : (
<Chart
yData={weights.map(set => set.weight)}
yFormat={value => `${value}${weights[0].unit}`}
xData={weights}
xFormat={(_value, index) => formatMonth(weights[index].created!)}
/>
)}
</View>
</>
2022-07-08 12:11:10 +00:00
);
}