2022-07-11 00:28:30 +00:00
|
|
|
import {
|
2022-08-28 08:54:07 +00:00
|
|
|
NavigationProp,
|
2022-07-11 00:28:30 +00:00
|
|
|
RouteProp,
|
|
|
|
useNavigation,
|
|
|
|
useRoute,
|
2023-08-12 03:22:50 +00:00
|
|
|
} from "@react-navigation/native";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
2023-11-08 23:58:26 +00:00
|
|
|
import { Pressable, StyleSheet, View } from "react-native";
|
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
IconButton,
|
|
|
|
Switch as PaperSwitch,
|
|
|
|
Text,
|
2023-11-14 01:03:40 +00:00
|
|
|
ActivityIndicator,
|
2023-11-08 23:58:26 +00:00
|
|
|
} from "react-native-paper";
|
|
|
|
import ReorderableList, {
|
|
|
|
ReorderableListRenderItemInfo,
|
|
|
|
} from "react-native-reorderable-list";
|
|
|
|
import AppInput from "./AppInput";
|
|
|
|
import { StackParams } from "./AppStack";
|
|
|
|
import { MARGIN, PADDING } from "./constants";
|
2023-11-06 01:27:27 +00:00
|
|
|
import { DAYS } from "./days";
|
2023-11-08 23:58:26 +00:00
|
|
|
import { planRepo, setRepo } from "./db";
|
2023-10-28 02:59:03 +00:00
|
|
|
import { DrawerParams } from "./drawer-param-list";
|
2023-11-13 05:13:23 +00:00
|
|
|
import GymSet, { defaultSet } from "./gym-set";
|
2023-11-12 04:05:37 +00:00
|
|
|
import StackHeader from "./StackHeader";
|
|
|
|
import Switch from "./Switch";
|
2023-11-14 01:03:40 +00:00
|
|
|
import { ProgressCircle } from "react-native-svg-charts";
|
2022-07-06 05:40:53 +00:00
|
|
|
|
2022-07-11 00:28:30 +00:00
|
|
|
export default function EditPlan() {
|
2023-10-28 02:59:03 +00:00
|
|
|
const { params } = useRoute<RouteProp<StackParams, "EditPlan">>();
|
2023-08-12 03:22:50 +00:00
|
|
|
const { plan } = params;
|
2023-08-21 12:25:29 +00:00
|
|
|
const [title, setTitle] = useState<string>(plan?.title);
|
2023-11-14 01:03:40 +00:00
|
|
|
const [names, setNames] = useState<string[]>();
|
2023-11-14 00:56:50 +00:00
|
|
|
|
2022-09-18 06:45:05 +00:00
|
|
|
const [days, setDays] = useState<string[]>(
|
2023-08-12 03:22:50 +00:00
|
|
|
plan.days ? plan.days.split(",") : []
|
|
|
|
);
|
2023-11-14 00:56:50 +00:00
|
|
|
|
2023-11-09 05:52:50 +00:00
|
|
|
const [exercises, setExercises] = useState<string[]>(
|
|
|
|
plan.exercises ? plan.exercises.split(",") : []
|
2023-08-12 03:22:50 +00:00
|
|
|
);
|
2023-11-14 00:56:50 +00:00
|
|
|
|
2023-10-28 02:59:03 +00:00
|
|
|
const { navigate: drawerNavigate } =
|
|
|
|
useNavigation<NavigationProp<DrawerParams>>();
|
|
|
|
const { navigate: stackNavigate } =
|
|
|
|
useNavigation<NavigationProp<StackParams>>();
|
2022-07-11 00:28:30 +00:00
|
|
|
|
2022-07-06 05:40:53 +00:00
|
|
|
useEffect(() => {
|
2022-10-31 00:20:36 +00:00
|
|
|
setRepo
|
|
|
|
.createQueryBuilder()
|
2023-08-12 03:22:50 +00:00
|
|
|
.select("name")
|
2022-10-31 00:20:36 +00:00
|
|
|
.distinct(true)
|
2023-08-12 03:22:50 +00:00
|
|
|
.orderBy("name")
|
2022-10-31 00:20:36 +00:00
|
|
|
.getRawMany()
|
2023-06-27 03:16:59 +00:00
|
|
|
.then((values) => {
|
2023-11-08 23:58:26 +00:00
|
|
|
const newNames = values.map((value) => value.name);
|
|
|
|
console.log(EditPlan.name, { newNames });
|
|
|
|
setNames(newNames);
|
2023-08-12 03:22:50 +00:00
|
|
|
});
|
|
|
|
}, []);
|
2022-07-06 05:40:53 +00:00
|
|
|
|
2022-07-09 23:51:52 +00:00
|
|
|
const save = useCallback(async () => {
|
2023-11-09 05:52:50 +00:00
|
|
|
console.log(`${EditPlan.name}.save`, { days, exercises, plan });
|
|
|
|
if (!days || !exercises) return;
|
|
|
|
const newExercises = exercises.filter((exercise) => exercise).join(",");
|
2023-08-12 03:22:50 +00:00
|
|
|
const newDays = days.filter((day) => day).join(",");
|
2023-08-21 12:25:29 +00:00
|
|
|
await planRepo.save({
|
|
|
|
title: title,
|
|
|
|
days: newDays,
|
2023-11-09 05:52:50 +00:00
|
|
|
exercises: newExercises,
|
2023-08-21 12:25:29 +00:00
|
|
|
id: plan.id,
|
|
|
|
});
|
2023-11-09 05:52:50 +00:00
|
|
|
}, [title, days, exercises, plan]);
|
2022-07-06 05:40:53 +00:00
|
|
|
|
2023-11-09 05:52:50 +00:00
|
|
|
const toggleExercise = useCallback(
|
2022-07-09 23:51:52 +00:00
|
|
|
(on: boolean, name: string) => {
|
|
|
|
if (on) {
|
2023-11-09 05:52:50 +00:00
|
|
|
setExercises([...exercises, name]);
|
2022-07-09 23:51:52 +00:00
|
|
|
} else {
|
2023-11-09 05:52:50 +00:00
|
|
|
setExercises(exercises.filter((exercise) => exercise !== name));
|
2022-07-09 23:51:52 +00:00
|
|
|
}
|
|
|
|
},
|
2023-11-09 05:52:50 +00:00
|
|
|
[setExercises, exercises]
|
2023-08-12 03:22:50 +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) {
|
2023-08-12 03:22:50 +00:00
|
|
|
setDays([...days, day]);
|
2022-07-09 23:51:52 +00:00
|
|
|
} else {
|
2023-08-12 03:22:50 +00:00
|
|
|
setDays(days.filter((d) => d !== day));
|
2022-07-09 23:51:52 +00:00
|
|
|
}
|
|
|
|
},
|
2023-08-12 03:22:50 +00:00
|
|
|
[setDays, days]
|
|
|
|
);
|
2022-07-06 05:40:53 +00:00
|
|
|
|
2023-11-08 23:58:26 +00:00
|
|
|
const renderDay = (day: string) => (
|
|
|
|
<Switch
|
|
|
|
key={day}
|
|
|
|
onChange={(value) => toggleDay(value, day)}
|
|
|
|
value={days.includes(day)}
|
|
|
|
title={day}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
2023-11-09 05:52:50 +00:00
|
|
|
const renderExercise = ({
|
2023-11-08 23:58:26 +00:00
|
|
|
item,
|
|
|
|
drag,
|
|
|
|
}: ReorderableListRenderItemInfo<string>) => (
|
|
|
|
<Pressable
|
2023-11-09 05:52:50 +00:00
|
|
|
onPress={() => toggleExercise(!exercises.includes(item), item)}
|
2023-11-08 23:58:26 +00:00
|
|
|
style={{ flexDirection: "row", alignItems: "center" }}
|
|
|
|
>
|
|
|
|
<PaperSwitch
|
2023-11-09 05:52:50 +00:00
|
|
|
value={exercises.includes(item)}
|
2023-11-08 23:58:26 +00:00
|
|
|
style={{ marginRight: MARGIN }}
|
2023-11-09 05:52:50 +00:00
|
|
|
onValueChange={(value) => toggleExercise(value, item)}
|
2023-11-08 23:58:26 +00:00
|
|
|
/>
|
|
|
|
<Text>{item}</Text>
|
2023-11-11 22:45:23 +00:00
|
|
|
<IconButton
|
|
|
|
icon="drag-vertical"
|
|
|
|
style={{ marginLeft: "auto" }}
|
|
|
|
onPressIn={drag}
|
|
|
|
/>
|
2023-11-08 23:58:26 +00:00
|
|
|
</Pressable>
|
|
|
|
);
|
|
|
|
|
2023-11-09 05:52:50 +00:00
|
|
|
const reorderExercise = (from: number, to: number) => {
|
2023-11-08 23:58:26 +00:00
|
|
|
const newNames = [...names];
|
|
|
|
const copy = newNames[from];
|
|
|
|
newNames[from] = newNames[to];
|
|
|
|
newNames[to] = copy;
|
2023-11-09 05:52:50 +00:00
|
|
|
const newExercises = newNames.filter((name) => exercises.includes(name));
|
|
|
|
console.log({ newExercises });
|
|
|
|
setExercises(newExercises);
|
2023-11-11 22:26:03 +00:00
|
|
|
setNames(newNames);
|
2023-11-08 23:58:26 +00:00
|
|
|
};
|
|
|
|
|
2022-07-06 05:40:53 +00:00
|
|
|
return (
|
2022-10-23 06:13:58 +00:00
|
|
|
<>
|
2023-01-08 05:05:59 +00:00
|
|
|
<StackHeader
|
2023-08-12 03:22:50 +00:00
|
|
|
title={typeof plan.id === "number" ? "Edit plan" : "Add plan"}
|
2023-06-27 03:16:59 +00:00
|
|
|
>
|
2023-08-12 03:22:50 +00:00
|
|
|
{typeof plan.id === "number" && (
|
2023-07-03 23:17:58 +00:00
|
|
|
<IconButton
|
|
|
|
onPress={async () => {
|
2023-08-12 03:22:50 +00:00
|
|
|
await save();
|
|
|
|
const newPlan = await planRepo.findOne({
|
|
|
|
where: { id: plan.id },
|
|
|
|
});
|
2023-11-13 05:13:23 +00:00
|
|
|
let first: Partial<GymSet> = await setRepo.findOne({
|
2023-11-09 05:52:50 +00:00
|
|
|
where: { name: exercises[0] },
|
2023-08-12 03:22:50 +00:00
|
|
|
order: { created: "desc" },
|
|
|
|
});
|
2023-11-09 05:52:50 +00:00
|
|
|
if (!first) first = { ...defaultSet, name: exercises[0] };
|
2023-08-12 03:22:50 +00:00
|
|
|
delete first.id;
|
2023-10-28 02:59:03 +00:00
|
|
|
stackNavigate("StartPlan", { plan: newPlan, first });
|
2023-07-03 23:17:58 +00:00
|
|
|
}}
|
2023-10-19 05:28:56 +00:00
|
|
|
icon="play"
|
2023-07-03 23:17:58 +00:00
|
|
|
/>
|
|
|
|
)}
|
2023-03-27 23:15:56 +00:00
|
|
|
</StackHeader>
|
2023-06-27 03:16:59 +00:00
|
|
|
<View style={{ padding: PADDING, flex: 1 }}>
|
2023-11-08 23:58:26 +00:00
|
|
|
<AppInput
|
|
|
|
label="Title"
|
|
|
|
value={title}
|
|
|
|
onChangeText={(value) => setTitle(value)}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Text style={styles.title}>Days</Text>
|
|
|
|
{DAYS.map((day) => renderDay(day))}
|
|
|
|
|
2023-11-09 05:52:50 +00:00
|
|
|
<Text style={[styles.title, { marginTop: MARGIN }]}>Exercises</Text>
|
2023-11-14 01:03:40 +00:00
|
|
|
{names === undefined ? (
|
|
|
|
<ActivityIndicator />
|
2023-11-08 23:58:26 +00:00
|
|
|
) : (
|
|
|
|
<ReorderableList
|
|
|
|
data={names}
|
2023-11-14 01:03:40 +00:00
|
|
|
ListEmptyComponent={<Text>No exercises yet</Text>}
|
2023-11-08 23:58:26 +00:00
|
|
|
onReorder={({ fromIndex, toIndex }) =>
|
2023-11-09 05:52:50 +00:00
|
|
|
reorderExercise(fromIndex, toIndex)
|
2023-11-08 23:58:26 +00:00
|
|
|
}
|
2023-11-09 05:52:50 +00:00
|
|
|
renderItem={renderExercise}
|
2023-11-08 23:58:26 +00:00
|
|
|
keyExtractor={(item) => item}
|
|
|
|
dragScale={1.025}
|
|
|
|
style={{
|
|
|
|
flex: 1,
|
|
|
|
}}
|
|
|
|
containerStyle={{ flex: 1 }}
|
2023-08-21 12:25:29 +00:00
|
|
|
/>
|
2023-11-08 23:58:26 +00:00
|
|
|
)}
|
2022-11-16 05:48:16 +00:00
|
|
|
|
|
|
|
<Button
|
2023-11-09 05:52:50 +00:00
|
|
|
disabled={exercises.length === 0 && days.length === 0}
|
2023-11-14 21:51:54 +00:00
|
|
|
mode="contained"
|
2023-10-19 05:28:56 +00:00
|
|
|
icon="content-save"
|
2023-07-31 03:54:32 +00:00
|
|
|
onPress={async () => {
|
2023-08-12 03:22:50 +00:00
|
|
|
await save();
|
2023-10-28 02:59:03 +00:00
|
|
|
drawerNavigate("Plans");
|
2023-07-31 03:54:32 +00:00
|
|
|
}}
|
2023-06-27 03:16:59 +00:00
|
|
|
>
|
2022-11-16 05:48:16 +00:00
|
|
|
Save
|
|
|
|
</Button>
|
2022-10-23 06:13:58 +00:00
|
|
|
</View>
|
|
|
|
</>
|
2023-08-12 03:22:50 +00:00
|
|
|
);
|
2022-07-06 05:40:53 +00:00
|
|
|
}
|
2022-07-07 04:17:55 +00:00
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
title: {
|
|
|
|
fontSize: 20,
|
2022-09-16 09:07:02 +00:00
|
|
|
marginBottom: MARGIN,
|
2022-07-07 04:17:55 +00:00
|
|
|
},
|
2023-08-12 03:22:50 +00:00
|
|
|
});
|