Как сделать календарь?

Подскажите пожалуйста как сделать в календаре дату по месяцам правильно? у меня сейчас до 32 числа почему-то выдает. Но число в input выводится правильно. Спасибо

const calendar = document.querySelector(".calendar__main");
if (calendar) {
    const input = document.querySelector("#date");
    const calHeader = document.querySelector(".calendar__header");
    const calHeaderTitle = document.querySelector(".calendar__header span");
    const calDays = document.querySelector(".calendar__days");
    const days = [
        "Пн",
        "Вт",
        "Ср",
        "Чт",
        "Пт",
        "Сб",
        "Вс"
    ];
    const months = [
        "Январь",
        "Февраль",
        "Март",
        "Апрель",
        "Май",
        "Июнь",
        "Июль",
        "Август",
        "Сентябрь",
        "Октябрь",
        "Ноябрь",
        "Декабрь"
    ];

    let oneDay = 60 * 60 * 24 * 1000;
    let todayTimestamp =
        Date.now() -
        (Date.now() % oneDay) +
        new Date().getTimezoneOffset() * 1000 * 60;

    let selectedDay = todayTimestamp;
    // console.log(selectedDay); // Str in millisec

    // Get num of days in month
    // month param 0-11
    const getNumberOfDays = (year, month) => {
        return 40 - new Date(year, month, 40).getDate();
    };
    // getNumberOfDays(2023, 1);

    // Calc day details
    const getDayDetails = (args) => {
        let date = args.index - args.firstDay;
        let day = args.index % 7;
        // console.log(day)
        let prevMonth = args.month - 1;
        let prevYear = args.year;
        if (prevMonth < 0) {
            prevMonth = 11;
            prevYear--;
        }
        let prevMonthNumberOfDays = getNumberOfDays(prevYear, prevMonth);

        let _date =
            (date < 0 ? prevMonthNumberOfDays + date : date % args.numberOfDays) + 1;
        // console.log(_date)
        let month = date < 0 ? -1 : date >= args.numberOfDays ? 1 : 0;
        let timestamp = new Date(args.year, args.month, _date).getTime();
        // console.log(timestamp)
        return {
            date: _date,
            day,
            month,
            timestamp,
            dayString: days[day]
        };
    };

    // [{}] each {} with details for each day of month
    const getMonthDetails = (year, month) => {
        let firstDay = new Date(year, month).getDay();
        let numberOfDays = getNumberOfDays(year, month);
        let monthArray = [];
        let rows = 5;
        let currentDay = null;
        let index = 0;
        let cols = 7;

        for (let row = 0; row < rows; row++) {
            for (let col = 0; col < cols; col++) {
                currentDay = getDayDetails({
                    index,
                    numberOfDays,
                    firstDay,
                    year,
                    month
                });
                monthArray.push(currentDay);
                index++;
            }
        }
        return monthArray;
    };
    // getMonthDetails(2023, 3)

    // Variables that get updated with "state" changes
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth();
    let monthDetails = getMonthDetails(year, month);

    const isCurrentDay = (day, cell) => {
        if (day.timestamp === todayTimestamp) {
            cell.classList.add("active");
            cell.classList.add("isCurrent");

        }
    };

    // Checks if day is one selected
    const isSelectedDay = (day, cell) => {
        if (day.timestamp === selectedDay) {
            cell.classList.add("active");
            cell.classList.add("isSelected");
        }
    };

    // Get month str
    const getMonthStr = (month) =>
        months[Math.max(Math.min(11, month), 0)] || "Month";
    // console.log(getMonthStr(month))

    // Set year using arrows
    const setHeaderNav = (offset) => {
        month = month + offset;
        if (month === -1) {
            month = 11;
            year--;
        } else if (month === 12) {
            month = 0;
            year++;
        }
        monthDetails = getMonthDetails(year, month);
        // console.log(getMonthDetails(year, month))
        return {
            year,
            month,
            monthDetails
        };
    };

    // Set dynamic calendar header
    const setHeader = (year, month) => {
        calHeaderTitle.innerHTML = getMonthStr(month) + " " + year;
    };

    // Set calendar header
    setHeader(year, month);

    // 1677139200000 => "2023-02-23"
    const getDateStringFromTimestamp = (timestamp) => {
        let dateObject = new Date(timestamp);
        let month = dateObject.getMonth();
        let date = dateObject.getDate();
        // return (
        //   dateObject.getFullYear() +
        //   "-" +
        //   (month < 10 ? "0" + month : month) +
        //   "-" +
        //   (date < 10 ? "0" + date : date)
        // );
        return `${getMonthStr(month)} ${date}, ${dateObject.getFullYear()}`;
    };

    const setDateToInput = (timestamp) => {
        let dateString = getDateStringFromTimestamp(timestamp);
        input.value = dateString;
    };
    setDateToInput(todayTimestamp);

    // Add days row to calendar
    for (let i = 0; i < days.length; i++) {
        let div = document.createElement("div"),
            span = document.createElement("span");

        div.classList.add("cell_wrapper");
        // div.classList.add("cal_days");
        span.classList.add("cell_item");

        span.innerText = days[i].slice(0, 2);

        div.appendChild(span);
        calDays.appendChild(div);
    }

    // Add dates to calendar
    const setCalBody = (monthDetails) => {
        // Add dates to calendar
        for (let i = 0; i < monthDetails.length; i++) {
            let div = document.createElement("div"),
                span = document.createElement("span");

            div.classList.add("cell_wrapper");
            div.classList.add("cal_date");
            monthDetails[i].month === 0 && div.classList.add("current");
            monthDetails[i].month === 0 && isCurrentDay(monthDetails[i], div);
            span.classList.add("cell_item");

            span.innerText = monthDetails[i].date;

            div.appendChild(span);
            calendar.appendChild(div);
        }
    };

    setCalBody(monthDetails);

    const updateCalendar = (btn) => {
        let newCal, offset;
        if (btn.classList.contains("calendar__btn-prev")) {
            // let { year, month, monthDetails } = setHeaderNav(-1);
            offset = -1;
        } else if (btn.classList.contains("calendar__btn-next")) {
            // let { year, month, monthDetails } = setHeaderNav(1);
            offset = 1;
        }
        newCal = setHeaderNav(offset);
        // console.log(monthDetails)
        setHeader(newCal.year, newCal.month);
        calendar.innerHTML = "";
        setCalBody(newCal.monthDetails);
    };

    // Only one calendar date is selected
    const selectOnClick = () => {
        document.querySelectorAll(".cell_wrapper").forEach((cell) => {
            cell.classList.contains("isSelected") && cell.classList.remove("active");

            if (cell.classList.contains("isCurrent") &&
                !cell.classList.contains("active")) {
                cell.querySelector("span").classList.add("inactive_indicator");
            }
        });
    };


    const updateInput = () => {
        let currentDay = document.querySelector(".isCurrent");

        // Update input based on clicked cell
        document.querySelectorAll(".cell_wrapper").forEach((cell) => {
            if (cell.classList.contains("current")) {
                cell.addEventListener("click", (e) => {
                    let cell_date = e.target.textContent;

                    currentDay !== null && currentDay.classList.remove("active");

                    for (let i = 0; i < monthDetails.length; i++) {
                        if (monthDetails[i].month === 0) {
                            if (monthDetails[i].date.toString() === cell_date) {
                                selectedDay = monthDetails[i].timestamp;
                                setDateToInput(selectedDay);
                                selectOnClick();

                                isSelectedDay(monthDetails[i], cell);

                                cell.querySelector('span').classList.contains('inactive_indicator')
                                    && cell.querySelector('span').classList.remove('inactive_indicator');
                            }
                        }
                    }
                });
            }
        });
    };

    updateInput();

    // Set header nav actions
    document.querySelectorAll(".calendar-btn").forEach((btn) => {
        btn.addEventListener("click", () => {
            updateCalendar(btn);
            updateInput();
        });
    });

    input.addEventListener('click', () => {
        document.querySelector('.calendar__content').classList.toggle('hidden');
        document.querySelector('.calendar__input').classList.toggle('showCal');
        document.querySelector('#date').classList.toggle('onFocus');
    });

}
.calendar{
  position: relative;
}
.calendar__input {
  position: relative;
  cursor: pointer;
  width: 100%;
}
.calendar__input input {
  cursor: pointer;
   width: 100%;
}
.calendar__input input._form-focus {
  border: 1px solid #ebebeb;
}
.calendar__input.showCal input {
  border: 1px solid green;
}
.calendar__input.showCal::before {
  color: green;
}
.calendar__input::before {
  position: absolute;
  right: 20px;
  font-size: 20px;
  color: #afafaf;
  top: 50%;
  transform: translate(0, -50%);
  pointer-events: none;
}
.calendar__content {
  position: absolute;
  z-index: 40;
  right: 0;
  padding: 25px;
  top: 99%;
  width: auto;
  background: #f8f8f8;
  border: 1px solid green;
  border-radius: 2px;
}
.calendar__header {
  display: flex;
  align-items: center;
  font-weight: 400;
  font-size: 16px;
  margin: 0px 0px 24px 0px;
}
.calendar__header span {
  flex: 1 1 auto;
}
.calendar__btn-prev {
  width: 24px;
  height: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0px 27px 0px 0px;
}
.calendar__btn-prev::before {
  font-size: 16px;
  transform: rotate(-90deg);
}
.calendar__btn-prev:hover::before {
  color: green;
}
.calendar__btn-next {
  width: 24px;
  height: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.calendar__btn-next::before {
  font-size: 16px;
  transform: rotate(90deg);
}
.calendar__btn-next:hover::before {
  color: green;
}
.calendar__days {
  display: grid;
  column-gap: 35px;
  grid-template-columns: repeat(7, 1fr);
  margin: 0px 0px 16px 0px;
}
.calendar__main {
  display: grid;
  column-gap: 35px;
  row-gap: 16px;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: repeat(5, min(32px));
}

.cal_date .cell_item {
  cursor: pointer;
  min-width: 32px;
  min-height: 32px;
}

.cell_wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
}
.cell_wrapper .cell_item {
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 32px;
  position: relative;
  font-weight: 400;
  font-size: 16px;
  border-radius: 50%;
  color: rgba(49, 49, 49, 0.5);
}
.cell_wrapper.active .cell_item {
  background: #efa021;
  color: #ffffff;
}

.current .cell_item {
  color: #111111;
}

.hidden {
  visibility: hidden;
}
<div class="tabs-transmit-readings__calendar calendar">
  <div class="calendar__input  _icon-calendar">
    <input autocomplete="off" type="text" id="date" class="onFocus" readonly>
  </div>
  <div class="calendar__content hidden">
    <div class="calendar__header">
      <span></span>
      <button class="calendar__btn-prev calendar-btn _icon-arrow-slider"></button>
      <button class="calendar__btn-next calendar-btn _icon-arrow-slider"></button>
    </div>
    <div class="calendar__wrapper">
      <div class="calendar__days"></div>
      <div class="calendar__main"></div>
    </div>
  </div>
</div>


Ответы (0 шт):