163 lines
3.7 KiB
TypeScript
163 lines
3.7 KiB
TypeScript
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;
|
|
}
|