import React, { useState, useEffect } from 'react'; import { Calendar, ChevronLeft, ChevronRight, Info, RefreshCw } from 'lucide-react'; // Nepali calendar data - months, days and conversion logic const nepaliMonths = [ 'Baishakh', 'Jestha', 'Ashadh', 'Shrawan', 'Bhadra', 'Ashwin', 'Kartik', 'Mangsir', 'Poush', 'Magh', 'Falgun', 'Chaitra' ]; const nepaliMonthDays = { 2080: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], // Days in each month for 2080 BS 2081: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], 2082: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], }; // Festivals data const festivals = { "2080-1-14": "Nepali New Year", "2080-2-23": "Buddha Jayanti", "2080-3-15": "Guru Purnima", "2080-5-16": "Janai Purnima", "2080-5-23": "Gai Jatra", "2080-5-24": "Krishna Janmashtami", "2080-6-10": "Indra Jatra", "2080-7-2": "Dashain Begins", "2080-7-10": "Vijaya Dashami", "2080-7-25": "Tihar Begins", "2080-7-27": "Laxmi Puja", "2080-7-29": "Bhai Tika", "2080-9-15": "Tamu Lhosar", "2080-10-1": "Maghe Sankranti", "2080-10-30": "Sonam Lhosar", "2080-11-7": "Shivaratri", "2080-11-21": "Gyalpo Lhosar", "2080-12-11": "Holi", "2080-12-24": "Ram Navami", }; // Simple BS to AD conversion (approximate) const convertBsToAd = (bsDate) => { const [bsYear, bsMonth, bsDay] = bsDate.split('-').map(Number); // This is a simplified conversion - in a real app, you'd use a more accurate algorithm const adDate = new Date(bsYear - 57, bsMonth - 1, bsDay + 14); return adDate.toISOString().split('T')[0]; }; // Simple AD to BS conversion (approximate) const convertAdToBs = (adDate) => { const date = new Date(adDate); const adYear = date.getFullYear(); const adMonth = date.getMonth() + 1; const adDay = date.getDate(); // This is a simplified conversion - in a real app, you'd use a more accurate algorithm const bsYear = adYear + 57; const bsMonth = adMonth; const bsDay = adDay - 14; // Handle month/year boundaries (simplified) let adjustedBsMonth = bsMonth; let adjustedBsDay = bsDay; let adjustedBsYear = bsYear; if (bsDay <= 0) { adjustedBsMonth = bsMonth - 1; if (adjustedBsMonth <= 0) { adjustedBsMonth = 12; adjustedBsYear = bsYear - 1; } adjustedBsDay = 30 + bsDay; // Simplified, should use actual days in previous month } return `${adjustedBsYear}-${adjustedBsMonth}-${adjustedBsDay}`; }; // Get current Nepali date (approximate) const getCurrentNepaliDate = () => { const today = new Date(); const adDate = today.toISOString().split('T')[0]; return convertAdToBs(adDate); }; export default function NepaliCalendarApp() { const [currentDate, setCurrentDate] = useState(getCurrentNepaliDate()); const [currentYear, currentMonth, currentDay] = currentDate.split('-').map(Number); const [showConverter, setShowConverter] = useState(false); const [adDate, setAdDate] = useState(''); const [bsDate, setBsDate] = useState(''); const [selectedDate, setSelectedDate] = useState(null); const [showInfo, setShowInfo] = useState(false); useEffect(() => { // Initialize converter dates const today = new Date().toISOString().split('T')[0]; setAdDate(today); setBsDate(convertAdToBs(today)); }, []); const handlePrevMonth = () => { let newMonth = currentMonth - 1; let newYear = currentYear; if (newMonth < 1) { newMonth = 12; newYear -= 1; } setCurrentDate(`${newYear}-${newMonth}-1`); setSelectedDate(null); }; const handleNextMonth = () => { let newMonth = currentMonth + 1; let newYear = currentYear; if (newMonth > 12) { newMonth = 1; newYear += 1; } setCurrentDate(`${newYear}-${newMonth}-1`); setSelectedDate(null); }; const handleDateClick = (day) => { const dateString = `${currentYear}-${currentMonth}-${day}`; setSelectedDate(dateString); }; const handleAdDateChange = (e) => { const newAdDate = e.target.value; setAdDate(newAdDate); setBsDate(convertAdToBs(newAdDate)); }; const handleBsDateChange = (e) => { const newBsDate = e.target.value; setBsDate(newBsDate); setAdDate(convertBsToAd(newBsDate)); }; const goToToday = () => { setCurrentDate(getCurrentNepaliDate()); setSelectedDate(null); }; // Generate calendar days const generateCalendarDays = () => { const daysInMonth = nepaliMonthDays[currentYear]?.[currentMonth - 1] || 30; const days = []; // Get first day of month (simplified - in a real app, calculate actual day of week) const firstDayOfWeek = 0; // Sunday // Add empty cells for days before the first day of the month for (let i = 0; i < firstDayOfWeek; i++) { days.push(
); } // Add days of the month for (let day = 1; day <= daysInMonth; day++) { const dateString = `${currentYear}-${currentMonth}-${day}`; const isFestival = festivals[dateString]; const isSelected = selectedDate === dateString; const isToday = dateString === getCurrentNepaliDate(); days.push(
handleDateClick(day)} className={`h-10 w-10 flex items-center justify-center rounded-full cursor-pointer relative ${isSelected ? 'bg-[#8B0000] text-white' : ''} ${isToday && !isSelected ? 'border-2 border-[#8B0000]' : ''} ${isFestival ? 'font-bold' : ''} hover:bg-[#F4C430] hover:text-[#8B0000]`} > {day} {isFestival &&
}
); } return days; }; return (
{/* Header */}

Nepali Calendar

{/* Info Panel */} {showInfo && (

About Nepali Calendar

The Nepali Calendar (Bikram Sambat) is approximately 56-57 years ahead of the Gregorian calendar. It begins in mid-April with the month of Baishakh and has its own system of months, days, and festivals.

)} {/* Month Navigation */}

{nepaliMonths[currentMonth - 1]} {currentYear}

{new Date(convertBsToAd(`${currentYear}-${currentMonth}-1`)).toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}

{/* Calendar Grid */}
{/* Weekday headers */}
Su
Mo
Tu
We
Th
Fr
Sa
{/* Calendar days */}
{generateCalendarDays()}
{/* Selected Date Info */} {selectedDate && (

{selectedDate.split('-')[2]} {nepaliMonths[currentMonth - 1]} {currentYear} BS

{new Date(convertBsToAd(selectedDate)).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}

{festivals[selectedDate] && (
Festival: {festivals[selectedDate]}
)}
)} {/* Date Converter */}
{showConverter && (
)}
{/* Footer */}
Nepali Calendar App
); }