-
Notifications
You must be signed in to change notification settings - Fork 0
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
[Feat] 결과 수정 - 상세 페이지 api 연동 #112
Changes from all commits
4878895
17c0c71
830f4b3
4247c6e
b15ac54
329009f
6cd46fe
39ee220
3ce7321
eaf2350
9951b7f
cc3c008
e870651
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { style } from '@vanilla-extract/css'; | ||
|
||
export const editDetailPage = style({ | ||
display: 'flex', | ||
height: '100vh', | ||
flexShrink: 0, | ||
}); | ||
|
||
export const flexColumn = style({ | ||
display: 'flex', | ||
width: '100%', | ||
justifyContent: 'center', | ||
}); | ||
Comment on lines
+3
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 스타일 중복을 제거해주세요. page.css.ts와 EditDetail.css.ts에서 동일한 스타일이 중복 정의되어 있습니다. 유지보수성 향상을 위해 다음과 같이 개선하는 것을 추천드립니다:
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,37 @@ | ||||||||||||||||||||||
'use client'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
import { createContext, Dispatch, SetStateAction } from 'react'; | ||||||||||||||||||||||
import { EditPost } from './_components/EditPost/EditPost'; | ||||||||||||||||||||||
import { EditSidebar } from './_components/EditSidebar/EditSidebar'; | ||||||||||||||||||||||
import { editDetailPage, flexColumn } from './EditDetail.css'; | ||||||||||||||||||||||
import { useState } from 'react'; | ||||||||||||||||||||||
import { Post } from '@web/types'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
// TODO 추후 Jotai, 또는 react-query 사용으로 수정할 예정 | ||||||||||||||||||||||
interface DetailPageContextType { | ||||||||||||||||||||||
loadingPosts: Post['id'][]; | ||||||||||||||||||||||
setLoadingPosts: Dispatch<SetStateAction<Post['id'][]>>; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
const defaultContextValue: DetailPageContextType = { | ||||||||||||||||||||||
loadingPosts: [], | ||||||||||||||||||||||
setLoadingPosts: () => {}, | ||||||||||||||||||||||
}; | ||||||||||||||||||||||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Context의 기본값 처리를 개선해 주세요. 현재 기본값의 다음과 같이 개선하는 것을 제안합니다: const defaultContextValue: DetailPageContextType = {
loadingPosts: [],
- setLoadingPosts: () => {},
+ setLoadingPosts: () => {
+ throw new Error('DetailPageContext가 Provider 외부에서 사용되었습니다.');
+ },
}; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
export const DetailPageContext = | ||||||||||||||||||||||
createContext<DetailPageContextType>(defaultContextValue); | ||||||||||||||||||||||
|
||||||||||||||||||||||
export function EditDetail() { | ||||||||||||||||||||||
const [loadingPosts, setLoadingPosts] = useState<Post['id'][] | []>([]); | ||||||||||||||||||||||
|
||||||||||||||||||||||
return ( | ||||||||||||||||||||||
<DetailPageContext.Provider value={{ loadingPosts, setLoadingPosts }}> | ||||||||||||||||||||||
<div className={editDetailPage}> | ||||||||||||||||||||||
<EditSidebar /> | ||||||||||||||||||||||
<div className={flexColumn}> | ||||||||||||||||||||||
<EditPost /> | ||||||||||||||||||||||
</div> | ||||||||||||||||||||||
</div> | ||||||||||||||||||||||
</DetailPageContext.Provider> | ||||||||||||||||||||||
); | ||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { style } from '@vanilla-extract/css'; | ||
import { vars } from '@repo/theme'; | ||
|
||
export const container = style({ | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
flexDirection: 'column', | ||
width: '100%', | ||
height: 'fit-content', | ||
borderRadius: vars.borderRadius[24], | ||
border: `1px solid ${vars.colors.grey50}`, | ||
background: vars.colors.grey, | ||
padding: vars.space[40], | ||
}); | ||
|
||
export const description = style({ | ||
textAlign: 'center', | ||
whiteSpace: 'pre-wrap', | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as styles from './DragGuide.css'; | ||
import { Text } from '@repo/ui'; | ||
|
||
type DragGuideProps = { | ||
description: string; | ||
}; | ||
|
||
export function DragGuide({ description }: DragGuideProps) { | ||
return ( | ||
<div className={styles.container}> | ||
<Text.H2 | ||
className={styles.description} | ||
fontSize={20} | ||
fontWeight="semibold" | ||
color="grey500" | ||
> | ||
{description} | ||
</Text.H2> | ||
<Text.H2 | ||
className={styles.description} | ||
fontSize={20} | ||
fontWeight="semibold" | ||
color="grey500" | ||
> | ||
끌어서 여기에 놓아주세요 | ||
</Text.H2> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -7,27 +7,51 @@ import { Badge } from '@repo/ui/Badge'; | |||||
import { PostEditor } from '../PostEditor/PostEditor'; | ||||||
import { EditPromptField } from '../EditPromptField/EditPromptField'; | ||||||
import { FormProvider, useForm } from 'react-hook-form'; | ||||||
import { useParams, useRouter, useSearchParams } from 'next/navigation'; | ||||||
import { useGroupPostsQuery } from '@web/store/query/useGroupPostsQuery'; | ||||||
import { useAdjacentPosts } from '../../_hooks/useAdjacentPosts'; | ||||||
|
||||||
export function EditPost() { | ||||||
const router = useRouter(); | ||||||
const methods = useForm(); | ||||||
const { agentId, postGroupId } = useParams(); | ||||||
const searchParams = useSearchParams(); | ||||||
const postId = searchParams.get('post'); | ||||||
const { data } = useGroupPostsQuery(Number(agentId), Number(postGroupId)); | ||||||
const post = data?.data?.posts.find((post) => post.id === Number(postId)); | ||||||
Comment on lines
+20
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터 유효성 검사 필요
다음과 같이 early return을 추가하는 것을 제안합니다: const postId = searchParams.get('post');
+ if (!postId) {
+ return <div>잘못된 접근입니다.</div>;
+ }
const { data } = useGroupPostsQuery(Number(agentId), Number(postGroupId)); |
||||||
const { routePreviousPost, routeNextPost, canMoveUp, canMoveDown } = | ||||||
useAdjacentPosts(data?.data?.posts, post); | ||||||
|
||||||
return ( | ||||||
<div className={wrapper}> | ||||||
<div className={controlBar}> | ||||||
<div> | ||||||
<IconButton icon="arrowLineTop" /> | ||||||
<IconButton icon="arrowLineBottom" /> | ||||||
<IconButton | ||||||
icon="arrowLineTop" | ||||||
disabled={!canMoveUp} | ||||||
onClick={routePreviousPost} | ||||||
/> | ||||||
<IconButton | ||||||
icon="arrowLineBottom" | ||||||
disabled={!canMoveDown} | ||||||
onClick={routeNextPost} | ||||||
/> | ||||||
</div> | ||||||
|
||||||
<div> | ||||||
<IconButton icon="dots" /> | ||||||
<IconButton icon="x" iconType="stroke" /> | ||||||
<IconButton | ||||||
icon="x" | ||||||
iconType="stroke" | ||||||
onClick={() => router.push(`/edit/${agentId}/${postGroupId}`)} | ||||||
/> | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div className={postWrapper}> | ||||||
<div className={titleWrapper}> | ||||||
<Text color="grey1000" fontSize={28} fontWeight="bold"> | ||||||
네이버 웨일, 본사로 이전하는 이유 | ||||||
{post?.summary} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 데이터 로딩 상태 처리 필요 post가 undefined일 때의 로딩 상태 처리가 누락되어 있습니다. 다음과 같이 로딩 상태를 표시하는 것을 제안합니다: - {post?.summary}
+ {post?.summary ?? <Skeleton width="80%" height="28px" />} 📝 Committable suggestion
Suggested change
|
||||||
</Text> | ||||||
<Badge size="large" variant="neutral" shape="square"> | ||||||
요약 | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,24 +2,94 @@ | |
|
||
import { Checkbox } from '@repo/ui/Checkbox'; | ||
import { TextField } from '@repo/ui/TextField'; | ||
import { useFormContext } from 'react-hook-form'; | ||
import { Controller, useForm, useFormContext } from 'react-hook-form'; | ||
import { wrapper } from './EditPromptField.css'; | ||
import { Spacing } from '@repo/ui/Spacing'; | ||
import { isEmptyStringOrNil } from '@web/utils'; | ||
import { usePatchPromptMutation } from '@web/store/mutation/usePatchPromptMutation'; | ||
import { useParams, useSearchParams } from 'next/navigation'; | ||
import { useContext, useEffect } from 'react'; | ||
import { DetailPageContext } from '../../EditDetail'; | ||
import { useGroupPostsQuery } from '@web/store/query/useGroupPostsQuery'; | ||
|
||
export function EditPromptField() { | ||
const { register } = useFormContext(); | ||
const { register, watch, control, handleSubmit } = useForm<{ | ||
isEntire: boolean; | ||
prompt: string; | ||
}>({ | ||
defaultValues: { | ||
isEntire: false, | ||
prompt: '', | ||
}, | ||
}); | ||
const { loadingPosts, setLoadingPosts } = useContext(DetailPageContext); | ||
const isEntire = watch('isEntire'); | ||
const prompt = watch('prompt'); | ||
const isSubmitDisabled = isEmptyStringOrNil(prompt); | ||
const { agentId, postGroupId } = useParams(); | ||
const searchParams = useSearchParams(); | ||
const postId = searchParams.get('post'); | ||
const { data } = useGroupPostsQuery(Number(agentId), Number(postGroupId)); | ||
const posts = data?.data.posts ?? []; | ||
const editingPosts = posts | ||
.filter((post) => post.status === 'EDITING') | ||
.map((post) => post.id); | ||
|
||
const { mutate: patchPrompt, isPending } = usePatchPromptMutation({ | ||
agentId: Number(agentId), | ||
postGroupId: Number(postGroupId), | ||
postId: Number(postId), | ||
}); | ||
|
||
// TODO 제거 예정 | ||
useEffect(() => { | ||
if (isPending) { | ||
// 요청이 진행 중이면 | ||
if (isEntire) { | ||
setLoadingPosts(editingPosts); | ||
} else { | ||
setLoadingPosts([Number(postId)]); | ||
} | ||
} else { | ||
if (isEntire) { | ||
setLoadingPosts((prev) => | ||
prev.filter((id) => !editingPosts.includes(id)) | ||
); | ||
} else { | ||
setLoadingPosts((prev) => prev.filter((id) => id !== Number(postId))); | ||
} | ||
} | ||
}, [isPending]); | ||
|
||
const onSubmit = async (data: { isEntire: boolean; prompt: string }) => { | ||
patchPrompt({ ...data }); | ||
}; | ||
|
||
return ( | ||
<div className={wrapper}> | ||
<Spacing size={8} /> | ||
<Checkbox | ||
label="수정 중인 글을 모두 업그레이드하기" | ||
defaultChecked | ||
onChange={(checked) => console.log(checked)} | ||
<Controller | ||
name="isEntire" | ||
control={control} | ||
render={({ field }) => ( | ||
<Checkbox | ||
label="수정 중인 글을 모두 업그레이드하기" | ||
defaultChecked | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 체크박스 defaultChecked 속성 제거 필요
다음과 같이 <Checkbox
label="수정 중인 글을 모두 업그레이드하기"
- defaultChecked
checked={field.value}
onChange={field.onChange}
/> |
||
checked={field.value} | ||
onChange={field.onChange} | ||
/> | ||
)} | ||
/> | ||
<Spacing size={16} /> | ||
<TextField id="ai-field" variant="button"> | ||
<TextField.Input | ||
sumbitButton={<TextField.Submit type="submit" />} | ||
sumbitButton={ | ||
<TextField.Submit | ||
type="submit" | ||
onClick={handleSubmit(onSubmit)} | ||
disabled={isSubmitDisabled} | ||
/> | ||
} | ||
placeholder="AI에게 요청하여 글 업그레이드하기" | ||
{...register('prompt', { | ||
required: '메시지를 입력해주세요', | ||
|
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.
🛠️ Refactor suggestion
devDependencies로 이동을 제안합니다.
@tanstack/react-query-devtools는 개발 도구이므로 dependencies가 아닌 devDependencies에 위치하는 것이 더 적절합니다. 이렇게 하면 프로덕션 빌드 크기를 줄일 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
- "@tanstack/react-query-devtools": "^5.66.0",
devDependencies 섹션에 추가:
+ "@tanstack/react-query-devtools": "^5.66.0",