From 6c9538666689854ff3ea11fa80061da15fdc7f45 Mon Sep 17 00:00:00 2001 From: Xc165543337 <90028194+Xc165543337@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:06:42 +0200 Subject: [PATCH] feat: add basic habit create form --- package-lock.json | 87 +++++++++++ package.json | 3 + .../HabitCreateForm/HabitCreateForm.tsx | 140 +++++++++++++++++- 3 files changed, 225 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4d370d..cf86dd1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index ed65cbd..27975e6 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/presentation/react/components/HabitCreateForm/HabitCreateForm.tsx b/presentation/react/components/HabitCreateForm/HabitCreateForm.tsx index e588ebc..43a6f02 100644 --- a/presentation/react/components/HabitCreateForm/HabitCreateForm.tsx +++ b/presentation/react/components/HabitCreateForm/HabitCreateForm.tsx @@ -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 = ({ user }) => { - useForm({ - // const { control, handleSubmit, setValue } = useForm({ + // const {createHabit, habitPresenter} = useHabitCreate() + + const onSubmit = async (data: HabitCreateData): Promise => { + // await habitPresenter.createHabit(data) + console.log(data) + } + + const { + control, + handleSubmit, + formState: { errors }, + } = useForm({ + mode: "onChange", + resolver: zodResolver(HabitCreateSchema), defaultValues: { userId: user.id, name: "", @@ -37,7 +56,118 @@ export const HabitCreateForm: React.FC = ({ user }) => { }} /> - {/* */} + + { + return ( + <> + + {errors.name != null ? ( + + {errors.name.type === "too_big" + ? "Name is too long" + : "Name is required"} + + ) : null} + + ) + }} + name="name" + /> + + { + return ( + { + onChange(value.hex) + }} + > + + + + + ) + }} + name="color" + /> + + { + return ( + + ) + }} + name="icon" + /> + + { + return ( + + ) + }} + name="goal.frequency" + /> + + { + return ( + + ) + }} + name="goal.target.type" + /> + + ) } + +const styles = { + input: { + margin: 8, + }, +}