From a9826df87b4c2fc636d150b4b5f891650e8e15dd Mon Sep 17 00:00:00 2001 From: zio Date: Fri, 24 Jul 2026 07:29:29 +0900 Subject: [PATCH] feat(schedule,dashboard): remove aside mini-calendar (compact month nav), hero inner scroll wrapper - schedule: MiniCalendar removed per owner; AsideMonthNav keeps month cursor for hall widgets - dashboard hero: overflow moved to .kx-timeline-scroll wrapper so the section never shows scrollbars Co-Authored-By: Claude Fable 5 --- .../dashboard/OrganizerDashboardPage.tsx | 2 + .../src/screens/dashboard/dashboard.css | 12 ++- .../schedule/ExhibitionSchedulePage.tsx | 74 +------------------ 3 files changed, 14 insertions(+), 74 deletions(-) diff --git a/src/frontend/src/screens/dashboard/OrganizerDashboardPage.tsx b/src/frontend/src/screens/dashboard/OrganizerDashboardPage.tsx index 4e6978d..8b2cc4b 100644 --- a/src/frontend/src/screens/dashboard/OrganizerDashboardPage.tsx +++ b/src/frontend/src/screens/dashboard/OrganizerDashboardPage.tsx @@ -105,6 +105,7 @@ export function OrganizerDashboardPage() { {data.milestones.length === 0 ? ( ) : ( +
    {data.milestones.map((m, i) => (
  1. @@ -124,6 +125,7 @@ export function OrganizerDashboardPage() {
  2. ))}
+
)} diff --git a/src/frontend/src/screens/dashboard/dashboard.css b/src/frontend/src/screens/dashboard/dashboard.css index 2022e2c..9db1f73 100644 --- a/src/frontend/src/screens/dashboard/dashboard.css +++ b/src/frontend/src/screens/dashboard/dashboard.css @@ -38,14 +38,18 @@ /* 히어로 타임라인 */ .kx-dash__hero { padding: var(--space-5) var(--space-4); - /* 하단 짤림 방지(소유자 2026-07-24): overflow-x:auto 시 가로 스크롤바가 - 마지막 라벨 줄을 덮지 않도록 스크롤바 몫의 하단 여유를 확보. */ - padding-bottom: calc(var(--space-5) + 14px); border: var(--border-card); border-radius: var(--radius-lg); background: var(--color-white); + /* 섹션 자체는 스크롤바 금지(소유자 2026-07-24 "상하 스크롤바 안 생기도록") — + 가로 스크롤은 내부 래퍼(.kx-timeline-scroll)가 전담, 섹션 높이는 내용에 맞춰 늘어난다. */ + overflow: visible; +} +.kx-timeline-scroll { overflow-x: auto; - scrollbar-gutter: stable; + overflow-y: hidden; + /* 스크롤바가 생겨도 라벨을 덮지 않도록 래퍼 하단 여유 */ + padding-bottom: var(--space-2); } .kx-timeline { display: grid; diff --git a/src/frontend/src/screens/schedule/ExhibitionSchedulePage.tsx b/src/frontend/src/screens/schedule/ExhibitionSchedulePage.tsx index 804b830..4210afc 100644 --- a/src/frontend/src/screens/schedule/ExhibitionSchedulePage.tsx +++ b/src/frontend/src/screens/schedule/ExhibitionSchedulePage.tsx @@ -17,7 +17,6 @@ import { CATEGORY_LABEL, EVENT_YEARS, STATUS_LABEL, - eventDaysFor, hallUtilizationFor, type EventCategory, type EventStatus, @@ -60,7 +59,6 @@ function isDegradable(err: unknown): boolean { const MOCK = `${import.meta.env.BASE_URL}mock/organizer_dashboard`; const THUMBS = [`${MOCK}/img1.jpg`, `${MOCK}/img2.jpg`, `${MOCK}/img3.jpg`]; -const TODAY = new Date(2026, 6, 11); // 2026-07-11 (currentDate) const TODAY_YMD = '2026-07-11'; const KNOWN_CATEGORIES = new Set(['exhibition', 'culture', 'trade', 'tech']); @@ -315,7 +313,7 @@ export function ExhibitionSchedulePage() { )} @@ -324,92 +322,28 @@ export function ExhibitionSchedulePage() { ); } -const WD = ['일', '월', '화', '수', '목', '금', '토']; -function MiniCalendar({ +function AsideMonthNav({ cursor, onCursor, - holidays, }: { cursor: Date; onCursor: (d: Date) => void; - holidays?: Map; }) { const { t } = useTranslation(); const year = cursor.getFullYear(); const month = cursor.getMonth(); - const firstDay = new Date(year, month, 1).getDay(); - const daysInMonth = new Date(year, month + 1, 0).getDate(); - - /* - * 실 원천: `GET /api/events/calendar?year=&month=` — event 테이블 기반 월 점유 집계. - * 실패(NETWORK/NOT_FOUND/NOT_IMPLEMENTED) 시에만 크롤링 샘플(eventDaysFor)로 폴백. - * eventDays 키 포맷은 `${year}-${month+1}-${day}`(무패딩) — 셀 렌더와 정합. - */ - const query = useQuery<{ days: Set; degraded: boolean }>({ - queryKey: ['schedule-calendar', year, month], - queryFn: async () => { - try { - const rows = await scheduleApi.calendar(year, month + 1); - const days = new Set(); - for (const r of rows) days.add(`${year}-${month + 1}-${Number(r.date.slice(8, 10))}`); - return { days, degraded: false }; - } catch (err) { - if (isDegradable(err)) return { days: eventDaysFor(year, month), degraded: true }; - throw err; - } - }, - }); - const eventDays = query.data?.days ?? new Set(); - const degraded = query.data?.degraded ?? false; - - const cells: (number | null)[] = []; - for (let i = 0; i < firstDay; i++) cells.push(null); - for (let d = 1; d <= daysInMonth; d++) cells.push(d); - - const isToday = (d: number) => - TODAY.getFullYear() === year && TODAY.getMonth() === month && TODAY.getDate() === d; - return ( -
- {/* 역할 명확화(소유자 2026-07-24): 미니 캘린더 = 아래 홀 위젯의 조회 월 커서 */} +
{t('schedule.asideMonthPicker')} {t('schedule.asideMonthPickerHint')}
- {t('schedule.yearMonth', { y: year, m: month + 1 })}{degraded && {t('schedule.offlineSample')}} + {t('schedule.yearMonth', { y: year, m: month + 1 })}
-
- {WD.map((w, i) => ( - {t(`common.weekday.${i}`)} - ))} - {cells.map((d, i) => { - if (d === null) return ; - const hasEvent = eventDays.has(`${year}-${month + 1}-${d}`); - const hkey = `${year}-${String(month + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`; - const holidayName = holidays?.get(hkey); - return ( - - {d} - - ); - })} -
); }