From bd53d31b517d8d113333331d5ee92a3169e14f17 Mon Sep 17 00:00:00 2001 From: Jio Date: Sun, 1 Feb 2026 21:58:10 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=EB=B7=B0=20ui=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/components/CampaignCard.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/app/routes/business/components/CampaignCard.tsx b/app/routes/business/components/CampaignCard.tsx index 4f02457..dce2442 100644 --- a/app/routes/business/components/CampaignCard.tsx +++ b/app/routes/business/components/CampaignCard.tsx @@ -39,39 +39,41 @@ export default function CampaignCard({ return ( -
- {/* 브랜드 + 제목/날짜 */} -
+ {/* 1. 컨테이너: 세로 배치, 간격 10px, 하단 정렬 */} +
+ + {/* 2. 상단 정보 섹션 */} +
+ {/* 브랜드명 */}
- {brand} + + {brand} + 이동
+ {/* 제목 및 날짜: 양 끝 정렬 */}
-

+

{title}

-
- {startDate}.25 - {endDate}.25 +
+ {startDate} + {endDate}
- {/* 캠페인 보기 버튼 */} + {/* 3. 캠페인 보기 버튼: 디자인 규격에 맞춰 높이와 너비 조정 */} {showButton && (
- - + {isLoading ? ( +

로딩 중...

+ ) : filteredList.length > 0 ? ( + filteredList.map((cp) => ( + 02.01) + startDate={cp.startDate.split('-').slice(1).join('.')} + endDate={cp.endDate.split('-').slice(1).join('.')} + /> + )) + ) : ( +
+ +
+ )}
diff --git a/app/routes/business/components/MonthlyCalendar.tsx b/app/routes/business/components/MonthlyCalendar.tsx index 3d7313c..b036301 100644 --- a/app/routes/business/components/MonthlyCalendar.tsx +++ b/app/routes/business/components/MonthlyCalendar.tsx @@ -1,24 +1,58 @@ +import { useState, useMemo } from "react"; +import type { CampaignCollaboration } from "../calendar/api/calendar"; import ArrowLeftIcon from "../../../assets/icon/arrow-left.svg"; import ArrowRightIcon from "../../../assets/icon/arrow-right.svg"; +interface MonthlyCalendarProps { + events: CampaignCollaboration[]; +} + const WEEK_DAYS = ["일", "월", "화", "수", "목", "금", "토"]; -export default function MonthlyCalendar() { - const emptyDays = Array(2).fill(null); - const days = Array.from({ length: 31 }, (_, i) => i + 1); - const allSlots = [...emptyDays, ...days]; +export default function MonthlyCalendar({ events }: MonthlyCalendarProps) { + // 1. 현재 표시할 날짜 상태 (누락되었던 부분 추가) + const [currentDate, setCurrentDate] = useState(new Date()); + + // 2. 해당 월의 정보 계산 + const { year, month, allSlots } = useMemo(() => { + const y = currentDate.getFullYear(); + const m = currentDate.getMonth(); // 0 ~ 11 + + const firstDay = new Date(y, m, 1).getDay(); + const lastDate = new Date(y, m + 1, 0).getDate(); + + const emptyDays = Array(firstDay).fill(null); + const days = Array.from({ length: lastDate }, (_, i) => i + 1); + + return { year: y, month: m + 1, allSlots: [...emptyDays, ...days] }; + }, [currentDate]); + + // 월 이동 핸들러 + const handlePrevMonth = () => setCurrentDate(new Date(year, month - 2, 1)); + const handleNextMonth = () => setCurrentDate(new Date(year, month, 1)); + + // 3. 특정 날짜에 이벤트가 있는지 확인하는 함수 + const getEventsForDay = (day: number | null) => { + if (!day) return []; + // YYYY-MM-DD 형식으로 비교 + const targetStr = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + + return events.filter(event => { + return event.startDate <= targetStr && event.endDate >= targetStr; + }); + }; return (
{/* 상단 월 이동 */}
- - 2025년 07월 + {year}년 {String(month).padStart(2, "0")}월 -
@@ -33,57 +67,44 @@ export default function MonthlyCalendar() { {/* 날짜 그리드 */}
- {allSlots.map((day, index) => ( -
-
- {day && ( - - {day} - - )} -
-
- ))} -
+ {allSlots.map((day, index) => { + const dayEvents = getEventsForDay(day); + const isToday = day === new Date().getDate() && month === (new Date().getMonth() + 1) && year === new Date().getFullYear(); - {/* 일정 바 */} -
- {/* 비플레인 */} -
- 비플레인 -
+ return ( +
+ {/* 날짜 표시 */} +
+ {day && ( + + {day} + + )} +
- {/* 라운드랩 */} -
- 라운드랩 -
+ {/* 해당 날짜의 일정 바 (이벤트가 있을 때만 표시) */} +
+ {dayEvents.slice(0, 2).map((event, idx) => ( +
+ {event.brandName} +
+ ))} + {dayEvents.length > 2 && ( + +{dayEvents.length - 2} + )} +
+
+ ); + })}
-
); -} +} \ No newline at end of file diff --git a/app/routes/business/components/WeeklyCalendar.tsx b/app/routes/business/components/WeeklyCalendar.tsx index bed289a..1e20c1d 100644 --- a/app/routes/business/components/WeeklyCalendar.tsx +++ b/app/routes/business/components/WeeklyCalendar.tsx @@ -1,7 +1,51 @@ +import type { CampaignCollaboration } from "../calendar/api/calendar"; +import { useMemo } from "react"; + +interface WeeklyCalendarProps { + events: CampaignCollaboration[]; // 이 부분을 추가하여 props를 정의합니다. +} + const WEEK_DAYS = ["일", "월", "화", "수", "목", "금", "토"]; -export default function WeeklyCalendar() { - const dates = [6, 7, 8, 9, 10, 11, 12]; +export default function WeeklyCalendar({ events }: WeeklyCalendarProps) { + console.log("주간 일정 데이터:", events); + + // 1. 이번 주 날짜 배열 생성 (일~토) + const weekDates = useMemo(() => { + const now = new Date(); + const dayOfWeek = now.getDay(); // 오늘 요일 (0: 일, 1: 월...) + const startOfWeek = new Date(now); + startOfWeek.setDate(now.getDate() - dayOfWeek); // 이번 주 일요일 계산 + + return Array.from({ length: 7 }, (_, i) => { + const date = new Date(startOfWeek); + date.setDate(startOfWeek.getDate() + i); + return date; + }); + }, []); + + const todayStr = new Date().toISOString().split("T")[0]; + + // 2. 일정 바 위치 계산 함수 + const getEventStyle = (startDate: string, endDate: string, index: number) => { + const start = new Date(startDate); + const end = new Date(endDate); + const weekStart = weekDates[0]; + const weekEnd = weekDates[6]; + + // 이번 주 범위에 포함되는지 확인 + const displayStart = start < weekStart ? 0 : start.getDay(); + const displayEnd = end > weekEnd ? 6 : end.getDay(); + const duration = displayEnd - displayStart + 1; + + return { + left: `${(displayStart * 100) / 7}%`, + width: `${(duration * 100) / 7}%`, + top: `${index * 26}px`, // 겹치지 않게 위아래 간격 조정 + height: "22px", + borderRadius: "11px", + }; + }; return (
@@ -14,50 +58,36 @@ export default function WeeklyCalendar() { {/* 날짜 그리드 */}
- {dates.map((date) => ( -
-
- {date} + {weekDates.map((dateObj) => { + const dateStr = dateObj.toISOString().split("T")[0]; + const isToday = dateStr === todayStr; + return ( +
+
+ {dateObj.getDate()} +
-
- ))} + ); + })}
{/* 일정 바 컨테이너 */}
- {/* 비플레인 */} -
- 비플레인 -
- - {/* 라운드랩 */} -
- 라운드랩 -
+ {events.slice(0, 3).map((event, idx) => ( // 최대 3개까지만 노출 예시 +
+ {event.brandName} +
+ ))}
); From fc089a7d4810a86c1f12f91d3698bae53d20e601 Mon Sep 17 00:00:00 2001 From: Jio Date: Mon, 2 Feb 2026 13:56:50 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=EB=B3=80=EC=88=98=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=20=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/routes/business/components/CampaignCard.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/routes/business/components/CampaignCard.tsx b/app/routes/business/components/CampaignCard.tsx index dce2442..48de4b8 100644 --- a/app/routes/business/components/CampaignCard.tsx +++ b/app/routes/business/components/CampaignCard.tsx @@ -24,7 +24,6 @@ export default function CampaignCard({ campaignId = 1, }: CampaignCardProps) { const navigate = useNavigate(); - const BUTTON_WIDTH = '280px'; // 로고 컴포넌트 const Logo = (