-
Notifications
You must be signed in to change notification settings - Fork 6
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
요청주제관리 페이지 UI 수정 및 API 연동 #285
base: dev
Are you sure you want to change the base?
Changes from all commits
667ce40
c7c7369
53ca41d
7f27b29
a28d20c
923047f
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,87 @@ | ||
'use client'; | ||
import { useState } from 'react'; | ||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; | ||
|
||
import BottomSheet from './BottomSheet'; | ||
|
||
import { RequestedTopicType } from '@/lib/types/requestedTopicType'; | ||
import editAdminTopic from '@/app/_api/adminTopics/editAdminTopic'; | ||
import formatDate from '@/lib/utils/dateFormat'; | ||
import getCategories from '@/app/_api/category/getCategories'; | ||
import { QUERY_KEYS } from '@/lib/constants/queryKeys'; | ||
import { CategoryType } from '@/lib/types/categoriesType'; | ||
|
||
import * as styles from './AdminTopicBox.css'; | ||
|
||
interface TopicBoxProps { | ||
topic: RequestedTopicType; | ||
} | ||
|
||
function TopicBox({ topic }: TopicBoxProps) { | ||
const queryClient = useQueryClient(); | ||
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false); | ||
|
||
const editTopicMutation = useMutation({ | ||
mutationFn: () => | ||
editAdminTopic({ | ||
topicId: topic?.id, | ||
isExposed: !topic.isExposed, | ||
title: topic?.title, | ||
categoryCode: topic?.categoryCode, | ||
}), | ||
onSuccess: () => { | ||
queryClient.invalidateQueries({ | ||
queryKey: [QUERY_KEYS.getAdminTopics], | ||
}); | ||
}, | ||
}); | ||
|
||
const handleClickEditButton = () => { | ||
setIsBottomSheetOpen(true); | ||
}; | ||
|
||
const handleToggleExposeButton = () => { | ||
editTopicMutation.mutate(); | ||
}; | ||
|
||
return ( | ||
<> | ||
<tr className={styles.bodyRow}> | ||
<td>{formatDate(topic?.createdDate)}</td> | ||
<td>{topic?.categoryKorName}</td> | ||
<td className={styles.rowItem}> | ||
<span className={styles.rowText}>{topic?.title}</span> | ||
<span className={styles.rowText}>{topic?.description}</span> | ||
</td> | ||
<td className={styles.buttons}> | ||
<span className={styles.rowText}>{topic?.isAnonymous ? 'O' : 'X'}</span> | ||
</td> | ||
Comment on lines
+56
to
+58
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.
|
||
<td className={styles.buttons}> | ||
<button className={styles.editButton} onClick={handleClickEditButton}> | ||
수정하기 | ||
</button> | ||
</td> | ||
<td> | ||
<select onChange={handleToggleExposeButton} value={topic?.isExposed ? '공개' : '비공개'}> | ||
<option>공개</option> | ||
<option>비공개</option> | ||
</select> | ||
</td> | ||
Comment on lines
+64
to
+69
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. (의견) 혹시 요청 주제 관리 페이지에서 토글로 노출상태를 바로 변경하는 기능을 두신 이유가 무엇인지 궁금합니당 👀 |
||
</tr> | ||
|
||
{isBottomSheetOpen && ( | ||
<BottomSheet | ||
onClose={() => { | ||
setIsBottomSheetOpen(false); | ||
}} | ||
topicTitle={topic?.title} | ||
category={topic?.categoryKorName} | ||
isExposed={topic?.isExposed} | ||
topicId={topic?.id} | ||
/> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
export default TopicBox; |
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. 해당 파일은 삭제해야 하는 파일이 맞을까요?! 👀 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,28 +2,26 @@ | |
|
||
import * as styles from './BottomSheet.css'; | ||
import { MouseEventHandler, useState } from 'react'; | ||
import { useMutation, useQuery } from '@tanstack/react-query'; | ||
import { useUser } from '@/store/useUser'; | ||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; | ||
import { QUERY_KEYS } from '@/lib/constants/queryKeys'; | ||
import useOnClickOutside from '@/hooks/useOnClickOutside'; | ||
import getCategories from '@/app/_api/category/getCategories'; | ||
import editAdminTopic from '@/app/_api/adminTopics/editAdminTopic'; | ||
|
||
import { CategoryType } from '@/lib/types/categoriesType'; | ||
import ArrowDown from '/public/icons/down_chevron.svg'; | ||
import useBooleanOutput from '@/hooks/useBooleanOutput'; | ||
import Modal from '@/components/Modal/Modal'; | ||
|
||
interface BottomSheetProps { | ||
onClose: MouseEventHandler<HTMLDivElement>; | ||
onClose: () => void; | ||
topicTitle: string; | ||
category: string; | ||
isExposed: boolean; | ||
topicId: number; | ||
} | ||
// TODO: 컴포넌트 공통화 작업 | ||
function BottomSheet({ onClose, topicTitle, category, isExposed }: BottomSheetProps) { | ||
function BottomSheet({ onClose, topicTitle, category, isExposed, topicId }: BottomSheetProps) { | ||
const [isDropdownOpen, setIsDropdownOpen] = useState(false); | ||
const { isOn: isModalOn, handleSetOn: openModal, handleSetOff: closeModal } = useBooleanOutput(false); | ||
const queryClient = useQueryClient(); | ||
|
||
const [title, setTitle] = useState(topicTitle); | ||
const [selectedCategory, setSelectedCategory] = useState<string>(category); | ||
|
@@ -35,17 +33,26 @@ function BottomSheet({ onClose, topicTitle, category, isExposed }: BottomSheetPr | |
queryFn: getCategories, | ||
}); | ||
|
||
const convertCategoryKorNameToCode = (korName: string) => { | ||
const category = categories?.find((cat) => cat.korName === korName); | ||
return category ? category.code : null; // 찾지 못하면 null 반환 | ||
}; | ||
|
||
const editTopicMutation = useMutation({ | ||
// mutationFn: () => | ||
// editAdminTopic({ | ||
// isExposed, | ||
// title, | ||
// categoryCode, | ||
// }), | ||
mutationFn: () => | ||
editAdminTopic({ | ||
topicId, | ||
isExposed, | ||
title, | ||
categoryCode: convertCategoryKorNameToCode(selectedCategory as string) || '', | ||
}), | ||
Comment on lines
+36
to
+48
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. 추후 리팩토링 하실 때 드롭다운을 ul, li태그가 아닌 select 태그를 사용하는 것으로 수정하면 카테고리 선택하고, 뮤테이션에 넣어주는 부분에 대해 코드 가독성면에서 좋을 것 같아요, 아래 코드 참고 부탁드립니당
|
||
onSuccess: () => { | ||
setTitle(''); | ||
setSelectedCategory(selectedCategory); | ||
openModal(); | ||
queryClient.invalidateQueries({ | ||
queryKey: [QUERY_KEYS.getAdminTopics], | ||
}); | ||
onClose(); | ||
}, | ||
onError: (error) => { | ||
setErrorMessage('요청 중 오류가 발생했습니다. 다시 시도해 주세요. :('); | ||
|
@@ -131,24 +138,10 @@ function BottomSheet({ onClose, topicTitle, category, isExposed }: BottomSheetPr | |
</div> | ||
|
||
<button type="submit" className={styles.submitButton} disabled={!title || title.length > 30}> | ||
요청 보내기 | ||
수정하기 | ||
</button> | ||
</form> | ||
</div> | ||
{isModalOn && ( | ||
<Modal handleModalClose={closeModal} size="large"> | ||
<div className={styles.modalText}>{`요청 주제 수정이 완료되었어요.`} </div> | ||
<button | ||
className={styles.modalButton} | ||
onClick={() => { | ||
closeModal(); | ||
setIsDropdownOpen(false); //실행안됨 | ||
}} | ||
> | ||
닫기 | ||
</button> | ||
</Modal> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ import { vars } from '@/styles/theme.css'; | |
import * as fonts from '@/styles/font.css'; | ||
|
||
export const body = style({ | ||
width: '100vw', | ||
width: '100%', | ||
minHeight: '100vh', | ||
padding: '16px 16px 120px', | ||
|
||
Comment on lines
-6
to
9
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. |
||
|
@@ -87,3 +87,36 @@ export const page = style([ | |
color: vars.color.bluegray6, | ||
}, | ||
]); | ||
|
||
export const table = style({ | ||
maxWidth: '850px', | ||
padding: '1rem', | ||
|
||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: '1rem', | ||
|
||
backgroundColor: vars.color.white, | ||
borderRadius: '8px', | ||
}); | ||
|
||
Comment on lines
+91
to
+102
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. 해당 스타일 파일에 사용하지 않는 클래스네임이 많은 것 같아서 제거하면 좋을 것 같습니당! |
||
export const headRow = style([ | ||
fonts.BodyRegular, | ||
{ | ||
padding: '1rem 0.5rem', | ||
|
||
display: 'grid', | ||
gridTemplateColumns: 'repeat(8, 1fr)', | ||
alignItems: 'center', | ||
|
||
textAlign: 'center', | ||
}, | ||
]); | ||
|
||
export const rowItem = style({ | ||
gridColumn: 'span 2', | ||
|
||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: '0.5rem', | ||
}); |
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.
useBooleanOutput() 훅을 사용해서 추후 리팩토링하면 좋을 것 같습니당✨👍