Make plans use stack navigation
This commit is contained in:
parent
6b8780c62e
commit
e72cdc8db7
4
App.tsx
4
App.tsx
|
@ -26,7 +26,7 @@ export type DrawerParamList = {
|
||||||
Home: {};
|
Home: {};
|
||||||
Settings: {};
|
Settings: {};
|
||||||
Best: {};
|
Best: {};
|
||||||
Plan: {};
|
Plans: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
|
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
|
||||||
|
@ -83,7 +83,7 @@ const App = () => {
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
name="Plan"
|
name="Plans"
|
||||||
component={PlanPage}
|
component={PlanPage}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
|
|
88
EditPlan.tsx
88
EditPlan.tsx
|
@ -1,23 +1,36 @@
|
||||||
|
import {
|
||||||
|
RouteProp,
|
||||||
|
useFocusEffect,
|
||||||
|
useNavigation,
|
||||||
|
useRoute,
|
||||||
|
} from '@react-navigation/native';
|
||||||
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
||||||
import {ScrollView, StyleSheet, Text, View} from 'react-native';
|
import {ScrollView, StyleSheet, Text, View} from 'react-native';
|
||||||
import {Button, Dialog, Portal, Switch} from 'react-native-paper';
|
import {Button, IconButton, Switch} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {Plan} from './plan';
|
import {PlanPageParams} from './PlanPage';
|
||||||
import {DAYS} from './time';
|
import {DAYS} from './time';
|
||||||
|
|
||||||
export default function EditPlan({
|
export default function EditPlan() {
|
||||||
plan,
|
const {params} = useRoute<RouteProp<PlanPageParams, 'EditPlan'>>();
|
||||||
onSave,
|
const [days, setDays] = useState<string[]>(params.plan.days.split(','));
|
||||||
setPlan,
|
const [workouts, setWorkouts] = useState<string[]>(
|
||||||
}: {
|
params.plan.workouts.split(','),
|
||||||
onSave: () => void;
|
);
|
||||||
plan?: Plan;
|
|
||||||
setPlan: (plan?: Plan) => void;
|
|
||||||
}) {
|
|
||||||
const [days, setDays] = useState<string[]>([]);
|
|
||||||
const [workouts, setWorkouts] = useState<string[]>([]);
|
|
||||||
const [names, setNames] = useState<string[]>([]);
|
const [names, setNames] = useState<string[]>([]);
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
navigation.getParent()?.setOptions({
|
||||||
|
headerLeft: () => (
|
||||||
|
<IconButton icon="arrow-back" onPress={() => navigation.goBack()} />
|
||||||
|
),
|
||||||
|
title: 'Plan',
|
||||||
|
});
|
||||||
|
}, []),
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
|
@ -26,19 +39,16 @@ export default function EditPlan({
|
||||||
);
|
);
|
||||||
if (!namesResult.rows.length) return setNames([]);
|
if (!namesResult.rows.length) return setNames([]);
|
||||||
setNames(namesResult.rows.raw().map(({name}) => name));
|
setNames(namesResult.rows.raw().map(({name}) => name));
|
||||||
if (!plan) return;
|
|
||||||
if (plan.days) setDays(plan.days.split(','));
|
|
||||||
if (plan.workouts) setWorkouts(plan.workouts.split(','));
|
|
||||||
};
|
};
|
||||||
refresh();
|
refresh();
|
||||||
}, [plan, db]);
|
}, [db]);
|
||||||
|
|
||||||
const save = useCallback(async () => {
|
const save = useCallback(async () => {
|
||||||
console.log(`${EditPlan.name}.save`, {days, workouts, plan});
|
console.log(`${EditPlan.name}.save`, {days, workouts, params});
|
||||||
if (!days || !workouts) return;
|
if (!days || !workouts) return;
|
||||||
const newWorkouts = workouts.filter(workout => workout).join(',');
|
const newWorkouts = workouts.filter(workout => workout).join(',');
|
||||||
const newDays = days.filter(day => day).join(',');
|
const newDays = days.filter(day => day).join(',');
|
||||||
if (!plan?.id)
|
if (!params.plan.id)
|
||||||
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
|
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
|
||||||
newDays,
|
newDays,
|
||||||
newWorkouts,
|
newWorkouts,
|
||||||
|
@ -46,11 +56,10 @@ export default function EditPlan({
|
||||||
else
|
else
|
||||||
await db.executeSql(
|
await db.executeSql(
|
||||||
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
|
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
|
||||||
[newDays, newWorkouts, plan.id],
|
[newDays, newWorkouts, params.plan.id],
|
||||||
);
|
);
|
||||||
setPlan(undefined);
|
navigation.goBack();
|
||||||
onSave();
|
}, [days, workouts, db, params.plan]);
|
||||||
}, [days, workouts, db, onSave, plan, setPlan]);
|
|
||||||
|
|
||||||
const toggleWorkout = useCallback(
|
const toggleWorkout = useCallback(
|
||||||
(on: boolean, name: string) => {
|
(on: boolean, name: string) => {
|
||||||
|
@ -75,15 +84,8 @@ export default function EditPlan({
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<View style={{padding: 10}}>
|
||||||
<Dialog visible={!!plan} onDismiss={() => setPlan(undefined)}>
|
<ScrollView style={{height: '90%'}}>
|
||||||
<Dialog.Title>
|
|
||||||
{plan?.days ? `Edit "${days.slice(0, 2).join(', ')}"` : 'Add a plan'}
|
|
||||||
</Dialog.Title>
|
|
||||||
<Dialog.ScrollArea>
|
|
||||||
<ScrollView
|
|
||||||
style={{height: '80%'}}
|
|
||||||
contentContainerStyle={{paddingHorizontal: 24}}>
|
|
||||||
<Text style={styles.title}>Days</Text>
|
<Text style={styles.title}>Days</Text>
|
||||||
{DAYS.map(day => (
|
{DAYS.map(day => (
|
||||||
<View key={day} style={[styles.row, {alignItems: 'center'}]}>
|
<View key={day} style={[styles.row, {alignItems: 'center'}]}>
|
||||||
|
@ -100,8 +102,8 @@ export default function EditPlan({
|
||||||
<Text style={[styles.title, {marginTop: 10}]}>Workouts</Text>
|
<Text style={[styles.title, {marginTop: 10}]}>Workouts</Text>
|
||||||
{names.length === 0 && (
|
{names.length === 0 && (
|
||||||
<Text style={{maxWidth: '80%'}}>
|
<Text style={{maxWidth: '80%'}}>
|
||||||
No sets found. Try going to the home page and adding some
|
No sets found. Try going to the home page and adding some workouts
|
||||||
workouts first.
|
first.
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
{names.map(name => (
|
{names.map(name => (
|
||||||
|
@ -111,24 +113,20 @@ export default function EditPlan({
|
||||||
style={{marginRight: 5}}
|
style={{marginRight: 5}}
|
||||||
onValueChange={value => toggleWorkout(value, name)}
|
onValueChange={value => toggleWorkout(value, name)}
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text onPress={() => toggleWorkout(!workouts.includes(name), name)}>
|
||||||
onPress={() => toggleWorkout(!workouts.includes(name), name)}>
|
|
||||||
{name}
|
{name}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</Dialog.ScrollArea>
|
<Button
|
||||||
<Dialog.Actions>
|
style={{marginTop: 10}}
|
||||||
<Button icon="close" onPress={() => setPlan(undefined)}>
|
mode="contained"
|
||||||
Cancel
|
icon="save"
|
||||||
</Button>
|
onPress={save}>
|
||||||
<Button mode="contained" icon="save" onPress={save}>
|
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</Dialog.Actions>
|
</View>
|
||||||
</Dialog>
|
|
||||||
</Portal>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
EditSet.tsx
32
EditSet.tsx
|
@ -1,17 +1,22 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import {RouteProp, useNavigation, useRoute} from '@react-navigation/native';
|
import {
|
||||||
|
RouteProp,
|
||||||
|
useFocusEffect,
|
||||||
|
useNavigation,
|
||||||
|
useRoute,
|
||||||
|
} from '@react-navigation/native';
|
||||||
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
||||||
import {NativeModules, ScrollView, StyleSheet} from 'react-native';
|
import {NativeModules, ScrollView, StyleSheet, View} from 'react-native';
|
||||||
import DateTimePickerModal from 'react-native-modal-datetime-picker';
|
import DateTimePickerModal from 'react-native-modal-datetime-picker';
|
||||||
import {Button, TextInput} from 'react-native-paper';
|
import {Button, IconButton, TextInput} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {StackParams} from './HomePage';
|
import {HomePageParams} from './HomePage';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import {DAYS, format} from './time';
|
import {DAYS, format} from './time';
|
||||||
|
|
||||||
export default function EditSet() {
|
export default function EditSet() {
|
||||||
const {params} = useRoute<RouteProp<StackParams, 'EditSet'>>();
|
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>();
|
||||||
const [name, setName] = useState(params.set.name);
|
const [name, setName] = useState(params.set.name);
|
||||||
const [reps, setReps] = useState(params.set.reps.toString());
|
const [reps, setReps] = useState(params.set.reps.toString());
|
||||||
const [weight, setWeight] = useState(params.set.weight.toString());
|
const [weight, setWeight] = useState(params.set.weight.toString());
|
||||||
|
@ -21,6 +26,17 @@ export default function EditSet() {
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
navigation.getParent()?.setOptions({
|
||||||
|
headerLeft: () => (
|
||||||
|
<IconButton icon="arrow-back" onPress={() => navigation.goBack()} />
|
||||||
|
),
|
||||||
|
title: 'Set',
|
||||||
|
});
|
||||||
|
}, []),
|
||||||
|
);
|
||||||
|
|
||||||
const getTodaysPlan = useCallback(async (): Promise<Plan[]> => {
|
const getTodaysPlan = useCallback(async (): Promise<Plan[]> => {
|
||||||
const today = DAYS[new Date().getDay()];
|
const today = DAYS[new Date().getDay()];
|
||||||
const [result] = await db.executeSql(
|
const [result] = await db.executeSql(
|
||||||
|
@ -113,7 +129,8 @@ export default function EditSet() {
|
||||||
}, [update, add, params.set.id]);
|
}, [update, add, params.set.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView style={{padding: 10}}>
|
<View style={{padding: 10}}>
|
||||||
|
<ScrollView style={{height: '90%'}}>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.marginBottom}
|
style={styles.marginBottom}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
@ -158,10 +175,11 @@ export default function EditSet() {
|
||||||
onCancel={() => setShowDate(false)}
|
onCancel={() => setShowDate(false)}
|
||||||
date={created}
|
date={created}
|
||||||
/>
|
/>
|
||||||
|
</ScrollView>
|
||||||
<Button mode="contained" icon="save" onPress={save}>
|
<Button mode="contained" icon="save" onPress={save}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</ScrollView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
HomePage.tsx
12
HomePage.tsx
|
@ -8,8 +8,8 @@ import EditSet from './EditSet';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import SetList from './SetList';
|
import SetList from './SetList';
|
||||||
|
|
||||||
const Stack = createStackNavigator<StackParams>();
|
const Stack = createStackNavigator<HomePageParams>();
|
||||||
export type StackParams = {
|
export type HomePageParams = {
|
||||||
Sets: {};
|
Sets: {};
|
||||||
EditSet: {
|
EditSet: {
|
||||||
set: Set;
|
set: Set;
|
||||||
|
@ -27,14 +27,6 @@ export default function HomePage() {
|
||||||
name="EditSet"
|
name="EditSet"
|
||||||
component={EditSet}
|
component={EditSet}
|
||||||
listeners={{
|
listeners={{
|
||||||
focus: () => {
|
|
||||||
navigation.setOptions({
|
|
||||||
headerLeft: () => (
|
|
||||||
<IconButton icon="arrow-back" onPress={navigation.goBack} />
|
|
||||||
),
|
|
||||||
title: 'Set',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
beforeRemove: () => {
|
beforeRemove: () => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerLeft: () => (
|
headerLeft: () => (
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
|
import {NavigationProp, useNavigation} from '@react-navigation/native';
|
||||||
import React, {useCallback, useContext, useState} from 'react';
|
import React, {useCallback, useContext, useState} from 'react';
|
||||||
import {GestureResponderEvent} from 'react-native';
|
import {GestureResponderEvent} from 'react-native';
|
||||||
import {List, Menu} from 'react-native-paper';
|
import {List, Menu} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
|
import {PlanPageParams} from './PlanPage';
|
||||||
|
|
||||||
export default function PlanItem({
|
export default function PlanItem({
|
||||||
item,
|
item,
|
||||||
setPlan,
|
|
||||||
onRemove,
|
onRemove,
|
||||||
}: {
|
}: {
|
||||||
item: Plan;
|
item: Plan;
|
||||||
setPlan: (plan: Plan) => void;
|
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
|
const navigation = useNavigation<NavigationProp<PlanPageParams>>();
|
||||||
|
|
||||||
const remove = useCallback(async () => {
|
const remove = useCallback(async () => {
|
||||||
await db.executeSql(`DELETE FROM plans WHERE id = ?`, [item.id]);
|
await db.executeSql(`DELETE FROM plans WHERE id = ?`, [item.id]);
|
||||||
|
@ -34,7 +35,7 @@ export default function PlanItem({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
onPress={() => setPlan(item)}
|
onPress={() => navigation.navigate('EditPlan', {plan: item})}
|
||||||
title={item.days.replace(/,/g, ', ')}
|
title={item.days.replace(/,/g, ', ')}
|
||||||
description={item.workouts.replace(/,/g, ', ')}
|
description={item.workouts.replace(/,/g, ', ')}
|
||||||
onLongPress={longPress}
|
onLongPress={longPress}
|
||||||
|
|
92
PlanList.tsx
Normal file
92
PlanList.tsx
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
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 MassiveFab from './MassiveFab';
|
||||||
|
import {Plan} from './plan';
|
||||||
|
import PlanItem from './PlanItem';
|
||||||
|
import {PlanPageParams} from './PlanPage';
|
||||||
|
|
||||||
|
export default function PlanList() {
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [plans, setPlans] = useState<Plan[]>([]);
|
||||||
|
const [refreshing, setRefresing] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
const navigation = useNavigation<NavigationProp<PlanPageParams>>();
|
||||||
|
|
||||||
|
const refresh = useCallback(async () => {
|
||||||
|
const selectPlans = `
|
||||||
|
SELECT * from plans
|
||||||
|
WHERE days LIKE ? OR workouts LIKE ?
|
||||||
|
`;
|
||||||
|
const getPlans = ({s}: {s: string}) =>
|
||||||
|
db.executeSql(selectPlans, [`%${s}%`, `%${s}%`]);
|
||||||
|
const [plansResult] = await getPlans({s: search});
|
||||||
|
setPlans(plansResult.rows.raw());
|
||||||
|
}, [search, db]);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
refresh();
|
||||||
|
}, [refresh]),
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!search) return;
|
||||||
|
refresh();
|
||||||
|
}, [search, refresh]);
|
||||||
|
|
||||||
|
const renderItem = useCallback(
|
||||||
|
({item}: {item: Plan}) => (
|
||||||
|
<PlanItem item={item} key={item.id} onRemove={refresh} />
|
||||||
|
),
|
||||||
|
[refresh],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Searchbar value={search} onChangeText={setSearch} placeholder="Search" />
|
||||||
|
<FlatList
|
||||||
|
style={{height: '100%'}}
|
||||||
|
data={plans}
|
||||||
|
renderItem={renderItem}
|
||||||
|
keyExtractor={set => set.id.toString()}
|
||||||
|
refreshing={refreshing}
|
||||||
|
onRefresh={() => {
|
||||||
|
setRefresing(true);
|
||||||
|
refresh().finally(() => setRefresing(false));
|
||||||
|
}}
|
||||||
|
ListEmptyComponent={
|
||||||
|
<List.Item
|
||||||
|
title="No plans yet"
|
||||||
|
description="A plan is a list of workouts for certain days."
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MassiveFab
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate('EditPlan', {
|
||||||
|
plan: {days: '', workouts: '', id: 0},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flexGrow: 1,
|
||||||
|
padding: 10,
|
||||||
|
paddingBottom: '10%',
|
||||||
|
},
|
||||||
|
progress: {
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
});
|
107
PlanPage.tsx
107
PlanPage.tsx
|
@ -1,85 +1,42 @@
|
||||||
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
import {DrawerNavigationProp} from '@react-navigation/drawer';
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {useNavigation} from '@react-navigation/native';
|
||||||
import {List, Searchbar} from 'react-native-paper';
|
import {createStackNavigator} from '@react-navigation/stack';
|
||||||
import {DatabaseContext} from './App';
|
import React from 'react';
|
||||||
|
import {IconButton} from 'react-native-paper';
|
||||||
|
import {DrawerParamList} from './App';
|
||||||
import EditPlan from './EditPlan';
|
import EditPlan from './EditPlan';
|
||||||
import MassiveFab from './MassiveFab';
|
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
import PlanItem from './PlanItem';
|
import PlanList from './PlanList';
|
||||||
|
|
||||||
|
const Stack = createStackNavigator<PlanPageParams>();
|
||||||
|
export type PlanPageParams = {
|
||||||
|
PlanList: {};
|
||||||
|
EditPlan: {
|
||||||
|
plan: Plan;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export default function PlanPage() {
|
export default function PlanPage() {
|
||||||
const [search, setSearch] = useState('');
|
const navigation = useNavigation<DrawerNavigationProp<DrawerParamList>>();
|
||||||
const [plans, setPlans] = useState<Plan[]>([]);
|
|
||||||
const [refreshing, setRefresing] = useState(false);
|
|
||||||
const [plan, setPlan] = useState<Plan>();
|
|
||||||
const db = useContext(DatabaseContext);
|
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
|
||||||
const selectPlans = `
|
|
||||||
SELECT * from plans
|
|
||||||
WHERE days LIKE ? OR workouts LIKE ?
|
|
||||||
`;
|
|
||||||
const getPlans = ({s}: {s: string}) =>
|
|
||||||
db.executeSql(selectPlans, [`%${s}%`, `%${s}%`]);
|
|
||||||
const [plansResult] = await getPlans({s: search});
|
|
||||||
setPlans(plansResult.rows.raw());
|
|
||||||
}, [search, db]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
refresh();
|
|
||||||
}, [search, refresh]);
|
|
||||||
|
|
||||||
const renderItem = useCallback(
|
|
||||||
({item}: {item: Plan}) => (
|
|
||||||
<PlanItem
|
|
||||||
item={item}
|
|
||||||
key={item.id}
|
|
||||||
setPlan={setPlan}
|
|
||||||
onRemove={refresh}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[setPlan, refresh],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<Stack.Navigator
|
||||||
<Searchbar value={search} onChangeText={setSearch} placeholder="Search" />
|
screenOptions={{headerShown: false, animationEnabled: false}}>
|
||||||
<FlatList
|
<Stack.Screen name="PlanList" component={PlanList} />
|
||||||
style={{height: '100%'}}
|
<Stack.Screen
|
||||||
data={plans}
|
name="EditPlan"
|
||||||
renderItem={renderItem}
|
component={EditPlan}
|
||||||
keyExtractor={set => set.id.toString()}
|
listeners={{
|
||||||
refreshing={refreshing}
|
beforeRemove: () => {
|
||||||
onRefresh={() => {
|
navigation.setOptions({
|
||||||
setRefresing(true);
|
headerLeft: () => (
|
||||||
refresh().finally(() => setRefresing(false));
|
<IconButton icon="menu" onPress={navigation.openDrawer} />
|
||||||
}}
|
),
|
||||||
ListEmptyComponent={
|
title: 'Plans',
|
||||||
<List.Item
|
});
|
||||||
title="No plans yet"
|
},
|
||||||
description="A plan is a list of workouts for certain days."
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EditPlan setPlan={setPlan} onSave={refresh} plan={plan} />
|
|
||||||
|
|
||||||
<MassiveFab
|
|
||||||
onPress={() => {
|
|
||||||
setPlan({} as Plan);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flexGrow: 1,
|
|
||||||
padding: 10,
|
|
||||||
paddingBottom: '10%',
|
|
||||||
},
|
|
||||||
progress: {
|
|
||||||
marginTop: 10,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React, {useCallback, useContext, useState} from 'react';
|
||||||
import {GestureResponderEvent} from 'react-native';
|
import {GestureResponderEvent} from 'react-native';
|
||||||
import {List, Menu} from 'react-native-paper';
|
import {List, Menu} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {StackParams} from './HomePage';
|
import {HomePageParams} from './HomePage';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
|
|
||||||
export default function SetItem({
|
export default function SetItem({
|
||||||
|
@ -16,7 +16,7 @@ export default function SetItem({
|
||||||
const [showMenu, setShowMenu] = useState(false);
|
const [showMenu, setShowMenu] = useState(false);
|
||||||
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
const navigation = useNavigation<NavigationProp<StackParams>>();
|
const navigation = useNavigation<NavigationProp<HomePageParams>>();
|
||||||
|
|
||||||
const remove = useCallback(async () => {
|
const remove = useCallback(async () => {
|
||||||
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import React, {useCallback, useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {FlatList, StyleSheet, View} from 'react-native';
|
||||||
import {List, Searchbar} from 'react-native-paper';
|
import {List, Searchbar} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {StackParams} from './HomePage';
|
import {HomePageParams} from './HomePage';
|
||||||
import MassiveFab from './MassiveFab';
|
import MassiveFab from './MassiveFab';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import SetItem from './SetItem';
|
import SetItem from './SetItem';
|
||||||
|
@ -21,7 +21,7 @@ export default function SetList() {
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [end, setEnd] = useState(false);
|
const [end, setEnd] = useState(false);
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
const navigation = useNavigation<NavigationProp<StackParams>>();
|
const navigation = useNavigation<NavigationProp<HomePageParams>>();
|
||||||
|
|
||||||
const selectSets = `
|
const selectSets = `
|
||||||
SELECT * from sets
|
SELECT * from sets
|
||||||
|
|
Loading…
Reference in New Issue
Block a user