Use switches for plan editing

This commit is contained in:
Brandon Presley 2022-07-07 16:17:55 +12:00
parent 1d68ba86f5
commit 29200cf248
5 changed files with 86 additions and 63 deletions

View File

@ -1,9 +1,18 @@
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext, useEffect, useState} from 'react';
import {Button, Dialog, Portal} from 'react-native-paper'; import {StyleSheet, Text, View} from 'react-native';
import {Button, Dialog, Portal, Switch} from 'react-native-paper';
import {DatabaseContext} from './App'; import {DatabaseContext} from './App';
import DayMenu from './DayMenu';
import {Plan} from './plan'; import {Plan} from './plan';
import WorkoutMenu from './WorkoutMenu';
const DAYS = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
];
export default function EditPlan({ export default function EditPlan({
plan, plan,
@ -16,8 +25,8 @@ export default function EditPlan({
setShow: (visible: boolean) => void; setShow: (visible: boolean) => void;
plan?: Plan; plan?: Plan;
}) { }) {
const [days, setDays] = useState(''); const [days, setDays] = useState<string[]>([]);
const [workouts, setWorkouts] = useState(''); const [workouts, setWorkouts] = useState<string[]>([]);
const [names, setNames] = useState<string[]>([]); const [names, setNames] = useState<string[]>([]);
const db = useContext(DatabaseContext); const db = useContext(DatabaseContext);
@ -26,8 +35,8 @@ export default function EditPlan({
if (!namesResult.rows.length) return; if (!namesResult.rows.length) return;
setNames(namesResult.rows.raw().map(({name}) => name)); setNames(namesResult.rows.raw().map(({name}) => name));
if (!plan) return; if (!plan) return;
setDays(plan.days); setDays(plan.days.split(','));
setWorkouts(plan.workouts); setWorkouts(plan.workouts.split(','));
}; };
useEffect(() => { useEffect(() => {
@ -36,76 +45,76 @@ export default function EditPlan({
const save = async () => { const save = async () => {
if (!days || !workouts) return; if (!days || !workouts) return;
const newWorkouts = workouts.filter(workout => workout).join(',');
const newDays = days.filter(day => day).join(',');
if (!plan) if (!plan)
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [ await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
days, newDays,
workouts, newWorkouts,
]); ]);
else else
await db.executeSql( await db.executeSql(
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`, `UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
[days, workouts, plan.id], [newDays, newWorkouts, plan.id],
); );
setShow(false); setShow(false);
onSave(); onSave();
}; };
const selectDay = (day: string, index: number) => { const toggleWorkout = (on: boolean, name: string) => {
const newDays = days.split(','); if (on) {
newDays[index] = day; setWorkouts([...workouts, name]);
setDays(newDays.join(',')); } else {
setWorkouts(workouts.filter(workout => workout !== name));
}
}; };
const selectWorkout = (workout: string, index: number) => { const toggleDay = (on: boolean, day: string) => {
const newWorkouts = workouts.split(','); if (on) {
newWorkouts[index] = workout; setDays([...days, day]);
setWorkouts(newWorkouts.join(',')); } else {
}; setDays(days.filter(d => d !== day));
}
const removeWorkout = (index: number) => {
const newWorkouts = workouts.split(',');
delete newWorkouts[index];
setWorkouts(newWorkouts.filter(day => day).join(','));
};
const removeDay = (index: number) => {
const newDays = days.split(',');
delete newDays[index];
setDays(newDays.filter(day => day).join(','));
}; };
return ( return (
<Portal> <Portal>
<Dialog visible={show} onDismiss={() => setShow(false)}> <Dialog visible={show} onDismiss={() => setShow(false)}>
<Dialog.Title>{plan ? `Edit "${days}"` : 'Add a plan'}</Dialog.Title> <Dialog.Title>
<Dialog.Content> {plan ? `Edit "${days.join(', ')}"` : 'Add a plan'}
{days.split(',').map((day, index) => ( </Dialog.Title>
<DayMenu <Dialog.Content style={[styles.row, {justifyContent: 'space-between'}]}>
index={index} <View>
onDelete={() => removeDay(index)} <Text style={styles.title}>Days</Text>
onSelect={option => selectDay(option, index)} {DAYS.map(day => (
onAdd={() => setDays(days + ',Monday')} <View key={day} style={[styles.row, {alignItems: 'center'}]}>
selected={day} <Switch
key={index} value={days.includes(day)}
/> style={{marginRight: 5}}
))} onValueChange={value => toggleDay(value, day)}
<Button icon="add" onPress={() => setDays(days + ',Monday')}> />
Add day <Text onPress={() => toggleDay(!days.includes(day), day)}>
</Button> {day}
{workouts.split(',').map((workout, index) => ( </Text>
<WorkoutMenu </View>
index={index} ))}
selected={workout} </View>
onAdd={() => setWorkouts(workouts + ',')} <View>
onSelect={option => selectWorkout(option, index)} <Text style={styles.title}>Workouts</Text>
onDelete={() => removeWorkout(index)} {names.map(name => (
names={names} <View key={name} style={[styles.row, {alignItems: 'center'}]}>
key={index} <Switch
/> value={workouts.includes(name)}
))} style={{marginRight: 5}}
<Button icon="add" onPress={() => setWorkouts(workouts + ',')}> onValueChange={value => toggleWorkout(value, name)}
Add workout />
</Button> <Text
onPress={() => toggleWorkout(!workouts.includes(name), name)}>
{name}
</Text>
</View>
))}
</View>
</Dialog.Content> </Dialog.Content>
<Dialog.Actions> <Dialog.Actions>
<Button icon="close" onPress={() => setShow(false)}> <Button icon="close" onPress={() => setShow(false)}>
@ -119,3 +128,13 @@ export default function EditPlan({
</Portal> </Portal>
); );
} }
const styles = StyleSheet.create({
title: {
fontSize: 20,
marginBottom: 10,
},
row: {
flexDirection: 'row',
},
});

View File

@ -30,8 +30,8 @@ export default function PlanItem({
setPlan(item); setPlan(item);
setShowEdit(true); setShowEdit(true);
}} }}
title={item.days} title={item.days.replace(/,/g, ', ')}
description={item.workouts} description={item.workouts.replace(/,/g, ', ')}
onLongPress={() => setShow(true)} onLongPress={() => setShow(true)}
right={() => ( right={() => (
<Menu <Menu

BIN
bun.lockb Executable file

Binary file not shown.

View File

@ -21,7 +21,6 @@
"react": "18.0.0", "react": "18.0.0",
"react-devtools": "^4.24.7", "react-devtools": "^4.24.7",
"react-native": "0.69.1", "react-native": "0.69.1",
"react-native-document-picker": "^8.1.1",
"react-native-gesture-handler": "^2.5.0", "react-native-gesture-handler": "^2.5.0",
"react-native-pager-view": "^5.4.24", "react-native-pager-view": "^5.4.24",
"react-native-paper": "^4.12.2", "react-native-paper": "^4.12.2",
@ -62,4 +61,4 @@
"node" "node"
] ]
} }
} }

View File

@ -1603,6 +1603,11 @@
resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.2.0.tgz#7d6d789ae8edf73dc9bed1246cd48277edea8066" resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.2.0.tgz#7d6d789ae8edf73dc9bed1246cd48277edea8066"
integrity sha512-o6aam+0Ug1xGK3ABYmBm0B1YuEKfM/5kaoZO0eHbZwSpw9UzDX4G5y4Nx/K20FHqUmJHkZmLvOUFYwN4N+HqKA== integrity sha512-o6aam+0Ug1xGK3ABYmBm0B1YuEKfM/5kaoZO0eHbZwSpw9UzDX4G5y4Nx/K20FHqUmJHkZmLvOUFYwN4N+HqKA==
"@react-native-picker/picker@^2.4.2":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.4.2.tgz#2925eb8e76ff6b584c80529adc251df963be9141"
integrity sha512-0nY8638h1J3wKz6P3IJMpOoxJDdOj7Dk/K2hP/xpqP3KnIY0lmoqYlhyNihuyVPocDGajf6SA7LFFsFepQ56ag==
"@react-native/assets@1.0.0": "@react-native/assets@1.0.0":
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e"