Spec Deviation Task List

Spec Deviation Task List

Generated from a spec-vs-implementation audit of Phases 0-9 of the QuranFlow Admin Mockup.

For the developer: Before fixing any item, verify the deviation first. Open the spec file, read the cited section, then open the implementation file and confirm the gap exists. The spec is the source of truth. If the spec and this task list disagree, follow the spec. If the implementation already handles the item in a different-but-acceptable way, note it and move on.

Reminder: This is a front-end mockup. Actions should show toasts, modals can open without persisting data. The goal is to demonstrate the correct UI elements, not build working functionality. A "missing button" means the button element itself is absent from the UI — not that the button doesn't perform real backend work.


Progress Tracker

Batch Focus Area Tasks Status
1A Email Management (18.1-18.5) 5 DONE
1B Close Workflow Steps 3-5 + gate (16.5-16.9) 5 DONE
1C Payments Tab (6.1-6.5) 5 DONE
2 Dashboard + Student Detail header/Profile + Scheduling 16 DONE
3 Student list + Semester Hub tabs + Close Workflow Steps 1-2 13 DONE
4 Student Detail remaining tabs + Teacher Mgmt + misc 18 DONE
5A Cross-cutting: DataTable states, edit modals, destructive confirmations 8 TODO
5B Teacher Management + Reporting interactivity 7 TODO
5C Admin & System + annotations + URL pre-filters 7 TODO
5D High-complexity screen polish (badges, confirmation text, labels) 4 TODO

Total: ~70 of ~70 prior tasks completed + 26 new tasks from post-completion audit (Batch 5)


How to use this list

  1. Pick a task
  2. Read the spec section cited — confirm the requirement exists and what it actually says
  3. Open the implementation file — confirm the gap is real and still present
  4. Fix the UI to match the spec
  5. Run bun run build && bun run lint to verify no regressions
  6. Mark the task done

Status key: Tasks marked with — DONE in the heading have a **Completed**: line at the bottom describing what was done and when.


Task format

Each task includes:


1. Dashboard

1.1 Alert tiles missing colored borders and icons — DONE

1.2 Phase prompt bar missing "submissions this week" stat — DONE

1.3 Appointment utilization tile should show ratio format — DONE

1.4 Tile labels don't match spec — DONE

1.5 "Search Student" quick action should open global search — ACCEPTABLE DEVIATION


2. Students List

2.1 Missing TA dropdown filter — DONE

2.2 Missing "Deactivate Selected" bulk action button — DONE

2.3 Add Student modal missing Phone and Timezone fields — DONE


3. Student Detail — Entity Header

3.1 Missing "Edit Profile" button and "View in Stripe" link — DONE

3.2 Missing copy icon on email — DONE

3.3 Missing tab badges on Payments, Appointments, Semester History — DONE


4. Student Detail — Profile Tab

4.1 Missing profile picture field — DONE

4.2 Missing Enrollment fields: Is Core Enrollment, Enrollment ID — DONE

4.3 Missing System fields: Registration Date, Temp Password, Push Token — DONE

4.4 Missing section edit buttons and "Manage Tags" link — DONE


5. Student Detail — Submissions Tab

5.1 Missing Review Date and Rejection Reason columns — DONE

5.2 Missing row actions: Play Recording, View Details, Delete — DONE


6. Student Detail — Payments Tab

6.1 Missing Payment Method section — DONE

6.2 Missing Upcoming Payment section — DONE

6.3 Missing subscription fields: Current Period, Cancel at Period End — DONE

6.4 Missing Invoice link in payment history — DONE

6.5 Missing action buttons: Cancel & Deactivate, Assign Scholarship, Link Family, Send Payment Link — DONE


7. Student Detail — Appointments Tab

7.1 Missing Reschedule and Cancel row actions — DONE


8. Student Detail — Semester History Tab

8.1 Missing Elective column — DONE

8.2 Missing Status filter dropdown — DONE


9. Student Detail — Actions Tab

9.1 Missing "Revert Temporary Password" action — DONE

