Skip to content

Commit

Permalink
♻️ Server action 마저 적용 (#104)
Browse files Browse the repository at this point in the history
* newsAction 추가

* noticeAction 관련 리팩토링

* newsAction 추가

* validateNoticeForm 추가

* noticeActions 추가

* autolinker 추가

* 예약 모달 보더 추가

* seminarAction 추가

* 편집 취소시 모달 추가

* 편집중 취소, 삭제 모달 추가

* 사소한 수정

* 소식 검색 결과 개수 반영
  • Loading branch information
yeolyi authored Sep 23, 2023
1 parent d1a199f commit beccac6
Show file tree
Hide file tree
Showing 34 changed files with 262 additions and 241 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ jobs:
script: |
cd ~/csereal-web
git pull
npm i
npm run build
pm2 restart csereal_front
26 changes: 26 additions & 0 deletions actions/newsActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use server';

import { revalidateTag } from 'next/cache';
import { redirect } from 'next/navigation';

import { deleteNews } from '@/apis/newsServer';

import { news } from '@/types/page';

import { getPath } from '@/utils/page';

const newsPath = getPath(news);

export const newsDeleteAction = async (id: number) => {
try {
await deleteNews(id);
revalidateNewsTag();
} catch (error) {
return { message: error instanceof Error ? error.message : '알 수 없는 에러: ' + error };
}
redirect(newsPath);
};

export const revalidateNewsTag = () => {
revalidateTag('news');
};
23 changes: 7 additions & 16 deletions actions/noticeActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@
import { revalidateTag } from 'next/cache';
import { redirect } from 'next/navigation';

import { NoticePreviewList, Notice } from '@/types/notice';
import { batchDeleteNotice, batchUnpinNotice, deleteNotice } from '@/apis/noticeServer';

import { notice } from '@/types/page';
import { PostSearchQueryParams } from '@/types/post';

import { getPath } from '@/utils/page';

import { deleteRequest, getRequest, patchRequest } from '../apis/serverIndex';

const noticeApiPath = '/notice';
const noticePath = getPath(notice);

export const batchDeleteAction = async (ids: Set<number>) => {
try {
await deleteRequest(noticeApiPath, {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idList: Array.from(ids) }),
});
await batchDeleteNotice(ids);
revalidateNoticeTag();
} catch (error) {
return { message: error instanceof Error ? error.message : '알 수 없는 에러: ' + error };
Expand All @@ -28,20 +22,17 @@ export const batchDeleteAction = async (ids: Set<number>) => {

export const batchUnpinAction = async (ids: Set<number>) => {
try {
await patchRequest(noticeApiPath, {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idList: Array.from(ids) }),
});
await batchUnpinNotice(ids);
revalidateNoticeTag();
} catch (error) {
return { message: error instanceof Error ? error.message : '알 수 없는 에러: ' + error };
}
};

