mirror of
https://github.com/opelly27/WinStudentGoalTracker.git
synced 2026-05-20 16:57:35 +00:00
Updates to encompass benchmarks
This commit is contained in:
@@ -4,6 +4,7 @@ import { ApiResult } from '../classes/api-result';
|
||||
import { StudentGoalSummary, StudentGoalItem } from '../classes/student-goal';
|
||||
import { CreateGoalDto } from '../classes/create-goal.dto';
|
||||
import { ProgressEventDto } from '../classes/progress-event.dto';
|
||||
import { StudentBenchmarkSummary, BenchmarkDto } from '../classes/benchmark.dto';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -18,41 +19,41 @@ export class DummyStudentService {
|
||||
'1': {
|
||||
studentIdentifier: 'J.B',
|
||||
goals: [
|
||||
{ goalId: 'g1', goalParentId: null, title: 'Improve reading comprehension', description: 'Work on main-idea identification and inference skills across fiction and nonfiction texts.', category: 'Academics', progressEventCount: 5 },
|
||||
{ goalId: 'g2', goalParentId: null, title: 'Complete algebra module', description: 'Finish all units in the algebra course including linear equations and graphing.', category: 'Academics', progressEventCount: 2 },
|
||||
{ goalId: 'g3', goalParentId: null, title: 'Weekly journal entries', description: 'Write a reflective journal entry each week to build writing fluency.', category: 'Communication', progressEventCount: 8 },
|
||||
{ goalId: 'g1', goalParentId: null, title: 'Improve reading comprehension', description: 'Work on main-idea identification and inference skills across fiction and nonfiction texts.', category: 'Academics', progressEventCount: 5, benchmarkCount: 2 },
|
||||
{ goalId: 'g2', goalParentId: null, title: 'Complete algebra module', description: 'Finish all units in the algebra course including linear equations and graphing.', category: 'Academics', progressEventCount: 2, benchmarkCount: 0 },
|
||||
{ goalId: 'g3', goalParentId: null, title: 'Weekly journal entries', description: 'Write a reflective journal entry each week to build writing fluency.', category: 'Communication', progressEventCount: 8, benchmarkCount: 1 },
|
||||
],
|
||||
},
|
||||
'2': {
|
||||
studentIdentifier: 'M.K',
|
||||
goals: [
|
||||
{ goalId: 'g4', goalParentId: null, title: 'Pass certification exam', description: 'Prepare for and pass the industry certification exam by end of quarter.', category: 'Career Readiness', progressEventCount: 3 },
|
||||
{ goalId: 'g5', goalParentId: null, title: 'Attendance above 90%', description: 'Maintain consistent attendance throughout the term.', category: 'Behavior', progressEventCount: 0 },
|
||||
{ goalId: 'g6', goalParentId: null, title: 'Complete internship hours', description: 'Log the required 40 hours at the assigned internship site.', category: 'Career Readiness', progressEventCount: 12 },
|
||||
{ goalId: 'g7', goalParentId: null, title: 'Portfolio project', description: 'Build a personal portfolio showcasing completed coursework and projects.', category: 'Career Readiness', progressEventCount: 1 },
|
||||
{ goalId: 'g4', goalParentId: null, title: 'Pass certification exam', description: 'Prepare for and pass the industry certification exam by end of quarter.', category: 'Career Readiness', progressEventCount: 3, benchmarkCount: 0 },
|
||||
{ goalId: 'g5', goalParentId: null, title: 'Attendance above 90%', description: 'Maintain consistent attendance throughout the term.', category: 'Behavior', progressEventCount: 0, benchmarkCount: 0 },
|
||||
{ goalId: 'g6', goalParentId: null, title: 'Complete internship hours', description: 'Log the required 40 hours at the assigned internship site.', category: 'Career Readiness', progressEventCount: 12, benchmarkCount: 0 },
|
||||
{ goalId: 'g7', goalParentId: null, title: 'Portfolio project', description: 'Build a personal portfolio showcasing completed coursework and projects.', category: 'Career Readiness', progressEventCount: 1, benchmarkCount: 0 },
|
||||
],
|
||||
},
|
||||
'3': {
|
||||
studentIdentifier: 'A.R',
|
||||
goals: [
|
||||
{ goalId: 'g8', goalParentId: null, title: 'GED preparation', description: 'Complete practice tests and study modules for GED math and reading sections.', category: 'Academics', progressEventCount: 6 },
|
||||
{ goalId: 'g9', goalParentId: null, title: 'Resume workshop', description: 'Attend the resume writing workshop and produce a final draft.', category: 'Career Readiness', progressEventCount: 0 },
|
||||
{ goalId: 'g8', goalParentId: null, title: 'GED preparation', description: 'Complete practice tests and study modules for GED math and reading sections.', category: 'Academics', progressEventCount: 6, benchmarkCount: 0 },
|
||||
{ goalId: 'g9', goalParentId: null, title: 'Resume workshop', description: 'Attend the resume writing workshop and produce a final draft.', category: 'Career Readiness', progressEventCount: 0, benchmarkCount: 0 },
|
||||
],
|
||||
},
|
||||
'4': {
|
||||
studentIdentifier: 'T.W',
|
||||
goals: [
|
||||
{ goalId: 'g10', goalParentId: null, title: 'Public speaking practice', description: 'Present in front of the class at least once per month.', category: 'Communication', progressEventCount: 4 },
|
||||
{ goalId: 'g11', goalParentId: null, title: 'Math placement improvement', description: 'Move up one placement level in math by the end of the semester.', category: 'Academics', progressEventCount: 7 },
|
||||
{ goalId: 'g12', goalParentId: null, title: 'Conflict resolution strategies', description: 'Learn and apply at least three de-escalation techniques.', category: 'Behavior', progressEventCount: 2 },
|
||||
{ goalId: 'g13', goalParentId: null, title: 'Daily attendance streak', description: 'Achieve a 30-day unbroken attendance streak.', category: 'Behavior', progressEventCount: 0 },
|
||||
{ goalId: 'g14', goalParentId: null, title: 'Job shadow experience', description: 'Complete a job shadow day in a field of interest.', category: 'Career Readiness', progressEventCount: 1 },
|
||||
{ goalId: 'g10', goalParentId: null, title: 'Public speaking practice', description: 'Present in front of the class at least once per month.', category: 'Communication', progressEventCount: 4, benchmarkCount: 0 },
|
||||
{ goalId: 'g11', goalParentId: null, title: 'Math placement improvement', description: 'Move up one placement level in math by the end of the semester.', category: 'Academics', progressEventCount: 7, benchmarkCount: 0 },
|
||||
{ goalId: 'g12', goalParentId: null, title: 'Conflict resolution strategies', description: 'Learn and apply at least three de-escalation techniques.', category: 'Behavior', progressEventCount: 2, benchmarkCount: 0 },
|
||||
{ goalId: 'g13', goalParentId: null, title: 'Daily attendance streak', description: 'Achieve a 30-day unbroken attendance streak.', category: 'Behavior', progressEventCount: 0, benchmarkCount: 0 },
|
||||
{ goalId: 'g14', goalParentId: null, title: 'Job shadow experience', description: 'Complete a job shadow day in a field of interest.', category: 'Career Readiness', progressEventCount: 1, benchmarkCount: 0 },
|
||||
],
|
||||
},
|
||||
'5': {
|
||||
studentIdentifier: 'L.C',
|
||||
goals: [
|
||||
{ goalId: 'g15', goalParentId: null, title: 'Improve typing speed', description: 'Reach 40 WPM with 95% accuracy on typing assessments.', category: 'Career Readiness', progressEventCount: 3 },
|
||||
{ goalId: 'g15', goalParentId: null, title: 'Improve typing speed', description: 'Reach 40 WPM with 95% accuracy on typing assessments.', category: 'Career Readiness', progressEventCount: 3, benchmarkCount: 0 },
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -119,6 +120,7 @@ export class DummyStudentService {
|
||||
description: data.description,
|
||||
category: data.category,
|
||||
progressEventCount: 0,
|
||||
benchmarkCount: 0,
|
||||
};
|
||||
|
||||
student.goals.push(newGoal);
|
||||
@@ -161,6 +163,28 @@ export class DummyStudentService {
|
||||
return ApiResult.ok(events);
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Returns hardcoded benchmarks for a given student.
|
||||
// TODO: Replace with actual API call
|
||||
// *****************************************************************
|
||||
async getBenchmarksForStudent(studentId: string): Promise<ApiResult<StudentBenchmarkSummary | null>> {
|
||||
const studentGoals = this.data[studentId];
|
||||
if (!studentGoals) {
|
||||
return ApiResult.fail('Student not found');
|
||||
}
|
||||
|
||||
const benchmarks: BenchmarkDto[] = [
|
||||
{ benchmarkId: 'bm1', goalId: 'g1', goalTitle: 'Improve reading comprehension', benchmark: 'Student will identify the main idea of a grade-level nonfiction passage with 80% accuracy.', createdByName: 'Jane Smith', createdAt: new Date('2026-02-15'), updatedAt: null },
|
||||
{ benchmarkId: 'bm2', goalId: 'g1', goalTitle: 'Improve reading comprehension', benchmark: 'Student will make at least two supported inferences per reading session.', createdByName: 'Jane Smith', createdAt: new Date('2026-02-16'), updatedAt: new Date('2026-02-20') },
|
||||
{ benchmarkId: 'bm3', goalId: 'g3', goalTitle: 'Weekly journal entries', benchmark: 'Student will complete a minimum of one paragraph (5 sentences) per journal entry.', createdByName: 'John Doe', createdAt: new Date('2026-02-18'), updatedAt: null },
|
||||
];
|
||||
|
||||
return ApiResult.ok({
|
||||
studentIdentifier: studentGoals.studentIdentifier,
|
||||
benchmarks: benchmarks
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ************************ Event Handlers *************************
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { inject, Injectable, signal } from '@angular/core';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { ApiResult } from '../classes/api-result';
|
||||
@@ -10,6 +10,7 @@ import { CreateGoalDto } from '../classes/create-goal.dto';
|
||||
import { StudentCardDto } from '../classes/student-card.dto';
|
||||
import { StudentGoalSummary, StudentGoalItem } from '../classes/student-goal';
|
||||
import { ProgressEventDto } from '../classes/progress-event.dto';
|
||||
import { StudentBenchmarkSummary } from '../classes/benchmark.dto';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -23,10 +24,20 @@ export class StudentService {
|
||||
private readonly http = inject(HttpClient);
|
||||
private readonly base = environment.apiBaseUrl;
|
||||
|
||||
// Incremented after any data mutation so subscribers can refresh.
|
||||
readonly dataVersion = signal(0);
|
||||
|
||||
// ************************** Properties ***************************
|
||||
|
||||
// ************************ Public Methods *************************
|
||||
|
||||
// *****************************************************************
|
||||
// Increments the data version signal so subscribers can refresh.
|
||||
// *****************************************************************
|
||||
notifyDataChanged() {
|
||||
this.dataVersion.update(v => v + 1);
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Returns student card summaries for the authenticated user.
|
||||
// *****************************************************************
|
||||
@@ -123,4 +134,100 @@ export class StudentService {
|
||||
// ************************ Event Handlers *************************
|
||||
|
||||
// ********************** Support Procedures ***********************
|
||||
|
||||
// *****************************************************************
|
||||
// Returns a single student by ID.
|
||||
// *****************************************************************
|
||||
async getStudentById(studentId: string): Promise<ApiResult<StudentCardDto>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.get<ResponseResult<StudentCardDto>>(`${this.base}/api/Student/${studentId}`)
|
||||
);
|
||||
return result.success && result.data
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Updates a student and returns the refreshed student data.
|
||||
// *****************************************************************
|
||||
async updateStudent(studentId: string, data: { identifier?: string; programYear?: number | null; enrollmentDate?: string | null; expectedGrad?: string | null }): Promise<ApiResult<StudentCardDto>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.put<ResponseResult<StudentCardDto>>(`${this.base}/api/Student/${studentId}`, data)
|
||||
);
|
||||
return result.success && result.data
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Returns benchmarks for a given student.
|
||||
// *****************************************************************
|
||||
async getBenchmarksForStudent(studentId: string): Promise<ApiResult<StudentBenchmarkSummary | null>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.get<ResponseResult<StudentBenchmarkSummary>>(`${this.base}/api/Student/${studentId}/benchmarks`)
|
||||
);
|
||||
return result.success && result.data
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Creates a new benchmark for a student.
|
||||
// *****************************************************************
|
||||
async createBenchmark(studentId: string, data: { goalId: string; benchmark: string }): Promise<ApiResult<any>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.post<ResponseResult<any>>(`${this.base}/api/Student/${studentId}/benchmarks`, data)
|
||||
);
|
||||
return result.success
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Updates a benchmark's text.
|
||||
// *****************************************************************
|
||||
async updateBenchmark(studentId: string, benchmarkId: string, benchmarkText: string): Promise<ApiResult<any>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.put<ResponseResult<any>>(`${this.base}/api/Student/${studentId}/benchmarks/${benchmarkId}`, { benchmark: benchmarkText })
|
||||
);
|
||||
return result.success
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Updates a goal's title, description, and category.
|
||||
// *****************************************************************
|
||||
async updateGoal(studentId: string, goalId: string, data: { title?: string; description?: string; category?: string }): Promise<ApiResult<any>> {
|
||||
try {
|
||||
const result = await firstValueFrom(
|
||||
this.http.put<ResponseResult<any>>(`${this.base}/api/Student/${studentId}/goals/${goalId}`, data)
|
||||
);
|
||||
return result.success
|
||||
? ApiResult.ok(result.data)
|
||||
: ApiResult.fail(result.message);
|
||||
} catch (error) {
|
||||
return ApiResult.fail(describeHttpError(error as HttpErrorResponse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user