Skip to content

Commit 54dd145

Browse files
authored
build: github actions 재실행 및 업데이트 코드 배포 시도
build: github actions 재실행 및 업데이트 코드 배포 시도
2 parents 3541aee + 381de1f commit 54dd145

5 files changed

Lines changed: 101 additions & 45 deletions

File tree

src/components/common/Tab/FolderTab.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
import React from 'react';
2+
import BaseBadge from '../Tag/BaseBadge';
23

34
type FolderTabProps = {
4-
children: React.ReactNode;
5+
TabTitle: React.ReactNode;
6+
TabAlarm?: number;
57
isActive?: boolean;
68
className?: string;
79
onClick?: () => void;
810
};
911

10-
const FolderTab = ({ children, isActive = false, className="", onClick }: FolderTabProps) => {
12+
const FolderTab = ({
13+
TabTitle,
14+
TabAlarm,
15+
isActive = false,
16+
className = '',
17+
onClick,
18+
}: FolderTabProps) => {
19+
const badge =
20+
TabAlarm && TabAlarm > 0 ? (
21+
<BaseBadge size="lg">{TabAlarm > 99 ? '99+' : TabAlarm}</BaseBadge>
22+
) : null;
23+
1124
return (
1225
<div
1326
className={`inline-flex h-[7rem] min-w-[10.6rem] flex-shrink-0 flex-wrap content-center items-center justify-center gap-[0.6rem] px-[3.2rem] py-0 text-body-16_M500 hover:text-black-130 ${
1427
isActive
15-
? 'rounded-tl-[12px] bg-black-10 rounded-tr-[12px] border border-solid border-l-black-50 border-r-black-50 border-t-black-50 border-b-black-10 text-black-130'
16-
: ' text-black-70'
28+
? 'rounded-tl-[12px] rounded-tr-[12px] border border-solid border-b-black-10 border-l-black-50 border-r-black-50 border-t-black-50 bg-black-10 text-black-130'
29+
: 'text-black-70'
1730
} ${className}`}
1831
onClick={onClick}
1932
>
20-
{children}
33+
<div>{TabTitle}</div>
34+
{badge}
2135
</div>
2236
);
2337
};

src/components/common/Tab/FolderTabGroup.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import FolderTab from "./FolderTab";
44
interface TabItem {
55
id: string | number;
66
label: React.ReactNode;
7+
alarm?: number;
78
className?: string;
89
}
910

@@ -32,9 +33,9 @@ export const FolderTabGroup: React.FC<FolderTabGroupProps> = ({
3233
isActive={idx === activeIndex}
3334
onClick={() => handleClick(idx)}
3435
className={`flex-1 basis-0 cursor-pointer ${tab.className ?? ""}`}
35-
>
36-
{tab.label}
37-
</FolderTab>
36+
TabTitle={tab.label}
37+
TabAlarm={tab.alarm}
38+
/>
3839
))}
3940
</div>
4041
);

src/constants/ProfilePostColumns.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import EditIc from '../assets/icons/profile/ic_edit.svg?react';
1414
import TrashIc from '../assets/icons/profile/ic_trashcan.svg?react';
1515
import BaseTag from '../components/common/Tag/BaseTag';
1616
import ArrowIc from '../assets/icons/ic_arrow_down_large.svg?react';
17-
import BaseBadge from '../components/common/Tag/BaseBadge.tsx';
1817