/** 성공시에 리턴값이 never(호출한 함수도 되돌아가지 않음)이어야하는데 이상하게 성공시에 undefined를 반환한다. */
export const noticeDeleteAction = async (id: string | number) => {
/** 성공시에 리턴값이 never(호출한 함수로 되돌아가지 않음)이어야하는데 이상하게 성공시에 undefined를 반환한다. */
export const noticeDeleteAction = async (id: number) => {
try {
await deleteRequest(`${noticeApiPath}/${id}`);
await deleteNotice(id);
revalidateNoticeTag();
} catch (error) {
return { message: error instanceof Error ? error.message : '알 수 없는 에러: ' + error };
Expand Down
26 changes: 26 additions & 0 deletions actions/seminarActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use server';

import { revalidateTag } from 'next/cache';
import { redirect } from 'next/navigation';

import { deleteSeminar } from '@/apis/seminarServer';

import { seminar } from '@/types/page';

import { getPath } from '@/utils/page';

const seminarPath = getPath(seminar);

export const seminarDeleteAction = async (id: number) => {
try {
await deleteSeminar(id);
revalidateSeminarTag();
} catch (error) {
return { message: error instanceof Error ? error.message : '알 수 없는 에러: ' + error };
}
redirect(seminarPath);
};

export const revalidateSeminarTag = () => {
revalidateTag('seminar');
};
2 changes: 2 additions & 0 deletions apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export const BASE_URL =
? 'https://cse-dev-waffle.bacchus.io/api/v1'
: 'http://localhost:8080/api/v1';

// export const BASE_URL = 'https://cse-dev-waffle.bacchus.io/api/v1';

export const getRequest = async <T = unknown>(
url: string,
params: object = {},
Expand Down
19 changes: 6 additions & 13 deletions apis/news.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { News, NewsPreviewList, PATCHNewsBody, POSTNewsBody } from '@/types/news';
import { PostSearchQueryParams } from '@/types/post';
import { PATCHNewsBody, POSTNewsBody } from '@/types/news';

import { deleteRequest, getRequest, patchRequest, postRequest } from '.';
import { patchRequestWithCookie, postRequestWithCookie } from '.';

const newsPath = '/news';

export const getNewsPosts = (params: PostSearchQueryParams) =>
getRequest(newsPath, params, { cache: 'no-store' }) as Promise<NewsPreviewList>;

export const getNewsPostDetail = (id: number, params?: PostSearchQueryParams) =>
getRequest(`${newsPath}/${id}`, params, { cache: 'no-store' }) as Promise<News>;

export const postNews = async (body: POSTNewsBody) => {
const formData = new FormData();

Expand All @@ -29,9 +22,11 @@ export const postNews = async (body: POSTNewsBody) => {
formData.append('attachments', attachment);
}

await postRequest(newsPath, {
await postRequestWithCookie(newsPath, {
body: formData,
});


};

export const patchNews = async (id: number, body: PATCHNewsBody) => {
Expand All @@ -52,9 +47,7 @@ export const patchNews = async (id: number, body: PATCHNewsBody) => {
formData.append('newAttachments', attachment);
}

await patchRequest(`${newsPath}/${id}`, {
await patchRequestWithCookie(`${newsPath}/${id}`, {
body: formData,
});
};

export const deleteNews = (id: number) => deleteRequest(`${newsPath}/${id}`);
14 changes: 14 additions & 0 deletions apis/newsServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { News, NewsPreviewList } from '@/types/news';
import { PostSearchQueryParams } from '@/types/post';

import { deleteRequest, getRequest } from './serverIndex';

const newsPath = '/news';

export const getNewsPosts = (params: PostSearchQueryParams) =>
getRequest(newsPath, params, { next: { tags: ['news'] } }) as Promise<NewsPreviewList>;

export const getNewsPostDetail = (id: number, params?: PostSearchQueryParams) =>
getRequest(`${newsPath}/${id}`, params, { next: { tags: ['news'] } }) as Promise<News>;

export const deleteNews = (id: number) => deleteRequest(`${newsPath}/${id}`);
4 changes: 1 addition & 3 deletions apis/notice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { POSTNoticeBody, PatchNoticeBody } from '@/types/notice';

import { deleteRequestWithCookie, patchRequestWithCookie, postRequestWithCookie } from '.';
import { patchRequestWithCookie, postRequestWithCookie } from '.';

const noticePath = '/notice';

Expand Down Expand Up @@ -39,5 +39,3 @@ export const patchNotice = async (id: number, body: PatchNoticeBody) => {
body: formData,
});
};

export const deleteNotice = (id: number) => deleteRequestWithCookie(`${noticePath}/${id}`);
18 changes: 17 additions & 1 deletion apis/noticeServer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NoticePreviewList, Notice } from '@/types/notice';
import { PostSearchQueryParams } from '@/types/post';

import { getRequest } from './serverIndex';
import { deleteRequest, getRequest, patchRequest } from './serverIndex';

const noticePath = '/notice';

Expand All @@ -14,3 +14,19 @@ export const getNoticePostDetail = (id: number, params: PostSearchQueryParams) =
getRequest(`${noticePath}/${id}`, params, {
next: { tags: ['notice'] },
}) as Promise<Notice>;

export const deleteNotice = (id: number) => deleteRequest(`${noticePath}/${id}`);

export const batchDeleteNotice = async (ids: Set<number>) => {
await deleteRequest(noticePath, {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idList: Array.from(ids) }),
});
};

export const batchUnpinNotice = async (ids: Set<number>) => {
await patchRequest(noticePath, {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idList: Array.from(ids) }),
});
};
75 changes: 0 additions & 75 deletions apis/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,78 +9,3 @@ export const getNewsSearch = (params: {
keyword: string;
number: number;
}): Promise<NewsSearchResult> => getRequest('/news/totalSearch', params);

// export const getNoticeSearch = async (params: {
// keyword: string;
// number: number;
// }): Promise<NoticeSearchResult> => ({
// total: 10,
// results: [
// {
// id: 1,
// title: 'TITLE',
// createdAt: new Date().toISOString(),
// partialDescription: '12345678912345 789',
// boldStartIndex: 3,
// boldEndIndex: 7,
// },
// {
// id: 2,
// title: 'TITLE2',
// createdAt: new Date().toISOString(),
// partialDescription: '12345678912345 789',
// boldStartIndex: 0,
// boldEndIndex: 4,
// },
// {
// id: 3,
// title: 'TITLE3',
// createdAt: new Date().toISOString(),
// partialDescription: '12345678912345 789',
// boldStartIndex: 0,
// boldEndIndex: 4,
// },
// ],
// });

// export const getNewsSearch = async (params: {
// keyword: string;
// number: number;
// }): Promise<NewsSearchResult> => ({
// total: 3,
// results: [
// {
// id: 1,
// title: 'TITLE1',
// date: new Date().toISOString(),
// partialDescription:
// "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
// boldStartIndex: 3,
// boldEndIndex: 7,
// tags: ['TAG1', 'TAG2'],
// imageUrl: null,
// },
// {
// id: 2,
// title: 'TITLE2',
// date: new Date().toISOString(),
// partialDescription:
// "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
// boldStartIndex: 3,
// boldEndIndex: 7,
// tags: ['TAG1', 'TAG2'],
// imageUrl: null,
// },
// {
// id: 3,
// title: 'TITLE3',
// date: new Date().toISOString(),
// partialDescription:
// "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
// boldStartIndex: 3,
// boldEndIndex: 7,
// tags: ['TAG1', 'TAG2'],
// imageUrl: null,
// },
// ],
// });
21 changes: 1 addition & 20 deletions apis/seminar.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import { PostSearchQueryParams } from '@/types/post';
import { PATCHSeminarBody, POSTSeminarBody, Seminar, SeminarList } from '@/types/seminar';

import {
deleteRequest,
getRequest,
patchRequestWithCookie,
postRequest,
postRequestWithCookie,
} from '.';
import { patchRequestWithCookie, postRequestWithCookie } from '.';

const seminarPath = '/seminar';

export const getSeminarPosts = async (params: PostSearchQueryParams) => {
return (await getRequest(seminarPath, params, { cache: 'no-store' })) as SeminarList;
};

export const getSeminarPost = async (id: number, params: PostSearchQueryParams) => {
return (await getRequest(`${seminarPath}/${id}`, params, {
cache: 'no-store',
})) as Seminar;
};

export const postSeminar = async (body: POSTSeminarBody) => {
const formData = new FormData();

Expand Down Expand Up @@ -62,5 +45,3 @@ export const editSeminar = async (id: number, body: PATCHSeminarBody) => {

await patchRequestWithCookie(`${seminarPath}/${id}`, { body: formData });
};

export const deleteSeminar = async (id: number) => deleteRequest(`${seminarPath}/${id}`);
18 changes: 18 additions & 0 deletions apis/seminarServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { PostSearchQueryParams } from '@/types/post';
import { SeminarList, Seminar } from '@/types/seminar';

import { deleteRequest, getRequest } from './serverIndex';

const seminarPath = '/seminar';

export const getSeminarPosts = async (params: PostSearchQueryParams) => {
return (await getRequest(seminarPath, params, { next: { tags: ['seminar'] } })) as SeminarList;
};

export const getSeminarPost = async (id: number, params: PostSearchQueryParams) => {
return (await getRequest(`${seminarPath}/${id}`, params, {
next: { tags: ['seminar'] },
})) as Seminar;
};

export const deleteSeminar = async (id: number) => deleteRequest(`${seminarPath}/${id}`);
2 changes: 1 addition & 1 deletion app/[locale]/community/news/[id]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getNewsPostDetail } from '@/apis/news';
import { getNewsPostDetail } from '@/apis/newsServer';

import EditNewsPageContent from '@/components/news/EditNewsPageContent';

Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/community/news/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getNewsPostDetail } from '@/apis/news';
import { getNewsPostDetail } from '@/apis/newsServer';

import AdjPostNav from '@/components/common/AdjPostNav';
import Attachments from '@/components/common/Attachments';
Expand Down
Loading

0 comments on commit beccac6

Please sign in to comment.