ICT School — a learning platform three audiences share
A teaching institute was running classes, attendance, lesson material and payments across paper and spreadsheets. They needed one system that admins, teachers and students could each use without seeing anyone else's half of it.
Role
Full-stack developer
Stack
Laravel, MySQL, jQuery, Ajax
Delivery
CI/CD via GitHub Actions
Users
Admin, teacher, student
The problem
The institute's teachers were tracking classes, attendance and payments by hand. Every teacher had their own spreadsheet, students had no reliable way to see what they had paid for, and the admin had no view across any of it. Anything built to replace that had to be genuinely simpler than paper, or staff would quietly go back to paper.
What I built
A role-based Laravel application where each of the three audiences gets its own surface and nothing more:
- Admin — full CRUD over teacher accounts, plus activation and deactivation so access can be revoked without deleting a history of classes.
- Teacher — student registration and records, physical and online class management, lesson and quiz authoring, and class payment tracking.
- Student — access to lessons once the matching payment has cleared, and quiz submission against the teacher's answer key.
The piece I am most pleased with is QR-based attendance. Roll-call was eating the first five minutes of every class; a scan at the door reduced that to nothing and produced an attendance record accurate enough to bill from.
Engineering decisions
- Payment gates content, not accounts. Access is checked per lesson at request time rather than by flipping a flag on the student, so a refund or a failed payment takes effect immediately instead of on next login.
- Deactivate over delete. Teacher accounts are deactivated, never removed, because the classes, payments and attendance rows attached to them are the institute's records.
- Continuous deployment from day one. A GitHub Actions pipeline pushes to the host on merge, which mattered on a project where the client would spot an issue mid-lesson and want it fixed the same evening.
What I would do differently
The front end leans on jQuery and Ajax, which was the pragmatic choice inside a Laravel-rendered app but left the interactive parts — quiz authoring especially — harder to test than they should be. If I rebuilt it today I would keep the server-rendered shell and isolate those interactive islands behind a component layer, so the complex state has somewhere to live that is not a jQuery selector.
See the other case study
Save Life — a donation platform with a forecasting model behind it.