-
Notifications
You must be signed in to change notification settings - Fork 1
게시글 수정 기능 추가 및 작성 폼 확장 #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 8 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1022b51
feat: 게시글 관련 에러 메시지 추가
Seono-Na da53854
feat: 게시글 수정 기능을 위한 Public API 및 서버 액션 추가
Seono-Na 745ba33
refactor: PostForm 컴포넌트를 생성/수정 모드로 확장
Seono-Na 915ce25
refactor: PostForm 컴포넌트 폴더명을 post-create에서 post-editor로 변경
Seono-Na 60f7531
feat: 글로벌 not-found 페이지 추가
Seono-Na 5dfed22
feat: 게시글 수정 페이지 구현
Seono-Na d8a67f8
design: 결과물 확인을 위한 임시 페이지 UI 개선
Seono-Na 2a4a402
Merge branch 'feature-group/post' of github.com:nettee-space/frontend…
Seono-Na 72bcb69
refactor: updatePostAction에서 validation 단계 나누기
Seono-Na 199b47e
refactor: updatePostAction에서 필드 유효성 검사를 반복문으로 개선
Seono-Na 769bf17
refactor: getValidatedField 함수 도입하여 유효성 검사 로직 개선
Seono-Na 73ef6d4
refactor: getValidatedField를 유틸로 분리하여 재사용성 향상
Seono-Na 0646022
refactor: 폼 데이터 검증 개선 및 중복 코드 제거
Seono-Na File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import Link from 'next/link'; | ||
|
||
export default function NotFound() { | ||
return ( | ||
<div className="flex min-h-screen items-center justify-center bg-gray-100 p-6"> | ||
<div className="w-full max-w-md rounded-lg bg-white p-8 text-center shadow-lg"> | ||
<h2 className="mb-4 text-2xl font-bold text-gray-800"> | ||
어머! 없어요... | ||
</h2> | ||
<p className="mb-6 text-gray-600">아니 없어요 그냥...</p> | ||
<Link | ||
href="/" | ||
className="inline-block rounded bg-blue-500 px-6 py-3 text-white transition hover:bg-blue-600" | ||
> | ||
홈으로 가기 | ||
</Link> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,10 @@ | ||
import Link from 'next/link'; | ||
|
||
import { PostDetail } from '@/features/post/post-detail'; | ||
|
||
// 특정 게시글 페이지 - 게시글 생성 후 넘어가지는지 확인용으로 만든 임시 페이지 | ||
export default function PostPage() { | ||
return ( | ||
<main> | ||
<PostDetail /> | ||
<Link href={'/'}>목록으로</Link> | ||
</main> | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { notFound } from 'next/navigation'; | ||
|
||
import { getPostById } from '@/entities/post'; | ||
import { PostForm } from '@/features/post/post-editor'; | ||
|
||
interface PostEditPageProps { | ||
params: { id: string }; | ||
} | ||
|
||
export default async function PostEditPage({ params }: PostEditPageProps) { | ||
const postId = (await params).id; | ||
const post = await getPostById(postId); | ||
|
||
if (!post) { | ||
notFound(); | ||
} | ||
|
||
return ( | ||
<main className="mx-auto max-w-2xl p-6"> | ||
<PostForm post={post} /> | ||
</main> | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
export const ERROR_MESSAGES = { | ||
INVALID_TYPE: '유효하지 않은 입력 형식입니다.', | ||
INVALID_ID: '유효하지 않은 게시글 입니다.', | ||
REQUIRED_TITLE: '제목을 입력해주세요', | ||
REQUIRED_CONTENT: '내용을 입력해주세요', | ||
REQUIRED_AUTHOR: '작성자를 입력해주세요', | ||
SAVE_FAILED: '게시글 저장에 실패했습니다:', | ||
UPDATE_FAILED: '게시글 수정에 실패했습니다.', | ||
} as const; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
export { createPostAction } from './post-actions'; | ||
export { createPostAction, updatePostAction } from './post-actions'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
'use client'; | ||
|
||
import { Button } from '@workspace/ui/components/button'; | ||
import { useRouter } from 'next/navigation'; | ||
import { useActionState } from 'react'; | ||
|
||
import { Post } from '@/entities/post'; | ||
import { createPostAction, updatePostAction } from '@/features/post/actions'; | ||
import { TextField } from '@/shared/ui'; | ||
|
||
interface PostFormProps { | ||
post?: Post; | ||
} | ||
|
||
export function PostForm({ post }: PostFormProps) { | ||
const router = useRouter(); | ||
const isEditMode = Boolean(post); | ||
|
||
const [actionResult, formAction, isPending] = useActionState( | ||
isEditMode ? updatePostAction : createPostAction, | ||
null | ||
); | ||
|
||
return ( | ||
<form action={formAction}> | ||
<h1 className="mb-4 text-xl font-bold"> | ||
{isEditMode ? '게시글 수정' : '새 게시글 작성'} | ||
</h1> | ||
|
||
{post?.id && <input type="hidden" name="postId" value={post.id} />} | ||
|
||
<TextField | ||
name="title" | ||
label="제목" | ||
required | ||
disabled={isPending} | ||
defaultValue={post?.title || ''} | ||
/> | ||
<TextField | ||
name="content" | ||
label="내용" | ||
required | ||
disabled={isPending} | ||
isTextArea | ||
defaultValue={post?.content || ''} | ||
/> | ||
<TextField | ||
name="author" | ||
label="작성자" | ||
required | ||
disabled={isPending} | ||
readOnly={!!post} | ||
defaultValue={post?.author || ''} | ||
/> | ||
|
||
{actionResult?.status === false && ( | ||
<p className="mt-2 text-sm text-red-500">{actionResult.error}</p> | ||
)} | ||
|
||
<Button | ||
type="button" | ||
variant="outline" | ||
onClick={() => router.back()} | ||
disabled={isPending} | ||
> | ||
취소 | ||
</Button> | ||
<Button type="submit" disabled={isPending}> | ||
{isPending ? '저장 중...' : '작성하기'} | ||
</Button> | ||
</form> | ||
); | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 updateData 객체를 생성하면서 값 추출과 밸리데이션이 함께 이루어지고 있는데, 객체를 생성하면서 바로 밸리데이션 검증을 진행하기보다는,
밸리데이션을 별도의 단계로 나눠서 유효성 검사를 진행하고, 문제가 없다는 것이 확인된 후에 updateData 객체를 생성하거나 다음 로직을 실행하는 흐름으로 구성하면 가독성이 더 좋아질 것 같습니다. ✨
이렇게 하면 코드 흐름이 더 직관적으로 보이고, 각 단계가 명확하게 구분되어 유지보수에도 도움이 될 것 같아요. 🛠️
이런 방향은 어떠신가요? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@choi1five 님 좋은 리뷰 감사합니다!🙏
피드백 주신 대로 밸리데이션 검증을 별도로 분리하는 방향으로 개선했습니다.
기존에는
updateData
객체를 만들면서 동시에validateFormField
를 호출했는데,이를 별도의 유효성 검사 함수
getValidatedField
로 분리하여 먼저 검증을 수행한 후,reduce
를 활용해validatedData
객체를 생성하는 방식으로 변경했습니다.getValidatedField
의 경우 공용으로 사용할 수 있어shared/util
로 분리할 수 있었지만,아직 post 관련 부분에서만 사용하고 있고
validateFormField
과 함꼐 사용하고 있기 떄문에entities/post/lib/form-validation.ts
안에 넣어두었습니다.이렇게 수정하면서 코드의 가독성이 향상되었고, 각 단계가 명확히 구분되었습니다.🔧
혹시 더 개선할 부분이 있다면 피드백 부탁드립니다. 감사합니다! 😊