feat: handle creation of habit target type
This commit is contained in:
parent
97ae14d182
commit
c00b96a8e2
@ -31,6 +31,7 @@ const TabLayout: React.FC = () => {
|
|||||||
name="habits/new"
|
name="habits/new"
|
||||||
options={{
|
options={{
|
||||||
title: "New Habit",
|
title: "New Habit",
|
||||||
|
unmountOnBlur: true,
|
||||||
tabBarIcon: ({ color }) => {
|
tabBarIcon: ({ color }) => {
|
||||||
return <TabBarIcon name="plus-square" color={color} />
|
return <TabBarIcon name="plus-square" color={color} />
|
||||||
},
|
},
|
||||||
@ -39,6 +40,7 @@ const TabLayout: React.FC = () => {
|
|||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="habits/[habitId]"
|
name="habits/[habitId]"
|
||||||
options={{
|
options={{
|
||||||
|
unmountOnBlur: true,
|
||||||
href: null,
|
href: null,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -27,7 +27,7 @@ export const GoalCreateSchema = z.object({
|
|||||||
z.object({ type: z.literal("boolean") }),
|
z.object({ type: z.literal("boolean") }),
|
||||||
z.object({
|
z.object({
|
||||||
type: z.literal("numeric"),
|
type: z.literal("numeric"),
|
||||||
value: z.number().int().min(0),
|
value: z.number().int().min(1),
|
||||||
unit: z.string().min(1),
|
unit: z.string().min(1),
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
@ -39,7 +39,9 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
reset,
|
||||||
formState: { errors },
|
watch,
|
||||||
|
|
||||||
|
formState: { errors, isValid },
|
||||||
} = useForm<HabitCreateData>({
|
} = useForm<HabitCreateData>({
|
||||||
mode: "onChange",
|
mode: "onChange",
|
||||||
resolver: zodResolver(HabitCreateSchema),
|
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 [isVisibleSnackbar, setIsVisibleSnackbar] = useState(false)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -128,7 +132,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
style={[
|
style={[
|
||||||
styles.spacing,
|
styles.spacing,
|
||||||
{
|
{
|
||||||
width: "90%",
|
width: "96%",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
mode="outlined"
|
mode="outlined"
|
||||||
@ -153,7 +157,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
<>
|
<>
|
||||||
<Text style={[styles.spacing]}>Habit Frequency</Text>
|
<Text style={[styles.spacing]}>Habit Frequency</Text>
|
||||||
<SegmentedButtons
|
<SegmentedButtons
|
||||||
style={[{ width: "90%" }]}
|
style={[{ width: "96%" }]}
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
value={value}
|
value={value}
|
||||||
buttons={GOAL_FREQUENCIES.map((frequency) => {
|
buttons={GOAL_FREQUENCIES.map((frequency) => {
|
||||||
@ -197,7 +201,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
</Tooltip> */}
|
</Tooltip> */}
|
||||||
</Text>
|
</Text>
|
||||||
<SegmentedButtons
|
<SegmentedButtons
|
||||||
style={[{ width: "90%" }]}
|
style={[{ width: "96%" }]}
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
value={value}
|
value={value}
|
||||||
buttons={GOAL_TYPES.map((type) => {
|
buttons={GOAL_TYPES.map((type) => {
|
||||||
@ -214,12 +218,74 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
name="goal.target.type"
|
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
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field: { onChange, value } }) => {
|
render={({ field: { onChange, value } }) => {
|
||||||
return (
|
return (
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
style={[styles.spacing, { width: "90%" }]}
|
style={[{ marginVertical: 15, width: "96%" }]}
|
||||||
value={value}
|
value={value}
|
||||||
onComplete={(value) => {
|
onComplete={(value) => {
|
||||||
onChange(value.hex)
|
onChange(value.hex)
|
||||||
@ -244,7 +310,7 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
gap: 20,
|
gap: 20,
|
||||||
marginVertical: 30,
|
marginVertical: 5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon size={36} icon={value as IconName} />
|
<FontAwesomeIcon size={36} icon={value as IconName} />
|
||||||
@ -269,8 +335,8 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
mode="contained"
|
mode="contained"
|
||||||
onPress={handleSubmit(onSubmit)}
|
onPress={handleSubmit(onSubmit)}
|
||||||
loading={habitCreate.state === "loading"}
|
loading={habitCreate.state === "loading"}
|
||||||
disabled={habitCreate.state === "loading"}
|
disabled={habitCreate.state === "loading" || !isValid}
|
||||||
style={[styles.spacing, { width: "100%" }]}
|
style={[{ width: "100%", marginVertical: 15 }]}
|
||||||
>
|
>
|
||||||
Create your habit! 🚀
|
Create your habit! 🚀
|
||||||
</Button>
|
</Button>
|
||||||
@ -289,6 +355,6 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
|
|||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
spacing: {
|
spacing: {
|
||||||
marginVertical: 16,
|
marginVertical: 10,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -28,7 +28,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
|||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors, isValid },
|
||||||
} = useForm<HabitEditData>({
|
} = useForm<HabitEditData>({
|
||||||
mode: "onChange",
|
mode: "onChange",
|
||||||
resolver: zodResolver(HabitEditSchema),
|
resolver: zodResolver(HabitEditSchema),
|
||||||
@ -80,7 +80,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
|||||||
style={[
|
style={[
|
||||||
styles.spacing,
|
styles.spacing,
|
||||||
{
|
{
|
||||||
width: "90%",
|
width: "96%",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
mode="outlined"
|
mode="outlined"
|
||||||
@ -103,7 +103,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
|||||||
render={({ field: { onChange, value } }) => {
|
render={({ field: { onChange, value } }) => {
|
||||||
return (
|
return (
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
style={[styles.spacing, { width: "90%" }]}
|
style={[styles.spacing, { width: "96%" }]}
|
||||||
value={value}
|
value={value}
|
||||||
onComplete={(value) => {
|
onComplete={(value) => {
|
||||||
onChange(value.hex)
|
onChange(value.hex)
|
||||||
@ -153,8 +153,8 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
|||||||
mode="contained"
|
mode="contained"
|
||||||
onPress={handleSubmit(onSubmit)}
|
onPress={handleSubmit(onSubmit)}
|
||||||
loading={habitEdit.state === "loading"}
|
loading={habitEdit.state === "loading"}
|
||||||
disabled={habitEdit.state === "loading"}
|
disabled={habitEdit.state === "loading" || !isValid}
|
||||||
style={[styles.spacing, { width: "90%" }]}
|
style={[styles.spacing, { width: "96%" }]}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
@ -166,7 +166,7 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
|||||||
}}
|
}}
|
||||||
loading={habitStop.state === "loading"}
|
loading={habitStop.state === "loading"}
|
||||||
disabled={habitStop.state === "loading"}
|
disabled={habitStop.state === "loading"}
|
||||||
style={[styles.spacing, { width: "90%" }]}
|
style={[styles.spacing, { width: "96%" }]}
|
||||||
>
|
>
|
||||||
Stop
|
Stop
|
||||||
</Button>
|
</Button>
|
||||||
|
Reference in New Issue
Block a user