Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | /** * Unified Student Type * * Combines data from multiple sources into a single type for display * in the unified student list. Used by teachers and parents. */ import type { Player } from '@/db/schema/players' import type { StudentIntervention } from '@/utils/studentGrouping' /** * Activity status for a student */ export type StudentActivityStatus = 'idle' | 'practicing' | 'learning' /** * Enrollment status for a student relative to a classroom */ export type EnrollmentStatus = 'enrolled' | 'pending-teacher' | 'pending-parent' | null /** * Session progress when student is practicing */ export interface SessionProgress { /** Current problem index (0-based) */ current: number /** Total problems in session */ total: number } /** * Tutorial progress when student is learning */ export interface TutorialProgress { /** Skill being learned */ skill: string /** Current step index */ step: number /** Total steps */ total: number } /** * Relationship indicators for a student * * Determines what views a student appears in and what actions are available. */ export interface StudentRelationship { /** Parent-child link exists (viewer is parent of this student) */ isMyChild: boolean /** Student is enrolled in viewer's classroom (teachers only) */ isEnrolled: boolean /** Student is currently present in viewer's classroom (teachers only) */ isPresent: boolean /** Enrollment status if any pending enrollment */ enrollmentStatus: EnrollmentStatus } /** * Activity state for a student * * Indicates what the student is currently doing (practicing, learning, or idle). */ export interface StudentActivity { /** Current activity status */ status: StudentActivityStatus /** Session progress when practicing */ sessionProgress?: SessionProgress /** Tutorial progress when learning */ tutorialProgress?: TutorialProgress /** Session ID for observation (when practicing) */ sessionId?: string } /** * Unified student type combining all data sources * * This is the main type used by the unified student list component. * It extends Player with: * - Skill/progress data from curriculum system * - Relationship data (is child, enrolled, present) * - Activity data (practicing, learning) * * Note: Fields that already exist in Player (like isArchived) are not redeclared * to avoid type conflicts. */ export interface UnifiedStudent extends Player { // ============================================================================ // From StudentWithSkillData / StudentWithProgress // (Only fields NOT already in Player) // ============================================================================ /** Current curriculum level (1-3) */ currentLevel?: number /** Current phase ID within level */ currentPhaseId?: string /** Overall mastery percentage (0-100) */ masteryPercent?: number /** List of skill IDs being practiced */ practicingSkills?: string[] /** Most recent practice session timestamp */ lastPracticedAt?: Date | null /** Computed skill category (highest level) */ skillCategory?: string | null /** Intervention data if student needs attention */ intervention?: StudentIntervention | null // ============================================================================ // New: Relationship and Activity Data // ============================================================================ /** Relationship to the current viewer (parent/teacher) */ relationship: StudentRelationship /** Current activity (practicing, learning, idle) */ activity: StudentActivity } /** * Create default relationship for a student */ export function createDefaultRelationship(): StudentRelationship { return { isMyChild: false, isEnrolled: false, isPresent: false, enrollmentStatus: null, } } /** * Create default activity for a student */ export function createDefaultActivity(): StudentActivity { return { status: 'idle', } } /** * Convert a basic Player to UnifiedStudent with defaults */ export function toUnifiedStudent(player: Player): UnifiedStudent { return { ...player, relationship: createDefaultRelationship(), activity: createDefaultActivity(), } } // ============================================================================= // Stakeholder Types // ============================================================================= // Rich relationship data for showing complete stakeholder information. // These types are used by the stakeholders API and RelationshipCard component. /** * Information about a parent linked to a student */ export interface ParentInfo { /** Parent user ID */ id: string /** Parent's display name */ name: string /** Parent's email (optional) */ email?: string /** Whether this parent is the current viewer */ isMe: boolean } /** * Information about a classroom the student is enrolled in */ export interface EnrolledClassroomInfo { /** Classroom ID */ id: string /** Classroom name */ name: string /** Teacher's display name */ teacherName: string /** Whether the current viewer is the teacher of this classroom */ isMyClassroom: boolean } /** * Information about a pending enrollment request */ export interface PendingEnrollmentInfo { /** Enrollment request ID */ id: string /** Target classroom ID */ classroomId: string /** Target classroom name */ classroomName: string /** Teacher's display name */ teacherName: string /** Who needs to approve: 'teacher' or 'parent' */ pendingApproval: 'teacher' | 'parent' /** Who initiated the request */ initiatedBy: 'teacher' | 'parent' } /** * Information about current classroom presence */ export interface PresenceInfo { /** Classroom ID where student is present */ classroomId: string /** Classroom name */ classroomName: string /** Teacher's display name */ teacherName: string } /** * A family event for the activity feed */ export interface FamilyEventInfo { /** Event ID */ id: string /** Type of event */ eventType: 'parent_linked' | 'parent_unlinked' | 'code_regenerated' /** Name of user who performed the action */ actorName: string /** Name of the parent being linked/unlinked (null for code_regenerated) */ targetName: string | null /** When the event occurred (ISO string) */ createdAt: string } /** * Complete stakeholder information for a student */ export interface StudentStakeholders { /** All parents linked to this student */ parents: ParentInfo[] /** All classrooms the student is enrolled in */ enrolledClassrooms: EnrolledClassroomInfo[] /** All pending enrollment requests */ pendingEnrollments: PendingEnrollmentInfo[] /** Current classroom presence (if any) */ currentPresence: PresenceInfo | null /** Recent family events (last 7 days) */ recentFamilyEvents: FamilyEventInfo[] } /** * Type of relationship the viewer has with a student */ export type ViewerRelationType = 'parent' | 'teacher' | 'observer' | 'none' /** * Summary of the viewer's relationship with a student */ export interface ViewerRelationshipSummary { /** Primary relationship type */ type: ViewerRelationType /** Human-readable description (e.g., "Your child", "Enrolled in Math 101") */ description: string /** Classroom name if relevant (for teacher/observer) */ classroomName?: string } |