From e191323fff2bb3a98112b1099bc9da466217043c Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Wed, 20 Jul 2022 15:48:48 +1200 Subject: [PATCH] Factor out EditSet and SetForm --- EditSet.tsx | 228 +++++++++------------------------------------------- SetForm.tsx | 196 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+), 191 deletions(-) create mode 100644 SetForm.tsx diff --git a/EditSet.tsx b/EditSet.tsx index 4704ac3..89eb552 100644 --- a/EditSet.tsx +++ b/EditSet.tsx @@ -5,31 +5,16 @@ import { useNavigation, useRoute, } from '@react-navigation/native'; -import React, { - useCallback, - useContext, - useEffect, - useRef, - useState, -} from 'react'; -import {NativeModules, ScrollView, StyleSheet, View} from 'react-native'; -import DateTimePickerModal from 'react-native-modal-datetime-picker'; -import {Button, IconButton, TextInput} from 'react-native-paper'; +import React, {useCallback, useContext} from 'react'; +import {NativeModules, View} from 'react-native'; +import {IconButton} from 'react-native-paper'; import {DatabaseContext} from './App'; import {HomePageParams} from './HomePage'; -import {Plan} from './plan'; import Set from './set'; -import {DAYS, format} from './time'; +import SetForm from './SetForm'; export default function EditSet() { const {params} = useRoute>(); - const [name, setName] = useState(params.set.name); - const [reps, setReps] = useState(params.set.reps.toString()); - const [weight, setWeight] = useState(params.set.weight.toString()); - const [created, setCreated] = useState(new Date(params.set.created)); - const [unit, setUnit] = useState(params.set.unit); - const [showDate, setShowDate] = useState(false); - const weightRef = useRef(null); const db = useContext(DatabaseContext); const navigation = useNavigation(); @@ -44,100 +29,6 @@ export default function EditSet() { }, [navigation]), ); - const getTodaysPlan = useCallback(async (): Promise => { - const today = DAYS[new Date().getDay()]; - const [result] = await db.executeSql( - `SELECT * FROM plans WHERE days LIKE ? LIMIT 1`, - [`%${today}%`], - ); - return result.rows.raw(); - }, [db]); - - const getTodaysSets = useCallback(async (): Promise => { - const today = new Date().toISOString().split('T')[0]; - const [result] = await db.executeSql( - `SELECT * FROM sets WHERE created LIKE ? ORDER BY created DESC`, - [`${today}%`], - ); - return result.rows.raw(); - }, [db]); - - const getBest = useCallback( - async (query: string): Promise => { - const bestWeight = ` - SELECT name, reps, unit, MAX(weight) AS weight - FROM sets - WHERE name = ? - GROUP BY name; - `; - const bestReps = ` - SELECT name, MAX(reps) as reps, unit, weight - FROM sets - WHERE name = ? - AND weight = ? - GROUP BY name; - `; - const [weightResult] = await db.executeSql(bestWeight, [query]); - if (!weightResult.rows.length) - return { - weight: 0, - name: '', - reps: 0, - created: new Date().toISOString(), - id: 0, - }; - const [repsResult] = await db.executeSql(bestReps, [ - query, - weightResult.rows.item(0).weight, - ]); - return repsResult.rows.item(0); - }, - [db], - ); - - const predict = useCallback(async () => { - if ((await AsyncStorage.getItem('predictiveSets')) === 'false') return; - const todaysPlan = await getTodaysPlan(); - if (todaysPlan.length === 0) return; - const todaysSets = await getTodaysSets(); - const todaysWorkouts = todaysPlan[0].workouts.split(','); - let nextWorkout = todaysWorkouts[0]; - if (todaysSets.length > 0) { - const count = todaysSets.filter( - set => set.name === todaysSets[0].name, - ).length; - const maxSets = await AsyncStorage.getItem('maxSets'); - nextWorkout = todaysSets[0].name; - if (count >= Number(maxSets)) - nextWorkout = - todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1]; - } - const best = await getBest(nextWorkout); - setName(best.name); - setReps(best.reps.toString()); - setWeight(best.weight.toString()); - setUnit(best.unit); - }, [getTodaysSets, getTodaysPlan, getBest]); - - useEffect(() => { - if (params.set.id) return; - predict(); - }, [predict, params.set.id]); - - const onConfirm = (date: Date) => { - setCreated(date); - setShowDate(false); - }; - - const update = useCallback(async () => { - console.log(`${EditSet.name}.update`, params.set); - await db.executeSql( - `UPDATE sets SET name = ?, reps = ?, weight = ?, created = ?, unit = ? WHERE id = ?`, - [name, reps, weight, created.toISOString(), unit, params.set.id], - ); - navigation.goBack(); - }, [params.set, name, reps, weight, created, unit, db, navigation]); - const notify = useCallback(async () => { const enabled = await AsyncStorage.getItem('alarmEnabled'); if (enabled !== 'true') return; @@ -147,88 +38,43 @@ export default function EditSet() { NativeModules.AlarmModule.timer(milliseconds); }, []); - const add = useCallback(async () => { - if (name === undefined || reps === '' || weight === '') return; - const insert = ` - INSERT INTO sets(name, reps, weight, created, unit) - VALUES (?,?,?,?,?) - `; - await db.executeSql(insert, [ - name, - reps, - weight, - created.toISOString(), - unit || 'kg', - ]); - notify(); - navigation.goBack(); - }, [name, reps, weight, created, unit, db, navigation, notify]); + const update = useCallback( + async (set: Set) => { + console.log(`${EditSet.name}.update`, set); + await db.executeSql( + `UPDATE sets SET name = ?, reps = ?, weight = ?, created = ?, unit = ? WHERE id = ?`, + [set.name, set.reps, set.weight, set.created, set.unit, set.id], + ); + navigation.goBack(); + }, + [db, navigation], + ); - const save = useCallback(async () => { - if (params.set.id) return update(); - return add(); - }, [update, add, params.set.id]); + const add = useCallback( + async (set: Set) => { + const {name, reps, weight, created, unit} = set; + const insert = ` + INSERT INTO sets(name, reps, weight, created, unit) + VALUES (?,?,?,?,?) + `; + await db.executeSql(insert, [name, reps, weight, created, unit]); + notify(); + navigation.goBack(); + }, + [db, navigation, notify], + ); + + const save = useCallback( + async (set: Set) => { + if (params.set.id) return update(set); + return add(set); + }, + [update, add, params.set.id], + ); return ( - - - weightRef.current?.focus()} - /> - - - - - setShowDate(false)} - date={created} - /> - - + ); } - -const styles = StyleSheet.create({ - marginBottom: { - marginBottom: 10, - }, -}); diff --git a/SetForm.tsx b/SetForm.tsx new file mode 100644 index 0000000..d46d7a0 --- /dev/null +++ b/SetForm.tsx @@ -0,0 +1,196 @@ +import React, { + useCallback, + useContext, + useEffect, + useRef, + useState, +} from 'react'; +import {ScrollView, StyleSheet} from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import DateTimePickerModal from 'react-native-modal-datetime-picker'; +import {Button, TextInput} from 'react-native-paper'; +import {DatabaseContext} from './App'; +import {Plan} from './plan'; +import Set from './set'; +import {DAYS, format} from './time'; + +export default function SetForm({ + save, + set, +}: { + set: Set; + save: (set: Set) => void; +}) { + const [name, setName] = useState(set.name); + const [reps, setReps] = useState(set.reps.toString()); + const [weight, setWeight] = useState(set.weight.toString()); + const [created, setCreated] = useState(new Date(set.created)); + const [unit, setUnit] = useState(set.unit); + const [showDate, setShowDate] = useState(false); + const weightRef = useRef(null); + const db = useContext(DatabaseContext); + + const getTodaysPlan = useCallback(async (): Promise => { + const today = DAYS[new Date().getDay()]; + const [result] = await db.executeSql( + `SELECT * FROM plans WHERE days LIKE ? LIMIT 1`, + [`%${today}%`], + ); + return result.rows.raw(); + }, [db]); + + const getTodaysSets = useCallback(async (): Promise => { + const today = new Date().toISOString().split('T')[0]; + const [result] = await db.executeSql( + `SELECT * FROM sets WHERE created LIKE ? ORDER BY created DESC`, + [`${today}%`], + ); + return result.rows.raw(); + }, [db]); + + const getBest = useCallback( + async (query: string): Promise => { + const bestWeight = ` + SELECT name, reps, unit, MAX(weight) AS weight + FROM sets + WHERE name = ? + GROUP BY name; + `; + const bestReps = ` + SELECT name, MAX(reps) as reps, unit, weight + FROM sets + WHERE name = ? + AND weight = ? + GROUP BY name; + `; + const [weightResult] = await db.executeSql(bestWeight, [query]); + if (!weightResult.rows.length) + return { + weight: 0, + name: '', + reps: 0, + created: new Date().toISOString(), + id: 0, + }; + const [repsResult] = await db.executeSql(bestReps, [ + query, + weightResult.rows.item(0).weight, + ]); + return repsResult.rows.item(0); + }, + [db], + ); + + const predict = useCallback(async () => { + if ((await AsyncStorage.getItem('predictiveSets')) === 'false') return; + const todaysPlan = await getTodaysPlan(); + if (todaysPlan.length === 0) return; + const todaysSets = await getTodaysSets(); + const todaysWorkouts = todaysPlan[0].workouts.split(','); + let nextWorkout = todaysWorkouts[0]; + if (todaysSets.length > 0) { + const count = todaysSets.filter( + s => s.name === todaysSets[0].name, + ).length; + const maxSets = await AsyncStorage.getItem('maxSets'); + nextWorkout = todaysSets[0].name; + if (count >= Number(maxSets)) + nextWorkout = + todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1]; + } + const best = await getBest(nextWorkout); + setName(best.name); + setReps(best.reps.toString()); + setWeight(best.weight.toString()); + setUnit(best.unit); + }, [getTodaysSets, getTodaysPlan, getBest]); + + useEffect(() => { + if (set.id) return; + predict(); + }, [predict, set.id]); + + const onConfirm = (date: Date) => { + setCreated(date); + setShowDate(false); + }; + + const handleSubmit = () => { + save({ + name, + reps: Number(reps), + created: created.toISOString(), + weight: Number(weight), + id: set.id, + unit, + }); + }; + + const textInputs = ( + <> + + weightRef.current?.focus()} + /> + + + + ); + + return ( + <> + + {textInputs} + + setShowDate(false)} + date={created} + /> + + + + ); +} + +const styles = StyleSheet.create({ + marginBottom: { + marginBottom: 10, + }, +});