From ad907a83c357adcc5a8a9f7b696f0c2d6e600aee Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Mon, 11 Jul 2022 13:00:17 +1200 Subject: [PATCH] Use stack navigation for Best --- BestList.tsx | 95 +++++++++++++++++++++++++++++++++++++++++ BestPage.tsx | 108 ++++++++++++++-------------------------------- PlanList.tsx | 1 - SetList.tsx | 1 - ViewBest.tsx | 118 +++++++++++++++++++++++++++------------------------ time.ts | 7 +++ 6 files changed, 197 insertions(+), 133 deletions(-) create mode 100644 BestList.tsx diff --git a/BestList.tsx b/BestList.tsx new file mode 100644 index 0000000..9956709 --- /dev/null +++ b/BestList.tsx @@ -0,0 +1,95 @@ +import { + NavigationProp, + useFocusEffect, + useNavigation, +} from '@react-navigation/native'; +import React, {useCallback, useContext, useEffect, useState} from 'react'; +import {FlatList, StyleSheet, View} from 'react-native'; +import {List, Searchbar} from 'react-native-paper'; +import {DatabaseContext} from './App'; +import Best from './best'; +import {BestPageParams} from './BestPage'; + +export default function BestList() { + const [bests, setBests] = useState([]); + const [search, setSearch] = useState(''); + const [refreshing, setRefresing] = useState(false); + const db = useContext(DatabaseContext); + const navigation = useNavigation>(); + + const refresh = useCallback(async () => { + const bestWeight = ` + SELECT name, reps, unit, MAX(weight) AS weight + FROM sets + WHERE name LIKE ? + GROUP BY name; + `; + const bestReps = ` + SELECT name, MAX(reps) as reps, unit, weight + FROM sets + WHERE name = ? + AND weight = ? + GROUP BY name; + `; + const [weight] = await db.executeSql(bestWeight, [`%${search}%`]); + if (!weight) return setBests([]); + let newBest: Best[] = []; + for (let i = 0; i < weight.rows.length; i++) { + const [reps] = await db.executeSql(bestReps, [ + weight.rows.item(i).name, + weight.rows.item(i).weight, + ]); + newBest = newBest.concat(reps.rows.raw()); + } + setBests(newBest); + }, [search, db]); + + useFocusEffect( + useCallback(() => { + refresh(); + }, [refresh]), + ); + + useEffect(() => { + refresh(); + }, [search, refresh]); + + const renderItem = ({item}: {item: Best}) => ( + navigation.navigate('ViewBest', {best: item})} + /> + ); + + return ( + + + + } + refreshing={refreshing} + onRefresh={async () => { + setRefresing(true); + await refresh(); + setRefresing(false); + }} + renderItem={renderItem} + data={bests} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + padding: 10, + flexGrow: 1, + paddingBottom: '10%', + }, +}); diff --git a/BestPage.tsx b/BestPage.tsx index c0274a8..b766ee0 100644 --- a/BestPage.tsx +++ b/BestPage.tsx @@ -1,86 +1,42 @@ -import React, {useCallback, useContext, useEffect, useState} from 'react'; -import {FlatList, StyleSheet, View} from 'react-native'; -import {List, Searchbar} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DrawerNavigationProp} from '@react-navigation/drawer'; +import {useNavigation} from '@react-navigation/native'; +import {createStackNavigator} from '@react-navigation/stack'; +import React from 'react'; +import {IconButton} from 'react-native-paper'; +import {DrawerParamList} from './App'; import Best from './best'; +import BestList from './BestList'; import ViewBest from './ViewBest'; +const Stack = createStackNavigator(); +export type BestPageParams = { + BestList: {}; + ViewBest: { + best: Best; + }; +}; + export default function BestPage() { - const [bests, setBests] = useState([]); - const [search, setSearch] = useState(''); - const [refreshing, setRefresing] = useState(false); - const [best, setBest] = useState(); - const db = useContext(DatabaseContext); - - const refresh = useCallback(async () => { - const bestWeight = ` - SELECT name, reps, unit, MAX(weight) AS weight - FROM sets - WHERE name LIKE ? - GROUP BY name; - `; - const bestReps = ` - SELECT name, MAX(reps) as reps, unit, weight - FROM sets - WHERE name = ? - AND weight = ? - GROUP BY name; - `; - const [weight] = await db.executeSql(bestWeight, [`%${search}%`]); - if (!weight) return setBests([]); - let newBest: Best[] = []; - for (let i = 0; i < weight.rows.length; i++) { - const [reps] = await db.executeSql(bestReps, [ - weight.rows.item(i).name, - weight.rows.item(i).weight, - ]); - newBest = newBest.concat(reps.rows.raw()); - } - setBests(newBest); - }, [search, db]); - - useEffect(() => { - refresh(); - }, [search, refresh]); - - const renderItem = ({item}: {item: Best}) => ( - setBest(item)} - /> - ); + const navigation = useNavigation>(); return ( - - - - } - refreshing={refreshing} - onRefresh={async () => { - setRefresing(true); - await refresh(); - setRefresing(false); + + + { + navigation.setOptions({ + headerLeft: () => ( + + ), + title: 'Home', + }); + }, }} - renderItem={renderItem} - data={bests} /> - - - + ); } - -const styles = StyleSheet.create({ - container: { - padding: 10, - flexGrow: 1, - paddingBottom: '10%', - }, -}); diff --git a/PlanList.tsx b/PlanList.tsx index 8d6d5b3..ce95fb9 100644 --- a/PlanList.tsx +++ b/PlanList.tsx @@ -37,7 +37,6 @@ export default function PlanList() { ); useEffect(() => { - if (!search) return; refresh(); }, [search, refresh]); diff --git a/SetList.tsx b/SetList.tsx index 6b67cf3..48f9cf6 100644 --- a/SetList.tsx +++ b/SetList.tsx @@ -51,7 +51,6 @@ export default function SetList() { }, [setRefreshing, refresh]); useEffect(() => { - if (!search) return; refresh(); }, [search, refresh]); diff --git a/ViewBest.tsx b/ViewBest.tsx index e09928a..f8eecef 100644 --- a/ViewBest.tsx +++ b/ViewBest.tsx @@ -1,21 +1,35 @@ +import { + RouteProp, + useFocusEffect, + useNavigation, + useRoute, +} from '@react-navigation/native'; import * as shape from 'd3-shape'; -import React, {useContext, useEffect, useState} from 'react'; -import {View} from 'react-native'; -import {Button, Dialog, Portal} from 'react-native-paper'; -import {Grid, LineChart, YAxis} from 'react-native-svg-charts'; +import React, {useCallback, useContext, useEffect, useState} from 'react'; +import {Text, View} from 'react-native'; +import {IconButton} from 'react-native-paper'; +import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts'; import {DatabaseContext} from './App'; -import Best from './best'; +import {BestPageParams} from './BestPage'; +import Set from './set'; +import {formatMonth} from './time'; -export default function ViewBest({ - best, - setBest, -}: { - best?: Best; - setBest: (best?: Best) => void; -}) { - const [data, setData] = useState([]); - const [unit, setUnit] = useState(); +export default function ViewBest() { + const {params} = useRoute>(); + const [sets, setSets] = useState([]); const db = useContext(DatabaseContext); + const navigation = useNavigation(); + + useFocusEffect( + useCallback(() => { + navigation.getParent()?.setOptions({ + headerLeft: () => ( + navigation.goBack()} /> + ), + title: params.best.name, + }); + }, [navigation, params.best.name]), + ); useEffect(() => { const selectBest = ` @@ -25,52 +39,46 @@ export default function ViewBest({ GROUP BY name, STRFTIME('%Y-%m-%d', created) `; const refresh = async () => { - const [result] = await db.executeSql(selectBest, [best?.name]); + const [result] = await db.executeSql(selectBest, [params.best.name]); if (result.rows.length === 0) return; console.log(`${ViewBest.name}.${refresh.name}:`, result.rows.raw()); - setData(result.rows.raw().map(row => row.weight)); - setUnit(result.rows.item(0).unit); + setSets(result.rows.raw()); }; refresh(); - }, [best, db]); - - const contentInset = {top: 20, bottom: 20}; + }, [params.best.name, db]); + const axesSvg = {fontSize: 10, fill: 'grey'}; + const verticalContentInset = {top: 10, bottom: 10}; + const xAxisHeight = 30; return ( - - setBest(undefined)}> - {best?.name} - - - `${value}${unit}`} - /> - - - - - - - - - - + + Best weight per day + + set.weight)} + style={{marginBottom: xAxisHeight}} + contentInset={verticalContentInset} + svg={axesSvg} + formatLabel={value => `${value}${sets[0].unit}`} + /> + + set.weight)} + contentInset={verticalContentInset} + curve={shape.curveNatural} + svg={{stroke: 'rgb(134, 65, 244)'}}> + + + formatMonth(sets[index].created)} + contentInset={{left: 10, right: 10}} + svg={axesSvg} + /> + + + ); } diff --git a/time.ts b/time.ts index cf14dd5..7b5d436 100644 --- a/time.ts +++ b/time.ts @@ -37,3 +37,10 @@ export function format(date: Date) { ].join(':') + (isPM ? ' pm' : 'am'); return `${day} ${dd} ${mm}, ${time}`; } + +export function formatMonth(iso: string) { + const date = new Date(iso); + const dd = date.getDate().toString(); + const mm = (date.getMonth() + 1).toString(); + return `${dd}/${mm}`; +}