Files
full_encoach_platform/frontend/src/services/institutional-exam.service.ts
Yamen Ahmad f1c4953a63 feat(v3): restructure project + add complete frontend
- Restructure: move backend from new_project/ to backend/
- Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks)
- Add docs/ with SRS specs, user stories, and workflow documentation
- Update .gitignore for new directory layout

Workflows implemented:
  WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration,
  WF4 General English Exam, WF5 Course Generation,
  WF6 Entity Student Onboarding, AI Course Generation,
  Adaptive Learning Engine UI, White-Label Branding, Score Release

Made-with: Cursor
2026-04-10 17:26:42 +04:00

168 lines
7.7 KiB
TypeScript

import { api } from "@/lib/api-client";
import type {
InstExamSession, InstExam, ExamType, GradeConfig,
ResultTemplate, Marksheet, CourseAssignment, AssignmentSubmission,
AssignmentType, SubjectRegistration,
InstExamSessionCreateRequest, InstExamCreateRequest,
ExamTypeCreateRequest, GradeConfigCreateRequest,
ResultTemplateCreateRequest, CourseAssignmentCreateRequest,
AssignmentTypeCreateRequest, SubjectRegistrationCreateRequest,
} from "@/types/institutional-exam";
import type { PaginatedResponse, PaginationParams, ApiSuccessResponse } from "@/types";
export const institutionalExamService = {
async listSessions(params?: PaginationParams): Promise<PaginatedResponse<InstExamSession>> {
return api.get<PaginatedResponse<InstExamSession>>("/inst-exam-sessions", params as Record<string, string | number | boolean | undefined>);
},
async getSession(id: number): Promise<InstExamSession> {
return api.get<InstExamSession>(`/inst-exam-sessions/${id}`);
},
async createSession(data: InstExamSessionCreateRequest): Promise<InstExamSession> {
return api.post<InstExamSession>("/inst-exam-sessions", data);
},
async updateSession(id: number, data: Partial<InstExamSessionCreateRequest>): Promise<InstExamSession> {
return api.patch<InstExamSession>(`/inst-exam-sessions/${id}`, data);
},
async deleteSession(id: number): Promise<ApiSuccessResponse> {
return api.delete<ApiSuccessResponse>(`/inst-exam-sessions/${id}`);
},
async scheduleSession(id: number): Promise<InstExamSession> {
return api.post<InstExamSession>(`/inst-exam-sessions/${id}/schedule`);
},
async markSessionDone(id: number): Promise<InstExamSession> {
return api.post<InstExamSession>(`/inst-exam-sessions/${id}/done`);
},
async createExam(data: InstExamCreateRequest): Promise<InstExam> {
return api.post<InstExam>("/inst-exams", data);
},
async updateExam(id: number, data: Partial<InstExamCreateRequest>): Promise<InstExam> {
return api.patch<InstExam>(`/inst-exams/${id}`, data);
},
async addAttendees(examId: number, data: { student_ids: number[] }): Promise<ApiSuccessResponse> {
return api.post<ApiSuccessResponse>(`/inst-exams/${examId}/attendees`, data);
},
async enterMarks(examId: number, data: { marks: { student_id: number; score: number }[] }): Promise<ApiSuccessResponse> {
return api.patch<ApiSuccessResponse>(`/inst-exams/${examId}/marks`, data);
},
async listExamTypes(params?: PaginationParams): Promise<PaginatedResponse<ExamType>> {
return api.get<PaginatedResponse<ExamType>>("/exam-types", params as Record<string, string | number | boolean | undefined>);
},
async createExamType(data: ExamTypeCreateRequest): Promise<ExamType> {
return api.post<ExamType>("/exam-types", data);
},
async listGradeConfigs(params?: PaginationParams): Promise<PaginatedResponse<GradeConfig>> {
return api.get<PaginatedResponse<GradeConfig>>("/grade-config", params as Record<string, string | number | boolean | undefined>);
},
async createGradeConfig(data: GradeConfigCreateRequest): Promise<GradeConfig> {
return api.post<GradeConfig>("/grade-config", data);
},
async listResultTemplates(params?: PaginationParams): Promise<PaginatedResponse<ResultTemplate>> {
return api.get<PaginatedResponse<ResultTemplate>>("/result-templates", params as Record<string, string | number | boolean | undefined>);
},
async createResultTemplate(data: ResultTemplateCreateRequest): Promise<ResultTemplate> {
return api.post<ResultTemplate>("/result-templates", data);
},
async generateMarksheets(templateId: number): Promise<ApiSuccessResponse> {
return api.post<ApiSuccessResponse>(`/result-templates/${templateId}/generate`);
},
async listMarksheets(params?: PaginationParams): Promise<PaginatedResponse<Marksheet>> {
return api.get<PaginatedResponse<Marksheet>>("/marksheets", params as Record<string, string | number | boolean | undefined>);
},
async getMarksheet(id: number): Promise<Marksheet> {
return api.get<Marksheet>(`/marksheets/${id}`);
},
async validateMarksheet(id: number): Promise<Marksheet> {
return api.post<Marksheet>(`/marksheets/${id}/validate`);
},
async listCourseAssignments(params?: PaginationParams & { course_id?: number; batch_id?: number; state?: string }): Promise<PaginatedResponse<CourseAssignment>> {
return api.get<PaginatedResponse<CourseAssignment>>("/course-assignments", params as Record<string, string | number | boolean | undefined>);
},
async createCourseAssignment(data: CourseAssignmentCreateRequest): Promise<CourseAssignment> {
return api.post<CourseAssignment>("/course-assignments", data);
},
async getCourseAssignment(id: number): Promise<CourseAssignment> {
return api.get<CourseAssignment>(`/course-assignments/${id}`);
},
async updateCourseAssignment(id: number, data: Partial<CourseAssignmentCreateRequest>): Promise<CourseAssignment> {
return api.patch<CourseAssignment>(`/course-assignments/${id}`, data);
},
async publishCourseAssignment(id: number): Promise<CourseAssignment> {
return api.post<CourseAssignment>(`/course-assignments/${id}/publish`);
},
async finishCourseAssignment(id: number): Promise<CourseAssignment> {
return api.post<CourseAssignment>(`/course-assignments/${id}/finish`);
},
async listSubmissions(assignmentId: number, params?: PaginationParams): Promise<PaginatedResponse<AssignmentSubmission>> {
return api.get<PaginatedResponse<AssignmentSubmission>>(`/course-assignments/${assignmentId}/submissions`, params as Record<string, string | number | boolean | undefined>);
},
async submitAssignment(assignmentId: number, file: File): Promise<AssignmentSubmission> {
const formData = new FormData();
formData.append("file", file);
return api.upload<AssignmentSubmission>(`/course-assignments/${assignmentId}/submit`, formData);
},
async gradeSubmission(submissionId: number, data: Partial<AssignmentSubmission>): Promise<AssignmentSubmission> {
return api.patch<AssignmentSubmission>(`/submissions/${submissionId}`, data);
},
async listAssignmentTypes(params?: PaginationParams): Promise<PaginatedResponse<AssignmentType>> {
return api.get<PaginatedResponse<AssignmentType>>("/assignment-types", params as Record<string, string | number | boolean | undefined>);
},
async createAssignmentType(data: AssignmentTypeCreateRequest): Promise<AssignmentType> {
return api.post<AssignmentType>("/assignment-types", data);
},
async listSubjectRegistrations(params?: PaginationParams & { student_id?: number; course_id?: number; state?: string }): Promise<PaginatedResponse<SubjectRegistration>> {
return api.get<PaginatedResponse<SubjectRegistration>>("/subject-registrations", params as Record<string, string | number | boolean | undefined>);
},
async createSubjectRegistration(data: SubjectRegistrationCreateRequest): Promise<SubjectRegistration> {
return api.post<SubjectRegistration>("/subject-registrations", data);
},
async updateSubjectRegistration(id: number, data: Partial<SubjectRegistrationCreateRequest>): Promise<SubjectRegistration> {
return api.patch<SubjectRegistration>(`/subject-registrations/${id}`, data);
},
async confirmSubjectRegistration(id: number): Promise<SubjectRegistration> {
return api.post<SubjectRegistration>(`/subject-registrations/${id}/confirm`);
},
async rejectSubjectRegistration(id: number): Promise<SubjectRegistration> {
return api.post<SubjectRegistration>(`/subject-registrations/${id}/reject`);
},
async getAvailableSubjects(params?: { student_id?: number; course_id?: number }): Promise<SubjectRegistration[]> {
return api.get<SubjectRegistration[]>("/subject-registrations/available", params as Record<string, string | number | boolean | undefined>);
},
};