- editorStore.setEditor({ content: value, contentLength: length })
- }
+ content={formContext.getValues("informationContent")}
+ onChange={(value: string, length: number) => {
+ formContext.setValue("informationContent", value);
+ formContext.setValue("contentLength", length);
+ formContext.trigger("informationContent");
+ }}
/>
- {editorStore.contentLength}/500
+ {formContext.getValues("contentLength")}/500
diff --git a/src/containers/informations/write/CategoryModalContainer.tsx b/src/containers/informations/write/CategoryModalContainer.tsx
index 5a01caf1..48c6a5e3 100644
--- a/src/containers/informations/write/CategoryModalContainer.tsx
+++ b/src/containers/informations/write/CategoryModalContainer.tsx
@@ -4,6 +4,7 @@ import CategoryModal from "@/components/informations/write/CategoryModal";
import useEditorStore from "@/store/editorStore";
import { CategoryResponseDto } from "@/types/CategoryDto";
import { useEffect, useState } from "react";
+import { useFormContext } from "react-hook-form";
interface Props {
closeModal: () => void;
@@ -12,26 +13,25 @@ interface Props {
const CategoryModalContainer = ({ closeModal }: Props) => {
const [parentCategory, setParentCategory] = useState(0);
const [categories, setCategories] = useState();
- const { categoryId, setEditor } = useEditorStore();
+ const formContext = useFormContext();
const setParentCategoryId = (parentCategoryId: number) => {
setParentCategory(parentCategoryId);
- setEditor({
- categoryId: 0,
- categoryName: "",
- });
+ formContext.setValue("categoryId", 0);
+ formContext.setValue("categoryName", "");
+ formContext.watch();
};
const setCategory = (categoryId: number, categoryName: string) => {
- setEditor({
- categoryId: categoryId,
- categoryName: categoryName,
- });
+ formContext.setValue("categoryId", categoryId);
+ formContext.setValue("categoryName", categoryName);
+ formContext.trigger("categoryId");
};
const onCancel = () => {
setParentCategory(0);
- setEditor({ categoryId: 0 });
+ formContext.setValue("categoryId", 0);
+ formContext.trigger("categoryId");
closeModal();
};
@@ -58,7 +58,7 @@ const CategoryModalContainer = ({ closeModal }: Props) => {
{
@@ -23,6 +25,31 @@ const InformationEditorContainer = () => {
const router = useRouter();
const [loading, setLoading] = useState(false);
+ const methods = useForm({
+ resolver: zodResolver(InformationCreateFormSchema),
+ defaultValues: {
+ userId: id,
+ informationTitle: "",
+ informationAddress: "",
+ province: "",
+ city: "",
+ placeId: "",
+ placeXAxis: "",
+ placeYAxis: "",
+ placeName: "",
+ categoryId: 0,
+ categoryName: "",
+ thumbnailImageUrl: "",
+ contentImagesUrl: [""],
+ mainImageIndex: 0,
+ informationContent: "",
+ contentLength: 0,
+ hashtags: [],
+ tips: [""],
+ },
+ mode: "onChange",
+ });
+
// 장소 선택 모달창이 보이는지 여부
const [locationModal, setLocationModal] = useState(false);
@@ -30,7 +57,14 @@ const InformationEditorContainer = () => {
const [categoryModal, setCategoryModal] = useState(false);
const showLocationModal = () => {
- editorStore.resetPlaceInfo();
+ methods.setValue("province", "");
+ methods.setValue("city", "");
+ methods.setValue("informationAddress", "");
+ methods.setValue("placeId", "");
+ methods.setValue("placeXAxis", "");
+ methods.setValue("placeYAxis", "");
+ methods.setValue("placeName", "");
+ methods.watch();
setLocationModal(true);
};
@@ -39,7 +73,7 @@ const InformationEditorContainer = () => {
};
const showCategoryModal = () => {
- editorStore.setEditor({ categoryId: 0 });
+ methods.setValue("categoryId", 0);
setCategoryModal(true);
};
@@ -60,76 +94,78 @@ const InformationEditorContainer = () => {
};
const onSubmit = async () => {
- // Validate from fields using Zod
- const validatedFields = InformationCreateFormSchema.safeParse({
- userId: id,
- informationTitle: editorStore.title,
- informationAddress: editorStore.address,
- province: editorStore.province,
- city: editorStore.city,
- placeId: editorStore.placeId,
- placeXAxis: editorStore.placeXAxis,
- placeYAxis: editorStore.placeYAxis,
- placeName: editorStore.placeName,
- categoryId: editorStore.categoryId,
- thumbnailImageUrl: editorStore.images[editorStore.mainImageIndex],
- contentImagesUrl: editorStore.images.filter(
- (url, index) => index !== editorStore.mainImageIndex && url !== "",
- ),
- informationContent: sanitizeHtml(editorStore.content, sanitizeOption),
- hashtags: editorStore.hashtags,
- tips: editorStore.tips,
- });
-
- // If validation fails, return errors early. Otherwise, continue.
- if (!validatedFields.success) {
- console.log(validatedFields.error.issues);
- alert(validatedFields.error.issues[0].message);
- return;
- }
-
- const data: CreateInformationRequestDto = {
- informationTitle: validatedFields.data.informationTitle,
- informationAddress: validatedFields.data.informationAddress,
- informationContent: validatedFields.data.informationContent,
- informationTips: validatedFields.data.tips.join(";"),
- placeRegisterRequest: {
- searchId: validatedFields.data.placeId,
- name: validatedFields.data.placeName,
- xAxis: validatedFields.data.placeXAxis,
- yAxis: validatedFields.data.placeYAxis,
- address: validatedFields.data.informationAddress,
- },
- categoryId: validatedFields.data.categoryId,
- zoneCategoryNameParent: validatedFields.data.province,
- zoneCategoryNameChild: validatedFields.data.city,
- thumbNailImageUrl: validatedFields.data.thumbnailImageUrl,
- contentImagesUrl: validatedFields.data.contentImagesUrl,
- tagRegisterRequests: validatedFields.data.hashtags.map((tag) => ({
- name: tag,
- })),
- };
-
- setLoading(true);
-
- const response = await fetch("/api/informations", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(data),
- cache: "no-store",
- });
-
- if (!response.ok) {
- alert("정보 등록에 실패하였습니다.");
- setLoading(false);
- throw new Error(response.statusText);
- }
-
- const result: InformationRegisterResponseDto = await response.json();
- router.push(`/informations/${result.id}`);
- router.refresh();
+ alert("테스트");
+
+ // // Validate from fields using Zod
+ // const validatedFields = InformationCreateFormSchema.safeParse({
+ // userId: id,
+ // informationTitle: editorStore.title,
+ // informationAddress: editorStore.address,
+ // province: editorStore.province,
+ // city: editorStore.city,
+ // placeId: editorStore.placeId,
+ // placeXAxis: editorStore.placeXAxis,
+ // placeYAxis: editorStore.placeYAxis,
+ // placeName: editorStore.placeName,
+ // categoryId: editorStore.categoryId,
+ // thumbnailImageUrl: editorStore.images[editorStore.mainImageIndex],
+ // contentImagesUrl: editorStore.images.filter(
+ // (url, index) => index !== editorStore.mainImageIndex && url !== "",
+ // ),
+ // informationContent: sanitizeHtml(editorStore.content, sanitizeOption),
+ // hashtags: editorStore.hashtags,
+ // tips: editorStore.tips,
+ // });
+
+ // // If validation fails, return errors early. Otherwise, continue.
+ // if (!validatedFields.success) {
+ // console.log(validatedFields.error.issues);
+ // alert(validatedFields.error.issues[0].message);
+ // return;
+ // }
+
+ // const data: CreateInformationRequestDto = {
+ // informationTitle: validatedFields.data.informationTitle,
+ // informationAddress: validatedFields.data.informationAddress,
+ // informationContent: validatedFields.data.informationContent,
+ // informationTips: validatedFields.data.tips.join(";"),
+ // placeRegisterRequest: {
+ // searchId: validatedFields.data.placeId,
+ // name: validatedFields.data.placeName,
+ // xAxis: validatedFields.data.placeXAxis,
+ // yAxis: validatedFields.data.placeYAxis,
+ // address: validatedFields.data.informationAddress,
+ // },
+ // categoryId: validatedFields.data.categoryId,
+ // zoneCategoryNameParent: validatedFields.data.province,
+ // zoneCategoryNameChild: validatedFields.data.city,
+ // thumbNailImageUrl: validatedFields.data.thumbnailImageUrl,
+ // contentImagesUrl: validatedFields.data.contentImagesUrl,
+ // tagRegisterRequests: validatedFields.data.hashtags.map((tag) => ({
+ // name: tag,
+ // })),
+ // };
+
+ // setLoading(true);
+
+ // const response = await fetch("/api/informations", {
+ // method: "POST",
+ // headers: {
+ // "Content-Type": "application/json",
+ // },
+ // body: JSON.stringify(data),
+ // cache: "no-store",
+ // });
+
+ // if (!response.ok) {
+ // alert("정보 등록에 실패하였습니다.");
+ // setLoading(false);
+ // throw new Error(response.statusText);
+ // }
+
+ // const result: InformationRegisterResponseDto = await response.json();
+ // router.push(`/informations/${result.id}`);
+ // router.refresh();
};
// 로그인을 하지 않은 사용자의 경우 로그인 페이지로 리다이렉트.
@@ -148,21 +184,23 @@ const InformationEditorContainer = () => {
}, [initialize]);
return (
-
+
+
+
);
};
diff --git a/src/containers/informations/write/PlaceModalContainer.tsx b/src/containers/informations/write/PlaceModalContainer.tsx
index 2d5432ef..8a8c04f1 100644
--- a/src/containers/informations/write/PlaceModalContainer.tsx
+++ b/src/containers/informations/write/PlaceModalContainer.tsx
@@ -3,6 +3,7 @@
import PlaceModal from "@/components/informations/write/PlaceModal";
import useEditorStore from "@/store/editorStore";
import { useEffect, useState } from "react";
+import { useFormContext } from "react-hook-form";
import { useDebouncedCallback } from "use-debounce";
interface Props {
@@ -10,8 +11,9 @@ interface Props {
}
const PlaceModalContainer = ({ closeModal }: Props) => {
- const { address, placeName, placeId, setEditor, resetPlaceInfo } =
- useEditorStore();
+ const formContext = useFormContext();
+ // const { address, placeName, placeId, setEditor, resetPlaceInfo } =
+ // useEditorStore();
const [isCustom, setIsCustom] = useState(false);
// 장소 검색 객체 (place search)
@@ -61,7 +63,14 @@ const PlaceModalContainer = ({ closeModal }: Props) => {
}, 300);
const onResetPlace = () => {
- resetPlaceInfo();
+ formContext.setValue("province", "");
+ formContext.setValue("city", "");
+ formContext.setValue("informationAddress", "");
+ formContext.setValue("placeId", "");
+ formContext.setValue("placeXAxis", "");
+ formContext.setValue("placeYAxis", "");
+ formContext.setValue("placeName", "");
+ formContext.trigger("placeName");
closeModal();
};
@@ -73,15 +82,14 @@ const PlaceModalContainer = ({ closeModal }: Props) => {
y: string;
}) => {
const temp = placeInfo.address_name.split(" ");
- setEditor({
- province: temp[0].slice(0, 2) ?? "",
- city: temp[1] ?? "",
- address: placeInfo.address_name,
- placeId: placeInfo.id,
- placeXAxis: placeInfo.x,
- placeYAxis: placeInfo.y,
- placeName: placeInfo.place_name,
- });
+ formContext.setValue("province", temp[0].slice(0, 2) ?? "");
+ formContext.setValue("city", temp[1] ?? "");
+ formContext.setValue("informationAddress", placeInfo.address_name);
+ formContext.setValue("placeId", placeInfo.id);
+ formContext.setValue("placeXAxis", placeInfo.x);
+ formContext.setValue("placeYAxis", placeInfo.y);
+ formContext.setValue("placeName", placeInfo.place_name);
+ formContext.watch();
closeModal();
};
@@ -91,18 +99,18 @@ const PlaceModalContainer = ({ closeModal }: Props) => {
y: string;
}) => {
const temp = addressInfo.address_name.split(" ");
- setEditor({
- province: temp[0].slice(0, 2) ?? "",
- city: temp[1] ?? "",
- address: addressInfo.address_name,
- placeXAxis: addressInfo.x,
- placeYAxis: addressInfo.y,
- placeId: "0",
- });
+ formContext.setValue("province", temp[0].slice(0, 2) ?? "");
+ formContext.setValue("city", temp[1] ?? "");
+ formContext.setValue("informationAddress", addressInfo.address_name);
+ formContext.setValue("placeXAxis", addressInfo.x);
+ formContext.setValue("placeYAxis", addressInfo.y);
+ formContext.setValue("placeId", "0");
+ formContext.watch();
};
const onChangeCustomPlaceName = (placeName: string) => {
- setEditor({ placeName: placeName });
+ formContext.setValue("placeName", placeName);
+ formContext.trigger("placeName");
};
const onClick = (isCustom: boolean) => {
@@ -128,8 +136,11 @@ const PlaceModalContainer = ({ closeModal }: Props) => {
handleLocationSearch={handleLocationSearch}
handleAddressSearch={handleAddressSearch}
isCustom={isCustom}
- canTypePlaceName={placeId === "0"}
- canRegister={address !== "" && placeName !== ""}
+ canTypePlaceName={formContext.getValues("placeId") === "0"}
+ canRegister={
+ formContext.getValues("informationAddress") !== "" &&
+ formContext.getValues("placeName") !== ""
+ }
onClick={onClick}
onResetPlace={onResetPlace}
onChangePlace={onChangePlace}
diff --git a/src/lib/zod/schema/InformationCreateFormSchema.ts b/src/lib/zod/schema/InformationCreateFormSchema.ts
index 4922e1c2..9e92a308 100644
--- a/src/lib/zod/schema/InformationCreateFormSchema.ts
+++ b/src/lib/zod/schema/InformationCreateFormSchema.ts
@@ -82,7 +82,6 @@ export const InformationCreateFormSchema = z.object({
required_error: "Content is required.",
invalid_type_error: "Content must be a string.",
})
- .min(1, { message: "내용을 입력해 주세요." })
.max(500, { message: "Must be 500 or fewer characters long" }),
hashtags: z
.string({