diff --git a/app/application/_layout.tsx b/app/application/_layout.tsx index 1bf47a03b74cf0e736df83f20759c8281c16eb95..f27ad5dfb7be2d6ab7ed4386230664541e013e41 100644 --- a/app/application/_layout.tsx +++ b/app/application/_layout.tsx @@ -31,6 +31,7 @@ const TabLayout: React.FC = () => { name="habits/new" options={{ title: "New Habit", + unmountOnBlur: true, tabBarIcon: ({ color }) => { return <TabBarIcon name="plus-square" color={color} /> }, @@ -39,6 +40,7 @@ const TabLayout: React.FC = () => { <Tabs.Screen name="habits/[habitId]" options={{ + unmountOnBlur: true, href: null, }} /> diff --git a/domain/entities/Goal.ts b/domain/entities/Goal.ts index ded0b303b3774a803ec178e4e99df1148da52dd6..e3c407729e7dc3dcdb76457633b8d22ebb8560c0 100644 --- a/domain/entities/Goal.ts +++ b/domain/entities/Goal.ts @@ -27,7 +27,7 @@ export const GoalCreateSchema = z.object({ z.object({ type: z.literal("boolean") }), z.object({ type: z.literal("numeric"), - value: z.number().int().min(0), + value: z.number().int().min(1), unit: z.string().min(1), }), ]), diff --git a/presentation/react/components/HabitForm/HabitCreateForm.tsx b/presentation/react/components/HabitForm/HabitCreateForm.tsx index deebdd8137a4440008e96e3b72c2423350b84efb..443ad35fe551c336eebc7d9d8105e4e46cc8a8c5 100644 --- a/presentation/react/components/HabitForm/HabitCreateForm.tsx +++ b/presentation/react/components/HabitForm/HabitCreateForm.tsx @@ -39,7 +39,9 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { control, handleSubmit, reset, - formState: { errors }, + watch, + + formState: { errors, isValid }, } = useForm<HabitCreateData>({ mode: "onChange", resolver: zodResolver(HabitCreateSchema), @@ -57,6 +59,8 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { }, }) + const watchGoalType = watch("goal.target.type") + const [isVisibleSnackbar, setIsVisibleSnackbar] = useState(false) const { @@ -128,7 +132,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { style={[ styles.spacing, { - width: "90%", + width: "96%", }, ]} mode="outlined" @@ -153,7 +157,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { <> <Text style={[styles.spacing]}>Habit Frequency</Text> <SegmentedButtons - style={[{ width: "90%" }]} + style={[{ width: "96%" }]} onValueChange={onChange} value={value} buttons={GOAL_FREQUENCIES.map((frequency) => { @@ -197,7 +201,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { </Tooltip> */} </Text> <SegmentedButtons - style={[{ width: "90%" }]} + style={[{ width: "96%" }]} onValueChange={onChange} value={value} buttons={GOAL_TYPES.map((type) => { @@ -214,12 +218,74 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { name="goal.target.type" /> + {watchGoalType === "numeric" ? ( + <View + style={{ + marginTop: 10, + flexDirection: "row", + gap: 10, + width: "96%", + }} + > + <Controller + control={control} + render={({ field: { onChange, onBlur, value } }) => { + return ( + <TextInput + placeholder="Target (e.g: 5 000)" + onBlur={onBlur} + onChangeText={(text) => { + if (text.length <= 0) { + onChange("") + return + } + onChange(Number.parseInt(text, 10)) + }} + value={value?.toString()} + style={[ + styles.spacing, + { + width: "50%", + }, + ]} + mode="outlined" + keyboardType="numeric" + /> + ) + }} + name="goal.target.value" + /> + + <Controller + control={control} + render={({ field: { onChange, onBlur, value } }) => { + return ( + <TextInput + placeholder="Unit (e.g: Steps)" + onBlur={onBlur} + onChangeText={onChange} + value={value} + style={[ + styles.spacing, + { + width: "50%", + }, + ]} + mode="outlined" + /> + ) + }} + name="goal.target.unit" + /> + </View> + ) : null} + <Controller control={control} render={({ field: { onChange, value } }) => { return ( <ColorPicker - style={[styles.spacing, { width: "90%" }]} + style={[{ marginVertical: 15, width: "96%" }]} value={value} onComplete={(value) => { onChange(value.hex) @@ -244,7 +310,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { alignItems: "center", flexDirection: "row", gap: 20, - marginVertical: 30, + marginVertical: 5, }} > <FontAwesomeIcon size={36} icon={value as IconName} /> @@ -269,8 +335,8 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { mode="contained" onPress={handleSubmit(onSubmit)} loading={habitCreate.state === "loading"} - disabled={habitCreate.state === "loading"} - style={[styles.spacing, { width: "100%" }]} + disabled={habitCreate.state === "loading" || !isValid} + style={[{ width: "100%", marginVertical: 15 }]} > Create your habit! 🚀 </Button> @@ -289,6 +355,6 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => { const styles = StyleSheet.create({ spacing: { - marginVertical: 16, + marginVertical: 10, }, }) diff --git a/presentation/react/components/HabitForm/HabitEditForm.tsx b/presentation/react/components/HabitForm/HabitEditForm.tsx index 8335396e0b1311fc5c37893d7de0d6d93b93f0b5..a97f84457952db95b0016cf94b819a7a19da2eb1 100644 --- a/presentation/react/components/HabitForm/HabitEditForm.tsx +++ b/presentation/react/components/HabitForm/HabitEditForm.tsx @@ -28,7 +28,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => { const { control, handleSubmit, - formState: { errors }, + formState: { errors, isValid }, } = useForm<HabitEditData>({ mode: "onChange", resolver: zodResolver(HabitEditSchema), @@ -80,7 +80,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => { style={[ styles.spacing, { - width: "90%", + width: "96%", }, ]} mode="outlined" @@ -103,7 +103,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => { render={({ field: { onChange, value } }) => { return ( <ColorPicker - style={[styles.spacing, { width: "90%" }]} + style={[styles.spacing, { width: "96%" }]} value={value} onComplete={(value) => { onChange(value.hex) @@ -153,8 +153,8 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => { mode="contained" onPress={handleSubmit(onSubmit)} loading={habitEdit.state === "loading"} - disabled={habitEdit.state === "loading"} - style={[styles.spacing, { width: "90%" }]} + disabled={habitEdit.state === "loading" || !isValid} + style={[styles.spacing, { width: "96%" }]} > Save </Button> @@ -166,7 +166,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => { }} loading={habitStop.state === "loading"} disabled={habitStop.state === "loading"} - style={[styles.spacing, { width: "90%" }]} + style={[styles.spacing, { width: "96%" }]} > Stop </Button>