Repository: rak517/Epigram
Pull request #124: EP-83 에픽그램 생성 페이지 api 연결 & 해당 id로 페이지로 이동
Author: login: jaehyeongjung
Labels: name: Priority: High 🔥
description: 우선순위 높음
name: Type: API 📬
description: 서버 API 통신
name: Type: Feature ✨
description: 기능 개발
Created: 2025-03-24T09:19:46Z | Merged: 2025-03-25T06:50:09Z

## ❓이슈
- close #116 

## :writing_hand: Description

생성 페이지의 api 연결을 하고
추가적으로 해당 id로 이동하게 작성을 했습니다.
이 pr이 머지되면 수정페이지 작업도 완료를 해서 
제 아이디로 만들고 제가만든 에픽그램을 수정을 테스트 해보려고합니다.

--
성락님의 피드백 대로 실패시의 모달 컴포넌트 가져와서 
trycatch문에서 처리를 해 봤습니다.

 -  throw new Error('테스트용 강제 에러');를 던져서 확인한 결과입니다.
<img width="1095" alt="스크린샷 2025-03-25 오후 1 19 44" src="https://github.com/user-attachments/assets/7623d092-5929-497d-9de1-4e672fc01785" />



<!-- 어떤 내용의 PR인지 작성해주세요. (ex. 메인 페이지 레이아웃 작업) -->
<!-- ⚠️ PR에는 해당 PR의 제목에 해당하는 내용만 들어가 있어야 합니다!  -->

## :white_check_mark: Checklist

### PR

<!-- 작성중인 PR인 경우, Draft 모드로 생성해주세요. -->

- [x] Branch Convention 확인
  > `feat/*` 기능 구현, `fix/*` 버그 수정, `refactor/*` 개선
- [x] Base Branch 확인
- [x] 적절한 Label 지정
- [x] Assignee 및 Reviewer 지정

### Test

- [x] 로컬 작동 확인

### Additional Notes

<!-- 추가 사항이 있을 경우, Todo list를 작성해주세요. -->

- [x] (없음)


Linked issue #116: [EP-83] Feat: 에픽그램 만들기 페이지 최종 구현 (api연동)
### 🎟️ 상위 작업 (에픽 키)

EP-33

### 📝 상세 내용 (Description)

에픽그램 만들기 버튼 -> api연동


### ✅ 체크리스트 (Tasks)

- [ ] 만들기 버튼에  api연동 
- [ ] 버튼 누르면 해당 에피그램 상세페이지로 이동




### 📄 참고 자료

_No response_

Diff:
diff --git a/src/components/addEditForm/AddEpigramForm.tsx b/src/components/addEditForm/AddEpigramForm.tsx
index 5b454be1..a56d1766 100644
--- a/src/components/addEditForm/AddEpigramForm.tsx
+++ b/src/components/addEditForm/AddEpigramForm.tsx
@@ -10,8 +10,14 @@ import Author from './Author';
 import Input from '../ui/Field/Input';
 import TagInput from './Tags';
 import Button from '../ui/buttons';
