kalender / index.html
YUIAIRIAI's picture
gabunkan tanggal nya ke 1 frime jadi masehui angka besar dan arab di kanan atas tanggal masehi dan cina kiri bawah - Initial Deployment
8dc9663 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kalender Multikultural</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<style>
.calendar-day:hover {
transform: scale(1.05);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.event-dot {
width: 6px;
height: 6px;
border-radius: 50%;
display: inline-block;
margin-right: 2px;
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="flex justify-between items-center mb-8" data-aos="fade-down">
<h1 class="text-3xl font-bold text-indigo-800">Kalender Multikultural</h1>
<div class="flex items-center space-x-4">
<button id="today-btn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
Hari Ini
</button>
<div class="relative">
<button id="month-selector" class="flex items-center px-4 py-2 bg-white rounded-lg shadow hover:bg-gray-50">
<span id="current-month-year" class="font-medium text-gray-700">Januari 2023</span>
<i data-feather="chevron-down" class="ml-2 text-gray-500"></i>
</button>
<div id="month-dropdown" class="hidden absolute z-10 mt-1 w-48 bg-white rounded-md shadow-lg">
<!-- Months will be populated by JS -->
</div>
</div>
<div class="flex">
<button id="prev-month" class="p-2 rounded-full hover:bg-gray-200">
<i data-feather="chevron-left"></i>
</button>
<button id="next-month" class="p-2 rounded-full hover:bg-gray-200">
<i data-feather="chevron-right"></i>
</button>
</div>
</div>
</header>
<!-- Calendar Grid -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden mb-6" data-aos="fade-up">
<!-- Weekday Headers -->
<div class="grid grid-cols-7 bg-indigo-600 text-white">
<div class="py-3 text-center font-medium">Minggu</div>
<div class="py-3 text-center font-medium">Senin</div>
<div class="py-3 text-center font-medium">Selasa</div>
<div class="py-3 text-center font-medium">Rabu</div>
<div class="py-3 text-center font-medium">Kamis</div>
<div class="py-3 text-center font-medium">Jumat</div>
<div class="py-3 text-center font-medium">Sabtu</div>
</div>
<!-- Calendar Days -->
<div id="calendar-days" class="grid grid-cols-7 gap-1 p-2">
<!-- Days will be populated by JS -->
</div>
</div>
<!-- Additional Calendars -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<!-- Chinese Calendar -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden" data-aos="fade-right">
<div class="bg-red-600 text-white py-3 text-center font-bold">
Kalender Cina
</div>
<div id="chinese-calendar" class="p-4">
<div class="text-center mb-4">
<h3 id="chinese-month-year" class="text-xl font-semibold"></h3>
<p id="chinese-zodiac" class="text-gray-600"></p>
</div>
<div id="chinese-dates" class="grid grid-cols-7 gap-1">
<!-- Chinese dates will be populated by JS -->
</div>
</div>
</div>
<!-- Hijri Calendar -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden" data-aos="fade-left">
<div class="bg-green-600 text-white py-3 text-center font-bold">
Kalender Hijriyah
</div>
<div id="hijri-calendar" class="p-4">
<div class="text-center mb-4">
<h3 id="hijri-month-year" class="text-xl font-semibold"></h3>
<p id="hijri-info" class="text-gray-600"></p>
</div>
<div id="hijri-dates" class="grid grid-cols-7 gap-1">
<!-- Hijri dates will be populated by JS -->
</div>
</div>
</div>
</div>
<!-- Events Section -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Today's Events -->
<div class="bg-white rounded-xl shadow-lg p-6" data-aos="fade-right">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-bold text-indigo-800">Acara Hari Ini</h2>
<span id="today-date" class="text-gray-500"></span>
</div>
<div id="today-events" class="space-y-3">
<div class="text-gray-500 italic">Tidak ada acara hari ini</div>
</div>
</div>
<!-- Add Event Form -->
<div class="bg-white rounded-xl shadow-lg p-6" data-aos="fade-left">
<h2 class="text-xl font-bold text-indigo-800 mb-4">Tambah Acara</h2>
<form id="add-event-form" class="space-y-4">
<div>
<label for="event-title" class="block text-sm font-medium text-gray-700">Judul Acara</label>
<input type="text" id="event-title" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 border">
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label for="event-date" class="block text-sm font-medium text-gray-700">Tanggal</label>
<input type="date" id="event-date" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 border">
</div>
<div>
<label for="event-time" class="block text-sm font-medium text-gray-700">Waktu</label>
<input type="time" id="event-time" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 border">
</div>
</div>
<div>
<label for="event-color" class="block text-sm font-medium text-gray-700">Warna</label>
<select id="event-color" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 border">
<option value="bg-blue-500">Biru</option>
<option value="bg-red-500">Merah</option>
<option value="bg-green-500">Hijau</option>
<option value="bg-yellow-500">Kuning</option>
<option value="bg-purple-500">Ungu</option>
</select>
</div>
<button type="submit" class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition">
Tambah Acara
</button>
</form>
</div>
</div>
</div>
<!-- Event Modal -->
<div id="event-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
<div class="bg-white rounded-xl p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 id="modal-event-title" class="text-xl font-bold"></h3>
<button id="close-modal" class="text-gray-500 hover:text-gray-700">
<i data-feather="x"></i>
</button>
</div>
<div class="space-y-2">
<div class="flex items-center">
<i data-feather="calendar" class="text-gray-500 mr-2"></i>
<span id="modal-event-date"></span>
</div>
<div class="flex items-center">
<i data-feather="clock" class="text-gray-500 mr-2"></i>
<span id="modal-event-time"></span>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3">
<button id="delete-event" class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 transition">
Hapus
</button>
<button id="edit-event" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition">
Edit
</button>
</div>
</div>
</div>
<script>
// Chinese Zodiac animals
const zodiacAnimals = [
"Tikus", "Kerbau", "Harimau", "Kelinci",
"Naga", "Ular", "Kuda", "Kambing",
"Monyet", "Ayam", "Anjing", "Babi"
];
// Chinese month names
const chineseMonths = [
"Zhēngyuè", "Èryuè", "Sānyuè", "Sìyuè",
"Wǔyuè", "Liùyuè", "Qīyuè", "Bāyuè",
"Jiǔyuè", "Shíyuè", "Shíyīyuè", "Shí'èryuè"
];
// Hijri month names
const hijriMonths = [
"Muharram", "Safar", "Rabi' al-Awwal", "Rabi' al-Thani",
"Jumada al-Awwal", "Jumada al-Thani", "Rajab", "Sha'ban",
"Ramadan", "Shawwal", "Dhu al-Qi'dah", "Dhu al-Hijjah"
];
document.addEventListener('DOMContentLoaded', function() {
// Initialize libraries
feather.replace();
AOS.init();
// Calendar functionality
let currentDate = new Date();
let events = JSON.parse(localStorage.getItem('calendarEvents')) || [];
// DOM elements
const calendarDays = document.getElementById('calendar-days');
const currentMonthYear = document.getElementById('current-month-year');
const prevMonthBtn = document.getElementById('prev-month');
const nextMonthBtn = document.getElementById('next-month');
const todayBtn = document.getElementById('today-btn');
const monthSelector = document.getElementById('month-selector');
const monthDropdown = document.getElementById('month-dropdown');
const addEventForm = document.getElementById('add-event-form');
const todayEvents = document.getElementById('today-events');
const todayDate = document.getElementById('today-date');
const eventModal = document.getElementById('event-modal');
const closeModal = document.getElementById('close-modal');
const deleteEventBtn = document.getElementById('delete-event');
const editEventBtn = document.getElementById('edit-event');
// Month names in Indonesian
const monthNames = [
"Januari", "Februari", "Maret", "April", "Mei", "Juni",
"Juli", "Agustus", "September", "Oktober", "November", "Desember"
];
// Day names in Indonesian
const dayNames = ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"];
// Render calendar
function renderCalendar() {
// Clear previous calendar
calendarDays.innerHTML = '';
// Set current month and year
currentMonthYear.textContent = `${monthNames[currentDate.getMonth()]} ${currentDate.getFullYear()}`;
// Get first day of month and total days in month
const firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
const lastDay = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
const totalDays = lastDay.getDate();
// Get day of week for first day (0-6)
const firstDayIndex = firstDay.getDay();
// Previous month days
const prevLastDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 0).getDate();
// Next month days
const nextDays = 7 - ((firstDayIndex + totalDays) % 7);
// Previous month days to show
for (let i = firstDayIndex; i > 0; i--) {
const day = prevLastDay - i + 1;
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day p-2 text-center text-gray-400';
dayElement.textContent = day;
calendarDays.appendChild(dayElement);
}
// Current month days
const today = new Date();
for (let i = 1; i <= totalDays; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day p-2 text-center cursor-pointer transition';
// Check if day is today
const isToday = i === today.getDate() &&
currentDate.getMonth() === today.getMonth() &&
currentDate.getFullYear() === today.getFullYear();
if (isToday) {
dayElement.classList.add('bg-indigo-100', 'font-bold');
}
dayElement.textContent = i;
// Check for events on this day
const dayEvents = events.filter(event => {
const eventDate = new Date(event.date);
return eventDate.getDate() === i &&
eventDate.getMonth() === currentDate.getMonth() &&
eventDate.getFullYear() === currentDate.getFullYear();
});
if (dayEvents.length > 0) {
const eventDots = document.createElement('div');
eventDots.className = 'flex justify-center mt-1';
dayEvents.slice(0, 3).forEach(event => {
const dot = document.createElement('span');
dot.className = `event-dot ${event.color}`;
eventDots.appendChild(dot);
});
if (dayEvents.length > 3) {
const moreDot = document.createElement('span');
moreDot.className = 'event-dot bg-gray-300';
eventDots.appendChild(moreDot);
}
dayElement.appendChild(eventDots);
}
// Add click event to show modal with events
dayElement.addEventListener('click', () => {
showDayEvents(i);
});
calendarDays.appendChild(dayElement);
}
// Next month days to show
for (let i = 1; i <= nextDays; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day p-2 text-center text-gray-400';
dayElement.textContent = i;
calendarDays.appendChild(dayElement);
}
// Update today's events
updateTodayEvents();
}
// Show events for a specific day
function showDayEvents(day) {
const modalTitle = document.getElementById('modal-event-title');
const modalDate = document.getElementById('modal-event-date');
const modalTime = document.getElementById('modal-event-time');
const selectedDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day);
const dayEvents = events.filter(event => {
const eventDate = new Date(event.date);
return eventDate.getDate() === day &&
eventDate.getMonth() === currentDate.getMonth() &&
eventDate.getFullYear() === currentDate.getFullYear();
});
if (dayEvents.length === 0) {
modalTitle.textContent = 'Tidak ada acara';
modalDate.textContent = dayNames[selectedDate.getDay()] + ', ' + day + ' ' + monthNames[currentDate.getMonth()] + ' ' + currentDate.getFullYear();
modalTime.textContent = '';
// Hide buttons
deleteEventBtn.classList.add('hidden');
editEventBtn.classList.add('hidden');
} else {
// For simplicity, showing first event
const event = dayEvents[0];
modalTitle.textContent = event.title;
const eventDate = new Date(event.date);
modalDate.textContent = dayNames[eventDate.getDay()] + ', ' + eventDate.getDate() + ' ' + monthNames[eventDate.getMonth()] + ' ' + eventDate.getFullYear();
modalTime.textContent = event.time;
// Show buttons and set data attributes
deleteEventBtn.classList.remove('hidden');
editEventBtn.classList.remove('hidden');
deleteEventBtn.dataset.eventId = event.id;
editEventBtn.dataset.eventId = event.id;
}
eventModal.classList.remove('hidden');
}
// Update today's events
function updateTodayEvents() {
const today = new Date();
todayDate.textContent = dayNames[today.getDay()] + ', ' + today.getDate() + ' ' + monthNames[today.getMonth()] + ' ' + today.getFullYear();
const todayEventsList = events.filter(event => {
const eventDate = new Date(event.date);
return eventDate.getDate() === today.getDate() &&
eventDate.getMonth() === today.getMonth() &&
eventDate.getFullYear() === today.getFullYear();
});
todayEvents.innerHTML = '';
if (todayEventsList.length === 0) {
todayEvents.innerHTML = '<div class="text-gray-500 italic">Tidak ada acara hari ini</div>';
} else {
todayEventsList.forEach(event => {
const eventElement = document.createElement('div');
eventElement.className = 'flex items-center p-3 bg-gray-50 rounded-lg';
const colorDot = document.createElement('div');
colorDot.className = `w-3 h-3 rounded-full mr-3 ${event.color}`;
const eventInfo = document.createElement('div');
eventInfo.className = 'flex-1';
const eventTitle = document.createElement('div');
eventTitle.className = 'font-medium';
eventTitle.textContent = event.title;
const eventTime = document.createElement('div');
eventTime.className = 'text-sm text-gray-500';
eventTime.textContent = event.time;
eventInfo.appendChild(eventTitle);
eventInfo.appendChild(eventTime);
eventElement.appendChild(colorDot);
eventElement.appendChild(eventInfo);
todayEvents.appendChild(eventElement);
});
}
}
// Event listeners
prevMonthBtn.addEventListener('click', () => {
currentDate.setMonth(currentDate.getMonth() - 1);
renderCalendar();
});
nextMonthBtn.addEventListener('click', () => {
currentDate.setMonth(currentDate.getMonth() + 1);
renderCalendar();
});
todayBtn.addEventListener('click', () => {
currentDate = new Date();
renderCalendar();
});
monthSelector.addEventListener('click', () => {
monthDropdown.classList.toggle('hidden');
if (!monthDropdown.classList.contains('hidden')) {
monthDropdown.innerHTML = '';
// Add months to dropdown
for (let i = 0; i < 12; i++) {
const monthItem = document.createElement('div');
monthItem.className = 'px-4 py-2 hover:bg-gray-100 cursor-pointer';
monthItem.textContent = monthNames[i];
monthItem.addEventListener('click', () => {
currentDate.setMonth(i);
renderCalendar();
monthDropdown.classList.add('hidden');
});
monthDropdown.appendChild(monthItem);
}
}
});
addEventForm.addEventListener('submit', function(e) {
e.preventDefault();
const title = document.getElementById('event-title').value;
const date = document.getElementById('event-date').value;
const time = document.getElementById('event-time').value;
const color = document.getElementById('event-color').value;
if (!title || !date || !time) {
alert('Harap isi semua field');
return;
}
const newEvent = {
id: Date.now().toString(),
title,
date,
time,
color
};
events.push(newEvent);
localStorage.setItem('calendarEvents', JSON.stringify(events));
// Reset form
addEventForm.reset();
// Update calendar
renderCalendar();
// Show success message
alert('Acara berhasil ditambahkan');
});
closeModal.addEventListener('click', () => {
eventModal.classList.add('hidden');
});
deleteEventBtn.addEventListener('click', () => {
const eventId = deleteEventBtn.dataset.eventId;
events = events.filter(event => event.id !== eventId);
localStorage.setItem('calendarEvents', JSON.stringify(events));
renderCalendar();
eventModal.classList.add('hidden');
});
// Set default date to today
document.getElementById('event-date').valueAsDate = new Date();
// Render Chinese Calendar
function renderChineseCalendar() {
const chineseCalendar = document.getElementById('chinese-dates');
chineseCalendar.innerHTML = '';
const now = new Date();
const chineseYear = now.getFullYear() - (now.getMonth() < 1 ? 1 : 0) + 2697; // Chinese year calculation
const zodiacIndex = (chineseYear - 4) % 12;
document.getElementById('chinese-month-year').textContent =
`${chineseMonths[now.getMonth()]} ${chineseYear}`;
document.getElementById('chinese-zodiac').textContent =
`Tahun ${zodiacAnimals[zodiacIndex]} (${zodiacIndex + 1}/12)`;
// Simplified Chinese calendar display
for (let i = 1; i <= 31; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'text-center p-1 border border-gray-100';
dayElement.textContent = i;
chineseCalendar.appendChild(dayElement);
}
}
// Render Hijri Calendar
function renderHijriCalendar() {
const hijriCalendar = document.getElementById('hijri-dates');
hijriCalendar.innerHTML = '';
// Simplified conversion (for accurate conversion, use a library)
const now = new Date();
const hijriDate = new Intl.DateTimeFormat('en-u-ca-islamic', {
day: 'numeric',
month: 'numeric',
year: 'numeric'
}).format(now);
const [hijriMonth, hijriDay, hijriYear] = hijriDate.split('/');
document.getElementById('hijri-month-year').textContent =
`${hijriMonths[parseInt(hijriMonth)-1]} ${hijriYear}H`;
document.getElementById('hijri-info').textContent =
`Hari ini: ${hijriDay} ${hijriMonths[parseInt(hijriMonth)-1]} ${hijriYear}H`;
// Simplified Hijri calendar display
for (let i = 1; i <= 30; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'text-center p-1 border border-gray-100';
dayElement.textContent = i;
hijriCalendar.appendChild(dayElement);
}
}
// Initial render
renderCalendar();
renderChineseCalendar();
renderHijriCalendar();
});
// Note: For production use, consider using libraries like:
// - https://github.com/iseahound/hijri.js for accurate Hijri dates
// - https://github.com/nuysoft/Moment.js for Chinese calendar
</script>
</body>
<style>
#chinese-dates, #hijri-dates {
grid-template-columns: repeat(7, minmax(0, 1fr));
}
#chinese-calendar .bg-red-600, #hijri-calendar .bg-green-600 {
background-color: #dc2626;
}
#hijri-calendar .bg-green-600 {
background-color: #16a34a;
}
</style>
</html>