import dayjs, { Dayjs } from 'dayjs'; import jalaliday from 'jalaliday'; dayjs.extend(jalaliday); export interface MonthInfo { isCurrentMonth: boolean; firstDateOfMonth: dayjs.Dayjs; lastDateOfMonth: dayjs.Dayjs; monthDaysCount: number; firstDayOfMonth: number; jalaliFirstDayOfMonth: number; monthTitle: string; monthIndex: number; prevMonthIsDisabled: boolean; nextMonthIsDisabled: boolean; isDisabled: boolean; } export interface MonthlyWeekDate { gregorianDate: string; date: string; isNextMonth: boolean; isPastMonth: boolean; isCurrentDay: boolean; isPastDate: boolean; isFutureDate: boolean; dayText: string; day: number; isHoliday: boolean; isDisabled: boolean; } export const daysName = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه']; export function prepareMonthInfo(activeDate: string | Date, min?: string, max?: string): MonthInfo { const date = dayjs(activeDate).calendar('jalali'); const firstDayOfMonth = date.startOf('month').day(); return { isCurrentMonth: dayjs().calendar('jalali').isSame(date, 'month'), firstDateOfMonth: date.startOf('month'), lastDateOfMonth: date.endOf('month'), monthDaysCount: date.daysInMonth(), firstDayOfMonth, jalaliFirstDayOfMonth: firstDayOfMonth === 6 ? 0 : firstDayOfMonth + 1, monthTitle: date.locale('fa').format('MMMM YYYY'), monthIndex: date.get('month'), isDisabled: false, nextMonthIsDisabled: false, prevMonthIsDisabled: false, }; } export function prepareWeekDayDates( monthInfo: MonthInfo, min?: string, max?: string ): MonthlyWeekDate[][] { const weekDaysDates: MonthlyWeekDate[][] = []; const { monthDaysCount, firstDateOfMonth } = monthInfo; for (let i = 0; i < monthDaysCount; i++) { const date = firstDateOfMonth.add(i, 'day'); const dateDay = date.day(); const persianDateDay = dateDay === 6 ? 0 : dateDay + 1; if (i === 0 || persianDateDay === 0) { weekDaysDates.push(new Array(7) as MonthlyWeekDate[]); } if (i === 0) { for (let j = 0; j < persianDateDay; j++) { weekDaysDates[0][j] = weekDateFactory( date.add(-persianDateDay + j, 'day'), monthInfo, min, max ); } } weekDaysDates[weekDaysDates.length - 1][persianDateDay] = weekDateFactory( date, monthInfo, min, max ); if (i === monthDaysCount - 1) { for (let j = persianDateDay + 1; j < 7; j++) { weekDaysDates[weekDaysDates.length - 1][j] = weekDateFactory( date.add(j - persianDateDay, 'day'), monthInfo, min, max ); } } } return weekDaysDates; } function weekDateFactory( date: dayjs.Dayjs, monthInfo: MonthInfo, min?: string, max?: string ): MonthlyWeekDate { const now = dayjs().calendar('jalali'); const formattedDate = date.format('YYYY-MM-DD'); return { gregorianDate: date.calendar('gregory').format('YYYY-MM-DD'), date: formattedDate, isNextMonth: date.month() > monthInfo.monthIndex, isPastMonth: date.month() < monthInfo.monthIndex, isCurrentDay: now.isSame(date, 'day'), isPastDate: date.isBefore(now, 'day'), isFutureDate: now.isBefore(date, 'day'), dayText: date.locale('fa').format('D MMMM'), day: Number(date.locale('fa').format('D')), isDisabled: isDisabledDate(date, min, max), // Replace with your own holiday service isHoliday: false, }; } function isDisabledDate(date: Dayjs, min?: string, max?: string) { if (min && date.isBefore(dayjs(min), 'day')) { return true; } if (max && date.isAfter(dayjs(max), 'day')) { return true; } return false; }