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.
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
// frontend/components/calendar/MiniCal.tsx — 미니 달력 (실제 날짜 기반)
|
|
"use client";
|
|
import { Icon } from "@/components/Icon";
|
|
import { dayNum, monthCells, monthNum, yearNum } from "@/lib/calendar/time";
|
|
|
|
export function MiniCal({
|
|
monthRef,
|
|
sel,
|
|
today,
|
|
weekdays,
|
|
eventsByDate,
|
|
onSel,
|
|
onMonth,
|
|
}: {
|
|
monthRef: string; // 보여줄 달(ISO)
|
|
sel: string; // 선택일(ISO)
|
|
today: string; // 오늘(ISO)
|
|
weekdays: string[];
|
|
eventsByDate: Record<string, number>;
|
|
onSel: (iso: string) => void;
|
|
onMonth: (dir: number) => void;
|
|
}) {
|
|
const cells = monthCells(monthRef);
|
|
return (
|
|
<div className="minical">
|
|
<div className="mc-head">
|
|
<span className="mc-title">
|
|
{yearNum(monthRef)}년 {monthNum(monthRef)}월
|
|
</span>
|
|
<span className="mc-nav">
|
|
<button aria-label="이전 달" onClick={() => onMonth(-1)}>
|
|
<Icon name="chev" className="ic flip" />
|
|
</button>
|
|
<button aria-label="다음 달" onClick={() => onMonth(1)}>
|
|
<Icon name="chev" />
|
|
</button>
|
|
</span>
|
|
</div>
|
|
<div className="mc-grid">
|
|
{weekdays.map((w) => (
|
|
<div key={w} className="mc-wd">
|
|
{w}
|
|
</div>
|
|
))}
|
|
{cells.map((c) => (
|
|
<button
|
|
key={c.date}
|
|
className={
|
|
"mc-day" +
|
|
(c.inMonth ? "" : " out") +
|
|
(c.inMonth && c.date === today ? " today" : "") +
|
|
(c.inMonth && c.date === sel ? " sel" : "")
|
|
}
|
|
onClick={() => c.inMonth && onSel(c.date)}
|
|
>
|
|
{dayNum(c.date)}
|
|
{c.inMonth && eventsByDate[c.date] && <span className="evdot" />}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|