Skip to content

Commit f084fc6

Browse files
authored
Merge pull request #590 from depromeet/develop
배포용 PR
2 parents 9951bc6 + 8128ce1 commit f084fc6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+625
-145
lines changed

src/apis/reaction.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ interface ModifyReactionRequest {
4343
emojiType: EmojiType;
4444
}
4545

46+
interface DeleteReactionRequest {
47+
reactionId: number;
48+
}
49+
4650
export const REACTION_API = {
4751
getReactions: async (recordId: number): Promise<GetReactionsResponse> => {
4852
const { data } = await apiInstance.get<GetReactionsResponse>(`/reactions?missionRecordId=${recordId}`);
@@ -53,10 +57,13 @@ export const REACTION_API = {
5357
return data;
5458
},
5559
modifyReaction: async ({ reactionId, emojiType }: ModifyReactionRequest) => {
56-
console.log('reactionId: ', reactionId);
5760
const { data } = await apiInstance.put<AddReactionResponse>(`/reactions/${reactionId}`, { emojiType });
5861
return data;
5962
},
63+
deleteReaction: async ({ reactionId }: DeleteReactionRequest) => {
64+
const { data } = await apiInstance.delete<AddReactionResponse>(`/reactions/${reactionId}`);
65+
return data;
66+
},
6067
};
6168

6269
export const useGetReactions = (recordId: number) => {

src/apis/schema/feed.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export interface FeedItemType extends FeedBaseType {
33
nickname: string;
44
profileImage?: string;
55
memberId: number;
6+
recordStartedAt: string;
67
}
78

89
export interface FeedBaseType {

src/app/feed/FeedItem.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function FeedItem({
2121
profileImage,
2222
recordImageUrl,
2323
duration,
24-
startedAt,
24+
recordStartedAt,
2525
recordId,
2626
}: FeedItemType) {
2727
const { memberId: myId } = useGetMyId();
@@ -54,7 +54,7 @@ function FeedItem({
5454
<p className={missionNameCss}>{name}</p>
5555
{remark && <p className={remarkCss}>{remark}</p>}
5656
<p className={captionCss}>
57-
{sinceDay}일차 <span className={dotCss} /> {dayjs(startedAt).format('YYYY년 MM월 DD일')}
57+
{sinceDay}일차 <div className={dotCss} /> {dayjs(recordStartedAt).format('YYYY년 MM월 DD일')}
5858
</p>
5959
</div>
6060
</Link>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useFollowMissions } from '@/apis/follow';
2+
import { MissionStatus } from '@/apis/schema/mission';
3+
import MissionList from '@/components/MissionList';
4+
import { EVENT_LOG_CATEGORY, EVENT_LOG_NAME } from '@/constants/eventLog';
5+
import { ROUTER } from '@/constants/router';
6+
import { eventLogger } from '@/utils';
7+
8+
interface FollowMissionListProps {
9+
followId: number;
10+
}
11+
12+
function FollowMissionList({ followId }: FollowMissionListProps) {
13+
const { data } = useFollowMissions(followId);
14+
15+
if (!data) {
16+
return null;
17+
}
18+
19+
if (!data || data.followMissions.length === 0) {
20+
return <MissionList.NoticeEmpty />;
21+
}
22+
23+
return (
24+
<MissionList.Container>
25+
{data.followMissions.map((item) => {
26+
const status = item.missionStatus;
27+
28+
const handleClick = () => {
29+
eventLogger.logEvent(EVENT_LOG_CATEGORY.HOME, EVENT_LOG_NAME.HOME.CLICK_FOLLOW_MISSION, {
30+
status,
31+
});
32+
};
33+
34+
if (item.missionRecordId && status === MissionStatus.COMPLETED) {
35+
return (
36+
<MissionList.ReactionLinkItem
37+
href={ROUTER.MISSION.FOLLOW(item.missionId.toString())}
38+
key={item.missionId}
39+
recordId={Number(item.missionRecordId)}
40+
onClick={() => onClickItem(true)}
41+
{...item}
42+
/>
43+
);
44+
}
45+
46+
return (
47+
<MissionList.LinkItem
48+
key={item.missionId}
49+
onClick={handleClick}
50+
href={ROUTER.MISSION.FOLLOW(item.missionId.toString())}
51+
{...item}
52+
/>
53+
);
54+
})}
55+
</MissionList.Container>
56+
);
57+
}
58+
59+
export default FollowMissionList;
60+
61+
const onClickItem = (isReaction: boolean) => {
62+
eventLogger.logEvent(EVENT_LOG_CATEGORY.HOME, EVENT_LOG_NAME.HOME.CLICK_FOLLOW_MISSION, {
63+
isReaction,
64+
});
65+
};
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { type MissionItemTypeWithRecordId, MissionStatus } from '@/apis/schema/mission';
2+
import { useMissions } from '@/app/home/home.hooks';
3+
import MissionList from '@/components/MissionList';
4+
import { EVENT_LOG_CATEGORY, EVENT_LOG_NAME } from '@/constants/eventLog';
5+
import { ROUTER } from '@/constants/router';
6+
import { eventLogger } from '@/utils';
7+
8+
function MissionListInner() {
9+
const { missionList, isLoading, progressMissionId } = useMissions();
10+
11+
if (isLoading) {
12+
return <MissionList.Skeleton />;
13+
}
14+
15+
if (missionList.length === 0) {
16+
return <MissionList.SuggestAdd />;
17+
}
18+
19+
return (
20+
<MissionList.Container>
21+
{missionList.map((item) => {
22+
const { moveHref, status } = getMoveHref(item, progressMissionId);
23+
24+
if (item.missionRecordId && status === MissionStatus.COMPLETED) {
25+
return (
26+
<MissionList.ReactionLinkItem
27+
href={moveHref}
28+
key={item.missionId}
29+
{...item}
30+
missionStatus={status}
31+
recordId={Number(item.missionRecordId)}
32+
onClick={() => onClickItem(true)}
33+
/>
34+
);
35+
}
36+
37+
return (
38+
<MissionList.LinkItem
39+
href={moveHref}
40+
key={item.missionId}
41+
{...item}
42+
missionStatus={status}
43+
onClick={() => onClickItem(false)}
44+
/>
45+
);
46+
})}
47+
</MissionList.Container>
48+
);
49+
}
50+
51+
export default MissionListInner;
52+
53+
const getMoveHref = (item: MissionItemTypeWithRecordId, progressMissionId: string | null) => {
54+
const isProgressingMission = progressMissionId === String(item.missionId);
55+
const status = isProgressingMission ? MissionStatus.PROGRESSING : item.missionStatus;
56+
57+
const missionId = item.missionId.toString();
58+
const moveHref = isProgressingMission
59+
? ROUTER.MISSION.STOP_WATCH(missionId)
60+
: item.missionRecordId && status === MissionStatus.REQUIRED
61+
? ROUTER.RECORD.CREATE(item.missionRecordId.toString())
62+
: ROUTER.MISSION.DETAIL(missionId);
63+
64+
return { moveHref, status };
65+
};
66+
67+
const onClickItem = (isReaction: boolean) => {
68+
eventLogger.logEvent(EVENT_LOG_CATEGORY.HOME, EVENT_LOG_NAME.HOME.CLICK_MY_MISSION, {
69+
isReaction,
70+
});
71+
};

src/app/home/MissionList.tsx src/app/home/FollowContent/MyMissionList.tsx

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
'use client';
22

33
import Link from 'next/link';
4-
import MissionListInner from '@/app/home/MissionInnerList';
4+
import MissionListInner from '@/app/home/FollowContent/MyMissionInnerList';
55
import Icon from '@/components/Icon';
66
import { EVENT_LOG_CATEGORY, EVENT_LOG_NAME } from '@/constants/eventLog';
77
import { ROUTER } from '@/constants/router';
88
import { css } from '@/styled-system/css';
99
import { flex } from '@/styled-system/patterns';
1010
import { eventLogger } from '@/utils';
1111

12+
function MissionList() {
13+
return (
14+
<div className={containerCss}>
15+
<MissionListHeader />
16+
<ul className={listCss}>
17+
<MissionListInner />
18+
</ul>
19+
</div>
20+
);
21+
}
22+
23+
export default MissionList;
24+
1225
function MissionListHeader() {
1326
const handlePlusClick = () => {
1427
eventLogger.logEvent(EVENT_LOG_CATEGORY.HOME, EVENT_LOG_NAME.HOME.CLICK_PLUS_BUTTON);
@@ -24,19 +37,6 @@ function MissionListHeader() {
2437
);
2538
}
2639

27-
function MissionList() {
28-
return (
29-
<div className={containerCss}>
30-
<MissionListHeader />
31-
<ul className={listCss}>
32-
<MissionListInner />
33-
</ul>
34-
</div>
35-
);
36-
}
37-
38-
export default MissionList;
39-
4040
const containerCss = css({
4141
height: '100%',
4242
});

src/app/home/FollowContent.tsx src/app/home/FollowContent/index.tsx

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,56 @@
11
import { useSearchParams } from 'next/navigation';
22
import { useFollowMembers } from '@/apis/follow';
33
import { type FollowMemberType } from '@/apis/schema/member';
4-
import FollowMissionList, { FollowMissionListSkeleton } from '@/app/home/FollowMissionList';
5-
import FollowSummary, { FollowSummarySkeleton } from '@/app/home/FollowSummary';
6-
import MissionList from '@/app/home/MissionList';
4+
import MissionList from '@/components/MissionList';
75
import { flex } from '@styled-system/patterns';
86

7+
import FollowMissionList from './FollowMissionList';
8+
import FollowSummary, { FollowSummarySkeleton } from './FollowSummary';
9+
import HomeMissionList from './MyMissionList';
10+
911
function FollowContent() {
1012
const { data: selectedFollowData, isLoading, isFollower } = useGetSelectFollowData();
1113

1214
if (!isFollower)
1315
return (
1416
<div className={containerCss}>
15-
<MissionList />
17+
<HomeMissionList />
1618
</div>
1719
);
1820

1921
if (isLoading || !selectedFollowData) {
2022
return (
2123
<div className={containerCss}>
2224
<FollowSummarySkeleton />
23-
<FollowMissionListSkeleton />
25+
26+
<h2 className={headingCss}>
27+
<span>미션 목록</span>
28+
</h2>
29+
<MissionList.Skeleton />
2430
</div>
2531
);
2632
}
2733

2834
return (
2935
<div className={containerCss}>
3036
<FollowSummary {...selectedFollowData} />
37+
38+
<h2 className={headingCss}>
39+
<span>미션 목록</span>
40+
</h2>
3141
<FollowMissionList followId={selectedFollowData.memberId} />
3242
</div>
3343
);
3444
}
3545

3646
export default FollowContent;
3747

48+
const headingCss = flex({
49+
padding: '12px 4px',
50+
textStyle: 'body4',
51+
color: 'text.primary',
52+
});
53+
3854
const useGetSelectFollowData = (): { data: FollowMemberType | null; isLoading: boolean; isFollower: boolean } => {
3955
const { data, isLoading } = useFollowMembers();
4056
const searchParams = useSearchParams();
File renamed without changes.

src/app/home/UserProfile.tsx src/app/home/FollowList/UserProfile.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useGetMembersMe } from '@/apis/member';
2-
import ProfileItem from '@/app/home/ProfileItem';
2+
import ProfileItem from '@/app/home/FollowList/ProfileItem';
33
import { type FollowDataState } from '@/app/page';
44

55
interface UserProfileProps {

src/app/home/FollowList.tsx src/app/home/FollowList/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Link from 'next/link';
22
import { useRouter, useSearchParams } from 'next/navigation';
33
import { useFollowMembers } from '@/apis/follow';
4-
import UserProfile from '@/app/home/UserProfile';
4+
import UserProfile from '@/app/home/FollowList/UserProfile';
55
import { type FollowDataState } from '@/app/page';
66
import Icon from '@/components/Icon';
77
import MotionDiv from '@/components/Motion/MotionDiv';

src/app/home/MissionInnerList.tsx

-67
This file was deleted.

src/app/mission/[id]/detail/MissionHistoryBanner/MissionHistoryBanner.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export default MissionHistoryBanner;
2929

3030
export const missionHistoryBannerCss = css({
3131
borderRadius: '22px',
32-
boxShadow: '0px 5px 50px 4px #5C4E7A80 inset, 0px 4px 20px 0px #100F1733',
33-
background: 'linear-gradient(92.59deg, rgba(25, 23, 27, 0.8) 0.82%, rgba(24, 25, 33, 0.8) 99.97%)',
32+
background: 'linear-gradient(0deg, rgba(181, 184, 255, 0.02) 0%, rgba(181, 184, 255, 0.02) 100%), #18181D',
33+
boxShadow: '-10px 0px 100px 4px rgba(93, 96, 178, 0.10) inset',
3434
transition: 'all 0.3s ease',
3535

3636
'& img': {

0 commit comments

Comments
 (0)