Skip to content

Commit

Permalink
Merge pull request #273 from TripInfoWeb/dev_informations
Browse files Browse the repository at this point in the history
Feat: 정보 수정 기능
  • Loading branch information
HyunJinNo authored Sep 7, 2024
2 parents aee60fb + ee9f77b commit dd28b1a
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/components/diary/write/DiaryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ const DiaryEditor = ({
</button>
{formContext.formState.errors.address && (
<p className="absolute -bottom-6 left-16 mt-1 text-xs text-red-500">
주소를 입력해 주세요.
모든 날짜의 주소를 입력해 주세요.
</p>
)}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/containers/diary/write/AddressModalContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const AddressModalContainer = ({ closeModal }: Props) => {
const addressList: string[] = formContext.getValues("address");
addressList[index] = "";
formContext.setValue("address", addressList);
formContext.trigger();
formContext.trigger("address");
closeModal();
};

Expand All @@ -48,7 +48,7 @@ const AddressModalContainer = ({ closeModal }: Props) => {
const addressList: string[] = formContext.getValues("address");
addressList[index] = placeInfo.address_name;
formContext.setValue("address", addressList);
formContext.trigger();
formContext.trigger("address");
closeModal();
};

Expand Down
19 changes: 14 additions & 5 deletions src/containers/diary/write/DiaryEditorContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,22 @@ const DiaryEditorContainer = () => {
const [addressModal, setAddressModal] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);

const methods = useForm({
const methods = useForm<{
userId: number;
title: string;
startDate: Date | null;
endDate: Date | null;
address: string[];
image: string;
moodLevels: number[];
contents: string[];
}>({
resolver: zodResolver(DiaryCreateFormSchema),
defaultValues: {
userId: authStore.id,
title: "",
startDate: new Date(),
endDate: new Date(),
startDate: null,
endDate: null,
address: [""],
image: "",
moodLevels: [],
Expand Down Expand Up @@ -61,8 +70,8 @@ const DiaryEditorContainer = () => {
const data: CreateDiaryRequestDto = {
title: title,
titleImage: image,
startDatetime: startDate,
endDatetime: endDate,
startDatetime: startDate!,
endDatetime: endDate!,
diaryDayRequests: Array.from(
{ length: diaryEditorStore.days },
(_, index) => ({
Expand Down
2 changes: 1 addition & 1 deletion src/containers/diary/write/QuillEditorContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const QuillEditorContainer = () => {
const contents: string[] = formContext.getValues("contents");
contents[diaryEditorStore.currentDay - 1] = value;
formContext.setValue("contents", contents);
formContext.trigger();
formContext.trigger("contents");
}}
/>
);
Expand Down
158 changes: 103 additions & 55 deletions src/containers/informations/edit/InformationEditorContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,28 @@ const InformationEditorContainer = ({ informationId, data }: Props) => {
const [originalThumbnailUrl, setOriginalThumbnailUrl] = useState<string>("");
const [originalContentUrl, setOriginalContentUrl] = useState<string[]>([]);

const methods = useForm({
const methods = useForm<{
userId: number;
informationTitle: string;
informationAddress: string;
province: string;
city: string;
placeId: string;
placeXAxis: string;
placeYAxis: string;
placeName: string;
categoryId: number;
categoryName: string;
newThumbNailUrl: string | null;
newThumbNailFromContent: string | null;
moveThumbNailToContent: string | null;
newContentImagesUrl: string[];
deleteImagesUrl: string[];
informationContent: string;
contentLength: number;
hashtags: string[];
tips: string[];
}>({
resolver: zodResolver(InformationUpdateFormSchema),
defaultValues: {
userId: id,
Expand All @@ -47,9 +68,9 @@ const InformationEditorContainer = ({ informationId, data }: Props) => {
placeName: "",
categoryId: 0,
categoryName: "",
newThumbNailUrl: "",
newThumbNailFromContent: "",
moveThumbNailToContent: "",
newThumbNailUrl: null,
newThumbNailFromContent: null,
moveThumbNailToContent: null,
newContentImagesUrl: Array<string>(0),
deleteImagesUrl: Array<string>(0),
informationContent: "",
Expand Down Expand Up @@ -121,19 +142,19 @@ const InformationEditorContainer = ({ informationId, data }: Props) => {

// 썸네일 이미지가 변경되지 않은 경우
if (originalThumbnailUrl === thumbnailUrl) {
methods.setValue("newThumbNailUrl", "");
methods.setValue("newThumbNailFromContent", "");
methods.setValue("moveThumbNailToContent", "");
methods.setValue("newThumbNailUrl", null);
methods.setValue("newThumbNailFromContent", null);
methods.setValue("moveThumbNailToContent", null);
} else {
// 기존 본문 이미지가 썸네일 이미지로 변경되는 경우
if (originalContentUrl.includes(thumbnailUrl)) {
methods.setValue("newThumbNailUrl", "");
methods.setValue("newThumbNailUrl", null);
methods.setValue("newThumbNailFromContent", thumbnailUrl);
}
// 새로운 썸네일 이미지를 사용하는 경우
else {
methods.setValue("newThumbNailUrl", thumbnailUrl);
methods.setValue("newThumbNailFromContent", "");
methods.setValue("newThumbNailFromContent", null);
}

// 기존 썸네일 이미지가 본문으로 이동하는 경우
Expand All @@ -142,7 +163,7 @@ const InformationEditorContainer = ({ informationId, data }: Props) => {
}
// 기존 썸네일 이미지를 삭제하는 경우
else {
methods.setValue("moveThumbNailToContent", "");
methods.setValue("moveThumbNailToContent", null);
}
}

Expand All @@ -169,51 +190,78 @@ const InformationEditorContainer = ({ informationId, data }: Props) => {
return;
}

alert("정보 수정 API 연동 예정");

// const data: UpdateInformationRequestDto = {
// title: validatedFields.data.informationTitle,
// address: validatedFields.data.informationAddress,
// content: validatedFields.data.informationContent,
// tips: validatedFields.data.tips.join(";"),
// placeModifyRequest: {
// 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,
// deleteImages: deletedImages,
// thumbNailUrl: validatedFields.data.thumbnailImageUrl,
// contentImagesUrl: validatedFields.data.contentImagesUrl,
// tagRegisterRequests: validatedFields.data.hashtags.map((tag) => ({
// name: tag,
// })),
// };

// setLoading(true);

// const response = await fetch(`/api/informations/${informationId}`, {
// method: "PUT",
// 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();
const {
informationTitle,
informationAddress,
informationContent,
tips,
placeId,
placeName,
placeXAxis,
placeYAxis,
categoryId,
province,
city,
newThumbNailUrl,
newThumbNailFromContent,
moveThumbNailToContent,
newContentImagesUrl,
deleteImagesUrl,
hashtags,
} = methods.getValues();

const data: UpdateInformationRequestDto = {
title: informationTitle,
address: informationAddress,
content: informationContent,
tips: tips.join(";"),
placeModifyRequest: {
searchId: placeId,
name: placeName,
xAxis: placeXAxis,
yAxis: placeYAxis,
address: informationAddress,
},
categoryId: categoryId,
zoneCategoryNameParent: province,
zoneCategoryNameChild: city,
newThumbNailUrl:
newThumbNailUrl === null ? null : { address: newThumbNailUrl },
newThumbNailFromContent:
newThumbNailFromContent === null
? null
: { address: newThumbNailFromContent },
moveThumbNailToContent:
moveThumbNailToContent === null
? null
: { address: moveThumbNailToContent },
newContentImagesUrl: newContentImagesUrl.map((url) => ({ address: url })),
deleteImagesUrl: deleteImagesUrl.map((url) => ({ address: url })),
tagRegisterRequests: hashtags.map((tag) => ({
name: tag,
})),
};

setLoading(true);

const response = await fetch(`/api/informations/${informationId}`, {
method: "PUT",
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();
};

// 로그인을 하지 않은 사용자의 경우 로그인 페이지로 리다이렉트.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/zod/schema/InformationCreateFormSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const InformationCreateFormSchema = z.object({
invalid_type_error: "Address must be a string.",
})
.min(1, { message: "장소를 입력해 주세요." })
.max(20, { message: "장소 길이는 20자 이하여야 합니다." }),
.max(50, { message: "장소 길이는 50자 이하여야 합니다." }),
province: z
.string({
required_error: "Province is required.",
Expand Down
32 changes: 19 additions & 13 deletions src/lib/zod/schema/InformationUpdateFormSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const InformationUpdateFormSchema = z.object({
invalid_type_error: "Address must be a string.",
})
.min(1, { message: "장소를 입력해 주세요." })
.max(20, { message: "장소 길이는 20자 이하여야 합니다." }),
.max(50, { message: "장소 길이는 50자 이하여야 합니다." }),
province: z
.string({
required_error: "Province is required.",
Expand Down Expand Up @@ -65,18 +65,24 @@ export const InformationUpdateFormSchema = z.object({
})
.int()
.positive({ message: "카테고리를 선택해 주세요." }),
newThumbNailUrl: z.string({
required_error: "newThumbNailUrl is required.",
invalid_type_error: "newThumbNailUrl must be a string.",
}),
newThumbNailFromContent: z.string({
required_error: "newThumbNailFromContent is required.",
invalid_type_error: "newThumbNailFromContent must be a string.",
}),
moveThumbNailToContent: z.string({
required_error: "moveThumbNailToContent is required.",
invalid_type_error: "moveThumbNailToContent must be a string.",
}),
newThumbNailUrl: z
.string({
required_error: "newThumbNailUrl is required.",
invalid_type_error: "newThumbNailUrl must be a string.",
})
.nullable(),
newThumbNailFromContent: z
.string({
required_error: "newThumbNailFromContent is required.",
invalid_type_error: "newThumbNailFromContent must be a string.",
})
.nullable(),
moveThumbNailToContent: z
.string({
required_error: "moveThumbNailToContent is required.",
invalid_type_error: "moveThumbNailToContent must be a string.",
})
.nullable(),
newContentImagesUrl: z
.string({
required_error: "newContentImagesUrl is required.",
Expand Down
8 changes: 5 additions & 3 deletions src/types/InformationDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export interface UpdateInformationRequestDto {
categoryId: number;
zoneCategoryNameParent: string;
zoneCategoryNameChild: string;
deleteImages: { address: string }[];
thumbNailUrl: string;
contentImagesUrl: string[];
newThumbNailUrl: { address: string } | null;
newThumbNailFromContent: { address: string } | null;
moveThumbNailToContent: { address: string } | null;
newContentImagesUrl: { address: string }[];
deleteImagesUrl: { address: string }[];
tagRegisterRequests: { name: string }[];
}

Expand Down

0 comments on commit dd28b1a

Please sign in to comment.