You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
// frontend/components/calendar/MonthView.tsx — 월 뷰 (실제 날짜 기반, 셀당 이벤트 ≤3 + +N개 더)
|
|
"use client";
|
|
import type { MouseEvent } from "react";
|
|
import { dayNum, monthCells, toMin } from "@/lib/calendar/time";
|
|
import type { CalEvent, Calendar } from "@/lib/calendar/types";
|
|
|
|
export function MonthView({
|
|
events,
|
|
calMap,
|
|
monthRef,
|
|
weekdays,
|
|
todayDate,
|
|
onOpen,
|
|
onSelDay,
|
|
}: {
|
|
events: CalEvent[];
|
|
calMap: Record<string, Calendar>;
|
|
monthRef: string; // 보여줄 달(ISO)
|
|
weekdays: string[];
|
|
todayDate: string;
|
|
onOpen: (ev: CalEvent, e: MouseEvent) => void;
|
|
onSelDay: (iso: string) => void;
|
|
}) {
|
|
const byDate: Record<string, CalEvent[]> = {};
|
|
events.forEach((e) => {
|
|
(byDate[e.date] = byDate[e.date] || []).push(e);
|
|
});
|
|
Object.values(byDate).forEach((a) => a.sort((x, y) => toMin(x.start) - toMin(y.start)));
|
|
const cells = monthCells(monthRef);
|
|
return (
|
|
<div className="cpanel">
|
|
<div className="mo-head">
|
|
{weekdays.map((w, i) => (
|
|
<div key={w} className={"mo-wd" + (i === 0 || i === 6 ? " wknd" : "")}>
|
|
{w}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="mo-grid">
|
|
{cells.map((c) => {
|
|
const evs = c.inMonth ? byDate[c.date] || [] : [];
|
|
return (
|
|
<div
|
|
key={c.date}
|
|
className={
|
|
"mo-cell" +
|
|
(c.inMonth ? "" : " out") +
|
|
(c.inMonth && c.date === todayDate ? " today" : "")
|
|
}
|
|
onClick={() => c.inMonth && onSelDay(c.date)}
|
|
>
|
|
<div className="mo-dn">{dayNum(c.date)}</div>
|
|
{evs.slice(0, 3).map((ev) => (
|
|
<div
|
|
key={ev.id}
|
|
className={"mo-ev tint-" + (calMap[ev.cal]?.tone ?? "ink")}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onOpen(ev, e);
|
|
}}
|
|
>
|
|
<span className="pdot" />
|
|
<span className="mt">{ev.start || "종일"}</span>
|
|
<span className="mn">{ev.title}</span>
|
|
</div>
|
|
))}
|
|
{evs.length > 3 && <div className="mo-more">+{evs.length - 3}개 더</div>}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|