Нужно доработать функцию JS, рассчитывающую расписание на семестр/указанный диапазон дат

Нужно доработать функцию "checkHours". Суть в том, что пользователь вводит в поле количество часов, которое нужно отработать и расписание должно вывестись в соответствие с заданными часами и датами начала/конца (1 weekType (т.е. количество пар) = 2 часа ). И нужно сделать так, чтобы функция возвращала новый массив с расписанием:

  1. Если количество введенных часов больше количества часов, которое высчитывается из заданного расписания, то должен вернуться новый массив с пересчитанным количеством пар и должно вывестись, сколько ПАР необходимо доставить;
  2. Если количество введенных часов меньше количества часов, которое высчитывается из заданного расписания, то должен вернуться новый массив, из которого убраны те пары, которые не умещаются по введенным часам.

На всякий случай (извиняюсь за "полотно" кода), приложу весь код, потому что мог накосячить где-то еще:

(() => {
  const $blocks = document.querySelectorAll(".main__td-counter"); // блоки с ползунками
  const $btnAdd = document.querySelector(".main__day-off-btn"); // кнопка добавления дат
  const $btnClearDaysOff = document.querySelector(".main__clear-days-off-list"); // кнопка очистки списка выходных дней
  let daysOff = []; // массив выходных дней

  // изменение счетчика
  function setCounter() {
    for (const $block of $blocks) {
      const $input = $block.querySelector(".main__day-count");
      const $counter = $block.querySelector(".main__counter");

      $counter.textContent = $input.value;

      $input.addEventListener("input", () => {
        $counter.textContent = $input.value;
      });
    }
  }

  $btnAdd.addEventListener("click", function(e) {
    e.preventDefault();

    // добавление дат
    let dateInputValue = document.querySelector(".main__day-off-picker").value;

    dateInputValue = new Date(dateInputValue).toLocaleDateString("ru-RU");

    if (!daysOff.includes(dateInputValue)) {
      daysOff.push(dateInputValue);
      renderDates();
    }
  });

  // Функция для удаления даты из массива
  function removeDate(date) {
    const index = daysOff.indexOf(date);
    if (index !== -1) {
      daysOff.splice(index, 1);
      renderDates();
    }
  }

  // Функция для перерисовки списка дат на странице
  function renderDates() {
    const datesList = document.querySelector(".main__days-off-list");

    // Очистка списка
    while (datesList.firstChild) {
      datesList.removeChild(datesList.firstChild);
    }

    // Создание элементов списка для каждой даты
    daysOff.forEach(function(date) {
      const listItem = document.createElement("li");
      const datePar = document.createElement("p");
      datePar.textContent = date;
      datePar.className = "main__day-off-text";

      // Создание кнопки удаления даты
      const deleteButton = document.createElement("button");
      deleteButton.className = "main__delete-day-btn";
      deleteButton.innerHTML = `<img class="main__delete-day-icon" src="./img/delete-icon.svg" alt="Удалить" />`;

      // Назначение обработчика события для кнопки удаления
      deleteButton.addEventListener("click", function() {
        removeDate(date);
      });

      listItem.appendChild(datePar);
      listItem.appendChild(deleteButton);
      datesList.appendChild(listItem);
    });
  }

  // очистка списка выходных дней
  $btnClearDaysOff.addEventListener("click", function(e) {
    e.preventDefault();

    daysOff = [];

    renderDates();
  });

  const form = document.querySelector(".main__make-schedule-btn"); // форма

  form.addEventListener("click", function(e) {
    e.preventDefault();

    const weeks = readWeeks();
    const beginOfSemester = getStartSemester();
    const endOfSemester = getEndSemester();
    const weekInfo = getWeekInfo();
    const hours = getHours();

    const begin = new Date(beginOfSemester);
    const end = new Date(endOfSemester);

    if (begin >= end) {
      alert(
        "Дата конца семестра не должна совпадать или быть меньше даты начала семестра!"
      );
      return;
    }

    const schedule = generateSchedule(
      weeks,
      beginOfSemester,
      endOfSemester,
      weekInfo
    );


    checkHours(hours, schedule);
  });

  // составление расписания
  function readWeeks() {
    const daysOfWeek = [
      "monday",
      "tuesday",
      "wednesday",
      "thursday",
      "friday",
      "saturday",
      "sunday",
    ];
    const data = {};

    daysOfWeek.forEach((day) => {
      data[`upper${day.charAt(0).toUpperCase()}${day.slice(1)}`] =
        document.querySelector(`input[name='upper-${day}']`).value;
      data[`lower${day.charAt(0).toUpperCase()}${day.slice(1)}`] =
        document.querySelector(`input[name='lower-${day}']`).value;
    });

    return data;
  }

  // дата начала семестра
  function getStartSemester() {
    const inputValue = document.querySelector(".main__date-picker_start").value;

    return inputValue;
  }

  // дата окончания семестра
  function getEndSemester() {
    const inputValue = document.querySelector(".main__date-picker_end").value;

    return inputValue;
  }

  // количество часов
  function getHours() {
    const inputValue = document.querySelector(".main__hours").value;

    return inputValue;
  }

  function getWeekInfo() {
    const radioValue = document.querySelector(
      "input[name='week']:checked"
    ).value;

    return radioValue;
  }

  // генерация расписания
  function generateSchedule(
    weeks,
    beginOfSemester,
    endOfSemester,
    weekInfo,
  ) {
    const startDate = new Date(beginOfSemester);
    const endDate = new Date(endOfSemester);
    let schedule = [];

    // Определение начального типа недели
    let currentWeekType = weekInfo === "upper" ? "upper" : "lower";

    // Перебор дат от начала до конца семестра
    for (
      let currentDate = new Date(startDate); currentDate <= endDate; currentDate.setDate(currentDate.getDate() + 1)
    ) {
      const month = currentDate.toLocaleString("default", {
        month: "long"
      });
      const fullDate = currentDate.toLocaleDateString("ru-RU", {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
      });
      const dayOfWeek = currentDate.toLocaleDateString("ru-RU", {
        weekday: "long",
      });

      const dayOfWeekEng = currentDate.toLocaleDateString("en-US", {
        weekday: "long",
      });

      const weekType = weeks[currentWeekType + dayOfWeekEng];

      if (Number(weekType) !== 0 && !daysOff.includes(fullDate)) {
        const formattedDate = {
          fullDate,
          dayOfWeek,
          weekType: Number(weekType),
          currentWeekType: currentWeekType === "upper" ? "верхняя" : "нижняя",
        };

        if (schedule.hasOwnProperty(month)) {
          schedule[month].push(formattedDate);
        } else {
          schedule[month] = [formattedDate];
        }
      }

      // Смена типа недели каждую неделю
      if (dayOfWeekEng === "Sunday") {
        currentWeekType = currentWeekType === "upper" ? "lower" : "upper";
      }
    }

    return schedule;
  }

  // функция проверки часов в расписании и обновления его при необходимости
  function checkHours(hours, schedule) {
    let hoursOfClasses = 0;
    const messageDiv = document.querySelector(".schedule__error");
    messageDiv.textContent = "";

    for (const month in schedule) {
      const monthSchedule = schedule[month];
      monthSchedule.forEach((item) => {
        hoursOfClasses += item.weekType * 2;
      });
    }

    console.log(hours);
    console.log(hoursOfClasses)

    if (hours < hoursOfClasses) {
      let updatedSchedule = {};

      for (const month in schedule) {
        const monthSchedule = schedule[month];
        let updatedMonthSchedule = [];

        for (const item of monthSchedule) {
          if (hours >= (item.weekType * 2)) {
            updatedMonthSchedule.push(item);
            hours -= item.weekType * 2;
          } else if (hours > 0) {
            const updatedItem = { ...item,
              weekType: hours
            };
            updatedMonthSchedule.push(updatedItem);
            hours = 0;
          } else {
            break;
          }
        }

        updatedSchedule[month] = updatedMonthSchedule;
      }

      renderUpdatedSchedule(updatedSchedule);
      messageDiv.textContent =
        "Общее количество часов в расписании было сокращено.";
    } else if (hours > hoursOfClasses) {
      messageDiv.textContent =
        "Общее количество часов в расписании превышает заданное количество часов.";
    } else {
      messageDiv.textContent =
        "Количество часов в расписании соответствует заданному количеству.";
    }
  }

  function renderUpdatedSchedule(schedule) {
    const scheduleContainer = document.querySelector(".schedule");

    // Очистка расписания
    while (scheduleContainer.firstChild) {
      scheduleContainer.removeChild(scheduleContainer.firstChild);
    }

    // Создание элементов для отображения расписания
    for (const month in schedule) {
      const monthSchedule = schedule[month];
      const monthHeader = document.createElement("h3");
      monthHeader.textContent = month;
      monthHeader.className = "schedule__month-header";
      scheduleContainer.append(monthHeader);

      monthSchedule.forEach((item) => {
        const scheduleItem = document.createElement("div");
        scheduleItem.className = "schedule__item";

        const date = document.createElement("span");
        date.textContent = `${item.fullDate} (${item.dayOfWeek}): ${item.weekType}, ${item.currentWeekType}`;
        date.className = "schedule__info";

        scheduleItem.append(date);
        scheduleContainer.append(scheduleItem);
      });
    }
  }

  setCounter();
  renderDates();
})();
* {
  font-family: "neris";
}

