Calendar: Various fixes (#1423)
This commit is contained in:
parent
9ec67df99d
commit
b5542462ac
@ -58,6 +58,9 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
const [isTimeInputFocused, markTimeInputAsFocused, unmarkTimeInputAsFocused] = useFlag(false);
|
const [isTimeInputFocused, markTimeInputAsFocused, unmarkTimeInputAsFocused] = useFlag(false);
|
||||||
|
|
||||||
const [selectedDate, setSelectedDate] = useState<Date>(defaultSelectedDate);
|
const [selectedDate, setSelectedDate] = useState<Date>(defaultSelectedDate);
|
||||||
|
const [currentMonthAndYear, setCurrentMonthAndYear] = useState<Date>(
|
||||||
|
new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1),
|
||||||
|
);
|
||||||
const [selectedHours, setSelectedHours] = useState<string>(
|
const [selectedHours, setSelectedHours] = useState<string>(
|
||||||
formatInputTime(defaultSelectedDate.getHours()),
|
formatInputTime(defaultSelectedDate.getHours()),
|
||||||
);
|
);
|
||||||
@ -65,15 +68,16 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
formatInputTime(defaultSelectedDate.getMinutes()),
|
formatInputTime(defaultSelectedDate.getMinutes()),
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentYear = selectedDate.getFullYear();
|
const selectedDay = formatDay(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
|
||||||
const currentMonth = selectedDate.getMonth();
|
const currentYear = currentMonthAndYear.getFullYear();
|
||||||
const currentDate = selectedDate.getDate();
|
const currentMonth = currentMonthAndYear.getMonth();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!prevIsOpen && isOpen) {
|
if (!prevIsOpen && isOpen) {
|
||||||
setSelectedDate(defaultSelectedDate);
|
setSelectedDate(defaultSelectedDate);
|
||||||
|
setCurrentMonthAndYear(new Date(defaultSelectedDate.getFullYear(), defaultSelectedDate.getMonth(), 1));
|
||||||
}
|
}
|
||||||
}, [isOpen, defaultSelectedDate, prevIsOpen]);
|
}, [defaultSelectedDate, isOpen, prevIsOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFutureMode && !isTimeInputFocused && selectedDate.getTime() < defaultSelectedDate.getTime()) {
|
if (isFutureMode && !isTimeInputFocused && selectedDate.getTime() < defaultSelectedDate.getTime()) {
|
||||||
@ -87,12 +91,12 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
|| (maxDate && currentYear >= maxDate.getFullYear() && currentMonth >= maxDate.getMonth());
|
|| (maxDate && currentYear >= maxDate.getFullYear() && currentMonth >= maxDate.getMonth());
|
||||||
const shouldDisablePrevMonth = isFutureMode && currentYear <= now.getFullYear() && currentMonth <= now.getMonth();
|
const shouldDisablePrevMonth = isFutureMode && currentYear <= now.getFullYear() && currentMonth <= now.getMonth();
|
||||||
|
|
||||||
const calendarGrid = useMemo(() => (
|
const { prevMonthGrid, currentMonthGrid, nextMonthGrid } = useMemo(() => (
|
||||||
buildCalendarGrid(currentYear, currentMonth)
|
buildCalendarGrid(currentYear, currentMonth)
|
||||||
), [currentMonth, currentYear]);
|
), [currentMonth, currentYear]);
|
||||||
|
|
||||||
function handlePrevMonth() {
|
function handlePrevMonth() {
|
||||||
setSelectedDate((d) => {
|
setCurrentMonthAndYear((d) => {
|
||||||
const dateCopy = new Date(d);
|
const dateCopy = new Date(d);
|
||||||
dateCopy.setMonth(dateCopy.getMonth() - 1);
|
dateCopy.setMonth(dateCopy.getMonth() - 1);
|
||||||
|
|
||||||
@ -101,7 +105,7 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleNextMonth() {
|
function handleNextMonth() {
|
||||||
setSelectedDate((d) => {
|
setCurrentMonthAndYear((d) => {
|
||||||
const dateCopy = new Date(d);
|
const dateCopy = new Date(d);
|
||||||
dateCopy.setMonth(dateCopy.getMonth() + 1);
|
dateCopy.setMonth(dateCopy.getMonth() + 1);
|
||||||
|
|
||||||
@ -113,6 +117,8 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
setSelectedDate((d) => {
|
setSelectedDate((d) => {
|
||||||
const dateCopy = new Date(d);
|
const dateCopy = new Date(d);
|
||||||
dateCopy.setDate(date);
|
dateCopy.setDate(date);
|
||||||
|
dateCopy.setMonth(currentMonth);
|
||||||
|
dateCopy.setFullYear(currentYear);
|
||||||
|
|
||||||
return dateCopy;
|
return dateCopy;
|
||||||
});
|
});
|
||||||
@ -204,9 +210,9 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<h4>
|
<h4>
|
||||||
{lang(`lng_month${selectedDate.getMonth() + 1}`)}
|
{lang(`lng_month${currentMonth + 1}`)}
|
||||||
{' '}
|
{' '}
|
||||||
{selectedDate.getFullYear()}
|
{currentYear}
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -238,7 +244,10 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
<span>{lang(day)}</span>
|
<span>{lang(day)}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{calendarGrid.map((gridDate) => (
|
{prevMonthGrid.map((gridDate) => (
|
||||||
|
<div className="day-button disabled"><span>{gridDate}</span></div>
|
||||||
|
))}
|
||||||
|
{currentMonthGrid.map((gridDate) => (
|
||||||
<div
|
<div
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
@ -250,7 +259,7 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
)
|
)
|
||||||
? 'disabled'
|
? 'disabled'
|
||||||
: `${gridDate ? 'clickable' : ''}`,
|
: `${gridDate ? 'clickable' : ''}`,
|
||||||
gridDate === currentDate && 'selected',
|
selectedDay === formatDay(currentYear, currentMonth, gridDate) && 'selected',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{!!gridDate && (
|
{!!gridDate && (
|
||||||
@ -258,6 +267,9 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{nextMonthGrid.map((gridDate) => (
|
||||||
|
<div className="day-button disabled"><span>{gridDate}</span></div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -278,26 +290,35 @@ const CalendarModal: FC<OwnProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
function buildCalendarGrid(year: number, month: number) {
|
function buildCalendarGrid(year: number, month: number) {
|
||||||
const grid: number[] = [];
|
const prevMonthGrid: number[] = [];
|
||||||
|
const currentMonthGrid: number[] = [];
|
||||||
|
const nextMonthGrid: number[] = [];
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
date.setFullYear(year);
|
|
||||||
date.setMonth(month);
|
|
||||||
date.setDate(1);
|
date.setDate(1);
|
||||||
|
date.setMonth(month);
|
||||||
|
date.setFullYear(year);
|
||||||
|
const firstDay = date.getDay();
|
||||||
|
const totalDaysInPrevMonth = new Date(year, month, 0).getDate();
|
||||||
|
|
||||||
const monthStartDay = date.getDay() || 7;
|
for (let i = 1; i < firstDay; i++) {
|
||||||
// Fill empty cells
|
prevMonthGrid.push(totalDaysInPrevMonth - firstDay + i + 1);
|
||||||
for (let i = 1; i < monthStartDay; i++) {
|
|
||||||
grid.push(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (date.getMonth() === month) {
|
while (date.getMonth() === month) {
|
||||||
const gridDate = date.getDate();
|
const gridDate = date.getDate();
|
||||||
grid.push(gridDate);
|
currentMonthGrid.push(gridDate);
|
||||||
date.setDate(gridDate + 1);
|
date.setDate(gridDate + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return grid;
|
const lastRowDaysCount = (currentMonthGrid.length + prevMonthGrid.length) % 7;
|
||||||
|
if (lastRowDaysCount > 0) {
|
||||||
|
for (let i = 1; i <= 7 - lastRowDaysCount; i++) {
|
||||||
|
nextMonthGrid.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { prevMonthGrid, currentMonthGrid, nextMonthGrid };
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDisabledDay(year: number, month: number, day: number, minDate?: Date, maxDate?: Date) {
|
function isDisabledDay(year: number, month: number, day: number, minDate?: Date, maxDate?: Date) {
|
||||||
@ -318,6 +339,10 @@ function formatInputTime(value: string | number) {
|
|||||||
return String(value).padStart(2, '0');
|
return String(value).padStart(2, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatDay(year: number, month: number, day: number) {
|
||||||
|
return `${year}-${month + 1}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
function formatSubmitLabel(lang: LangFn, date: Date) {
|
function formatSubmitLabel(lang: LangFn, date: Date) {
|
||||||
const day = formatDateToString(date, lang.code);
|
const day = formatDateToString(date, lang.code);
|
||||||
const today = formatDateToString(new Date(), lang.code);
|
const today = formatDateToString(new Date(), lang.code);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user