feat: handle creation of habit target type

This commit is contained in:
Théo LUDWIG 2024-04-13 17:57:58 +02:00
parent 97ae14d182
commit c00b96a8e2
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
4 changed files with 84 additions and 16 deletions

View File

@ -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,
}}
/>

View File

@ -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),
}),
]),

View File

@ -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,
},
})

View File

@ -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>