9.2 Deactivate should show dual-option dialog when subscription active — DONE


10. Submissions Page

10.1 Missing row actions on Assessments view — DONE

10.2 Missing row actions on Submissions view — DONE


11. Promoted Students

11.1 Missing "Repeat Signups Only" toggle — DONE


12. Failed Sign Ups

12.1 Missing date range filter — DONE

12.2 Missing per-row Delete icon and "Delete Selected" bulk action — DONE


13. Semester Hub — Overview Tab

13.1 Missing Auto-Transition toggle — DONE

13.2 Missing Cancel button in date editing mode — DONE

13.3 Email Schedule Preview missing trigger and date columns — DONE


14. Semester Hub — Setup Checklist Tab

14.1 Missing "Mark as N/A" checkbox per item — DONE

14.2 Missing "Add Note" per item — DONE

14.3 Missing expandable inline content preview for configured items — DONE

14.4 Missing amber left border on unconfigured items — DONE


15. Semester Hub — Enrollment Tab

15.1 Missing "Submission Progress" column with progress bar — DONE

15.2 Missing core enrollment toggle in Enroll Student modal — DONE

15.3 Missing "Assign TA" bulk action — DONE


16. Semester Hub — Close Workflow (Major)

The Close Workflow has the most significant deviations. Steps 3, 4, and 5 are placeholder summaries rather than the full per-student data tables the spec requires. Read 04-semester-management.md Section 3.8 carefully before working on these.

16.1 Step 1: Missing filter bar — DONE

16.2 Step 1: Missing Override button and reason field — DONE

16.3 Step 1: meetsCriteria computation incomplete — DONE

16.4 Step 2: Missing filter bar and "Mark All as Leaving" button — DONE

16.5 Step 3: Needs full per-student data table — DONE

16.6 Step 4: Needs full per-student data table — DONE

16.7 Step 5: Missing 5 metrics and Exception Details section — DONE

16.8 Gate override missing confirmation modal and badge — DONE

16.9 Missing phase check and completed state details — DONE


17. Welcome Package

17.1 Missing Edit action on rows — DONE

17.2 Upload dialog should have file picker, not file type dropdown — DONE


18. Email Management (Major) — ALL 5 TASKS DONE

This screen has the most deviations in the Semester Management section. The current implementation is essentially a plain list of template names — it's missing the key data that makes email management useful (triggers, dates, editing capability).

18.1 Missing "Trigger" column (shows "Category" instead) — DONE

18.2 Missing "Last Edited" column — DONE

18.3 Missing row actions: Edit, Delete, Preview, Test Send — DONE

18.4 Create Template modal missing fields — DONE

18.5 Semester filter not wired up — DONE


19. Tags

19.1 Missing Edit action on rows — DONE


20. Content — Recordings

20.1 Missing Level filter — DONE

20.2 "Invalid Date" bug in last row — DONE

20.3 Return to Checklist banner missing semester name — DONE


21. Calendar View

21.1 Missing click-to-create-appointment on empty slots — DONE

21.2 Missing event detail modal on click — DONE


22. Live Sessions

22.1 Missing Edit and Delete row actions — DONE


23. Upcoming Appointments

23.1 "Rescheduled To" column should not be sortable — DONE

23.2 Missing "View in Calendar" link per row — DONE

23.3 Create buttons should open modals, not just fire toasts — DONE


24. TA Schedules

24.1 Shows global holidays instead of TA-specific holidays — DONE

24.2 Timezone should be editable, not display-only — DONE


25. Teacher Detail — Schedule Tab

25.1 Missing Personal Holidays section — DONE


26. Teacher Detail — Students & Groups Tab

26.1 Missing "Create Group" button — DONE

26.2 Missing "Manage Group Members" action — DONE


27. Teacher Detail — Performance Tab

27.1 "Reviews This Semester" and "Reviews Total" show same value — DONE


28. Student Groups

28.1 "Protected" should be its own column, not an icon in Group Name — DONE


Summary by priority

High priority (significantly off-spec, structurally incomplete)

