-
Notifications
You must be signed in to change notification settings - Fork 3
♻️ refactor(#121, #114, #21): 컬럼 수정 모달 리팩토링 및 적용 #147
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import { useQueryClient } from '@tanstack/react-query'; | ||
| import { AxiosError } from 'axios'; | ||
| import { useRouter } from 'next/router'; | ||
| import { useState } from 'react'; | ||
|
|
||
| import ModalActionButton from '@/components/Button/ModalActionButton'; | ||
| import ModalCancelButton from '@/components/Button/ModalCancelButton'; | ||
| import useModal from '@/hooks/useModal'; | ||
| import { deleteColumn } from '@/services/deleteService'; | ||
| import { putColumn } from '@/services/putService'; | ||
| import { ModifyColumnModalProps } from '@/types/Modal.interface'; | ||
|
|
||
| export default function ModifyColumnModal({ columnId, columnTitle = '', columns }: ModifyColumnModalProps) { | ||
| const { openModal, closeModal } = useModal(); | ||
| const queryClient = useQueryClient(); | ||
|
|
||
| const router = useRouter(); | ||
| const { id: dashboardId } = router.query; | ||
| const [title, setTitle] = useState(columnTitle); | ||
| const [errorMessage, setErrorMessage] = useState(''); | ||
| const columnNames = columns.map((column) => column.title); | ||
|
|
||
| const handleValidCheck = () => { | ||
| if (!title) { | ||
| setErrorMessage('이름을 입력해주세요'); | ||
| } else if (title.length > 10) { | ||
| setErrorMessage('10자 이내로 입력해주세요'); | ||
| } else if (columnNames.includes(title)) { | ||
| setErrorMessage('중복된 컬럼 이름입니다'); | ||
| } else { | ||
| setErrorMessage(''); | ||
| } | ||
| }; | ||
|
|
||
| const handleModifyClick = async () => { | ||
| try { | ||
| await putColumn(columnId, { title }); | ||
| queryClient.invalidateQueries({ queryKey: ['columns', dashboardId] }); | ||
| openModal({ type: 'notification', modalProps: { text: '컬럼이 성공적으로 변경되었습니다.' } }); | ||
| } catch (error) { | ||
| if (error instanceof AxiosError) { | ||
| setErrorMessage(error.response?.data.message || '컬럼 변경을 실패하였습니다.'); | ||
| } else { | ||
| setErrorMessage('컬럼 변경을 실패하였습니다.'); | ||
| console.log(error); | ||
| } | ||
| } | ||
|
Contributor
Author
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. 이 try catch도 요청 보내는 모달마다 반복되어서, 묶을 수 있으면 좋을 것 같습니다!
Contributor
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. 혜원님!! 저 개인적인 질문 있습니다. 만약에 이런 부분 묶는다고 하신다면, 프로젝트 내에서 try catch 사용되는 모든 부분 확인해서 공통된 부분 찾아서 만드시는걸까요?? 저는 그런 식으로 하는데 더 똑똑하게 하는 방법이 있나해서 여쭤봅니다
Contributor
Author
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. 저도 그렇게 합니다! 이번에 말씀드린 건 모든 try catch보다는 모달에서 자꾸 똑같은 에러 핸들링이 사용되는 걸 합치는 건데, |
||
| }; | ||
|
|
||
| const handleDeleteClick = async () => { | ||
| try { | ||
| await deleteColumn(columnId); | ||
| queryClient.invalidateQueries({ queryKey: ['columns', dashboardId] }); | ||
| openModal({ type: 'notification', modalProps: { text: '컬럼이 삭제되었습니다.' } }); | ||
| } catch (error) { | ||
| if (error instanceof AxiosError && error.response?.data.message) { | ||
| openModal({ type: 'notification', modalProps: { text: error.response.data.message } }); | ||
| } else { | ||
| openModal({ type: 'notification', modalProps: { text: '컬럼이 삭제에 실패했습니다.' } }); | ||
| console.log(error); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <div className='modal w-[327px] md:w-[540px]'> | ||
| <h2 className='section-title'>컬럼 관리</h2> | ||
|
|
||
| <div className='my-6 md:mb-7 md:mt-8'> | ||
| <label className='label'>이름</label> | ||
| <input | ||
| type='text' | ||
| className={`input mt-[10px] ${errorMessage ? 'border-2 border-red' : ''}`} | ||
| placeholder='변경될 컬럼 이름을 입력해 주세요' | ||
| value={title} | ||
| onChange={(e) => setTitle(e.target.value)} | ||
| onBlur={handleValidCheck} | ||
| /> | ||
| {errorMessage && <p className='mt-2 text-sm text-red'>{errorMessage}</p>} | ||
| </div> | ||
|
|
||
| <div className='flex flex-col gap-4 md:flex-row md:items-end md:justify-between'> | ||
| <button | ||
| className='text-left text-sm text-gray-9f underline hover:font-bold active:text-gray-78' | ||
| onClick={() => { | ||
| openModal({ | ||
| type: 'confirm', | ||
| modalProps: { text: '컬럼의 모든 카드가 삭제됩니다.', onActionClick: handleDeleteClick }, | ||
| }); | ||
| }} | ||
| > | ||
| 삭제하기 | ||
| </button> | ||
| <div className='flex justify-between md:justify-end md:gap-3'> | ||
| <ModalCancelButton type='button' onClick={closeModal}> | ||
| 취소 | ||
| </ModalCancelButton> | ||
| <ModalActionButton type='button' onClick={handleModifyClick} disabled={!!errorMessage}> | ||
| 변경 | ||
| </ModalActionButton> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| import Image from 'next/image'; | ||
| import React from 'react'; | ||
|
|
||
| import Card from './Card'; | ||
|
|
||
|
|
@@ -11,9 +10,10 @@ import { Column as ColumnType } from '@/types/Column.interface'; | |
|
|
||
| interface ColumnProps { | ||
| column: ColumnType; | ||
| columns: ColumnType[]; | ||
| } | ||
|
|
||
| function Column({ column }: ColumnProps) { | ||
| function Column({ column, columns }: ColumnProps) { | ||
| const { openModal } = useModal(); | ||
| const { | ||
| data: cardList, | ||
|
|
@@ -43,9 +43,12 @@ function Column({ column }: ColumnProps) { | |
| </div> | ||
| {/* Column Edit Button */} | ||
| <button | ||
| className='duration-400 transition ease-in-out hover:rotate-90' | ||
| className='transition duration-300 ease-in-out hover:rotate-90' | ||
|
Contributor
Author
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. @wayandway 마침 딱 400 없고 300/500 있길래 300으로 해뒀습니다!
Contributor
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. 감사합니다 :) |
||
| onClick={() => { | ||
| openModal({ type: 'columnModify', modalProps: { columnId: column.id, columnTitle: column.title } }); | ||
| openModal({ | ||
| type: 'modifyColumn', | ||
| modalProps: { columnId: column.id, columnTitle: column.title, columns }, | ||
| }); | ||
| }} | ||
| > | ||
| <Image src='/icons/gear.svg' width={24} height={24} alt='톱니바퀴 아이콘' /> | ||
|
|
||
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.
실패시 입력 하단에 에러메시지 뜨는 방식이 더 좋은 듯 해서 (대양님 코드 참고) 이 방식 사용했습니다.