diff --git a/package-lock.json b/package-lock.json
index 17295683..39c6eae2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
+ "@hookform/resolvers": "^5.0.1",
"axios": "^1.9.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
@@ -19,8 +20,10 @@
"react-calendar": "^5.1.0",
"react-dom": "^19.0.0",
"react-error-boundary": "^6.0.0",
+ "react-hook-form": "^7.56.4",
"react-intersection-observer": "^9.16.0",
- "react-toastify": "^11.0.5"
+ "react-toastify": "^11.0.5",
+ "zod": "^3.25.41"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
@@ -2048,6 +2051,18 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@hookform/resolvers": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.0.1.tgz",
+ "integrity": "sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/utils": "^0.3.0"
+ },
+ "peerDependencies": {
+ "react-hook-form": "^7.55.0"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -2774,6 +2789,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@standard-schema/utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
+ "license": "MIT"
+ },
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
@@ -8181,6 +8202,22 @@
"react": ">=16.13.1"
}
},
+ "node_modules/react-hook-form": {
+ "version": "7.56.4",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.4.tgz",
+ "integrity": "sha512-Rob7Ftz2vyZ/ZGsQZPaRdIefkgOSrQSPXfqBdvOPwJfoGnjwRJUs7EM7Kc1mcoDv3NOtqBzPGbcMB8CGn9CKgw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
"node_modules/react-intersection-observer": {
"version": "9.16.0",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz",
@@ -9718,6 +9755,15 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zod": {
+ "version": "3.25.41",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.41.tgz",
+ "integrity": "sha512-8+sDJTGtCYIDBhdqDygp0ffj8kzziRKqAJPhpYObbElJ+3TRe/mnlnwH+/OMa3kKhueS4Drm5UMW00/u1p07zA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
diff --git a/package.json b/package.json
index fe185f42..53b9ef08 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
+ "@hookform/resolvers": "^5.0.1",
"axios": "^1.9.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
@@ -20,8 +21,10 @@
"react-calendar": "^5.1.0",
"react-dom": "^19.0.0",
"react-error-boundary": "^6.0.0",
+ "react-hook-form": "^7.56.4",
"react-intersection-observer": "^9.16.0",
- "react-toastify": "^11.0.5"
+ "react-toastify": "^11.0.5",
+ "zod": "^3.25.41"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
diff --git a/src/components/common/formField/Fields.tsx b/src/components/common/formField/Fields.tsx
new file mode 100644
index 00000000..94b82820
--- /dev/null
+++ b/src/components/common/formField/Fields.tsx
@@ -0,0 +1,32 @@
+'use client';
+
+import clsx from 'clsx';
+import { GAP_SIZE, LABEL_SIZE } from './style';
+import { FieldProps } from './type';
+
+export default function Fields({
+ label,
+ required,
+ errorMessage,
+ gapSize = '12',
+ labelSize = '16/16',
+ render,
+}: FieldProps) {
+ const showError = !!errorMessage;
+
+ return (
+
+
+ {label && (
+
+ )}
+ {render()}
+
+
+ {showError &&
{errorMessage}}
+
+ );
+}
diff --git a/src/components/common/formField/compound/ImageUploader.tsx b/src/components/common/formField/compound/ImageUploader.tsx
index 30691c3f..4fef0de7 100644
--- a/src/components/common/formField/compound/ImageUploader.tsx
+++ b/src/components/common/formField/compound/ImageUploader.tsx
@@ -41,12 +41,12 @@ export default function ImageUploader({ imageUploaderType, image, inputRef }: Im