1918
export type PostRow = {
2019
id: string;

src/hooks/useApplicants.ts

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import {
44
approveApplicant,
55
rejectApplicant,
66
UserProfile,
7+
getMyApply,
8+
postApply,
79
} from '../api/applicants';
10+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
811

912
export function useApplicants(projectId?: number) {
1013
const [list, setList] = useState<UserProfile[]>([]);
1114
const [loading, setLoading] = useState(false);
12-
const [error, setError] = useState<string | null>(null);
15+
const [error, setError] = useState<string | null>(null);
1316

1417
const fetch = useCallback(async () => {
1518
if (projectId == null) return;
@@ -25,29 +28,63 @@ export function useApplicants(projectId?: number) {
2528
}
2629
}, [projectId]);
2730

28-
useEffect(() => { fetch(); }, [fetch]);
31+
useEffect(() => {
32+
fetch();
33+
}, [fetch]);
2934

30-
const approve = useCallback(async (userId: string) => {
31-
if (projectId == null) return;
32-
setList(prev => prev.filter(u => u.id !== userId));
33-
try {
34-
await approveApplicant(projectId, userId);
35-
} finally {
36-
fetch();
37-
}
38-
}, [projectId, fetch]);
35+
const approve = useCallback(
36+
async (userId: string) => {
37+
if (projectId == null) return;
38+
setList((prev) => prev.filter((u) => u.id !== userId));
39+
try {
40+
await approveApplicant(projectId, userId);
41+
} finally {
42+
fetch();
43+
}
44+
},
45+
[projectId, fetch],
46+
);
3947

40-
const reject = useCallback(async (userId: string) => {
41-
if (projectId == null) return;
42-
setList(prev => prev.filter(u => u.id !== userId));
43-
try {
44-
await rejectApplicant(projectId, userId);
45-
} finally {
46-
fetch();
47-
}
48-
}, [projectId, fetch]);
48+
const reject = useCallback(
49+
async (userId: string) => {
50+
if (projectId == null) return;
51+
setList((prev) => prev.filter((u) => u.id !== userId));
52+
try {
53+
await rejectApplicant(projectId, userId);
54+
} finally {
55+
fetch();
56+
}
57+
},
58+
[projectId, fetch],
59+
);
4960

5061
return { applicants: list, loading, error, refetch: fetch, approve, reject };
5162
}
5263

5364
export default useApplicants;
65+
66+
// 프로젝트 지원
67+
68+
export const usePostApply = (projectId: number) => {
69+
const queryClient = useQueryClient();
70+
return useMutation({
71+
mutationFn: (position: string) => postApply(projectId, position),
72+
onSuccess: () => {
73+
queryClient.invalidateQueries({ queryKey: ['postApply', projectId] });
74+
},
75+
onError: (error) => {
76+
console.error('Error Apply:', error);
77+
},
78+
});
79+
};
80+
81+
// 내가 지원한 프로젝트 조회
82+
83+
export const useGetMyApply = (status?: string) => {
84+
return useQuery({
85+
queryKey: ['getMyApply', status],
86+
queryFn: () => getMyApply(status),
87+
staleTime: 1000 * 60 * 5, // 5분 동안 캐시 유지
88+
refetchOnWindowFocus: false, // 윈도우 포커스 시 재요청하지 않음
89+
});
90+
};

src/pages/profile/ProfilePosts.tsx

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ export default function ProfilePosts() {
127127
[data, sortKey, searchText],
128128
);
129129

130-
const [baselines, setBaselines] = useState<Record<TabKey, number>>(loadBaselines());
130+
const [baselines, setBaselines] =
131+
useState<Record<TabKey, number>>(loadBaselines());
131132
const [totals, setTotals] = useState<Record<TabKey, number>>({
132133
postManagement: 0,
133134
applicantManagement: 0,
@@ -143,7 +144,9 @@ export default function ProfilePosts() {
143144
useEffect(() => {
144145
let alive = true;
145146
(async () => {
146-
const ids = rows.map((r) => Number(r.id)).filter((n) => Number.isFinite(n));
147+
const ids = rows
148+
.map((r) => Number(r.id))
149+
.filter((n) => Number.isFinite(n));
147150
if (ids.length === 0) {
148151
if (!alive) return;
149152
setTotals((prev) => ({ ...prev, memberManagement: 0 }));
@@ -177,9 +180,18 @@ export default function ProfilePosts() {
177180
}, [postsTotal, applicantsTotal]);
178181

179182
const badgeCounts = {
180-
postManagement: Math.max(0, totals.postManagement - baselines.postManagement),
181-
applicantManagement: Math.max(0, totals.applicantManagement - baselines.applicantManagement),
182-
memberManagement: Math.max(0, totals.memberManagement - baselines.memberManagement),
183+
postManagement: Math.max(
184+
0,
185+
totals.postManagement - baselines.postManagement,
186+
),
187+
applicantManagement: Math.max(
188+
0,
189+
totals.applicantManagement - baselines.applicantManagement,
190+
),
191+
memberManagement: Math.max(
192+
0,
193+
totals.memberManagement - baselines.memberManagement,
194+
),
183195
};
184196

185197
useEffect(() => {
@@ -193,18 +205,10 @@ export default function ProfilePosts() {
193205
const tabsWithBadges = useMemo(() => {
194206
return profilePostTabs.map((t) => {
195207
const key = t.key as TabKey;
196-
const n = badgeCounts[key];
197-
const badge =
198-
n > 0 ? <BaseBadge size="lg">{n > 99 ? '99+' : n}</BaseBadge> : null;
199-
200208
return {
201209
...t,
202-
label: (
203-
<span className="flex items-center gap-[0.6rem]">
204-
{t.label}
205-
{badge}
206-
</span>
207-
),
210+
label: t.label,
211+
alarm: badgeCounts[key],
208212
};
209213
});
210214
}, [badgeCounts]);
@@ -237,7 +241,8 @@ export default function ProfilePosts() {
237241
<FolderTabGroup
238242
tabs={tabsWithBadges.map((t) => ({
239243
id: t.key,
240-
label: t.label,
244+
label: <>{t.label}</>,
245+
alarm: badgeCounts[t.key],
241246
}))}
242247
activeIndex={tabsWithBadges.findIndex((t) => t.key === activeKey)}
243248
onTabChange={(idx) => setActiveKey(tabsWithBadges[idx].key as TabKey)}

0 commit comments

Comments
 (0)