body {
  height: 100vw;
  background-color: #fbf8fd;
}

a {
  text-decoration: none;
  outline: none;
}

.header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.header__logo {
  min-width: 100px;
  width: 7%;
  padding-top: 1%;
}

.header__title {
  padding-top: 1%;
  line-height: 80%;
  text-align: center;
  font-weight: 900;
  font-size: 5rem;
  margin: 0 auto;
  margin-bottom: 4%;
  color: #3b313a;
}

.main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.main__content {
  display: flex;
  flex-direction: row;
  margin-bottom: 3%;
  min-height: 500px;
  height: 100%;
  width: 95%;
  border-radius: 10px;
  box-shadow: 0px 0px 30px 0px rgba(59, 49, 58, 0.4);
  padding: 10px 20px;
}

.main__data-input {
  width: 80%;
  display: flex;
  justify-content: space-between;
  flex-direction: row;
  align-items: center;
  padding: 10px 0px 10px 0px;
}

.main__label {
  margin: 0;
  font-size: 22px;
  margin-right: 20px;
  color: #3b313a;
}

.main__date-picker {
  min-width: 142px;
  min-height: 26px;
  background-color: #5c505b;
  padding: 10px;
  font-family: "neris";
  text-align: center;
  text-transform: uppercase;
  color: #fbf8fd;
  font-size: 16px;
  border: none;
  outline: none;
  border-radius: 5px;
}

