Cara Membangun Component Kalender dengan Claude Code
Pelajari cara membangun component kalender menggunakan Claude Code. Dilengkapi contoh kode praktis dan panduan langkah demi langkah.
Kebutuhan Component Kalender
UI kalender dibutuhkan di banyak aplikasi seperti sistem reservasi, manajemen jadwal, pemilihan tanggal, dan lainnya. Bisa mengandalkan library eksternal, tapi jika menginginkan kebebasan desain dan fungsionalitas, membuatnya sendiri adalah yang terbaik. Dengan Claude Code, component kalender yang fleksibel bisa dibangun dengan cepat.
Implementasi Dasar Kalender Tampilan Bulanan
> Buat component kalender tampilan bulanan menggunakan date-fns.
> Dukung perpindahan bulan dan pemilihan tanggal.
import { useState } from 'react';
import {
startOfMonth, endOfMonth, startOfWeek, endOfWeek,
eachDayOfInterval, format, addMonths, subMonths, isSameMonth, isSameDay, isToday,
} from 'date-fns';
interface CalendarProps {
selected?: Date;
onSelect: (date: Date) => void;
events?: { date: Date; title: string }[];
}
function Calendar({ selected, onSelect, events = [] }: CalendarProps) {
const [currentMonth, setCurrentMonth] = useState(new Date());
const monthStart = startOfMonth(currentMonth);
const monthEnd = endOfMonth(currentMonth);
const calendarStart = startOfWeek(monthStart);
const calendarEnd = endOfWeek(monthEnd);
const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });
const weekDays = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];
const getEventsForDay = (day: Date) =>
events.filter((e) => isSameDay(e.date, day));
return (
<div className="w-full max-w-md mx-auto" role="application" aria-label="kalender">
<div className="flex items-center justify-between mb-4">
<button onClick={() => setCurrentMonth(subMonths(currentMonth, 1))} aria-label="Bulan sebelumnya">
←
</button>
<h2 className="text-lg font-bold" aria-live="polite">
{format(currentMonth, 'MMMM yyyy')}
</h2>
<button onClick={() => setCurrentMonth(addMonths(currentMonth, 1))} aria-label="Bulan berikutnya">
→
</button>
</div>
<div className="grid grid-cols-7 gap-px" role="grid">
{weekDays.map((day) => (
<div key={day} className="text-center text-sm font-medium text-gray-500 py-2" role="columnheader">
{day}
</div>
))}
{days.map((day) => {
const dayEvents = getEventsForDay(day);
const isSelected = selected && isSameDay(day, selected);
const inMonth = isSameMonth(day, currentMonth);
return (
<button
key={day.toISOString()}
onClick={() => onSelect(day)}
role="gridcell"
aria-selected={isSelected}
className={`p-2 text-center rounded-lg relative ${
!inMonth ? 'text-gray-300' :
isSelected ? 'bg-blue-600 text-white' :
isToday(day) ? 'bg-blue-100 font-bold' :
'hover:bg-gray-100'
}`}
>
{format(day, 'd')}
{dayEvents.length > 0 && (
<span className="absolute bottom-1 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-blue-500" />
)}
</button>
);
})}
</div>
</div>
);
}
Pemilihan Rentang Tanggal
> Dukung pemilihan rentang tanggal seperti check-in/check-out.
function useDateRange() {
const [range, setRange] = useState<{ start: Date | null; end: Date | null }>({
start: null,
end: null,
});
const handleSelect = (date: Date) => {
if (!range.start || (range.start && range.end)) {
setRange({ start: date, end: null });
} else if (date < range.start) {
setRange({ start: date, end: range.start });
} else {
setRange({ start: range.start, end: date });
}
};
const isInRange = (date: Date) => {
if (!range.start || !range.end) return false;
return date >= range.start && date <= range.end;
};
return { range, handleSelect, isInRange };
}
Kalender dengan Tampilan Event
function EventCalendar({ events }: { events: CalendarEvent[] }) {
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
const dayEvents = events.filter((e) => isSameDay(e.date, selectedDate));
return (
<div className="flex gap-4">
<Calendar selected={selectedDate} onSelect={setSelectedDate} events={events} />
<div className="flex-1">
<h3 className="font-bold mb-2">
Jadwal {format(selectedDate, 'd MMM')}
</h3>
{dayEvents.length === 0 ? (
<p className="text-gray-500">Tidak ada jadwal</p>
) : (
<ul className="space-y-2">
{dayEvents.map((event) => (
<li key={event.id} className="p-3 rounded-lg border">
<span className="font-medium">{event.title}</span>
<span className="text-sm text-gray-500 ml-2">
{format(event.date, 'HH:mm')}
</span>
</li>
))}
</ul>
)}
</div>
</div>
);
}
Summary
Dengan Claude Code, component kalender yang fleksibel bisa dibangun sesuai kebutuhan seperti tampilan bulanan, pemilihan rentang tanggal, dan tampilan event. Untuk kombinasi dengan tampilan tabel, lihat Component Tabel, dan untuk dukungan responsif, lihat Responsive Design.
Untuk detail date-fns, lihat Situs Resmi date-fns.
Related Posts
10 Tips untuk Melipatgandakan Produktivitas dengan Claude Code
Temukan 10 tips praktis untuk memaksimalkan Claude Code. Dari strategi prompt hingga shortcut workflow, teknik-teknik ini akan meningkatkan efisiensimu mulai hari ini.
Optimasi Canvas/WebGL dengan Claude Code
Pelajari tentang optimasi Canvas/WebGL menggunakan Claude Code. Tips praktis dan contoh kode disertakan.
Markdown Implementation dengan Claude Code
Pelajari tentang markdown implementation menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.