diff --git a/app/components/common/ConfirmModal.tsx b/app/components/common/ConfirmModal.tsx
new file mode 100644
index 0000000..c45ee0e
--- /dev/null
+++ b/app/components/common/ConfirmModal.tsx
@@ -0,0 +1,64 @@
+import Modal from "./Modal";
+import Button from "./Button";
+import CheckCircleIcon from "../../assets/icon/icon-check-circle.svg";
+import closeIcon from "../../assets/icon/icon-close.svg";
+
+
+type ConfirmModalProps = {
+ isOpen: boolean;
+ onClose: () => void;
+ onConfirm: () => void;
+ title: string;
+};
+
+export default function ConfirmModal({
+ isOpen,
+ onClose,
+ onConfirm,
+ title,
+}: ConfirmModalProps) {
+ return (
+
+ {/* 상단 좌측 X 아이콘 추가 */}
+
+
+
+
+ {/* 이미지 섹션 */}
+

+
+ {/* 문구 섹션 */}
+
+ {title}
+
+
+
+ {/* 버튼 섹션 */}
+
+ {/* '예' 버튼 */}
+
+
+ {/* '아니오' 버튼 */}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/routes/business/calendar/calendar-content.tsx b/app/routes/business/calendar/calendar-content.tsx
index 1d593e8..0380632 100644
--- a/app/routes/business/calendar/calendar-content.tsx
+++ b/app/routes/business/calendar/calendar-content.tsx
@@ -1,7 +1,7 @@
import { useState, useEffect, useMemo } from "react";
import { useNavigate, useLocation } from "react-router-dom";
-import { getMyCollaborations } from "./api/calendar";
-import type { CampaignCollaboration } from "./api/calendar";
+import { getMyCollaborations, searchCollaborations } from "./api/calendar";
+import type { CampaignCollaboration, } from "./api/calendar";
import FilterBottomSheet from "../components/FilterBottomSheet";
import WeeklyCalendar from "../components/WeeklyCalendar";
import MonthlyCalendar from "../components/MonthlyCalendar";
@@ -30,25 +30,31 @@ export default function CalendarContent() {
const isFiltered = activeFilter !== "전체";
useEffect(() => {
- const fetchAllCampaigns = async () => {
+ const fetchCampaigns = async () => {
try {
setIsLoading(true);
+ // 1. 키워드가 있을 때는 searchCollaborations API 사용
+ // 2. 키워드가 없을 때는 getMyCollaborations API 사용
+
+ const fetchFunction = keyword.trim() ? searchCollaborations : getMyCollaborations;
+
const [applied, sent, received] = await Promise.all([
- getMyCollaborations({ type: "APPLIED", keyword: keyword.trim() || undefined }),
- getMyCollaborations({ type: "SENT", keyword: keyword.trim() || undefined }),
- getMyCollaborations({ type: "RECEIVED", keyword: keyword.trim() || undefined }),
+ fetchFunction({ type: "APPLIED", keyword: keyword.trim() || undefined }),
+ fetchFunction({ type: "SENT", keyword: keyword.trim() || undefined }),
+ fetchFunction({ type: "RECEIVED", keyword: keyword.trim() || undefined }),
]);
setCampaigns([...applied, ...sent, ...received]);
} catch (error) {
- console.error("로드 실패:", error);
+ console.error("데이터 로드 실패:", error);
+ setCampaigns([]); // 에러 시 빈 배열 처리
} finally {
setIsLoading(false);
}
};
- fetchAllCampaigns();
+ fetchCampaigns();
}, [keyword, location.key]);
// 날짜 계산을 별도 useMemo로 분리
@@ -92,8 +98,11 @@ export default function CalendarContent() {
}
};
+ // CalendarContent.tsx 내부 matchingList
+
const matchingList = useMemo(() => {
return campaigns.filter((item) => {
+ // 탭 필터링
const isCorrectSubTab =
matchingSubTab === "sent" ? item.type === "SENT" :
matchingSubTab === "received" ? item.type === "RECEIVED" :
@@ -101,18 +110,14 @@ export default function CalendarContent() {
if (!isCorrectSubTab) return false;
- if (activeFilter === "전체") return true;
-
- const statusMatches = getStatusLabel(item.status) === activeFilter;
-
- const keywordMatches = keyword ? item.brandName.includes(keyword) : true;
-
- return statusMatches && keywordMatches;
-
-
+ // 상태 필터링 (activeFilter가 "전체"가 아닐 때만 적용)
+ if (activeFilter !== "전체") {
+ return getStatusLabel(item.status) === activeFilter;
+ }
+ return true;
});
- }, [campaigns, matchingSubTab, activeFilter, keyword]);
+ }, [campaigns, matchingSubTab, activeFilter]); // keyword는 이제 API 결과(campaigns)에 반영되어 있으므로 제외 가능
console.log("전체 데이터:", campaigns);
console.log("필터된 데이터:", matchingList);
@@ -226,20 +231,18 @@ export default function CalendarContent() {
매칭 현황