::-webkit-datetime-edit {
  padding-right: 10px;
}

::-webkit-calendar-picker-indicator {
  background-color: #fbf8fd;
  padding: 5px;
  cursor: pointer;
  border-radius: 3px;
}

.main__number-picker {
  min-width: 138px;
  min-height: 26px;
  background-color: #fbf8fd;
  padding: 10px;
  font-family: "neris";
  text-align: center;
  text-transform: uppercase;
  font-weight: 700;
  color: #5c505b;
  font-size: 16px;
  border: 2px solid #5c505b;
  outline: none;
  border-radius: 5px;
}

.main__shedule {
  display: flex;
  flex-direction: column;
  margin-top: 10px;
  padding-top: 20px;
  width: 100%;
  border-top: 2px solid #bebac1;
}

.main__shedule-title {
  margin: 0;
  font-size: 30px;
  color: #3b313a;
  font-weight: 700;
  text-align: center;
  line-height: 70%;
  padding-bottom: 10px;
}

.main__day {
  margin: 0;
  margin-right: auto;
  padding-top: 10px;
  padding-bottom: 10px;
  font-size: 20px;
  color: #3b313a;
}

.main__block {
  display: flex;
  justify-content: flex-end;
  flex-direction: row;
  align-items: center;
}

.main__left,
.main__right {
  width: 50%;
}

.main__day-count {
  margin-right: 20px;
  cursor: pointer;
}

.main__help-block {
  width: 100%;
}

.main__counter {
  display: inline-block;
  min-width: 10px;
}