+import { usePostEpigram } from '@/apis/epigram/queries';
+import { useRouter } from 'next/navigation';
+import { useModalStore } from '@/stores/ModalStore';
 
 export default function AddEpigramForm() {
+  const router = useRouter();
+  const { openModal } = useModalStore();
+
   const {
     handleSubmit,
     register,
@@ -27,12 +33,33 @@ export default function AddEpigramForm() {
     mode: 'onBlur',
   });
 
+  const { mutateAsync: postEpigram } = usePostEpigram();
+
   const handleTagChange = (newTag: string[]) => {
     setValue('tag', newTag, { shouldValidate: true });
   };
 
-  const onSubmit = (data: MakeEpigramForm) => {
-    console.log(data);
+  const onSubmit = async (data: MakeEpigramForm) => {
+    const epigramForm = {
+      content: data.content,
+      author: data.authorName || '',
+      referenceTitle: data.sourceTitle,
+      referenceUrl: data.sourceUrl,
+      tags: data.tag,
+    };
+
+    try {
+      const response = await postEpigram(epigramForm);
+      if (response?.id) {
+        router.push(`/epigrams/${response.id}`);
+      }
+    } catch (error) {
+      openModal({
+        type: 'alert',
+        title: '에피그램 생성 실패',
+        callback: () => console.error('에러 메시지:', error),
+      });
+    }
   };
 
   return (
diff --git a/tests/addEpigramForm.test.tsx b/tests/addEpigramForm.test.tsx
index 418d21a3..e906c7eb 100644
--- a/tests/addEpigramForm.test.tsx
+++ b/tests/addEpigramForm.test.tsx
@@ -2,6 +2,7 @@ import AddEpigramForm from '@/components/addEditForm/AddEpigramForm';
 // import { MakeEpigramApiRequest } from '@/types';
 import { fireEvent, render, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
 
 jest.mock('next/navigation', () => ({
   useRouter: () => ({
@@ -15,9 +16,26 @@ jest.mock('next/navigation', () => ({
 // }));
 
 describe('AddEpigram Component', () => {
+  const queryClient = new QueryClient({
+    defaultOptions: {
+      queries: {
+        retry: false,
+      },
+    },
+  });
+
+  // QueryClientProvider로 컴포넌트를 감싸는 함수
+  const renderWithQueryClient = () => {
+    return render(
+      <QueryClientProvider client={queryClient}>
+        <AddEpigramForm />
+      </QueryClientProvider>,
+    );
+  };
+
   beforeEach(() => {
     // mockCreateEpigram.mockClear();
-    render(<AddEpigramForm />);
+    renderWithQueryClient();
   });
 
   test('에피그램 추가폼을 불러온다', () => {


Reviews:
user: login: rak517
body: 테스트 코드 쪽에 뭔가 문제가 있는거 같습니다! 확인 한 번 부탁드립니다!
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-24T09:36:56Z
user: login: rak517
body: 보완하면 좋을거 같은 부분 리뷰 남겨놨습니다! 
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-24T11:43:28Z
user: login: rak517
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-24T11:48:18Z
user: login: jaehyeongjung
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T04:25:19Z
user: login: rak517
body: 고생하셨습니다! 승인눌러둘게요
state: APPROVED
author_association: OWNER
submitted_at: 2025-03-25T04:54:26Z
user: login: CJewon
body: 문제되거나 수정해야하는 부분은 없어보입니다 ! 고생하셨습니다 !
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-25T06:37:34Z
user: login: jaehyeongjung
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T06:46:02Z
user: login: jaehyeongjung
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T06:48:56Z
user: login: CJewon
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T06:58:28Z

Review comments:
diff_hunk: @@ -28,12 +31,31 @@ export default function AddEpigramForm() {
     mode: 'onBlur',
   });
 
+  const { mutate: postEpigram } = usePostEpigram();
+
   const handleTagChange = (newTag: string[]) => {
     setValue('tag', newTag, { shouldValidate: true });
   };
 
   const onSubmit = (data: MakeEpigramForm) => {
-    console.log(data);
+    const epigramForm = {
+      content: data.content,
+      author: data.authorName || '',
+      referenceTitle: data.sourceTitle,
+      referenceUrl: data.sourceUrl,
+      tags: data.tag,
+    };
+
+    postEpigram(epigramForm, {
+      onSuccess: (response) => {
+        if (response && response.id) {
+          router.push(`/epigrams/${response.id}`);
+        }
+      },
+      onError: (error) => {
+        console.error('에피그램 생성 실패:', error);
+      },
+    });
path: src/components/addEditForm/AddEpigramForm.tsx
user: login: rak517
body: try catch 문 안에서 작성하고

```
catch (error) {
  openModal({
    type: 'alert',
    title: '에피그램 생성 실패',
    callback: () => getErrorMessage(err),
  });
}
```
이런 식으로 에러처리해줘도 좋을거 같습니다!
created_at: 2025-03-24T11:40:25Z
author_association: OWNER
diff_hunk: @@ -28,12 +31,31 @@ export default function AddEpigramForm() {
     mode: 'onBlur',
   });
 
+  const { mutate: postEpigram } = usePostEpigram();
+
   const handleTagChange = (newTag: string[]) => {
     setValue('tag', newTag, { shouldValidate: true });
   };
 
   const onSubmit = (data: MakeEpigramForm) => {
-    console.log(data);
+    const epigramForm = {
+      content: data.content,
+      author: data.authorName || '',
+      referenceTitle: data.sourceTitle,
+      referenceUrl: data.sourceUrl,
+      tags: data.tag,
+    };
+
+    postEpigram(epigramForm, {
+      onSuccess: (response) => {
+        if (response && response.id) {
+          router.push(`/epigrams/${response.id}`);
+        }
+      },
+      onError: (error) => {
+        console.error('에피그램 생성 실패:', error);
+      },
+    });
path: src/components/addEditForm/AddEpigramForm.tsx
user: login: rak517
body: try/cacth를 안쓴다면 onError 에서 모달열어서 실패 케이스 처리해도 좋을거 같아용
```
onError: (error) => openModal({
  type: 'alert',
  title: '에피그램 생성 실패',
  callback: () => getErrorMessage(error)
})
```
created_at: 2025-03-24T11:45:15Z
author_association: OWNER
diff_hunk: @@ -28,12 +31,31 @@ export default function AddEpigramForm() {
     mode: 'onBlur',
   });
 
+  const { mutate: postEpigram } = usePostEpigram();
+
   const handleTagChange = (newTag: string[]) => {
     setValue('tag', newTag, { shouldValidate: true });
   };
 
   const onSubmit = (data: MakeEpigramForm) => {
-    console.log(data);
+    const epigramForm = {
+      content: data.content,
+      author: data.authorName || '',
+      referenceTitle: data.sourceTitle,
+      referenceUrl: data.sourceUrl,
+      tags: data.tag,
+    };
+
+    postEpigram(epigramForm, {
+      onSuccess: (response) => {
+        if (response && response.id) {
+          router.push(`/epigrams/${response.id}`);
+        }
+      },
+      onError: (error) => {
+        console.error('에피그램 생성 실패:', error);
+      },
+    });
path: src/components/addEditForm/AddEpigramForm.tsx
user: login: jaehyeongjung
body: > try catch 문 안에서 작성하고
> 
> ```
> catch (error) {
>   openModal({
>     type: 'alert',
>     title: '에피그램 생성 실패',
>     callback: () => getErrorMessage(err),
>   });
> }
> ```
> 
> 이런 식으로 에러처리해줘도 좋을거 같습니다!

넵 감사합니다 ! 반영했습니다 ㅎㅎ
created_at: 2025-03-25T04:25:19Z
author_association: COLLABORATOR
diff_hunk: @@ -15,9 +16,26 @@ jest.mock('next/navigation', () => ({
 // }));
 
 describe('AddEpigram Component', () => {
+  const queryClient = new QueryClient({
+    defaultOptions: {
+      queries: {
+        retry: false,
+      },
+    },
+  });
+
+  // QueryClientProvider로 컴포넌트를 감싸는 함수
+  const renderWithQueryClient = () => {
+    return render(
+      <QueryClientProvider client={queryClient}>
+        <AddEpigramForm />
+      </QueryClientProvider>,
+    );
+  };
+
   beforeEach(() => {
     // mockCreateEpigram.mockClear();
-    render(<AddEpigramForm />);
+    renderWithQueryClient();
path: tests/addEpigramForm.test.tsx
user: login: CJewon
body: `addEpigramForm.test.tsx` 파일에서 주석으로 된 부분들은 나중에 사용하는걸까요? 아니라면 지워주는것도 좋아보입니다 !
created_at: 2025-03-25T06:36:48Z
author_association: COLLABORATOR
diff_hunk: @@ -15,9 +16,26 @@ jest.mock('next/navigation', () => ({
 // }));
 
 describe('AddEpigram Component', () => {
+  const queryClient = new QueryClient({
+    defaultOptions: {
+      queries: {
+        retry: false,
+      },
+    },
+  });
+
+  // QueryClientProvider로 컴포넌트를 감싸는 함수
+  const renderWithQueryClient = () => {
+    return render(
+      <QueryClientProvider client={queryClient}>
+        <AddEpigramForm />
+      </QueryClientProvider>,
+    );
+  };
+
   beforeEach(() => {
     // mockCreateEpigram.mockClear();
-    render(<AddEpigramForm />);
+    renderWithQueryClient();
path: tests/addEpigramForm.test.tsx
user: login: jaehyeongjung
body: 음 형진님이 작성하신 부분이라 일단 남겨뒀습니다! 
created_at: 2025-03-25T06:46:02Z
author_association: COLLABORATOR
diff_hunk: @@ -15,9 +16,26 @@ jest.mock('next/navigation', () => ({
 // }));
 
 describe('AddEpigram Component', () => {
+  const queryClient = new QueryClient({
+    defaultOptions: {
+      queries: {
+        retry: false,
+      },
+    },
+  });
+
+  // QueryClientProvider로 컴포넌트를 감싸는 함수
+  const renderWithQueryClient = () => {
+    return render(
+      <QueryClientProvider client={queryClient}>
+        <AddEpigramForm />
+      </QueryClientProvider>,
+    );
+  };
+
   beforeEach(() => {
     // mockCreateEpigram.mockClear();
-    render(<AddEpigramForm />);
+    renderWithQueryClient();
path: tests/addEpigramForm.test.tsx
user: login: jaehyeongjung
body: 우선 머지하고 나중에 리팩토링 하면서 한 번에 여쭤보고 지우겠습니다!
created_at: 2025-03-25T06:48:56Z
author_association: COLLABORATOR
diff_hunk: @@ -15,9 +16,26 @@ jest.mock('next/navigation', () => ({
 // }));
 
 describe('AddEpigram Component', () => {
+  const queryClient = new QueryClient({
+    defaultOptions: {
+      queries: {
+        retry: false,
+      },
+    },
+  });
+
+  // QueryClientProvider로 컴포넌트를 감싸는 함수
+  const renderWithQueryClient = () => {
+    return render(
+      <QueryClientProvider client={queryClient}>
+        <AddEpigramForm />
+      </QueryClientProvider>,
+    );
+  };
+
   beforeEach(() => {
     // mockCreateEpigram.mockClear();
-    render(<AddEpigramForm />);
+    renderWithQueryClient();
path: tests/addEpigramForm.test.tsx
user: login: CJewon
body: 넵 !!
created_at: 2025-03-25T06:58:28Z
author_association: COLLABORATOR

PR comments:
user: login: vercel[bot]
created_at: 2025-03-24T09:19:51Z
body: [vc]: #t9CZJYSePItML9IsmjJwdlnNvj9/ouBOpnjtL2PKZS4=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJlcGlncmFtIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImVwaWdyYW0tZ2l0LWZlYXQtZXAtODNhZGRwYWdlLWFwaWNvbm5lY3QtcmFrNTE3cy1wcm9qZWN0cy52ZXJjZWwuYXBwIn0sImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9yYWs1MTdzLXByb2plY3RzL2VwaWdyYW0vM0VoZWpWbW5mRXhTRGVuMThHRzFxWnJvTlRqSCIsInByZXZpZXdVcmwiOiJlcGlncmFtLWdpdC1mZWF0LWVwLTgzYWRkcGFnZS1hcGljb25uZWN0LXJhazUxN3MtcHJvamVjdHMudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsInJvb3REaXJlY3RvcnkiOm51bGx9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **epigram** | ✅ Ready ([Inspect](https://vercel.com/rak517s-projects/epigram/3EhejVmnfExSDen18GG1qZroNTjH)) | [Visit Preview](https://epigram-git-feat-ep-83addpage-apiconnect-rak517s-projects.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/epigram-git-feat-ep-83addpage-apiconnect-rak517s-projects.vercel.app?via=pr-comment-feedback-link) | Mar 25, 2025 4:23am |


author_association: NONE
user: login: jaehyeongjung
created_at: 2025-03-24T09:53:06Z
body: > 테스트 코드 쪽에 뭔가 문제가 있는거 같습니다! 확인 한 번 부탁드립니다!

네 확인해보니 테스트코드 쪽에 QueryClientProvider를 제공 안 해줘서 그랬나봅니다!
author_association: COLLABORATOR