Calendar: Various fixes (#1423)

This commit is contained in:
Alexander Zinchuk 2021-09-03 18:31:32 +03:00
parent 9ec67df99d
commit b5542462ac

View File

@ -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);