import type { IconName } from "@fortawesome/free-solid-svg-icons" import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome" import { zodResolver } from "@hookform/resolvers/zod" import { useState } from "react" import { Controller, useForm } from "react-hook-form" import { ScrollView, StyleSheet, View } from "react-native" import { Button, HelperText, SegmentedButtons, Snackbar, Text, TextInput, } from "react-native-paper" import { SafeAreaView } from "react-native-safe-area-context" import ColorPicker, { HueSlider, Panel1, Preview, } from "reanimated-color-picker" import type { GoalFrequency, GoalType } from "@/domain/entities/Goal" import { GOAL_FREQUENCIES, GOAL_TYPES } from "@/domain/entities/Goal" import type { HabitCreateData } from "@/domain/entities/Habit" import { HabitCreateSchema } from "@/domain/entities/Habit" import type { User } from "@/domain/entities/User" import { useHabitsTracker } from "@/presentation/react/contexts/HabitsTracker" import { useBoolean } from "@/presentation/react/hooks/useBoolean" import { IconSelectorModal } from "./IconSelectorModal" export interface HabitCreateFormProps { user: User } export const HabitCreateForm: React.FC = ({ user }) => { const { habitCreate, habitsTrackerPresenter } = useHabitsTracker() const { control, formState: { errors, isValid }, handleSubmit, reset, watch, } = useForm({ mode: "onChange", resolver: zodResolver(HabitCreateSchema), defaultValues: { userId: user.id, name: "", color: "#006CFF", icon: "circle-question", goal: { frequency: "daily", target: { type: "boolean", }, }, }, }) const watchGoalType = watch("goal.target.type") const [isVisibleSnackbar, setIsVisibleSnackbar] = useState(false) const { value: isModalIconSelectorVisible, setTrue: openModalIconSelector, setFalse: closeModalIconSelector, } = useBoolean() const onDismissSnackbar = (): void => { setIsVisibleSnackbar(false) } const onSubmit = async (data: HabitCreateData): Promise => { await habitsTrackerPresenter.habitCreate(data) setIsVisibleSnackbar(true) closeModalIconSelector() reset() } const habitFrequenciesTranslations: { [key in GoalFrequency]: { label: string; icon: string } } = { daily: { label: "Daily", icon: "calendar", }, weekly: { label: "Weekly", icon: "calendar-week", }, monthly: { label: "Monthly", icon: "calendar-month", }, } const habitTypesTranslations: { [key in GoalType]: { label: string; icon: string } } = { boolean: { label: "Routine", icon: "clock", }, numeric: { label: "Target", icon: "target", }, } return ( { return ( <> {errors.name != null ? ( {errors.name.type === "too_big" ? "Name is too long" : "Name is required"} ) : null} ) }} name="name" /> { return ( <> Habit Frequency { return { label: habitFrequenciesTranslations[frequency].label, value: frequency, icon: habitFrequenciesTranslations[frequency].icon, } })} /> ) }} name="goal.frequency" /> { return ( <> Habit Type { return { label: habitTypesTranslations[type].label, value: type, icon: habitTypesTranslations[type].icon, } })} /> ) }} name="goal.target.type" /> {watchGoalType === "numeric" ? ( { return ( { 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" /> { return ( ) }} name="goal.target.unit" /> ) : null} { return ( { onChange(value.hex) }} > ) }} name="color" /> { return ( ) }} name="icon" /> ✅ Habit created successfully! ) } const styles = StyleSheet.create({ spacing: { marginVertical: 10, }, })