К содержимому
Hub
Integral — electronic gradebook

Integral — electronic gradebook

Web2026JavaScriptHTMLCSSБез зависимостейОбразование

A gradebook for a private tutor: grades, attendance, student payments and monthly income — including a doubled fee when marks drop.

A gradebook for a teacher who runs their own groups: grades, attendance, student records, payments, reports and monthly income.

The unusual part is the doubling rule. If a student's monthly average drops below a set threshold, the fee for that month is doubled automatically, and a message with the full breakdown goes out to the teacher and the parents. The threshold, the multiplier and the rule itself are all configurable, and the teacher can pin a multiplier by hand for a particular student.

A month counts in full whether the student attended or not: at the start of a new month the fee is charged automatically. Charges across the whole period are recomputed from the enrolment month, so the outstanding balance is correct no matter when the journal was last opened — a detail that matters, because a tutor opens it in bursts and not every day.

There are two separate logins: the teacher with their own password, and the student, who sees only their own grades and balance. Reports cover the group average, monthly totals, and a ready-made message for parents to send through Telegram.

Written as a single page in plain HTML, CSS and JavaScript, with no build step and no dependencies — it opens on a double click and works without an internet connection.

How it's built

A fragment of the project's real code — so you can see what's inside.

Repository
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 };}
Get in touch

Project request

Fill in the form — we'll discuss scope and timing.

Regarding: Integral — electronic gradebook
Next project

Restaurant table booking bot