Skip to main content

Student Creation (Manual & Bulk)

Admins add students one of two ways: a 3-step wizard that captures the student, links one or more parents/guardians, and dispatches set-password emails; or CSV bulk import for onboarding a whole roster at once. The wizard auto-creates linked parent accounts as part of the same submission — there's no separate "create parent" page.

At a glance

Who can do thisAdmins assigned to the school. (Super admins via the school-scoped dashboard route.)
Where it livesAdmin panel → /dashboard/school/:id/studentsCreate Student (manual) or Bulk Import (CSV)
Auto-creates parent accounts?Yes — the wizard's step 2 captures up to 3 parents (mother / father / guardian); each one with a name becomes a linked parent user when the student is submitted.
CSV template?Not currently downloadable from the UI — uploads only accept .csv.
Related featuresTeacher Creation · Sections & Teacher Assignment · Student Details

How it flows

Step-by-step — Path A: Manual creation (3-step wizard)

Step 1 — Student Details

  • Modal title: "Create Student" with a Steps indicator at the top.
  • Card 1 — Basic Information:
    • First Name (required, max 100, free-text)
    • Last Name (required, max 100, free-text)
    • Email Address (required, valid email format) — pressed Next triggers a live uniqueness check; if taken, inline error "This email is already registered. Please use a different email."
  • Card 2 — Class & Section:
    • Class (required, single-select; populated from school's assigned classes)
    • Section (required, single-select; locked until a class is picked, then filtered to sections of that class)

Step 2 — Parent / Guardian

  • Info banner: "Please provide details for at least one parent or guardian."
  • Three identical cards: Mother's Details, Father's Details, Guardian's Details. Each has:
    • First Name (letters/spaces only, max 100)
    • Last Name (letters/spaces only, max 100)
    • Email (optional, but if present must be valid format)
    • Contact Number (optional, max 15 chars)
  • At least one card must have a First Name filled — otherwise Next shows warning toast: "Please provide details for at least one parent or guardian."

Step 3 — Review & Invite

  • Three summary cards:
    1. Student Details — name, email, class, section.
    2. Parent / Guardian Details — only the parents you actually filled in (others are hidden); if all three are empty you'll see "No parent details provided" (but you couldn't have reached this step).
    3. Invitation Emails — two toggles:
      • Send password setup link to student (default ON, shows the student's email)
      • Send password setup link to parent(s) (default ON, shown only if at least one parent has an email; lists all parent emails)
  • Create Student button submits everything in one shot. On success:
    • Student user is created with the chosen class and section.
    • Each parent with a First Name becomes a parent user; if they have an email and the parent toggle is on, they receive a set-password invitation.
    • Toast: "Student created successfully!" — modal closes and the table refreshes.
  • Back preserves what you typed (parent step also re-hydrates from the in-memory parentData).
  • Cancel discards everything (no draft persistence).

Step-by-step — Path B: Bulk CSV import

1. Open the import control

  • Route: /dashboard/school/:id/students.
  • Click the Bulk Import button at the top of the table (next to the search field).

2. Pick a CSV

  • File picker opens; only .csv is accepted (.xlsx is not handled by this control today).
  • The upload starts immediately on file selection (no confirmation modal).
  • The file is uploaded against the current school ID (taken from the URL) — there's no school picker.

3. Read the result

  • On success, a toast surfaces the backend's message (e.g. "Students imported successfully") and the table refreshes.
  • On failure, a toast surfaces "Import failed" or the backend's error string.
  • The current upload control surfaces a single message — it does not display per-row errors in the UI. To see per-row failures, check the response payload via DevTools.

There is no in-app "Download Template" button. The expected CSV columns must be obtained from the backend team or by inspecting recent successful imports. The bulk import is a partial-success operation: rows that pass validation are created; rows that fail are skipped with errors.

What gets linked automatically

  • Student → Section: based on the section picked in step 1; the student appears in the section's roster immediately.
  • Student → Parent: parents created in step 2 are linked to the student record. Parents reuse existing parent accounts if their email already maps to one (otherwise a new parent user is created).
  • Multi-child parents: if you create two students and add the same parent email to each, the parent's app shows both children under one parent account.

Edge cases & things to test

  • Email uniqueness — live check: in Step 1, type an email used by an existing user → tab away → confirm inline error "This email is already registered" before reaching Step 2.
  • Email uniqueness — race: two admins enter the same email at the same time. Confirm the second submitter gets a clear "already exists" failure on Step 3, not a silent dupe.
  • Class with no sections: pick a class that has no sections defined — confirm the Section dropdown shows "No sections" and Next is blocked.
  • Switching class clears section: pick Class 8 → Section A → switch class to Class 9. Confirm Section field resets to empty (not stale "A").
  • All three parents empty in step 2: hit Next — confirm warning toast and the step doesn't advance.
  • Parent with letters-only names: try "O'Brien" — currently the regex /^[A-Za-z\s]*$/ rejects apostrophes. Decide whether that's intended.
  • Parent with no email: fill only First Name + phone for one parent. Confirm Step 3's "Send to parent(s)" toggle is hidden (no addresses to send to), and the student is still created with the parent linked.
  • Toggle off student invite: in Step 3, turn off the student email toggle. Confirm the student user is created but no email goes out — the admin will need to share credentials manually (super admin password reset on /dashboard/admins is admin-only; for students, no in-UI password reset exists).
  • Wizard close + reopen: open wizard, fill Step 1, close, reopen — confirm the form resets to a blank Step 1 (no draft survival).
  • CSV — wrong file type: try uploading .xlsx or .txt — confirm the file picker rejects it (accept attribute).
  • CSV — empty file: upload a 0-byte CSV — confirm a clean error toast, not a crash.
  • CSV — partial success: upload 100 rows where 5 are malformed — confirm the toast surfaces the count of created vs skipped (or at least clearly indicates partial success). If the UI only shows "Students imported successfully" with no count, that's a known limitation worth flagging.
  • CSV — duplicate email within the same file: confirm rows with the same email don't both create users (one wins, the rest are skipped/errored).
  • CSV — row referencing a non-existent class/section: confirm the row is rejected, not silently dropped.
  • Section reassignment after creation: create a student in Section A, then edit them into Section B — confirm the section roster on Section A drops them and Section B gains them.
  • Filters page interaction: with status=Inactive filter active, create a new student — they're created Active by default, so confirm they show up only after clearing the filter (no surprise empty list).
  • Parent multi-child: create Student 1 with parent mom@example.com, then create Student 2 with the same parent email. Confirm in the parent app both children appear under one account.
  • Pending invite resend: after creation, the parent never receives the email — open the student row's actions and use Resend Parent Invitation (available in the table dropdown) to re-dispatch.