feat: add basic habit create form

This commit is contained in:
Xc165543337 2024-04-04 17:06:42 +02:00
parent f17c7d6e11
commit 6c95386666
3 changed files with 225 additions and 5 deletions

87
package-lock.json generated
View File

@ -29,12 +29,15 @@
"react-native": "0.73.6",
"react-native-calendars": "1.1304.1",
"react-native-elements": "3.4.3",
"react-native-gesture-handler": "2.16.0",
"react-native-paper": "5.12.3",
"react-native-reanimated": "~3.6.2",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "3.29.0",
"react-native-url-polyfill": "2.0.0",
"react-native-vector-icons": "10.0.3",
"react-native-web": "0.19.10",
"reanimated-color-picker": "3.0.3",
"zod": "3.22.4"
},
"devDependencies": {
@ -1451,6 +1454,20 @@
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-object-assign": {
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.24.1.tgz",
"integrity": "sha512-I1kctor9iKtupb7jv7FyjApHCuKLBKCblVAeHVK9PB6FW7GI0ac6RtobC3MwwJy8CZ1JxuhQmnbrsqI5G8hAIg==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz",
@ -2453,6 +2470,17 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@egjs/hammerjs": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
"dependencies": {
"@types/hammerjs": "^2.0.36"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@ -8071,6 +8099,11 @@
"@types/node": "*"
}
},
"node_modules/@types/hammerjs": {
"version": "2.0.45",
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.45.tgz",
"integrity": "sha512-qkcUlZmX6c4J8q45taBKTL3p+LbITgyx7qhlPYOdOHZB7B31K0mXbP5YA7i7SgDeEGuI9MnumiKPEMrxg8j3KQ=="
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@ -20246,6 +20279,22 @@
"color-string": "^1.6.0"
}
},
"node_modules/react-native-gesture-handler": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.16.0.tgz",
"integrity": "sha512-1hFkx7RIfeJSyTQQ0Nkv4icFVZ5+XjQkd47OgZMBFzoB7ecL+nFSz8KLi3OCWOhq+nbHpSPlSG5VF3CQNCJpWA==",
"dependencies": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
"invariant": "^2.2.4",
"lodash": "^4.17.21",
"prop-types": "^15.7.2"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-paper": {
"version": "5.12.3",
"resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.12.3.tgz",
@ -20283,6 +20332,27 @@
"react-native": "*"
}
},
"node_modules/react-native-reanimated": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.3.tgz",
"integrity": "sha512-2KkkPozoIvDbJcHuf8qeyoLROXQxizSi+2CTCkuNVkVZOxxY4B0Omvgq61aOQhSZUh/649x1YHoAaTyGMGDJUw==",
"dependencies": {
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"convert-source-map": "^2.0.0",
"invariant": "^2.2.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0-0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0-0",
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
"@babel/plugin-transform-shorthand-properties": "^7.0.0-0",
"@babel/plugin-transform-template-literals": "^7.0.0-0",
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-safe-area-context": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.8.2.tgz",
@ -20776,6 +20846,23 @@
"resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz",
"integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg=="
},
"node_modules/reanimated-color-picker": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/reanimated-color-picker/-/reanimated-color-picker-3.0.3.tgz",
"integrity": "sha512-zSYIr+cGpIt5m3eIhlr2aLxJjnrI43HzQiO3fwTQpSfAKG23SDfmO3IX/Z+EbHr2tcxCtU3vkqqThEvyQ8el1Q==",
"peerDependencies": {
"expo": ">=44.0.0",
"react": "*",
"react-native": "*",
"react-native-gesture-handler": ">=2.0.0",
"react-native-reanimated": "^2.0.0 || ^3.0.0"
},
"peerDependenciesMeta": {
"expo": {
"optional": true
}
}
},
"node_modules/recast": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.21.5.tgz",

View File

@ -39,12 +39,15 @@
"react-native": "0.73.6",
"react-native-calendars": "1.1304.1",
"react-native-elements": "3.4.3",
"react-native-gesture-handler": "2.16.0",
"react-native-paper": "5.12.3",
"react-native-reanimated": "~3.6.2",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "3.29.0",
"react-native-url-polyfill": "2.0.0",
"react-native-vector-icons": "10.0.3",
"react-native-web": "0.19.10",
"reanimated-color-picker": "3.0.3",
"zod": "3.22.4"
},
"devDependencies": {

View File

@ -1,8 +1,15 @@
import { useForm } from "react-hook-form"
import { Appbar } from "react-native-paper"
import { zodResolver } from "@hookform/resolvers/zod"
import { Controller, useForm } from "react-hook-form"
import { Appbar, Button, HelperText, TextInput } from "react-native-paper"
import { SafeAreaView } from "react-native-safe-area-context"
import ColorPicker, {
HueSlider,
Panel1,
Preview,
} from "reanimated-color-picker"
import type { HabitCreateData } from "@/domain/entities/Habit"
import { HabitCreateSchema } from "@/domain/entities/Habit"
import type { User } from "@/domain/entities/User"
export interface HabitCreateFormProps {
@ -10,8 +17,20 @@ export interface HabitCreateFormProps {
}
export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
useForm<HabitCreateData>({
// const { control, handleSubmit, setValue } = useForm<HabitCreateData>({
// const {createHabit, habitPresenter} = useHabitCreate()
const onSubmit = async (data: HabitCreateData): Promise<void> => {
// await habitPresenter.createHabit(data)
console.log(data)
}
const {
control,
handleSubmit,
formState: { errors },
} = useForm<HabitCreateData>({
mode: "onChange",
resolver: zodResolver(HabitCreateSchema),
defaultValues: {
userId: user.id,
name: "",
@ -37,7 +56,118 @@ export const HabitCreateForm: React.FC<HabitCreateFormProps> = ({ user }) => {
}}
/>
</Appbar.Header>
{/* <Controller></Controller> */}
<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}
render={({ field: { onChange, onBlur, value } }) => {
return (
<TextInput
placeholder="Goal Frequency"
onBlur={onBlur}
onChangeText={onChange}
value={value}
style={[styles.input]}
mode="outlined"
/>
)
}}
name="goal.frequency"
/>
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => {
return (
<TextInput
placeholder="Goal Target Type"
onBlur={onBlur}
onChangeText={onChange}
value={value}
style={[styles.input]}
mode="outlined"
/>
)
}}
name="goal.target.type"
/>
<Button
mode="contained"
onPress={handleSubmit(onSubmit)}
// loading={createHabit.state === "loading"}
// disabled={createHabit.state === "loading"}
>
Create your habit
</Button>
</SafeAreaView>
)
}
const styles = {
input: {
margin: 8,
},
}