$(() => {
  $('#scheduler').dxScheduler({
    dataSource: data,
    views: ['workWeek', 'month'],
    currentView: 'workWeek',
    currentDate: new Date(2021, 3, 27),
    firstDayOfWeek: 0,
    startDayHour: 9,
    endDayHour: 19,
    showAllDayPanel: false,
    height: 730,
    dataCellTemplate(itemData, itemIndex, itemElement) {
      const date = itemData.startDate;
      const element = $('<div />');
      if (isDisableDate(date)) {
        element.addClass('disable-date');
      } else if (isDinner(date)) {
        element.addClass('dinner');
      }
      const isMonth = this.option('currentView') === 'month';
      if (isMonth) {
        element.text(date.getDate());
        element.addClass('dx-scheduler-date-table-cell-text');
      }
      return itemElement.append(element);
    },
    dateCellTemplate(itemData, itemIndex, itemElement) {
      const element = $(`<div>${itemData.text}</div>`);
      const isMonth = this.option('currentView') === 'month';
      const isDisabled = isMonth
        ? isWeekend(itemData.date)
        : isDisableDate(itemData.date);
      if (isDisabled) {
        element.addClass('disable-date');
      }
      return itemElement.append(element);
    },
    timeCellTemplate(itemData, itemIndex, itemElement) {
      const element = $(`<div>${itemData.text}</div>`);
      const { date } = itemData;
      if (isDinner(date)) {
        element.addClass('dinner');
      }
      if (hasCoffeeCupIcon(date)) {
        element.append('<div class="cafe" />');
      }
      return itemElement.append(element);
    },
    onContentReady(e) {
      setComponentAria(e.component.$element());
    },
    onAppointmentFormOpening(e) {
      const startDate = new Date(e.appointmentData.startDate);
      if (!isValidAppointmentDate(startDate)) {
        e.cancel = true;
        notifyDisableDate();
      }
      applyDisableDatesToDateEditors(e.form);
    },
    onAppointmentAdding(e) {
      if (!isValidAppointment(e.component, e.appointmentData)) {
        e.cancel = true;
        notifyDisableDate();
      }
    },
    onAppointmentUpdating(e) {
      if (!isValidAppointment(e.component, e.newData)) {
        e.cancel = true;
        notifyDisableDate();
      }
    },
  });
});
const dinnerTime = { from: 12, to: 13 };
const holidays = [
  new Date(2021, 3, 29),
  new Date(2021, 5, 6),
];
const ariaDescription = () => {
  const disabledDates = holidays
    .filter(date => !isWeekend(date))
    .map(date => new Date(date).toLocaleDateString('en-US', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
      })
    );
  if (disabledDates?.length === 1) {
    return `${disabledDates} is a disabled date`;
  }
  if (disabledDates?.length > 1) {
    return `${disabledDates.join(', ')} are disabled dates`;
  }
};
function notifyDisableDate() {
  DevExpress.ui.notify('Cannot create or move an appointment/event to disabled time/date regions.', 'warning', 1000);
}
function isValidAppointment(component, appointmentData) {
  const startDate = new Date(appointmentData.startDate);
  const endDate = new Date(appointmentData.endDate);
  const cellDuration = component.option('cellDuration');
  return isValidAppointmentInterval(startDate, endDate, cellDuration);
}
function isValidAppointmentInterval(startDate, endDate, cellDuration) {
  const edgeEndDate = new Date(endDate.getTime() - 1);
  if (!isValidAppointmentDate(edgeEndDate)) {
    return false;
  }
  const durationInMs = cellDuration * 60 * 1000;
  const date = startDate;
  while (date <= endDate) {
    if (!isValidAppointmentDate(date)) {
      return false;
    }
    const newDateTime = date.getTime() + durationInMs - 1;
    date.setTime(newDateTime);
  }
  return true;
}
function isValidAppointmentDate(date) {
  return !isHoliday(date) && !isDinner(date) && !isWeekend(date);
}
function isHoliday(date) {
  const localeDate = date.toLocaleDateString();
  return holidays.filter((holiday) => holiday.toLocaleDateString() === localeDate).length > 0;
}
function isWeekend(date) {
  const day = date.getDay();
  return day === 0 || day === 6;
}
function isDisableDate(date) {
  return isHoliday(date) || isWeekend(date);
}
function isDinner(date) {
  const hours = date.getHours();
  return hours >= dinnerTime.from && hours < dinnerTime.to;
}
function hasCoffeeCupIcon(date) {
  const hours = date.getHours();
  const minutes = date.getMinutes();
  return hours === dinnerTime.from && minutes === 0;
}
function applyDisableDatesToDateEditors(form) {
  const startDateEditor = form.getEditor('startDate');
  startDateEditor.option('disabledDates', holidays);
  const endDateEditor = form.getEditor('endDate');
  endDateEditor.option('disabledDates', holidays);
}
function setComponentAria(element) {
  const prevAria = element?.attr('aria-label') || '';
  element?.attr('aria-label', `${prevAria} ${ariaDescription()}`);
}
    
    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <title>DevExtreme Demo</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script>
    <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/25.1.6/css/dx.light.css" />
    <script src="js/dx.all.js?v=25.1.6"></script>
    <script src="data.js"></script>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <script src="index.js"></script>
  </head>
  <body class="dx-viewport">
    <div class="demo-container">
      <div id="scheduler"></div>
    </div>
  </body>
