К содержимому
Hub
Integral — электронный журнал

Integral — электронный журнал

Веб2026JavaScriptHTMLCSSБез зависимостейОбразование

Журнал для репетитора: оценки, посещаемость, оплата учеников и доход за месяц. Считает всё сам, включая удвоение тарифа при плохих оценках.

Журнал для преподавателя, который ведёт группы сам: оценки, посещаемость, ученики, оплата, отчёты и доход за месяц.

Необычная часть — правило удвоения. Если средний балл ученика за месяц падает ниже порога, оплата за месяц удваивается автоматически, а учителю и родителям уходит сообщение с расчётом. Порог, множитель и само правило настраиваются; учитель может зафиксировать множитель вручную для конкретного ученика.

Месяц считается целиком, ходил ученик или нет: в начале нового месяца тариф списывается автоматически. Начисления за всё время пересчитываются от месяца зачисления, поэтому долг виден сразу и не зависит от того, когда учитель последний раз открывал журнал.

Разделены два входа: учитель со своим паролем и ученик, который видит только свои оценки и баланс. Есть отчёты по группе, средний балл, месячные итоги и выгрузка сообщения родителям в Telegram.

Написан одной страницей на чистом HTML, CSS и JavaScript, без сборки и без зависимостей — открывается двойным щелчком и работает без интернета.

Как это устроено

Фрагмент из настоящего кода проекта — чтобы было видно, что внутри.

Репозиторий
JavaScript
function calcPay(stu){  const avg = monthAvg(stu.id);  const r = state.settings.doubling;  let mult = 1, why = "обычная";  if(stu.mult !== "auto"){    mult = Number(stu.mult);    why = mult > 1 ? "вручную учителем" : "зафиксирована учителем";  } else if(r.enabled && avg !== null && avg <= r.threshold){    mult = r.multiplier;    why = `ср. балл ${fmtAvg(avg)} ≤ ${fmtAvg(r.threshold)}`;  }  return { avg, base: stu.basePay, mult,           total: Math.round(stu.basePay * mult), why };}/* Месячная оплата: месяц считается целиком, ходил ученик или нет.   В начале нового месяца тариф списывается автоматически. */function totalCharges(stu){  let start = stu.startMonth || CUR_MONTH;  if(start > CUR_MONTH) start = CUR_MONTH;  const months = monthsBetween(start, CUR_MONTH);  let total = 0;  months.forEach(m => { total += Math.round(stu.basePay * monthMult(stu, m)); });  return { total, months: months.length };}
Связаться

Заявка на проект

Заполните форму — обсудим детали и сроки.

По проекту: Integral — электронный журнал
Следующий проект

Бот бронирования столиков