feat: 일정 주간/월간 뷰 전환 추가
상단 토글(주간/월간)로 보기 전환. 월간은 전통 달력 그리드(주×요일). - scheduleDate: firstOfMonth/addMonths/monthLabel/monthGridWeeks(+MonthDay) 추가 - schedule.store: viewMode + anchor 기반으로 주간/월간 범위·라벨·네비 일원화 (goPrev/goNext 가 모드별로 주/월 이동, setViewMode 시 범위 재조회) - ScheduleMonthGrid: 주 단위 다중일 막대(레인 패킹) + 초과 '+N', 카테고리 색·유형 필터·오늘/주말/이전·다음달 표기, 막대 클릭 시 상세 패널 - SchedulePage: SegmentedTabs 토글 + 주간/월간 조건부 렌더 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,3 +92,63 @@ export function eventDateText(start: string, end: string): string {
|
||||
export function spanDays(start: string, end: string): number {
|
||||
return Math.round((dateOf(end).getTime() - dateOf(start).getTime()) / 86400000) + 1
|
||||
}
|
||||
|
||||
// ===== 월간(달력 그리드) =====
|
||||
|
||||
// 해당 월의 1일 ISO
|
||||
export function firstOfMonth(iso: string): string {
|
||||
const d = dateOf(iso)
|
||||
return isoOf(new Date(d.getFullYear(), d.getMonth(), 1))
|
||||
}
|
||||
|
||||
// iso + n개월 (말일 넘침 보정)
|
||||
export function addMonths(iso: string, n: number): string {
|
||||
const d = dateOf(iso)
|
||||
const day = d.getDate()
|
||||
const base = new Date(d.getFullYear(), d.getMonth() + n, 1)
|
||||
const dim = new Date(base.getFullYear(), base.getMonth() + 1, 0).getDate()
|
||||
base.setDate(Math.min(day, dim))
|
||||
return isoOf(base)
|
||||
}
|
||||
|
||||
// 월 라벨 — '2026년 6월'
|
||||
export function monthLabel(iso: string): string {
|
||||
const d = dateOf(iso)
|
||||
return `${d.getFullYear()}년 ${d.getMonth() + 1}월`
|
||||
}
|
||||
|
||||
// 달력 그리드의 하루(요일 + 이번 달 여부)
|
||||
export interface MonthDay extends WeekDay {
|
||||
inMonth: boolean
|
||||
}
|
||||
|
||||
// 월 달력 그리드 — 1일이 속한 주의 월요일부터 말일이 속한 주의 일요일까지(4~6주)
|
||||
export function monthGridWeeks(iso: string): MonthDay[][] {
|
||||
const monthIdx = dateOf(firstOfMonth(iso)).getMonth()
|
||||
const gridStart = mondayOf(firstOfMonth(iso))
|
||||
const first = dateOf(firstOfMonth(iso))
|
||||
const lastDayIso = isoOf(new Date(first.getFullYear(), first.getMonth() + 1, 0))
|
||||
const gridEnd = addDays(mondayOf(lastDayIso), 6)
|
||||
const today = todayIso()
|
||||
|
||||
const weeks: MonthDay[][] = []
|
||||
let cur = gridStart
|
||||
while (cur <= gridEnd) {
|
||||
const week: MonthDay[] = []
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const dayIso = addDays(cur, i)
|
||||
const dt = dateOf(dayIso)
|
||||
week.push({
|
||||
iso: dayIso,
|
||||
dow: DOW_KO[i] ?? '',
|
||||
d: dt.getDate(),
|
||||
weekend: i >= 5,
|
||||
isToday: dayIso === today,
|
||||
inMonth: dt.getMonth() === monthIdx,
|
||||
})
|
||||
}
|
||||
weeks.push(week)
|
||||
cur = addDays(cur, 7)
|
||||
}
|
||||
return weeks
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user