</html>
    
    @-moz-document url-prefix() {
  .dx-scheduler-work-space-month .dx-scheduler-date-table-cell {
    position: relative;
  }
  .dx-scheduler-work-space-month .dx-scheduler-date-table-cell .disable-date {
    position: absolute;
    width: 100%;
    height: 100%;
  }
}
.disable-date,
.dinner {
  height: 100%;
  width: 100%;
}
.disable-date {
  background-image:
    repeating-linear-gradient(
      135deg,
      rgba(247, 234, 224, 1),
      rgba(247, 234, 224, 1) 4px,
      transparent 4px,
      transparent 9px
    );
  color: rgba(178, 74, 0, 1);
}
.dx-scheduler-header-panel-cell .disable-date {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.dx-theme-fluent .dx-scheduler-header-panel-cell .disable-date,
.dx-theme-material .dx-scheduler-header-panel-cell .disable-date {
  flex-direction: row;
  align-items: flex-end;
  justify-content: initial;
}
.dinner {
  background: #FBF1EB;
}
.dx-scheduler-time-panel-cell .dinner {
  color: #C25100;
  font-weight: 400;
  background: transparent;
}
.dx-draggable {
  cursor: auto;
}
td.dx-scheduler-time-panel-cell .dinner .cafe {
  height: 200%;
  width: 100%;
  left: 50%;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 3H4v10c0 2.21 1.79 4 4 4h6c2.21 0 4-1.79 4-4v-3h2c1.11 0 2-.9 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM4 19h16v2H4z"/></svg>');
  mask-repeat: no-repeat;
  -webkit-mask-position-y: 50%;
  -webkit-mask-position-x: 100%;
  margin-top: -4px;
  background-color: #C25100;
}
.dx-scheduler-date-table-cell {
  padding: 0;
  opacity: 1;
}
@media all and (-ms-high-contrast: none) {
  td.dx-scheduler-time-panel-cell .dinner .cafe {
    background-color: transparent;
  }
}
    
    const data = [
  {
    text: 'Website Re-Design Plan',
    startDate: new Date(2021, 3, 26, 9, 30),
    endDate: new Date(2021, 3, 26, 11, 30),
  },
  {
    text: 'Install New Router in Dev Room',
    startDate: new Date(2021, 3, 26, 13),
    endDate: new Date(2021, 3, 26, 14),
  },
  {
    text: 'Approve Personal Computer Upgrade Plan',
    startDate: new Date(2021, 3, 27, 10),
    endDate: new Date(2021, 3, 27, 11),
  },
  {
    text: 'Final Budget Review',
    startDate: new Date(2021, 3, 27, 13, 30),
    endDate: new Date(2021, 3, 27, 15),
  },
  {
    text: 'New Brochures',
    startDate: new Date(2021, 3, 26, 15),
    endDate: new Date(2021, 3, 26, 16, 15),
  },
  {
    text: 'Install New Database',
    startDate: new Date(2021, 3, 28, 9, 45),
    endDate: new Date(2021, 3, 28, 12),
  },
  {
    text: 'Approve New Online Marketing Strategy',
    startDate: new Date(2021, 3, 28, 14, 30),
    endDate: new Date(2021, 3, 28, 16, 30),
  },
  {
    text: 'Upgrade Personal Computers',
    startDate: new Date(2021, 3, 27, 15, 30),
    endDate: new Date(2021, 3, 27, 16, 45),
  },
  {
    text: 'Prepare 2021 Marketing Plan',
    startDate: new Date(2021, 4, 3, 13),
    endDate: new Date(2021, 4, 3, 15),
  },
  {
    text: 'Brochure Design Review',
    startDate: new Date(2021, 4, 4, 15, 30),
    endDate: new Date(2021, 4, 5),
  },
  {
    text: 'Create Icons for Website',
    startDate: new Date(2021, 3, 30, 10),
    endDate: new Date(2021, 3, 30, 12),
  },
  {
    text: 'Upgrade Server Hardware',
    startDate: new Date(2021, 3, 30, 16, 30),
    endDate: new Date(2021, 3, 30, 18),
  },
  {
    text: 'Submit New Website Design',
    startDate: new Date(2021, 4, 5, 10),
    endDate: new Date(2021, 4, 5, 11, 30),
  },
  {
    text: 'Launch New Website',
    startDate: new Date(2021, 3, 30, 14, 30),
    endDate: new Date(2021, 3, 30, 16, 10),
  },
];