Medium priority (missing columns, filters, or action buttons)

Lower priority (minor polish, badges, labels)


Batch 5: Post-Completion Audit

Generated from a 4-loop automated review (completeness, cross-reference consistency, workflow walkthrough, mockup-readiness) run against the admin-spec, then verified against the built mockup code. Focuses on gaps that remain after the initial 70-task implementation pass.

Audit methodology: Each gap was identified by the spec audit, then verified by reading the actual implementation file. Items already resolved by the implementation (even if the spec audit flagged them) are marked ALREADY DONE.

Reminder: This is a front-end mockup. Actions should show toasts, modals can open without persisting data. The goal is to demonstrate the correct UI elements, not build working functionality.


Batch 5A: Cross-Cutting Structural Gaps (8 tasks)

These affect multiple screens and should be fixed first since they establish patterns reused everywhere.

5A.1 DataTable: add loading state support

Loading state rendering specification (when isLoading is true):

Element Behavior
Table header row Rendered normally — column headers visible so user sees structure during load
Table body Replace data rows with 5 skeleton rows
Each skeleton cell shadcn Skeleton component (import { Skeleton } from "@/components/ui/skeleton"), h-4 rounded, width varies by column index (first column: w-3/4, middle columns: w-1/2, last column: w-1/3) to create visual variety
Row height Match normal row height (h-12 or py-3)
Animation Skeleton's built-in pulse animation (shadcn default)
Pagination Hidden — table.getPageCount() === 0 when loading
Filter bar Remains visible and interactive — user can set filters before data arrives
Bulk selection Disabled — checkbox column shows disabled skeleton
Empty state Suppressed — never show empty state while loading

Usage pattern (optional, for demonstrating on 1-2 key screens like Students List):

const [isLoading, setIsLoading] = useState(true)
useEffect(() => { const t = setTimeout(() => setIsLoading(false), 800); return () => clearTimeout(t) }, [])

Props to add to DataTableProps:

isLoading?: boolean  // Shows skeleton rows instead of data

5A.2 DataTable: add error state support

Error state rendering specification (when isError is true):

Element Behavior
Layout Centered vertically within the table body area (replaces all rows)
Icon AlertTriangle from lucide-react, size-12, text-muted-foreground
Primary message errorMessage prop value, or default: "Unable to load data. Please try again."
Secondary message (Stripe variant) When errorMessage contains "Stripe": add "Showing cached data from local database." in text-muted-foreground text-sm below primary message
Retry button <Button variant="outline" size="sm"> with RotateCcw icon + "Retry" text. Calls onRetry() on click. Hidden if onRetry prop not provided.
Table header Still rendered (provides structural context even on error)
Pagination Hidden
Filter bar Remains visible (user may want to adjust filters before retry)
Minimum height min-h-[200px] so the error state doesn't collapse to nothing

Props to add to DataTableProps:

isError?: boolean        // Shows error state instead of data
errorMessage?: string    // Custom error message (default: "Unable to load data. Please try again.")
onRetry?: () => void     // Called when Retry button clicked. If omitted, Retry button hidden.

Stripe-specific variant (for Student Detail Payments Tab payments-tab.tsx): The Payments tab has its own error handling (lines 132-137 show an Alert variant="destructive" for "no subscription found"). The DataTable error state is for the payment history sub-table specifically. Confirmation text per spec 03-student-management.md Section 3.7:

5A.3 Content screens: add edit modals (6 screens)