.main__table {
  width: 100%;
}

.main__delete-day-icon {
  width: 15px;
}

.table__column-head {
  padding-top: 20px;
  padding-bottom: 10px;
  font-size: 22px;
  text-transform: lowercase;
  color: #3b313a;
}

.main__td-counter {
  text-align: center;
}

.main__btn-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  margin: 0;
  margin-bottom: 3%;
}

.main__make-schedule-btn {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: 0;
  border-radius: 10px;
  background-color: #5c505b;
  padding: 15px 25px;
  font-size: 25px;
  text-transform: uppercase;
  color: #fbf8fd;
  transition: box-shadow .3s linear;
}

.main__make-schedule-btn:hover {
  box-shadow: 0px 0px 20px 0px rgba(59, 49, 58, 0.8);
}

.main__make-schedule-btn:active {
  background-color: #2f272e;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="shortcut icon" href="/img/app_icon.ico" type="image/x-icon">
  <link rel="stylesheet" href="/style/style.css">
  <link rel="stylesheet" href="/style/fonts.css">
  <script defer src="./scripts/script.js"></script>
  <title>ScheduleCalc</title>
</head>

<body>
  <header class="header">
    <img class="header__logo" src="./img/title-img.svg" alt="">
    <h1 class="header__title">ScheduleCALC</h1>
  </header>
  <main class="main">
    <section class="main__content">
      <div class="main__left">
        <div class="main__data-input">
          <p class="main__label">Укажите дату начала семестра:</p>
          <input class="main__date-picker main__date-picker_start" type="date" name="" id="">
        </div>
        <div class="main__data-input">
          <p class="main__label">Укажите дату окончания семестра:</p>
          <input class="main__date-picker main__date-picker_end" type="date" name="" id="">
        </div>
        <div class="main__data-input">
          <p class="main__label">Укажите кол-во часов дисциплины:</p>
          <input class="main__number-picker main__hours" type="number" step="1" min="1" max="200" name="" id="">
        </div>
        <div class="main__data-input">
          <p class="main__label">Укажите неделю начала семестра:</p>
          <label>
                        <p>Верхняя неделя</p>
                        <input class="main__week" type="radio" name="week" value="upper">
                    </label>
          <label>
                        <p>Нижняя неделя</p>
                        <input class="main__week" type="radio" name="week" value="lower">
                    </label>
        </div>
        <div class="main__shedule">
          <form class="main__help-block">
            <table class="main__table">
              <caption>
                <le class="main__shedule-title">Количество занятий</le>
              </caption>
              <thead>
                <th class="table__column-head">День недели</th>
                <th class="table__column-head">Верхняя неделя</th>
                <th class="table__column-head">Нижняя неделя</th>
              </thead>
              <tbody>
                <tr>
                  <td>
                    <p class="main__day">Понедельник:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-monday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-monday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Вторник:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-tuesday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-tuesday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Среда:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-wednesday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-wednesday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Четверг:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-thursday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-thursday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Пятница:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-friday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-friday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Суббота:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-saturday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-saturday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
                <tr>
                  <td>
                    <p class="main__day">Воскресенье:</p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="upper-sunday">
                    <p class="main__counter"></p>
                  </td>
                  <td class="main__td-counter">
                    <input class="main__day-count" type="range" step="1" min="0" max="6" value="0" name="lower-sunday">
                    <p class="main__counter"></p>
                  </td>
                </tr>
              </tbody>
            </table>
          </form>
        </div>
      </div>
      <div class="main__right">
        <div class="main__data-input">
          <p class="main__label">Укажите праздничные дни:</p>
          <input class="main__date-picker main__day-off-picker" type="date">
          <button class="main__day-off-btn">Добавить</button>
          <ul class="main__days-off-list"></ul>
          <button class="main__clear-days-off-list">Очистить список</button>
        </div>
      </div>
    </section>
    <div class="main__btn-container">
      <button class="main__make-schedule-btn" type="submit">Составить график занятий</button>
    </div>
    <section class="result">
      <div class="result__container">
        <div class="schedule__error"></div>
        <div class="schedule__container schedule"></div>
      </div>
    </section>
  </main>
</body>

</html>


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