11 / 11
Full Stack
ShadowSensei
A three-sided school management system: one set of screens for admins, one for teachers, one for students.
- ROLE
- Full-stack developer, solo project
- STACK
- PHP (procedural, mysqli), MySQL, vanilla JS + jQuery, Ionicons, SweetAlert, hand-written CSS per page
- PLATFORM
- Web app (server-rendered, XAMPP/Apache-style local hosting)

THE PROBLEM
Running even a small school means juggling several interlocking records: which departments exist, which courses belong to them, which sections of a course are running, which teacher is assigned to which section, which students are enrolled, and how attendance and grades get recorded for each lecture. Spreadsheets get unwieldy fast once three different kinds of users — administrators, teachers, and students — all need their own view into the same data, with different permissions.
ShadowSensei (internally labeled "Ninja — Database Management System") tackles this by giving each role its own login and panel, backed by a single shared MySQL database, so the admin's work (creating a department or assigning a teacher) is immediately visible in the teacher's and student's views.
THE IDEA
Keep it simple and role-scoped: three parallel login flows that set a cookie after checking credentials against the database, then gate every subsequent page behind a check_cookie include that re-validates the cookie against the DB on every load.
Each role gets its own panel and navbar, but all of them read and write the same underlying tables through a shared mysqli connection.
WHAT IT DOES
01
Three role-based logins, one database
A landing selector routes into Student, Admin, or Teacher login, each its own PHP file. On login, a user cookie is set for 30 days, and every protected page re-queries the matching details table to confirm the cookie still corresponds to a real account before rendering.

02
Role-themed login screens
Each role's login page carries its own color and ninja-avatar theme — orange for students, red for admin, blue for teachers — set by a matching navbar include per role/section.

03
Admin dashboard
Live counts of students, teachers, and courses pulled straight from COUNT-style queries, with recent teachers/students lists. From here the admin reaches dedicated CRUD screens for departments, courses, sections, faculty, students, and course-to-teacher assignment.

04
Student panel
Read access to a student's own data: enrolled courses, attendance history, and a marks table broken down by assignment, quiz, mid-terms, and finals.

HOW IT WORKS
Browser (vanilla JS + jQuery AJAX, Ionicons, SweetAlert)
|
v
PHP pages (role-specific: Admin_*, Teacher_*, Student_*)
| each guarded by check_cookie_{admin,faculty,student}.php
v
Insert/*.php, Update/*.php, Delete/*.php, get_*.php <-- action/query endpoints
|
v
connect.php (mysqli_connect to 127.0.0.1:4306, DB "Project")
|
v
MySQL tables: admin_details, teacher_details, student_details,
department_details, course_details, section_details,
assign_course, attendance, marks, ...No framework, no router
Each "page" is a standalone .php file that both renders HTML and runs its own queries inline, and every action (insert/update/delete) is its own separate file, posted to directly from a form action.
Cascading dropdowns, the classic way
Department → course → section → student selectors are implemented with a get_*.php file that returns rows for the selected parent ID, called via jQuery AJAX on change — around 10 of these endpoints exist purely to back AJAX-populated selects.
Cookie-based auth, not sessions
On login, a user cookie is set to the username for 30 days, and every protected page re-queries the matching details table to confirm the cookie still corresponds to a real account before rendering. There's one check_cookie include per role, included at the top of every page that role is allowed to see.
Teacher attendance and marks
A teacher picks a section/lecture and marks each student present/absent, posted via AJAX to an endpoint that runs a targeted UPDATE and echoes 1/0 for success. Marks assignment works the same way: section and student dropdowns populated via AJAX, then an update endpoint for the score.
CHALLENGES AND WHAT I LEARNED
SQL built via string concatenation
Queries like the login check and the attendance-marking endpoint interpolate POST/REQUEST values directly into SQL strings — classic SQL-injection surface. A production version would move to prepared statements (mysqli_prepare / bound params) everywhere.
Plaintext password comparison
The login query compares password directly with no hashing visible in the account-creation or login queries — a real deployment would need password_hash() / password_verify().
No central router or shared layout
Every page re-includes its own navbar, re-opens its own DB connection, and duplicates the toggle/menu JS inline — functional, but a lot of copy-pasted boilerplate across roughly 40 top-level PHP files that a template layer or includes-based layout would collapse significantly.
Cookie-as-session-store
Works for a small app but re-runs a DB query on every page load just to check who's logged in, where PHP sessions would have avoided the per-request lookup.
RESULTS
Three independent role-based portals (Admin, Teacher, Student) sharing one MySQL schema.
Full CRUD coverage for departments, courses, sections, faculty, and students via dedicated Insert/Update/Delete endpoints.
AJAX-driven cascading dropdowns (department → course → section → student) across roughly 10 get_*.php endpoints.
Attendance marking and marks assignment workflows for teachers, with read-only views for students.
STACK
LINKS

NEXT PROJECT
DayMark
05 / CONTACT