Implementation pattern (same for all 6 — refactor each screen's existing create dialog):

Aspect Create Mode (current) Edit Mode (to add)
Dialog title "Add [Content Type]" "Edit [Content Type]"
Submit button text "Add" or "Create" "Save Changes"
Form fields Empty defaults Pre-filled from selected row data
Toast on submit "[Name] created successfully" "[Name] updated successfully"
Trigger Header button "Add [Type]" PencilIcon button in row actions column

Row action column (add to each screen's columns array):

Element Detail
Column position Rightmost, after existing columns
Column header Empty string (no header text)
Width Fixed w-[80px]
Edit trigger <Button variant="ghost" size="icon"> with <PencilIcon className="size-4" />
On click setEditData(row.original) + open dialog
Delete trigger Existing delete action if present, or add <TrashIcon> with ConfirmDialog

State to add per screen:

const [editData, setEditData] = useState<ContentType | null>(null)
// Pass to dialog: editData={editData}, onOpenChange={open => { if (!open) setEditData(null) }}

Per-screen edit modal field tables — these are the fields each edit modal should pre-fill:

Video Lessons:

Field Type Source for Pre-fill Editable Notes
Title Text input lesson.title Yes Required
Semester Select (from semesters data) lesson.semester Yes NEW field — missing from create modal too (see 5A.7)
Level Select (Level 0-4, Year 2) lesson.level Yes NEW field — missing from create modal too (see 5A.7)
Week Number input lesson.week Yes Required
Video Count Number input lesson.videoCount Yes Required
Duration Text input lesson.duration Yes Format: "45 min"

Resources:

Field Type Source for Pre-fill Editable
Title Text input resource.title Yes
Level Select resource.level Yes
Semester Select resource.semester Yes
File File picker or text resource.fileName Yes

Recordings:

Field Type Source for Pre-fill Editable
Title Text input recording.title Yes
Semester Select recording.semester Yes
Session Date Date picker recording.sessionDate Yes
Duration Text input recording.duration Yes
Video URL Text input (URL) recording.videoUrl Yes

Tutorials:

Field Type Source for Pre-fill Editable
Title Text input tutorial.title Yes
Level Select tutorial.level Yes
Semester Select tutorial.semester Yes
Pages Number input tutorial.pages Yes

MCQ Questions:

Field Type Source for Pre-fill Editable
Question Textarea question.question Yes
Level Select question.level Yes
Semester Select question.semester Yes
Options Number input question.options Yes
Correct Option Number input question.correctOption Yes

Quizzes:

Field Type Source for Pre-fill Editable Notes
Title Text input quiz.title Yes
Semester Select quiz.semester Yes NEW field — missing from create modal too (see 5A.8)
Level Select quiz.level Yes NEW field — missing from create modal too (see 5A.8)
Week Number input quiz.week Yes
Question Count Number input quiz.questions Yes

5A.4 Scheduling: add destructive confirmation dialogs (3 screens)

Per-screen confirmation dialog specification:

Upcoming Appointments — Cancel:

Element Value
Trigger XCircleIcon button on appointment row
Dialog variant Destructive
Title "Cancel Appointment?"
Description "Cancel the appointment on {formatDate(appointment.dateTime)} with {appointment.taName}? The student will be notified."
Confirm button "Cancel Appointment" (red)
Cancel button "Keep"
On confirm toast "Appointment cancelled successfully"
State needed `const [cancelTarget, setCancelTarget] = useState<Appointment

Live Sessions — Delete:

Element Value
Trigger "Delete" item in DropdownMenu on session row (line 195)
Dialog variant Destructive
Title "Delete Session?"
Description "Delete '{session.title}'? Students will no longer see this session on their schedule."
Confirm button "Delete Session" (red)
Cancel button "Keep"
On confirm toast "Session '{session.title}' deleted"
State needed `const [deleteTarget, setDeleteTarget] = useState<LiveSession

Holidays — Remove:

Element Value
Trigger TrashIcon button on holiday row
Dialog variant Destructive
Title "Delete Holiday?"
Description "Delete '{holiday.name}' ({formatDate(holiday.date)})? All affected sessions will resume their normal schedule."
Confirm button "Delete Holiday" (red)
Cancel button "Keep"
On confirm toast "Holiday '{holiday.name}' deleted"
State needed `const [deleteTarget, setDeleteTarget] = useState<Holiday

5A.5 Live Sessions: add edit modal

Edit modal field table:

Field Type Pre-fill Source Editable Required
Session Title Text input session.title Yes Yes
Date Date picker session.date Yes Yes
Time Time input session.time Yes Yes
Zoom Link Text input (URL) session.zoomLink Yes No
Level Select session.level No (display only)

Approach: Refactor existing CreateSessionDialog to accept optional editSession prop. When provided: title changes to "Edit Session", button to "Save Changes", fields pre-filled. State: const [editSession, setEditSession] = useState<LiveSession | null>(null).

5A.6 Holidays: add edit modal

Edit modal field table:

Field Type Pre-fill Source Editable Required
Holiday Name Text input holiday.name Yes Yes
Date Date picker holiday.date Yes Yes
Type Select (System-wide / Live Sessions only / Appointments only) holiday.type Yes Yes

Approach: Refactor existing Add Holiday dialog to accept optional editHoliday prop. Same pattern as 5A.5.

5A.7 Video Lessons create modal: add semester/level fields

Fields to add (insert after Title field in the dialog form):

Field Type Options Default Required
Semester Select Populated from semesters data array, showing semester.name Current/active semester (first with isCurrent: true) Yes
Level Select Level 0, Level 1, Level 2, Level 3, Level 4, Year 2 None (must select) Yes

5A.8 Quizzes create modal: add semester/level fields


Batch 5B: Teacher Management + Reporting Polish (7 tasks)

5B.1 TA Reports: add FilterBar

FilterBar configuration:

Filter Type Key Options Placeholder
Search Text input search "Search by TA name..."
Status Dropdown status All, Active, Inactive "All Statuses"
Performance Dropdown performance All, Flagged (response time >48h), On Track "All Performance"

Filter logic:

5B.2 Teaching Assistants List: add Edit/Delete row actions

Actions column specification:

Action Icon Variant Behavior Confirmation
Edit PencilIcon ghost, size="icon" Opens existing Create TA dialog pre-filled with TA data. Dialog title: "Edit Teaching Assistant". Button: "Save Changes". On submit toast: "[TA Name] updated." None
Delete TrashIcon ghost, size="icon" Opens ConfirmDialog Destructive: "Delete [TA Name]? This will remove their profile and unassign all students. This cannot be undone." Confirm button: "Delete" (red)

Column definition (add as last item in columns array):

{
  id: "actions",
  header: "",
  cell: ({ row }) => (
    <div className="flex items-center gap-1">
      <Button variant="ghost" size="icon" onClick={(e) => { e.stopPropagation(); setEditTA(row.original) }}>
        <PencilIcon className="size-4" />
      </Button>
      <Button variant="ghost" size="icon" onClick={(e) => { e.stopPropagation(); setDeleteTarget(row.original) }}>
        <TrashIcon className="size-4" />
      </Button>
    </div>
  ),
  enableSorting: false,
}

Note: e.stopPropagation() prevents the row click (navigate to detail) from also firing.

5B.3 TA Detail Schedule Tab: add empty state for availability grid

Empty state specification (replaces the blank grid when no slots exist):

Element Value
Layout Centered within the "Weekly Availability" card body, replacing the grid
Icon CalendarOff from lucide-react, size-12, text-muted-foreground
Title "No availability configured"
Description "This TA has no scheduled availability. Set up their weekly schedule to enable appointment booking."
Action button "Edit Availability" → navigates to /scheduling/ta-schedules?ta={taId}
Condition When the TA's taScheduleSlots array is empty or all slots have available: false

5B.4 Student Groups: add row click / group detail view

Expanded detail layout (renders below the clicked row, full table width):

Section Content Layout
Group info header Group name (bold), TA name (linked: <Link to={/teachers/${taId}}>), Semester, Created date Horizontal row with flex justify-between
Members table Sub-table with columns below Standard sub-table with muted header
Action buttons "Add Member" + "Transfer to Another TA" Right-aligned button row above members table
Collapse control "Close" button or re-click row Small text button bottom-right

Members sub-table columns:

Column Source Clickable
Student Name From mock students data matched to group members Yes → /students/${studentId}
Level Student's current enrollment level No
Submissions This Semester Count from mock submissions No
Last Submission Date Most recent submission date No

State: const [expandedGroupId, setExpandedGroupId] = useState<string | null>(null). Toggle on row click. Render inline content via conditional {expandedGroupId === group.id && <GroupDetail ... />} after the DataTable row.

5B.5 Specific Reports: add parameter configuration dialog

RunReportDialog specification:

Field Type Required Default Options
Report Name Text (read-only) Pre-filled from clicked report Display only
Date Range — Start Date picker Yes First day of current semester Calendar picker
Date Range — End Date picker Yes Today's date Calendar picker
Semester Select No Current/active semester All semesters from semesters data
Output Format Radio group Yes "On-Screen" CSV, PDF, On-Screen

Dialog layout:

5B.6 Student Composition: fix row click to expandable student list

Expanded section specification (renders below clicked row):

Column Source Format
Student Name Mock students filtered by level Text, linked to /students/${id}
Status Enrollment status StatusBadge: Active (green), Inactive (gray)
Type New or Returning StatusBadge: New (blue), Returning (green)
Submissions Count for current semester Number

Implementation:

5B.7 Logs: add date range filter

Date range filter specification:

Filter Type Key Default Behavior
From Date Date picker dateFrom 30 days before today Filters: log.timestamp >= selectedDate
To Date Date picker dateTo Today Filters: log.timestamp <= selectedDate

Placement: After the User dropdown in the FilterBar, before Clear All.


Batch 5C: Admin & System + Annotations (7 tasks)

5C.1 Admins: add FilterBar

FilterBar configuration:

Filter Type Key Options Placeholder
Search Text input search "Search by name or email..."
Role Dropdown role All, Admin, View-Only "All Roles"
Status Dropdown status All, Active, Inactive "All Statuses"

5C.2 Issue Queue: add editable status/priority in detail view

Editable fields specification:

Field Current Rendering Required Rendering Options On Change
Status <StatusBadge status={issue.status} /> (static) <Select> with StatusBadge-styled options Open, In Progress, Resolved, Closed Toast: "Status updated to {value}"
Priority <StatusBadge status={issue.priority} /> (static) <Select> with StatusBadge-styled options High (red), Medium (yellow), Low (gray) Toast: "Priority updated to {value}"

Visual treatment: Each Select option should render a colored dot or badge matching the StatusBadge colors so the admin sees at a glance what each status/priority means. Selected value displays as a StatusBadge within the Select trigger.

Note: The existing "Resolve" and "Close" buttons can remain as convenience shortcuts — they set status to Resolved/Closed respectively. The Select dropdown provides full control.

5C.3 Issue Queue: add admin create issue capability

CreateIssueDialog field specification:

Field Type Required Options / Placeholder Validation
Student Searchable Select (autocomplete) Yes Search students by name. Display: "Name — Email" per option. Source: students data array Must select a valid student
Type Select Yes Bug, Content, Account, Other Must select
Priority Select Yes High, Medium, Low Must select, default: Medium
Subject Text input Yes "Brief description of the issue" Min 5 characters
Description Textarea (4 rows) No "Detailed description, steps to reproduce, screenshots notes..."

Dialog layout:

5C.4 Student Report: support URL-param pre-filtering from Dashboard

Implementation:

const [searchParams] = useSearchParams()
const initialStatus = searchParams.get("status") || searchParams.get("pace") || ""
// Use initialStatus as default value for the Status filter in FilterBar

Reference pattern: All 6 content screens already implement this pattern for the Setup Checklist deep links (reading semester, level, from params). Same approach.

5C.5 Calendar View: add empty state for no-events week

Empty state specification:

Element Value
Condition filteredEvents.length === 0 for the current week/month view
Layout Centered overlay within the calendar grid area
Icon CalendarX from lucide-react, size-12, text-muted-foreground
Message "No sessions or appointments for this {view === 'week' ? 'week' : 'month'}."
Sub-text "Try adjusting your filters or selecting a different date range."
Suggested action None (filters are already visible and interactive)

5C.6 Student Detail Payments Tab: add Support Staff view annotation

Annotation specification:

Element Value
Placement Top of Payments tab content, above the Subscription Status card
Component <Alert> with <InfoIcon> (not destructive variant — use default/info)
Text "Support Staff view: All billing data on this tab is visible to Support Staff. Action buttons (Cancel, Pause, Apply Discount, etc.) and 'View in Stripe' link are hidden for Support Staff per role-based access rules."
Style Muted, text-sm, compact. Should not dominate the tab.
Dismissable No (it's specification documentation, not a runtime notification)

5C.7 Dashboard: add deprecated features note

Implementation options (pick one):

Option A — Code comment only (minimal, invisible to stakeholders):

{/* Deprecated features removed per spec 02-dashboard.md Section 1.1:
    - Daily Notes / scratchpad: provided no operational value (interview Q6, Q7)
    - Live Session Notifications widget: replaced by Semester Progress tile (Tile 6)
      and Calendar View in Scheduling domain
*/}

Option B — Visible collapsible block (recommended for mockup review):

Element Value
Placement Bottom of dashboard, below Quick Actions
Component Collapsible with trigger "What changed from the previous dashboard?"
Content "The previous dashboard's Daily Notes and Live Session Notifications have been replaced with operational alert tiles and the Phase Prompt Bar. Session information is now in Scheduling > Calendar View."
Default state Collapsed
Style text-muted-foreground text-sm, secondary visual weight

Batch 5D: High-Complexity Screen Polish (4 tasks)

5D.1 Student Detail Payments Tab: add Cancel & Deactivate confirmation dialog

ConfirmDialog specification:

Element Value
Trigger Existing "Cancel & Deactivate" button (line 267)
Variant Destructive
Title "Cancel & Deactivate?"
Description "This will cancel {studentName}'s Stripe subscription at the end of the current billing period and deactivate their account. They will lose access to all content immediately."
Confirm button text "Cancel & Deactivate" (red)
Cancel button text "Never mind"
On confirm toast "{studentName} deactivated and subscription cancelled."
State needed const [showDeactivateConfirm, setShowDeactivateConfirm] = useState(false)

Note: The spec text is intentionally precise about timing — subscription cancels at period end (not immediately), but account access is removed immediately. This distinction matters for stakeholder review.

5D.2 Student Detail entity header: Incomplete/Unpaid/None subscription badges — ALREADY DONE

5D.3 Semester Hub Overview: Draft badge color — ALREADY DONE

5D.4 Close Workflow Step 4: button label consistency — ALREADY DONE


Implementation Priority

Tier 1: Structural (do first — enables patterns across all screens)

  1. 5A.1 DataTable loading state — affects 30+ screens
  2. 5A.2 DataTable error state — affects 30+ screens

Tier 2: High value (most visible gaps, highest screen count)

  1. 5A.3 Content edit modals — 6 screens gain full CRUD
  2. 5A.4 Scheduling destructive confirmations — 3 screens, safety pattern
  3. 5B.1 TA Reports FilterBar — consistency gap
  4. 5C.2 Issue Queue editable status/priority — core workflow
  5. 5C.3 Issue Queue create issue — missing feature per spec

Tier 3: Medium value (polish + completeness)

  1. 5B.2 TA List edit/delete row actions
  2. 5A.5 Live Sessions edit modal
  3. 5A.6 Holidays edit modal
  4. 5B.5 Specific Reports parameter dialog
  5. 5B.6 Student Composition expandable rows
  6. 5D.1 Payments Cancel & Deactivate confirmation dialog

Tier 4: Lower priority (minor polish + annotations)

  1. 5A.7 Video Lessons semester/level fields
  2. 5A.8 Quizzes semester/level fields
  3. 5B.3 TA Schedule grid empty state
  4. 5B.4 Student Groups row click detail
  5. 5B.7 Logs date range filter
  6. 5C.1 Admins FilterBar
  7. 5C.4 Student Report URL-param pre-filter
  8. 5C.5 Calendar View empty state
  9. 5C.6 Payments Support Staff annotation
  10. 5C.7 Dashboard deprecated features note

Already resolved (no action needed)