From 7d6a635449069d69f7e2148afef62913c59282fb Mon Sep 17 00:00:00 2001 From: 0-hu Date: Tue, 27 May 2025 21:43:01 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20rounded=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ui/Card/index.tsx | 2 +- src/components/ui/CardTag/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ui/Card/index.tsx b/src/components/ui/Card/index.tsx index a2debb8..69217af 100644 --- a/src/components/ui/Card/index.tsx +++ b/src/components/ui/Card/index.tsx @@ -163,7 +163,7 @@ const Card: React.FC = ({ onMouseLeave={() => setIsHovered(false)} onClick={handleClick} className={clsx( - 'z-10 flex flex-col justify-between rounded-[8px] p-[16px] transition-all', + 'z-10 flex flex-col justify-between rounded-[6px] p-[16px] transition-all', sizeStyle[variant], backgroundStyle[variant][state], variant === 'small' && state === 'hover' ? 'z-30' : 'z-10', diff --git a/src/components/ui/CardTag/index.tsx b/src/components/ui/CardTag/index.tsx index e767767..58c6577 100644 --- a/src/components/ui/CardTag/index.tsx +++ b/src/components/ui/CardTag/index.tsx @@ -7,7 +7,7 @@ interface CardTagProps { const CardTag: React.FC = ({ text }) => { return ( -
+
{text}
); From 378c1dcca1f4e138809e925c8c7d4b54c91c9ba8 Mon Sep 17 00:00:00 2001 From: 0-hu Date: Tue, 27 May 2025 21:46:13 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EC=B9=B4=EB=93=9C=20small=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=B5=9C=EB=8C=80=20=ED=91=9C=EA=B8=B0=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=ED=83=9C=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ui/Card/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ui/Card/index.tsx b/src/components/ui/Card/index.tsx index 69217af..1a6918e 100644 --- a/src/components/ui/Card/index.tsx +++ b/src/components/ui/Card/index.tsx @@ -174,7 +174,10 @@ const Card: React.FC = ({
- {tags && tags.map((tag, idx) => )} + {tags && + tags + .slice(0, variant === 'small' && state !== 'hover' ? 2 : tags.length) + .map((tag, idx) => )}
{title}
Date: Tue, 27 May 2025 21:48:47 +0900 Subject: [PATCH 3/4] =?UTF-8?q?TagSearchButton=20=EC=BD=98=EC=86=94=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ui/TagSearchButton/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/ui/TagSearchButton/index.tsx b/src/components/ui/TagSearchButton/index.tsx index 1ade4a4..febf497 100644 --- a/src/components/ui/TagSearchButton/index.tsx +++ b/src/components/ui/TagSearchButton/index.tsx @@ -58,10 +58,7 @@ export const TagSearchButton: React.FC = ({ loadIcon(); }, [id, code, selected]); - console.log('TagSearchButton 렌더링:', tag, '선택됨:', selected); - const handleClick = () => { - console.log('TagSearchButton 클릭:', tag, '현재 선택 상태:', selected); if (onClick) { onClick(); } From 8332a359d10030488f91e340460fd77854dee31b Mon Sep 17 00:00:00 2001 From: 0-hu Date: Wed, 28 May 2025 16:31:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EB=B3=80=EA=B2=BD(=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80->state)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/ArchiveCardGrid/index.tsx | 74 +------------------ src/components/ui/Card/index.tsx | 57 ++++---------- 2 files changed, 15 insertions(+), 116 deletions(-) diff --git a/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx b/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx index 53f2c0a..6d4002d 100644 --- a/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx +++ b/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx @@ -15,66 +15,6 @@ interface ArchiveCardGridProps { sortType: 'popular' | 'latest'; } -// 템플릿 데이터 타입 정의 (현재 사용되지 않음 - API 타입으로 대체됨) -// interface TemplateData { -// id: string; -// templateId: number; -// title: string; -// description: string; -// tags: string[]; -// likes: number; -// content: string; -// folderId: string; -// } - -// 폴더별 더미 데이터 (현재 사용되지 않음 - API 연동으로 대체됨) -// const folderData: Record = { -// '1': Array.from({ length: 32 }, (_, index) => ({ -// id: `fav_${index + 1}`, -// templateId: index + 1, -// title: `찜한 템플릿 ${index + 1}`, -// description: -// '찜한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', -// tags: ['인사말', '자기소개'], -// likes: 150 + index, -// content: `찜한 템플릿 ${index + 1}의 내용입니다.\n\n안녕하세요 잘 부탁드립니다.`, -// folderId: '1', -// })), -// '2': Array.from({ length: 5 }, (_, index) => ({ -// id: `recent_${index + 1}`, -// templateId: 100 + index + 1, -// title: `최근 사용한 템플릿 ${index + 1}`, -// description: -// '최근에 사용한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', -// tags: ['감사글', '공지글'], -// likes: 80 + index, -// content: `최근 사용한 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, -// folderId: '2', -// })), -// '3': Array.from({ length: 8 }, (_, index) => ({ -// id: `user1_${index + 1}`, -// templateId: 200 + index + 1, -// title: `사용자 폴더1 템플릿 ${index + 1}`, -// description: -// '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', -// tags: ['부탁글', '제안글'], -// likes: 60 + index, -// content: `사용자 폴더1 템플릿 ${index + 1}의 내용입니다.\n\n잘 부탁드립니다.`, -// folderId: '3', -// })), -// '4': Array.from({ length: 3 }, (_, index) => ({ -// id: `user2_${index + 1}`, -// templateId: 300 + index + 1, -// title: `사용자 폴더2 템플릿 ${index + 1}`, -// description: -// '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', -// tags: ['후기작성', '소셜글'], -// likes: 40 + index, -// content: `사용자 폴더2 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, -// folderId: '4', -// })), -// }; - export default function ArchiveCardGrid({ selectedFolderId, selectedTag, @@ -82,7 +22,7 @@ export default function ArchiveCardGrid({ }: ArchiveCardGridProps) { const [visibleCards, setVisibleCards] = useState(15); const [isLoading, setIsLoading] = useState(false); - const { openModal, currentModal } = useModalStore(); + const { openModal } = useModalStore(); // 폴더별 데이터 API 연동 const isLikes = selectedFolderId === '1'; @@ -124,14 +64,6 @@ export default function ArchiveCardGrid({ const displayedCards = filteredTemplates.slice(0, visibleCards); const hasMoreCards = visibleCards < filteredTemplates.length; - // 컴포넌트 마운트 시와 모달이 닫힐 때만 카드 클릭 상태 초기화 - useEffect(() => { - // 모달이 닫힐 때만 카드 클릭 상태를 초기화 - if (currentModal === null) { - // clearAllCards(); // useCardStore가 없으므로 주석 처리 - } - }, [currentModal]); - // 폴더가 변경될 때 visibleCards 초기화 useEffect(() => { setVisibleCards(15); @@ -139,14 +71,13 @@ export default function ArchiveCardGrid({ const handleLoadMore = () => { setIsLoading(true); - // 더 불러오기 로직 (추후 API 연결) setTimeout(() => { setVisibleCards((prev) => prev + 15); setIsLoading(false); }, 1000); }; - // 모달 열기 핸들러 - 카드 클릭 시 모달 연결을 위한 상태 처리 + // 모달 열기 핸들러 const handleCardClick = (templateId: number, cardData: Template) => { console.log('카드 클릭:', { templateId, @@ -156,7 +87,6 @@ export default function ArchiveCardGrid({ timestamp: new Date().toISOString(), }); - // 모달 열기 - 모달 스토어에서 지원하는 파라미터만 전달 openModal('view', { templateId, }); diff --git a/src/components/ui/Card/index.tsx b/src/components/ui/Card/index.tsx index 1a6918e..e2c37f5 100644 --- a/src/components/ui/Card/index.tsx +++ b/src/components/ui/Card/index.tsx @@ -15,6 +15,9 @@ interface CardProps { likes: number; onClick?: () => void; className?: string; + isSelected?: boolean; + onSelectionChange?: (cardId: string) => void; + cardId?: string; } const Card: React.FC = ({ @@ -25,14 +28,15 @@ const Card: React.FC = ({ likes, onClick, className, + isSelected = false, + onSelectionChange, + cardId, }) => { - const [isClicked, setIsClicked] = useState(false); const [isHovered, setIsHovered] = useState(false); - const cardRef = useRef(null); const descriptionRef = useRef(null); const [truncatedDescription, setTruncatedDescription] = useState(description); - const state = isClicked ? 'click' : isHovered ? 'hover' : 'default'; + const state = isSelected ? 'click' : isHovered ? 'hover' : 'default'; const sizeStyle: Record = { large: 'w-[320px] h-[204px]', @@ -74,7 +78,7 @@ const Card: React.FC = ({ 'w-[168px] h-[26px] overflow-hidden text-ellipsis whitespace-nowrap', ); - // 3줄 제한을 위한 커스텀 로직 추가 + // 3줄 제한을 위한 커스텀 로직 useEffect(() => { function truncateToThreeLines() { const element = descriptionRef.current; @@ -110,47 +114,13 @@ const Card: React.FC = ({ }; }, [description, variant, state]); - // 클릭 상태 유지 - useEffect(() => { - if (isClicked) { - // 클릭 상태를 로컬 스토리지에 저장하여 페이지 새로고침 후에도 유지 - const cardId = `${title}-${variant}`; - localStorage.setItem(`card-clicked-${cardId}`, 'true'); - } - }, [isClicked, title, variant]); - - // 컴포넌트 마운트 시 이전 클릭 상태 복원 - useEffect(() => { - const cardId = `${title}-${variant}`; - const wasClicked = localStorage.getItem(`card-clicked-${cardId}`); - if (wasClicked === 'true') { - setIsClicked(true); - } - }, [title, variant]); - - // 모달 닫힘 이벤트 감지 - useEffect(() => { - // 모달 닫힘 이벤트 리스너 설정 - const handleModalClose = () => { - const cardId = `${title}-${variant}`; - localStorage.removeItem(`card-clicked-${cardId}`); - setIsClicked(false); - }; - - // 사용자 정의 이벤트 생성 및 구독 - window.addEventListener('modal-closed', handleModalClose); - - // cleanup - return () => { - window.removeEventListener('modal-closed', handleModalClose); - }; - }, [title, variant]); - const handleClick = () => { - if (!isClicked) { - setIsClicked(true); + // 선택 상태 변경 (cardId가 있고 onSelectionChange가 제공된 경우에만) + if (cardId && onSelectionChange) { + onSelectionChange(cardId); } + // 기존 onClick 핸들러 호출 if (onClick) { onClick(); } @@ -158,7 +128,6 @@ const Card: React.FC = ({ return (
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} onClick={handleClick} @@ -167,7 +136,7 @@ const Card: React.FC = ({ sizeStyle[variant], backgroundStyle[variant][state], variant === 'small' && state === 'hover' ? 'z-30' : 'z-10', - isClicked ? 'clicked' : '', // 클릭 상태를 나타내는 CSS 클래스 추가 + isSelected ? 'selected' : '', // 선택 상태를 나타내는 CSS 클래스 className, )} >