GetCourse
Yesterday

Как показать дату открытия уроков в модуле GetCourse

В стандартном интерфейсе GetCourse не отображается дата открытия уроков на уровне модуля.

Чтобы понять, когда откроется следующий урок, ученику приходится заходить внутрь каждого модуля и смотреть расписание вручную.

На практике это приводит к:

— лишним кликам
— вопросам в поддержку
— непониманию, почему модуль всё ещё закрыт

Особенно часто с этим сталкиваются онлайн-курсы с поэтапным доступом и расписанием.


В чём проблема интерфейса GetCourse

GetCourse показывает дату открытия внутри урока, но не выводит её в общем списке модулей.
Для пользователя это выглядит так, будто модуль «просто закрыт», без объяснений.


Решение: вывод даты открытия через JS

Эта задача решается с помощью небольшого JavaScript-скрипта, без плагинов и сторонних сервисов.

Логика работы простая:

— скрипт проходит по списку модулей
— заходит внутрь каждого модуля
— находит первый доступный урок с датой старта
— берёт дату из расписания
— выводит её прямо в списке модулей

В итоге пользователь сразу видит дату открытия модуля и понимает, когда именно появится доступ, не заходя внутрь.


Что это даёт

— меньше вопросов в поддержку
— понятная логика доступа для учеников
— аккуратный и информативный интерфейс
— ощущение «живого» и продуманного курса

$(function () {

  const notReachedClassName = 'not_reached';
  const modules = $('.stream-table > tbody > tr');
  if (!modules.length) return;

  modules.each(function (_, tr) {

    const link = $(tr).find('a').attr('href');
    if (!link) return;

    $.get(link, function (data) {

      const pageDom = $('<div></div>').html(data);
      const lessons = pageDom.find('.lesson-list li:not(.lesson-is-hidden)');

      showFirstLessonStart(lessons, tr);
      checkLessonsNotReached(lessons, tr);

    });

  });

  function checkLessonsNotReached(lessons, tr) {

    if (!lessons.length) return;

    let isNotReached = true;

    lessons.each(function () {
      if (!$(this).hasClass('user-state-not_reached')) {
        isNotReached = false;
        return false;
      }
    });

    if (isNotReached) {
      $(tr).addClass(notReachedClassName);
    }
  }

  function showFirstLessonStart(lessons, tr) {

    const dateStartEl = lessons.eq(0).find('.has-start-at');
    if (!dateStartEl.length) return;

   
    $(tr).find('a').prepend(dateStartEl);

    setTimeout(function () {

      const el = $(tr).find('.has-start-at').first();
      if (!el.length) return;

      const text = el.text().toLowerCase();

      let date = new Date();

      // === сегодня ===
      if (text.includes('сегодня')) {
        // date уже сегодня
      }

      // === завтра ===
      else if (text.includes('завтра')) {
        date.setDate(date.getDate() + 1);
      }

      // === конкретная дата ===
      else {
        const match = text.match(/(\d{1,2})\s(янв|фев|мар|апр|май|июн|июл|авг|сен|окт|ноя|дек)/);
        if (match) {

          const monthMap = {
            'янв': 0,
            'фев': 1,
            'мар': 2,
            'апр': 3,
            'май': 4,
            'июн': 5,
            'июл': 6,
            'авг': 7,
            'сен': 8,
            'окт': 9,
            'ноя': 10,
            'дек': 11
          };

          date = new Date(
            new Date().getFullYear(),
            monthMap[match[2]],
            match[1]
          );
        }
      }

      const day = String(date.getDate()).padStart(2, '0');
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const year = date.getFullYear();

      el.text(`Дата открытия ${day}.${month}.${year}`);

    }, 0);
  }

});