Factor out MassiveFab
This commit is contained in:
parent
dc21f1266e
commit
b12b41b77e
14
EditPlan.tsx
14
EditPlan.tsx
|
@ -17,13 +17,11 @@ const DAYS = [
|
||||||
export default function EditPlan({
|
export default function EditPlan({
|
||||||
plan,
|
plan,
|
||||||
onSave,
|
onSave,
|
||||||
show,
|
setPlan,
|
||||||
setShow,
|
|
||||||
}: {
|
}: {
|
||||||
onSave: () => void;
|
onSave: () => void;
|
||||||
show: boolean;
|
|
||||||
setShow: (visible: boolean) => void;
|
|
||||||
plan?: Plan;
|
plan?: Plan;
|
||||||
|
setPlan: (plan?: Plan) => void;
|
||||||
}) {
|
}) {
|
||||||
const [days, setDays] = useState<string[]>([]);
|
const [days, setDays] = useState<string[]>([]);
|
||||||
const [workouts, setWorkouts] = useState<string[]>([]);
|
const [workouts, setWorkouts] = useState<string[]>([]);
|
||||||
|
@ -41,7 +39,7 @@ export default function EditPlan({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh();
|
refresh();
|
||||||
}, [plan, show]);
|
}, [plan]);
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
if (!days || !workouts) return;
|
if (!days || !workouts) return;
|
||||||
|
@ -57,7 +55,7 @@ export default function EditPlan({
|
||||||
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
|
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
|
||||||
[newDays, newWorkouts, plan.id],
|
[newDays, newWorkouts, plan.id],
|
||||||
);
|
);
|
||||||
setShow(false);
|
setPlan(undefined);
|
||||||
onSave();
|
onSave();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +77,7 @@ export default function EditPlan({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<Dialog visible={show} onDismiss={() => setShow(false)}>
|
<Dialog visible={!!plan} onDismiss={() => setPlan(undefined)}>
|
||||||
<Dialog.Title>
|
<Dialog.Title>
|
||||||
{plan ? `Edit "${days.slice(0, 2).join(', ')}"` : 'Add a plan'}
|
{plan ? `Edit "${days.slice(0, 2).join(', ')}"` : 'Add a plan'}
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
|
@ -123,7 +121,7 @@ export default function EditPlan({
|
||||||
</View>
|
</View>
|
||||||
</Dialog.Content>
|
</Dialog.Content>
|
||||||
<Dialog.Actions>
|
<Dialog.Actions>
|
||||||
<Button icon="close" onPress={() => setShow(false)}>
|
<Button icon="close" onPress={() => setPlan(undefined)}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button mode="contained" icon="save" onPress={save}>
|
<Button mode="contained" icon="save" onPress={save}>
|
||||||
|
|
11
Home.tsx
11
Home.tsx
|
@ -1,9 +1,10 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import React, {useContext, useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, NativeModules, StyleSheet, View} from 'react-native';
|
import {FlatList, NativeModules, StyleSheet, View} from 'react-native';
|
||||||
import {AnimatedFAB, List, Searchbar} from 'react-native-paper';
|
import {List, Searchbar} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import EditSet from './EditSet';
|
import EditSet from './EditSet';
|
||||||
|
import MassiveFab from './MassiveFab';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import SetItem from './SetItem';
|
import SetItem from './SetItem';
|
||||||
|
|
||||||
|
@ -99,13 +100,7 @@ export default function Home() {
|
||||||
/>
|
/>
|
||||||
<EditSet set={edit} setSet={setEdit} onSave={save} />
|
<EditSet set={edit} setSet={setEdit} onSave={save} />
|
||||||
|
|
||||||
<AnimatedFAB
|
<MassiveFab onPress={() => setEdit({} as Set)} />
|
||||||
extended={false}
|
|
||||||
label="Add"
|
|
||||||
icon="add"
|
|
||||||
style={{position: 'absolute', right: 10, bottom: 50}}
|
|
||||||
onPress={() => setEdit({} as Set)}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
16
MassiveFab.tsx
Normal file
16
MassiveFab.tsx
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import {AnimatedFAB} from 'react-native-paper';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function MassiveFab(
|
||||||
|
props: Partial<React.ComponentProps<typeof AnimatedFAB>>,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<AnimatedFAB
|
||||||
|
{...props}
|
||||||
|
extended={false}
|
||||||
|
label="Add"
|
||||||
|
icon="add"
|
||||||
|
style={{position: 'absolute', right: 10, bottom: 50}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
28
PlanItem.tsx
28
PlanItem.tsx
|
@ -1,20 +1,20 @@
|
||||||
import React, {useContext, useState} from 'react';
|
import React, {useContext, useState} from 'react';
|
||||||
import {IconButton, List, Menu} from 'react-native-paper';
|
import {GestureResponderEvent} from 'react-native';
|
||||||
|
import {List, Menu} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
|
|
||||||
export default function PlanItem({
|
export default function PlanItem({
|
||||||
item,
|
item,
|
||||||
setPlan,
|
setPlan,
|
||||||
setShowEdit,
|
|
||||||
onRemove,
|
onRemove,
|
||||||
}: {
|
}: {
|
||||||
item: Plan;
|
item: Plan;
|
||||||
setPlan: (plan: Plan) => void;
|
setPlan: (plan: Plan) => void;
|
||||||
setShowEdit: (show: boolean) => void;
|
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
|
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
|
@ -23,26 +23,20 @@ export default function PlanItem({
|
||||||
onRemove();
|
onRemove();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const longPress = (e: GestureResponderEvent) => {
|
||||||
|
setAnchor({x: e.nativeEvent.pageX, y: e.nativeEvent.pageY});
|
||||||
|
setShow(true);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
onPress={() => {
|
onPress={() => setPlan(item)}
|
||||||
setPlan(item);
|
|
||||||
setShowEdit(true);
|
|
||||||
}}
|
|
||||||
title={item.days.replace(/,/g, ', ')}
|
title={item.days.replace(/,/g, ', ')}
|
||||||
description={item.workouts.replace(/,/g, ', ')}
|
description={item.workouts.replace(/,/g, ', ')}
|
||||||
onLongPress={() => setShow(true)}
|
onLongPress={longPress}
|
||||||
right={() => (
|
right={() => (
|
||||||
<Menu
|
<Menu anchor={anchor} visible={show} onDismiss={() => setShow(false)}>
|
||||||
anchor={
|
|
||||||
<IconButton
|
|
||||||
icon="ellipsis-vertical"
|
|
||||||
onPress={() => setShow(true)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
visible={show}
|
|
||||||
onDismiss={() => setShow(false)}>
|
|
||||||
<Menu.Item icon="trash" onPress={remove} title="Delete" />
|
<Menu.Item icon="trash" onPress={remove} title="Delete" />
|
||||||
</Menu>
|
</Menu>
|
||||||
)}
|
)}
|
||||||
|
|
28
Plans.tsx
28
Plans.tsx
|
@ -1,8 +1,9 @@
|
||||||
import React, {useContext, useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {FlatList, StyleSheet, View} from 'react-native';
|
||||||
import {AnimatedFAB, List, Searchbar} from 'react-native-paper';
|
import {List, Searchbar} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} 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 PlanItem from './PlanItem';
|
||||||
|
|
||||||
|
@ -11,7 +12,6 @@ export default function Plans() {
|
||||||
const [plans, setPlans] = useState<Plan[]>([]);
|
const [plans, setPlans] = useState<Plan[]>([]);
|
||||||
const [refreshing, setRefresing] = useState(false);
|
const [refreshing, setRefresing] = useState(false);
|
||||||
const [plan, setPlan] = useState<Plan>();
|
const [plan, setPlan] = useState<Plan>();
|
||||||
const [showEdit, setShowEdit] = useState(false);
|
|
||||||
const db = useContext(DatabaseContext);
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const selectPlans = `
|
const selectPlans = `
|
||||||
|
@ -31,13 +31,7 @@ export default function Plans() {
|
||||||
}, [search]);
|
}, [search]);
|
||||||
|
|
||||||
const renderItem = ({item}: {item: Plan}) => (
|
const renderItem = ({item}: {item: Plan}) => (
|
||||||
<PlanItem
|
<PlanItem item={item} key={item.id} setPlan={setPlan} onRemove={refresh} />
|
||||||
item={item}
|
|
||||||
key={item.id}
|
|
||||||
setShowEdit={setShowEdit}
|
|
||||||
setPlan={setPlan}
|
|
||||||
onRemove={refresh}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -61,21 +55,11 @@ export default function Plans() {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EditPlan
|
<EditPlan setPlan={setPlan} onSave={refresh} plan={plan} />
|
||||||
onSave={refresh}
|
|
||||||
setShow={setShowEdit}
|
|
||||||
show={showEdit}
|
|
||||||
plan={plan}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AnimatedFAB
|
<MassiveFab
|
||||||
extended={false}
|
|
||||||
label="Add"
|
|
||||||
icon="add"
|
|
||||||
style={{position: 'absolute', right: 20, bottom: 50}}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setPlan(undefined);
|
setPlan({} as Plan);
|
||||||
setShowEdit(true);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
13
SetItem.tsx
13
SetItem.tsx
|
@ -13,25 +13,25 @@ export default function SetItem({
|
||||||
setSet: (set: Set) => void;
|
setSet: (set: Set) => void;
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [showMenu, setShowMenu] = 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 remove = async () => {
|
const remove = async () => {
|
||||||
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
||||||
setShowMenu(false);
|
setShow(false);
|
||||||
onRemove();
|
onRemove();
|
||||||
};
|
};
|
||||||
|
|
||||||
const copy = () => {
|
const copy = () => {
|
||||||
const {id, ...set} = {...item};
|
const {id, ...set} = {...item};
|
||||||
setSet(set);
|
setSet(set);
|
||||||
setShowMenu(false);
|
setShow(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const longPress = (e: GestureResponderEvent) => {
|
const longPress = (e: GestureResponderEvent) => {
|
||||||
setAnchor({x: e.nativeEvent.pageX, y: e.nativeEvent.pageY});
|
setAnchor({x: e.nativeEvent.pageX, y: e.nativeEvent.pageY});
|
||||||
setShowMenu(true);
|
setShow(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -44,10 +44,7 @@ export default function SetItem({
|
||||||
description={`${item.reps} x ${item.weight}${item.unit}`}
|
description={`${item.reps} x ${item.weight}${item.unit}`}
|
||||||
onLongPress={longPress}
|
onLongPress={longPress}
|
||||||
right={() => (
|
right={() => (
|
||||||
<Menu
|
<Menu anchor={anchor} visible={show} onDismiss={() => setShow(false)}>
|
||||||
anchor={anchor}
|
|
||||||
visible={showMenu}
|
|
||||||
onDismiss={() => setShowMenu(false)}>
|
|
||||||
<Menu.Item icon="trash" onPress={remove} title="Delete" />
|
<Menu.Item icon="trash" onPress={remove} title="Delete" />
|
||||||
<Menu.Item icon="copy" onPress={copy} title="Copy" />
|
<Menu.Item icon="copy" onPress={copy} title="Copy" />
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user