Massive/EditPlan.tsx

145 lines
4.3 KiB
TypeScript
Raw Normal View History

2022-07-09 23:51:52 +00:00
import React, {useCallback, useContext, useEffect, useState} from 'react';
2022-07-09 05:10:28 +00:00
import {ScrollView, StyleSheet, Text, View} from 'react-native';
2022-07-07 04:17:55 +00:00
import {Button, Dialog, Portal, Switch} from 'react-native-paper';
import {DatabaseContext} from './App';
2022-07-06 05:40:53 +00:00
import {Plan} from './plan';
2022-07-09 04:38:57 +00:00
import {DAYS} from './time';
2022-07-06 05:40:53 +00:00
export default function EditPlan({
plan,
2022-07-06 05:40:53 +00:00
onSave,
2022-07-08 02:59:19 +00:00
setPlan,
2022-07-06 05:40:53 +00:00
}: {
onSave: () => void;
plan?: Plan;
2022-07-08 02:59:19 +00:00
setPlan: (plan?: Plan) => void;
2022-07-06 05:40:53 +00:00
}) {
2022-07-07 04:17:55 +00:00
const [days, setDays] = useState<string[]>([]);
const [workouts, setWorkouts] = useState<string[]>([]);
2022-07-06 06:26:43 +00:00
const [names, setNames] = useState<string[]>([]);
const db = useContext(DatabaseContext);
2022-07-06 05:40:53 +00:00
useEffect(() => {
2022-07-09 01:27:19 +00:00
const refresh = async () => {
const [namesResult] = await db.executeSql(
'SELECT DISTINCT name FROM sets',
);
if (!namesResult.rows.length) return setNames([]);
setNames(namesResult.rows.raw().map(({name}) => name));
if (!plan) return;
2022-07-09 05:10:28 +00:00
if (plan.days) setDays(plan.days.split(','));
if (plan.workouts) setWorkouts(plan.workouts.split(','));
2022-07-09 01:27:19 +00:00
};
refresh();
2022-07-09 01:48:45 +00:00
}, [plan, db]);
2022-07-06 05:40:53 +00:00
2022-07-09 23:51:52 +00:00
const save = useCallback(async () => {
2022-07-10 04:10:06 +00:00
console.log(`${EditPlan.name}.save`, {days, workouts, plan});
2022-07-06 05:40:53 +00:00
if (!days || !workouts) return;
2022-07-07 04:17:55 +00:00
const newWorkouts = workouts.filter(workout => workout).join(',');
const newDays = days.filter(day => day).join(',');
2022-07-10 04:10:06 +00:00
if (!plan?.id)
2022-07-06 05:40:53 +00:00
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
2022-07-07 04:17:55 +00:00
newDays,
newWorkouts,
2022-07-06 05:40:53 +00:00
]);
else
await db.executeSql(
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
2022-07-07 04:17:55 +00:00
[newDays, newWorkouts, plan.id],
2022-07-06 05:40:53 +00:00
);
2022-07-08 02:59:19 +00:00
setPlan(undefined);
2022-07-06 05:40:53 +00:00
onSave();
2022-07-09 23:54:23 +00:00
}, [days, workouts, db, onSave, plan, setPlan]);
2022-07-06 05:40:53 +00:00
2022-07-09 23:51:52 +00:00
const toggleWorkout = useCallback(
(on: boolean, name: string) => {
if (on) {
setWorkouts([...workouts, name]);
} else {
setWorkouts(workouts.filter(workout => workout !== name));
}
},
2022-07-09 23:54:23 +00:00
[setWorkouts, workouts],
2022-07-09 23:51:52 +00:00
);
2022-07-06 06:26:43 +00:00
2022-07-09 23:51:52 +00:00
const toggleDay = useCallback(
(on: boolean, day: string) => {
if (on) {
setDays([...days, day]);
} else {
setDays(days.filter(d => d !== day));
}
},
2022-07-09 23:54:23 +00:00
[setDays, days],
2022-07-09 23:51:52 +00:00
);
2022-07-06 05:40:53 +00:00
return (
<Portal>
2022-07-08 02:59:19 +00:00
<Dialog visible={!!plan} onDismiss={() => setPlan(undefined)}>
2022-07-07 04:17:55 +00:00
<Dialog.Title>
2022-07-09 05:10:28 +00:00
{plan?.days ? `Edit "${days.slice(0, 2).join(', ')}"` : 'Add a plan'}
2022-07-07 04:17:55 +00:00
</Dialog.Title>
2022-07-09 05:10:28 +00:00
<Dialog.ScrollArea>
<ScrollView
style={{height: '80%'}}
contentContainerStyle={{paddingHorizontal: 24}}>
2022-07-07 04:17:55 +00:00
<Text style={styles.title}>Days</Text>
{DAYS.map(day => (
<View key={day} style={[styles.row, {alignItems: 'center'}]}>
<Switch
value={days.includes(day)}
style={{marginRight: 5}}
onValueChange={value => toggleDay(value, day)}
/>
<Text onPress={() => toggleDay(!days.includes(day), day)}>
{day}
</Text>
</View>
))}
2022-07-09 05:10:28 +00:00
<Text style={[styles.title, {marginTop: 10}]}>Workouts</Text>
{names.length === 0 && (
<Text style={{maxWidth: '80%'}}>
No sets found. Try going to the home page and adding some
workouts first.
</Text>
)}
2022-07-07 04:17:55 +00:00
{names.map(name => (
<View key={name} style={[styles.row, {alignItems: 'center'}]}>
<Switch
value={workouts.includes(name)}
style={{marginRight: 5}}
onValueChange={value => toggleWorkout(value, name)}
/>
<Text
onPress={() => toggleWorkout(!workouts.includes(name), name)}>
{name}
</Text>
</View>
))}
2022-07-09 05:10:28 +00:00
</ScrollView>
</Dialog.ScrollArea>
<Dialog.Actions>
2022-07-08 02:59:19 +00:00
<Button icon="close" onPress={() => setPlan(undefined)}>
2022-07-06 05:40:53 +00:00
Cancel
</Button>
2022-07-06 10:02:43 +00:00
<Button mode="contained" icon="save" onPress={save}>
Save
</Button>
</Dialog.Actions>
</Dialog>
2022-07-06 05:40:53 +00:00
</Portal>
);
}
2022-07-07 04:17:55 +00:00
const styles = StyleSheet.create({
title: {
fontSize: 20,
marginBottom: 10,
},
row: {
flexDirection: 'row',
2022-07-09 05:10:28 +00:00
flexWrap: 'wrap',
2022-07-07 04:17:55 +00:00
},
});