From 1e3084e9dd74056ad0a84bfbcea0860cad4f26d5 Mon Sep 17 00:00:00 2001
From: Ji Ho June <129824629+ho0010@users.noreply.github.com>
Date: Sun, 2 Nov 2025 15:25:50 +0900
Subject: [PATCH 1/4] =?UTF-8?q?fix:=20Fragment=EC=97=90=20key=EA=B0=80=20?=
=?UTF-8?q?=EC=97=86=EC=96=B4=EC=84=9C=20=EC=83=9D=EA=B8=B0=EB=8A=94=20?=
=?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/feed/TotalFeed.tsx | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/components/feed/TotalFeed.tsx b/src/components/feed/TotalFeed.tsx
index b183a129..4d2dbf86 100644
--- a/src/components/feed/TotalFeed.tsx
+++ b/src/components/feed/TotalFeed.tsx
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
+import { Fragment } from 'react';
import FollowList from './FollowList';
import FeedPost from './FeedPost';
import RecommendedFeedSection from './RecommendedFeedSection';
@@ -14,19 +15,13 @@ const TotalFeed = ({ showHeader, posts = [], isTotalFeed }: FeedListProps) => {
{hasPosts ? (
<>
{posts.map((post, index) => (
- <>
-
+
+
{/* 10개마다 추천 섹션 반복 표시 */}
{(index + 1) % 10 === 0 && (
)}
- >
+
))}
>
) : (
From 03853b1e6896460677f6e1ce7f7f14d210cd9871 Mon Sep 17 00:00:00 2001
From: Ji Ho June <129824629+ho0010@users.noreply.github.com>
Date: Sun, 2 Nov 2025 15:30:49 +0900
Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?=
=?UTF-8?q?=EB=AA=A8=EC=9E=84=EB=B0=A9=EC=9D=84=20=EB=82=B4=20=EB=AA=A8?=
=?UTF-8?q?=EC=9E=84=EB=B0=A9=20=EC=98=B5=EC=85=98=EC=9C=BC=EB=A1=9C=20?=
=?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=AA=A8=EC=9E=84=20=EB=A9=94=EC=9D=B8=20?=
=?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=82=AC=EC=9A=A9=EC=84=B1=20?=
=?UTF-8?q?=EA=B0=9C=EC=84=A0=202=EC=B0=A8=20=EC=9E=91=EC=97=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/common/MainHeader.tsx | 10 +-
src/components/group/CompletedGroupModal.tsx | 195 -------------------
src/components/group/GroupCard.tsx | 16 +-
src/components/group/MyGroupModal.tsx | 64 ++----
src/pages/group/Group.tsx | 8 +-
5 files changed, 38 insertions(+), 255 deletions(-)
delete mode 100644 src/components/group/CompletedGroupModal.tsx
diff --git a/src/components/common/MainHeader.tsx b/src/components/common/MainHeader.tsx
index a2aaf386..29da8d20 100644
--- a/src/components/common/MainHeader.tsx
+++ b/src/components/common/MainHeader.tsx
@@ -1,6 +1,5 @@
import { useEffect, useState } from 'react';
import headerLogo from '../../assets/header/header-logo.svg';
-import groupDoneLogo from '../../assets/header/group-done.svg';
import findUserLogo from '../../assets/header/findUser.svg';
import bellLogo from '../../assets/header/bell.svg';
import bellExistLogo from '../../assets/header/exist-bell.svg';
@@ -40,11 +39,10 @@ const MainHeader = ({ type, leftButtonClick, rightButtonClick }: MainHeaderProps
-
+ {type === 'home' && (
+
+ )}
+
void;
-}
-
-const CompletedGroupModal = ({ onClose }: CompletedGroupModalProps) => {
- const navigate = useNavigate();
- const [rooms, setRooms] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
- const [nickname, setNickname] = useState('');
-
- useEffect(() => {
- document.body.style.overflow = 'hidden';
- return () => {
- document.body.style.overflow = '';
- };
- }, []);
-
- const convertRoomToGroup = (room: Room): Group => {
- return {
- id: room.roomId.toString(),
- title: room.roomName,
- userName: '',
- participants: room.memberCount,
- maximumParticipants: room.recruitCount,
- coverUrl: room.bookImageUrl,
- deadLine: '',
- isOnGoing: false,
- type: room.type,
- };
- };
-
- const handleGroupCardClick = (group: Group) => {
- navigate(`/group/detail/joined/${group.id}`);
- };
-
- useEffect(() => {
- const fetchCompletedRooms = async () => {
- try {
- setIsLoading(true);
- setError(null);
- const response = await getMyRooms('expired', null);
- if (response.isSuccess) {
- setRooms(response.data.roomList);
- } else {
- setError(response.message);
- }
- } catch (error) {
- console.error('완료된 방 목록 조회 실패:', error);
- setError('완료된 방 목록을 불러오는데 실패했습니다.');
- } finally {
- setIsLoading(false);
- }
- };
-
- const fetchNickname = async () => {
- try {
- const profile = await getMyProfile();
- setNickname(profile.nickname);
- } catch {
- setNickname('');
- }
- };
-
- fetchCompletedRooms();
- fetchNickname();
- }, []);
-
- const convertedGroups = rooms.map(convertRoomToGroup);
- return (
-
-
- }
- onLeftClick={onClose}
- />
-
- {nickname
- ? `${nickname}님이 참여했던 모임방들을 확인해보세요.`
- : '참여했던 모임방들을 확인해보세요.'}
-
-
- {isLoading ? (
- 로딩 중...
- ) : error ? (
- {error}
- ) : convertedGroups.length > 0 ? (
- convertedGroups.map(group => (
- handleGroupCardClick(group)}
- />
- ))
- ) : (
-
- 완료된 모임방이 없어요
- 아직 완료된 모임방이 없습니다.
-
- )}
-
-
-
- );
-};
-
-export default CompletedGroupModal;
-
-const Text = styled.p`
- font-size: ${typography.fontSize.sm};
- font-weight: ${typography.fontWeight.regular};
- color: ${colors.white};
- margin: 20px;
-`;
-
-const Content = styled.div<{ isEmpty?: boolean }>`
- display: grid;
- gap: 20px;
- overflow-y: ${({ isEmpty }) => (isEmpty ? 'visible' : 'auto')};
- padding: 0 20px;
- grid-template-columns: 1fr;
- margin-bottom: 70px;
-
- @media (min-width: 584px) {
- grid-template-columns: 1fr 1fr;
- }
-
- & > *:only-child {
- grid-column: 1 / -1;
- }
- &::-webkit-scrollbar {
- display: none;
- }
- -ms-overflow-style: none;
- scrollbar-width: none;
-`;
-
-const LoadingMessage = styled.div`
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 40px 20px;
- color: ${colors.white};
- font-size: ${typography.fontSize.base};
-`;
-
-const ErrorMessage = styled.div`
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 40px 20px;
- color: #ff6b6b;
- font-size: ${typography.fontSize.base};
-`;
-
-const EmptyState = styled.div`
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- padding: 40px 20px;
- color: ${colors.grey[100]};
- text-align: center;
- height: 70%;
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
-`;
-
-const EmptyTitle = styled.p`
- font-size: ${typography.fontSize.lg};
- font-weight: ${typography.fontWeight.semibold};
- margin-bottom: 8px;
- color: ${colors.white};
-`;
-
-const EmptySubText = styled.p`
- font-size: ${typography.fontSize.sm};
- font-weight: ${typography.fontWeight.regular};
- color: ${colors.grey[100]};
-`;
diff --git a/src/components/group/GroupCard.tsx b/src/components/group/GroupCard.tsx
index 79700a0a..797750b4 100644
--- a/src/components/group/GroupCard.tsx
+++ b/src/components/group/GroupCard.tsx
@@ -13,10 +13,14 @@ interface Props {
onClick?: () => void;
isFirstCard?: boolean;
isPublic?: boolean;
+ isCompleted?: boolean;
}
export const GroupCard = forwardRef(
- ({ group, isOngoing, type = 'main', isRecommend = false, onClick, isFirstCard }, ref) => {
+ (
+ { group, isOngoing, type = 'main', isRecommend = false, onClick, isFirstCard, isCompleted },
+ ref,
+ ) => {
return (
@@ -33,9 +37,13 @@ export const GroupCard = forwardRef(
{group.participants}
- / {group.maximumParticipants}명
+ {!isCompleted && (
+ / {group.maximumParticipants}명
+ )}
+ {isCompleted && 명}
- {(type !== 'modal' || group.type !== 'expired') &&
+ {!isCompleted &&
+ (type !== 'modal' || group.type !== 'expired') &&
(isOngoing === true ? (
{group.deadLine} 종료
@@ -138,7 +146,7 @@ const Bottom = styled.div`
const Participant = styled.div<{ isRecommend: boolean }>`
display: flex;
align-items: center;
- gap: 6px;
+ gap: 4px;
color: ${colors.white};
font-size: ${typography.fontSize.xs};
font-weight: ${typography.fontWeight.medium};
diff --git a/src/components/group/MyGroupModal.tsx b/src/components/group/MyGroupModal.tsx
index 6605ece2..813b623a 100644
--- a/src/components/group/MyGroupModal.tsx
+++ b/src/components/group/MyGroupModal.tsx
@@ -21,7 +21,7 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
};
}, []);
const navigate = useNavigate();
- const [selected, setSelected] = useState<'진행중' | '모집중' | ''>('');
+ const [selected, setSelected] = useState<'진행중' | '모집중' | '완료' | ''>('');
const [rooms, setRooms] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
@@ -52,12 +52,14 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
setNextCursor(null);
setIsLast(false);
- const roomType: RoomType =
+ const roomType: RoomType | 'expired' =
selected === '진행중'
? 'playing'
: selected === '모집중'
? 'recruiting'
- : 'playingAndRecruiting';
+ : selected === '완료'
+ ? 'expired'
+ : 'playingAndRecruiting';
const response = await getMyRooms(roomType, null);
@@ -87,12 +89,14 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
isFetchingRef.current = true;
setIsLoading(true);
try {
- const roomType: RoomType =
+ const roomType: RoomType | 'expired' =
selected === '진행중'
? 'playing'
: selected === '모집중'
? 'recruiting'
- : 'playingAndRecruiting';
+ : selected === '완료'
+ ? 'expired'
+ : 'playingAndRecruiting';
const res = await getMyRooms(roomType, nextCursor);
if (res.isSuccess) {
@@ -119,40 +123,6 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
}
};
- useEffect(() => {
- const fetchRooms = async () => {
- try {
- setIsLoading(true);
- setError(null);
- setNextCursor(null);
- setIsLast(false);
-
- const roomType: RoomType =
- selected === '진행중'
- ? 'playing'
- : selected === '모집중'
- ? 'recruiting'
- : 'playingAndRecruiting';
-
- const res = await getMyRooms(roomType, null);
- if (res.isSuccess) {
- setRooms(res.data.roomList);
- setNextCursor(res.data.nextCursor);
- setIsLast(res.data.isLast);
- } else {
- setError(res.message);
- }
- } catch (e) {
- console.log(e);
- setError('방 목록을 불러오는데 실패했습니다.');
- } finally {
- setIsLoading(false);
- }
- };
-
- fetchRooms();
- }, [selected]);
-
useEffect(() => {
const tryFill = async () => {
if (!contentRef.current || isLast) return;
@@ -169,6 +139,7 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
}
};
tryFill();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [rooms, nextCursor, isLast]);
useEffect(() => {
@@ -180,7 +151,9 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
const convertedGroups = rooms.map(convertRoomToGroup);
const handleGroupCardClick = (group: Group) => {
- if (selected === '모집중') {
+ if (selected === '완료') {
+ navigate(`/group/detail/joined/${group.id}`);
+ } else if (selected === '모집중') {
navigate(`/group/detail/${group.id}`);
} else if (selected === '진행중') {
navigate(`/group/detail/joined/${group.id}`);
@@ -202,7 +175,7 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
/>
- {(['진행중', '모집중'] as const).map(tab => (
+ {(['진행중', '모집중', '완료'] as const).map(tab => (
{
group={group}
isOngoing={group.isOnGoing}
type="modal"
+ isCompleted={selected === '완료'}
onClick={() => handleGroupCardClick(group)}
/>
))}
@@ -235,14 +209,18 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
? '진행중인 모임방이 없어요'
: selected === '모집중'
? '모집중인 모임방이 없어요'
- : '참여중인 모임방이 없어요'}
+ : selected === '완료'
+ ? '완료된 모임방이 없어요'
+ : '참여중인 모임방이 없어요'}
{selected === '진행중'
? '진행중인 모임방에 참여해보세요!'
: selected === '모집중'
? '모집중인 모임방에 참여해보세요!'
- : '첫 번째 모임방에 참여해보세요!'}
+ : selected === '완료'
+ ? '아직 완료된 모임방이 없습니다.'
+ : '첫 번째 모임방에 참여해보세요!'}
)}
diff --git a/src/pages/group/Group.tsx b/src/pages/group/Group.tsx
index 9c43a6f8..24bbc767 100644
--- a/src/pages/group/Group.tsx
+++ b/src/pages/group/Group.tsx
@@ -8,7 +8,6 @@ import styled from '@emotion/styled';
import { RecruitingGroupCarousel, type Section } from '@/components/group/RecruitingGroupCarousel';
import { useState, useEffect } from 'react';
import { MyGroupModal } from '@/components/group/MyGroupModal';
-import CompletedGroupModal from '@/components/group/CompletedGroupModal';
import { useNavigate } from 'react-router-dom';
import makegroupfab from '../../assets/common/makegroupfab.svg';
import searchChar from '../../assets/common/searchChar.svg';
@@ -32,7 +31,6 @@ const convertRoomItemToGroup = (
const Group = () => {
const navigate = useNavigate();
const [isMyGroupModalOpen, setIsMyGroupModalOpen] = useState(false);
- const [isCompletedGroupModalOpen, setIsCompletedGroupModalOpen] = useState(false);
const [sections, setSections] = useState([
{ title: '최근 생성된 독서 모임방', groups: [] },
{ title: '마감 임박한 독서 모임방', groups: [] },
@@ -86,9 +84,6 @@ const Group = () => {
const openMyGroupModal = () => setIsMyGroupModalOpen(true);
const closeMyGroupModal = () => setIsMyGroupModalOpen(false);
- const openCompletedGroupModal = () => setIsCompletedGroupModalOpen(true);
- const closeCompletedGroupModal = () => setIsCompletedGroupModalOpen(false);
-
const handleSearchBarClick = () => {
navigate('/group/search');
};
@@ -108,10 +103,9 @@ const Group = () => {
return (
{isMyGroupModalOpen && }
- {isCompletedGroupModalOpen && }
From 967390cd3e3fdf86dc9bdb39b76ae7aa5711869e Mon Sep 17 00:00:00 2001
From: Ji Ho June <129824629+ho0010@users.noreply.github.com>
Date: Sun, 2 Nov 2025 15:56:01 +0900
Subject: [PATCH 3/4] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?=
=?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/group/MyGroupModal.tsx | 2 +-
src/pages/group/Group.tsx | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/components/group/MyGroupModal.tsx b/src/components/group/MyGroupModal.tsx
index 813b623a..c950e909 100644
--- a/src/components/group/MyGroupModal.tsx
+++ b/src/components/group/MyGroupModal.tsx
@@ -52,7 +52,7 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
setNextCursor(null);
setIsLast(false);
- const roomType: RoomType | 'expired' =
+ const roomType: RoomType =
selected === '진행중'
? 'playing'
: selected === '모집중'
diff --git a/src/pages/group/Group.tsx b/src/pages/group/Group.tsx
index 24bbc767..43c3b4fb 100644
--- a/src/pages/group/Group.tsx
+++ b/src/pages/group/Group.tsx
@@ -103,11 +103,7 @@ const Group = () => {
return (
{isMyGroupModalOpen && }
-
+
From f4eb20b5ba21d1ffadd72b935a04cd44bbd74096 Mon Sep 17 00:00:00 2001
From: Ji Ho June <129824629+ho0010@users.noreply.github.com>
Date: Sun, 2 Nov 2025 16:02:39 +0900
Subject: [PATCH 4/4] =?UTF-8?q?remove:=20=EC=A4=91=EB=B3=B5=EB=90=9C=20?=
=?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=84=A0=EC=96=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/group/MyGroupModal.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/group/MyGroupModal.tsx b/src/components/group/MyGroupModal.tsx
index c950e909..75351bd9 100644
--- a/src/components/group/MyGroupModal.tsx
+++ b/src/components/group/MyGroupModal.tsx
@@ -89,7 +89,7 @@ export const MyGroupModal = ({ onClose }: MyGroupModalProps) => {
isFetchingRef.current = true;
setIsLoading(true);
try {
- const roomType: RoomType | 'expired' =
+ const roomType: RoomType =
selected === '진행중'
? 'playing'
: selected === '모집중'