Розробка системи домашніх завдань для LMS

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка системи домашніх завдань для LMS
Середня
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розроблення системи домашніх завдань у LMS

Система домашніх завдань — для завдань з відправленням файлів, дедлайнів, обробки запізнілих відправлень, рубрик оцінювання та зворотного зв'язку. Викладачі створюють шаблони завдань, учні відправляють роботи, викладачі оцінюють з коментарями.

Модель завдання

interface Assignment {
  id: string;
  lessonId: string;
  title: string;
  description: string;
  dueDate: Date;
  maxScore: number;
  rubric?: Array<{ criterion: string; points: number }>;
  allowLateSubmission: boolean;
  lateDeductionPercent?: number;
}

interface Submission {
  id: string;
  assignmentId: string;
  userId: string;
  files: Array<{ name: string; url: string; size: number }>;
  submittedAt: Date;
  isLate: boolean;
  grade?: number;
  feedback?: string;
  rubricScores?: Record<string, number>;
}

API створення завдання

app.post('/api/assignments', authenticate, async (req, res) => {
  const { lessonId, title, description, dueDate, maxScore, rubric } = req.body;

  const assignment = await db.assignments.create({
    lessonId,
    title,
    description,
    dueDate: new Date(dueDate),
    maxScore,
    rubric: rubric || [],
    createdBy: req.user.id,
  });

  res.json(assignment);
});

// Відправлення учня
app.post('/api/assignments/:assignmentId/submit', authenticate, upload.array('files'), async (req, res) => {
  const assignment = await db.assignments.findById(req.params.assignmentId);
  const existingSubmission = await db.submissions.findByUserAndAssignment(
    req.user.id, req.params.assignmentId
  );

  if (existingSubmission && !assignment.allowResubmission) {
    return res.status(409).json({ error: 'Already submitted' });
  }

  const now = new Date();
  const isLate = now > new Date(assignment.dueDate);

  const files = await Promise.all(
    req.files?.map(async (f) => ({
      name: f.originalname,
      url: await uploadToStorage(f),
      size: f.size,
    })) || []
  );

  const submission = await db.submissions.create({
    assignmentId: req.params.assignmentId,
    userId: req.user.id,
    files,
    submittedAt: now,
    isLate,
  });

  res.json(submission);
});

Інтерфейс оцінювання

function GradingPanel({ submission, assignment, onSave }) {
  const [rubricScores, setRubricScores] = useState<Record<string, number>>({});
  const [feedback, setFeedback] = useState(submission.feedback || '');
  const [grade, setGrade] = useState(submission.grade || 0);

  const handleSave = async () => {
    await fetch(`/api/submissions/${submission.id}/grade`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        grade,
        rubricScores,
        feedback,
      }),
    });
    onSave?.();
  };

  return (
    <div className="max-w-2xl mx-auto p-6 space-y-6">
      <div>
        <h3 className="font-semibold mb-4">Файли відправлення</h3>
        {submission.files.map(f => (
          <a key={f.url} href={f.url} className="block text-blue-600 hover:underline">
            {f.name}
          </a>
        ))}
      </div>

      {assignment.rubric?.length > 0 && (
        <div>
          <h3 className="font-semibold mb-4">Рубрика</h3>
          {assignment.rubric.map(criterion => (
            <div key={criterion.criterion} className="mb-3">
              <label className="text-sm text-gray-600">{criterion.criterion} (макс {criterion.points})</label>
              <input
                type="number"
                min="0"
                max={criterion.points}
                value={rubricScores[criterion.criterion] || 0}
                onChange={(e) => setRubricScores({
                  ...rubricScores,
                  [criterion.criterion]: Number(e.target.value),
                })}
                className="w-24 border rounded px-2 py-1"
              />
            </div>
          ))}
        </div>
      )}

      <div>
        <label className="block text-sm font-medium mb-2">Заключна оцінка</label>
        <input
          type="number"
          min="0"
          max={assignment.maxScore}
          value={grade}
          onChange={(e) => setGrade(Number(e.target.value))}
          className="w-24 border rounded px-2 py-1"
        />
      </div>

      <div>
        <label className="block text-sm font-medium mb-2">Зворотний зв'язок</label>
        <textarea
          value={feedback}
          onChange={(e) => setFeedback(e.target.value)}
          rows={6}
          className="w-full border rounded px-3 py-2"
        />
      </div>

      <button
        onClick={handleSave}
        className="w-full bg-blue-600 text-white rounded-lg py-2 font-medium hover:bg-blue-700"
      >
        Зберегти оцінку
      </button>
    </div>
  );
}

Обробка запізнілих відправлень

async function calculateGrade(submission: Submission, assignment: Assignment): Promise<number> {
  let finalGrade = submission.grade || 0;

  if (submission.isLate && assignment.lateDeductionPercent) {
    finalGrade = finalGrade * (1 - assignment.lateDeductionPercent / 100);
  }

  return Math.round(finalGrade * 100) / 100;
}

Строки виконання

Базова відправка завдання та оцінювання — 1 тиждень. З рубриками, штрафами за запізнення та детальним зворотним зв'язком — 2–3 тижні.