1
1
mirror of https://github.com/theoludwig/p61-project.git synced 2024-07-17 07:00:12 +02:00
p61-project/presentation/react/components/HabitCreateForm/HabitCreateForm.tsx

210 lines
5.1 KiB
TypeScript
Raw Normal View History

2024-04-04 17:06:42 +02:00
import { zodResolver } from "@hookform/resolvers/zod"
import { Controller, useForm } from "react-hook-form"
2024-04-04 17:26:48 +02:00
import {
Appbar,
Button,
HelperText,
SegmentedButtons,
TextInput,
} from "react-native-paper"
2024-04-04 12:31:56 +02:00
import { SafeAreaView } from "react-native-safe-area-context"
2024-04-04 17:06:42 +02:00
import ColorPicker, {
HueSlider,
Panel1,
Preview,
} from "reanimated-color-picker"
2024-04-04 12:31:56 +02:00
import type { HabitCreateData } from "@/domain/entities/Habit"
2024-04-04 17:06:42 +02:00
import { HabitCreateSchema } from "@/domain/entities/Habit"
2024-04-04 12:31:56 +02:00
import type { User } from "@/domain/entities/User"
2024-04-04 17:26:48 +02:00
import type { GoalFrequency, GoalType } from "@/domain/entities/Goal"
import { GOAL_FREQUENCIES, GOAL_TYPES } from "@/domain/entities/Goal"
import { capitalize } from "@/presentation/presenters/utils/strings"
2024-04-04 12:31:56 +02:00
export interface HabitCreateFormProps {
user: User
}
export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
2024-04-04 17:06:42 +02:00
// const {createHabit, habitPresenter} = useHabitCreate()
const onSubmit = async (data: HabitCreateData): Promise<void> => {
// await habitPresenter.createHabit(data)
console.log(data)
}
2024-04-04 17:26:48 +02:00
const frequenciesIcons: {
[key in GoalFrequency]: string
} = {
daily: "calendar",
weekly: "calendar-week",
monthly: "calendar-month",
}
const habitTypesTranslations: {
[key in GoalType]: { label: string; icon: string }
} = {
boolean: {
label: "Routine",
icon: "clock",
},
numeric: {
label: "Target",
icon: "target",
},
}
2024-04-04 17:06:42 +02:00
const {
control,
handleSubmit,
formState: { errors },
} = useForm<HabitCreateData>({
mode: "onChange",
resolver: zodResolver(HabitCreateSchema),
2024-04-04 12:31:56 +02:00
defaultValues: {
userId: user.id,
name: "",
color: "#006CFF",
icon: "lightbulb",
goal: {
frequency: "daily",
target: {
type: "boolean",
},
},
},
})
return (
<SafeAreaView>
<Appbar.Header>
<Appbar.Content
title="New Habit"
style={{
alignItems: "center",
justifyContent: "center",
}}
/>
</Appbar.Header>
2024-04-04 17:06:42 +02:00
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => {
return (
<>
<TextInput
placeholder="Name"
onBlur={onBlur}
onChangeText={onChange}
value={value}
style={[styles.input]}
mode="outlined"
/>
{errors.name != null ? (
<HelperText type="error" visible>
{errors.name.type === "too_big"
? "Name is too long"
: "Name is required"}
</HelperText>
) : null}
</>
)
}}
name="name"
/>
<Controller
control={control}
render={({ field: { onChange, value } }) => {
return (
<ColorPicker
style={{ width: "70%" }}
value={value}
onChange={(value) => {
onChange(value.hex)
}}
>
<Preview hideInitialColor />
<Panel1 />
<HueSlider />
</ColorPicker>
)
}}
name="color"
/>
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => {
return (
<TextInput
placeholder="Icon"
onBlur={onBlur}
onChangeText={onChange}
value={value}
style={[styles.input]}
mode="outlined"
/>
)
}}
name="icon"
/>
<Controller
control={control}
2024-04-04 17:26:48 +02:00
render={({ field: { onChange, value } }) => {
2024-04-04 17:06:42 +02:00
return (
2024-04-04 17:26:48 +02:00
<SegmentedButtons
onValueChange={onChange}
2024-04-04 17:06:42 +02:00
value={value}
2024-04-04 17:26:48 +02:00
buttons={GOAL_FREQUENCIES.map((frequency) => {
return {
label: capitalize(frequency),
value: frequency,
icon: frequenciesIcons[frequency],
}
})}
2024-04-04 17:06:42 +02:00
/>
)
}}
name="goal.frequency"
/>
<Controller
control={control}
2024-04-04 17:26:48 +02:00
render={({ field: { onChange, value } }) => {
2024-04-04 17:06:42 +02:00
return (
2024-04-04 17:26:48 +02:00
<SegmentedButtons
onValueChange={onChange}
2024-04-04 17:06:42 +02:00
value={value}
2024-04-04 17:26:48 +02:00
buttons={GOAL_TYPES.map((type) => {
return {
label: habitTypesTranslations[type].label,
value: type,
icon: habitTypesTranslations[type].icon,
}
})}
2024-04-04 17:06:42 +02:00
/>
)
}}
name="goal.target.type"
/>
<Button
mode="contained"
onPress={handleSubmit(onSubmit)}
// loading={createHabit.state === "loading"}
// disabled={createHabit.state === "loading"}
>
Create your habit
</Button>
2024-04-04 12:31:56 +02:00
</SafeAreaView>
)
}
2024-04-04 17:06:42 +02:00
const styles = {
input: {
margin: 8,
},
}