add parent pages
This commit is contained in:
+186
-7
@@ -1,21 +1,33 @@
|
||||
import { apiFetch } from './http'
|
||||
import { apiUrl } from '../lib/apiOrigin'
|
||||
import { apiFetch, getStoredToken } from './http'
|
||||
import type {
|
||||
ApiEnvelope,
|
||||
DashboardPayload,
|
||||
LoginFailure,
|
||||
LoginResponse,
|
||||
LoginSuccess,
|
||||
NavBuilderDataResponse,
|
||||
NavBuilderDeleteResponse,
|
||||
NavBuilderSaveResponse,
|
||||
NavMenuResponse,
|
||||
ParentAttendanceResponse,
|
||||
ParentAttendanceReportFormResponse,
|
||||
ParentEnrollmentsResponse,
|
||||
ParentEventsResponse,
|
||||
ParentEventsOverviewResponse,
|
||||
ParentInvoicesResponse,
|
||||
ParentProfileResponse,
|
||||
ParentRegistrationResponse,
|
||||
ParentRegistrationOverviewResponse,
|
||||
ParentEmergencyContactsResponse,
|
||||
ParentAttendanceReportsListResponse,
|
||||
ParentAuthorizedUsersApiResponse,
|
||||
ParentMessagesResponse,
|
||||
SchoolCalendarEventsResponse,
|
||||
StudentScoresResponse,
|
||||
ReportCardAcknowledgementResponse,
|
||||
ReportCardMetaResponse,
|
||||
ClassProgressGroupsResponse,
|
||||
ClassProgressShowResponse,
|
||||
ParentProfileRecord,
|
||||
ContactSubmitResponse,
|
||||
} from './types'
|
||||
|
||||
@@ -49,6 +61,42 @@ export async function fetchNavMenu(): Promise<NavMenuResponse> {
|
||||
return apiFetch<NavMenuResponse>('/api/v1/nav-builder/menu')
|
||||
}
|
||||
|
||||
export async function fetchNavBuilderData(): Promise<NavBuilderDataResponse> {
|
||||
return apiFetch<NavBuilderDataResponse>('/api/v1/nav-builder/data')
|
||||
}
|
||||
|
||||
export async function saveNavBuilderItem(payload: {
|
||||
id?: number | null
|
||||
menu_parent_id?: number | null
|
||||
label: string
|
||||
url?: string | null
|
||||
icon_class?: string | null
|
||||
target?: string | null
|
||||
sort_order?: number
|
||||
is_enabled?: boolean
|
||||
roles?: number[]
|
||||
}): Promise<NavBuilderSaveResponse> {
|
||||
return apiFetch<NavBuilderSaveResponse>('/api/v1/nav-builder', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteNavBuilderItem(id: number): Promise<NavBuilderDeleteResponse> {
|
||||
return apiFetch<NavBuilderDeleteResponse>(`/api/v1/nav-builder/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
export async function reorderNavBuilderItems(orders: Record<string, number>): Promise<ApiEnvelope<{ ok: true }>> {
|
||||
return apiFetch<ApiEnvelope<{ ok: true }>>('/api/v1/nav-builder/reorder', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ orders }),
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchParentAttendance(
|
||||
schoolYear: string | null,
|
||||
): Promise<ParentAttendanceResponse> {
|
||||
@@ -74,12 +122,12 @@ export async function fetchParentInvoices(
|
||||
return apiFetch<ParentInvoicesResponse>(`/api/v1/parents/invoices${q}`)
|
||||
}
|
||||
|
||||
export async function fetchParentEventsOverview(): Promise<ParentEventsResponse> {
|
||||
return apiFetch<ParentEventsResponse>('/api/v1/parents/events')
|
||||
export async function fetchParentEventsOverview(): Promise<ParentEventsOverviewResponse> {
|
||||
return apiFetch<ParentEventsOverviewResponse>('/api/v1/parents/events')
|
||||
}
|
||||
|
||||
export async function fetchParentRegistrationOverview(): Promise<ParentRegistrationResponse> {
|
||||
return apiFetch<ParentRegistrationResponse>('/api/v1/parents/registration')
|
||||
export async function fetchParentRegistrationOverview(): Promise<ParentRegistrationOverviewResponse> {
|
||||
return apiFetch<ParentRegistrationOverviewResponse>('/api/v1/parents/registration')
|
||||
}
|
||||
|
||||
export async function fetchAttendanceReportForm(): Promise<ParentAttendanceReportFormResponse> {
|
||||
@@ -120,3 +168,134 @@ export async function fetchParentAttendanceReportsList(
|
||||
export async function fetchParentAuthorizedUsers(): Promise<ParentAuthorizedUsersApiResponse> {
|
||||
return apiFetch<ParentAuthorizedUsersApiResponse>('/api/v1/parents/authorized-users')
|
||||
}
|
||||
|
||||
export async function inviteParentAuthorizedUser(email: string): Promise<ContactSubmitResponse> {
|
||||
return apiFetch<ContactSubmitResponse>('/api/v1/parents/authorized-users', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email }),
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchParentMessagesInbox(): Promise<ParentMessagesResponse> {
|
||||
return apiFetch<ParentMessagesResponse>('/api/v1/messages/inbox')
|
||||
}
|
||||
|
||||
export async function fetchSchoolCalendarEvents(): Promise<SchoolCalendarEventsResponse> {
|
||||
return apiFetch<SchoolCalendarEventsResponse>(
|
||||
'/api/v1/settings/school-calendar/events?audience=parent',
|
||||
)
|
||||
}
|
||||
|
||||
export async function fetchStudentScores(studentId: number): Promise<StudentScoresResponse> {
|
||||
return apiFetch<StudentScoresResponse>(`/api/v1/students/${studentId}/scores`)
|
||||
}
|
||||
|
||||
export async function fetchReportCardMeta(): Promise<ReportCardMetaResponse> {
|
||||
return apiFetch<ReportCardMetaResponse>('/api/v1/reports/report-cards/meta')
|
||||
}
|
||||
|
||||
export async function fetchReportCardAcknowledgement(
|
||||
studentId: number,
|
||||
schoolYear?: string | null,
|
||||
semester?: string | null,
|
||||
): Promise<ReportCardAcknowledgementResponse> {
|
||||
const query = new URLSearchParams({ student_id: String(studentId) })
|
||||
if (schoolYear) query.set('school_year', schoolYear)
|
||||
if (semester) query.set('semester', semester)
|
||||
return apiFetch<ReportCardAcknowledgementResponse>(
|
||||
`/api/v1/reports/report-cards/acknowledgement?${query.toString()}`,
|
||||
)
|
||||
}
|
||||
|
||||
export async function fetchClassProgressGroups(): Promise<ClassProgressGroupsResponse> {
|
||||
return apiFetch<ClassProgressGroupsResponse>('/api/v1/class-progress?group_by_week=1')
|
||||
}
|
||||
|
||||
export async function fetchClassProgressDetail(id: number): Promise<ClassProgressShowResponse> {
|
||||
return apiFetch<ClassProgressShowResponse>(`/api/v1/class-progress/${id}`)
|
||||
}
|
||||
|
||||
export async function updateParentProfile(
|
||||
payload: Required<
|
||||
Pick<
|
||||
ParentProfileRecord,
|
||||
'firstname' | 'lastname' | 'cellphone' | 'address_street' | 'city' | 'state' | 'zip'
|
||||
>
|
||||
>,
|
||||
): Promise<ParentProfileResponse> {
|
||||
return apiFetch<ParentProfileResponse>('/api/v1/parents/profile', {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateParentStudent(
|
||||
studentId: number,
|
||||
payload: Record<string, unknown>,
|
||||
): Promise<{ ok: true }> {
|
||||
return apiFetch<{ ok: true }>(`/api/v1/parents/students/${studentId}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function storeParentRegistration(payload: {
|
||||
students?: Record<string, unknown>[]
|
||||
emergency_contacts?: Record<string, unknown>[]
|
||||
}): Promise<{ ok: true; created_student_ids?: number[] }> {
|
||||
return apiFetch<{ ok: true; created_student_ids?: number[] }>('/api/v1/parents/registration', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function storeParentEmergencyContact(payload: {
|
||||
name: string
|
||||
cellphone: string
|
||||
email?: string
|
||||
relation?: string
|
||||
}): Promise<ParentEmergencyContactsResponse> {
|
||||
return apiFetch<ParentEmergencyContactsResponse>('/api/v1/parents/emergency-contacts', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateParentEmergencyContact(
|
||||
contactId: number,
|
||||
payload: { name: string; cellphone: string; email?: string; relation?: string },
|
||||
): Promise<ParentEmergencyContactsResponse> {
|
||||
return apiFetch<ParentEmergencyContactsResponse>(`/api/v1/parents/emergency-contacts/${contactId}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function submitParentAttendanceReport(payload: Record<string, unknown>): Promise<{
|
||||
ok: true
|
||||
inserted?: number
|
||||
blocked?: number
|
||||
}> {
|
||||
return apiFetch('/api/v1/parents/attendance-reports', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchReportCardPdf(studentId: number): Promise<Blob> {
|
||||
const headers = new Headers({ Accept: 'application/pdf' })
|
||||
const token = getStoredToken()
|
||||
if (token) headers.set('Authorization', `Bearer ${token}`)
|
||||
const res = await fetch(apiUrl(`/api/v1/reports/report-cards/students/${studentId}`), {
|
||||
headers,
|
||||
})
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
||||
return res.blob()
|
||||
}
|
||||
|
||||
+213
-2
@@ -46,6 +46,47 @@ export type NavItem = {
|
||||
|
||||
export type NavMenuResponse = ApiEnvelope<{ items: NavItem[] }>
|
||||
|
||||
export type NavBuilderRoleOption = {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export type NavBuilderParentOption = {
|
||||
id: number
|
||||
label: string
|
||||
}
|
||||
|
||||
export type NavBuilderItem = {
|
||||
id: number
|
||||
label: string
|
||||
url?: string | null
|
||||
icon_class?: string | null
|
||||
target?: string | null
|
||||
menu_parent_id?: number | null
|
||||
parent_id?: number | null
|
||||
parent_label?: string | null
|
||||
sort_order?: number
|
||||
order?: number
|
||||
is_enabled?: number | boolean
|
||||
enabled?: boolean
|
||||
depth?: number
|
||||
roles?: {
|
||||
ids?: number[]
|
||||
names?: string[]
|
||||
}
|
||||
raw?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type NavBuilderData = {
|
||||
items: NavBuilderItem[]
|
||||
roles: NavBuilderRoleOption[]
|
||||
parentOptions: NavBuilderParentOption[]
|
||||
}
|
||||
|
||||
export type NavBuilderDataResponse = ApiEnvelope<{ data: NavBuilderData }>
|
||||
export type NavBuilderSaveResponse = ApiEnvelope<{ id: number }>
|
||||
export type NavBuilderDeleteResponse = ApiEnvelope<null>
|
||||
|
||||
export type ParentAttendanceRow = {
|
||||
firstname: string
|
||||
lastname: string
|
||||
@@ -96,7 +137,13 @@ export type ParentEnrollmentStudent = {
|
||||
id: number
|
||||
firstname: string
|
||||
lastname: string
|
||||
dob?: string | null
|
||||
gender?: string | null
|
||||
registration_grade?: string | null
|
||||
class_section?: string | null
|
||||
enrollment_status?: string | null
|
||||
admission_status?: string | null
|
||||
disable_enroll?: boolean
|
||||
}
|
||||
|
||||
export type ParentEnrollmentsResponse = {
|
||||
@@ -114,7 +161,15 @@ export type ContactSubmitResponse = {
|
||||
/** Loose JSON payloads for complex parent dashboards (events, registration, attendance report form). */
|
||||
export type ParentEventsResponse = Record<string, unknown>
|
||||
export type ParentRegistrationResponse = Record<string, unknown>
|
||||
export type ParentAttendanceReportFormResponse = Record<string, unknown>
|
||||
export type ParentAttendanceReportFormResponse = {
|
||||
ok: true
|
||||
students?: ParentEnrollmentStudent[]
|
||||
today?: string
|
||||
sundays?: string[]
|
||||
defaultDate?: string
|
||||
myReports?: Record<string, unknown>[]
|
||||
cutoffThreshold?: string | null
|
||||
}
|
||||
|
||||
export type ParentEmergencyContactRow = {
|
||||
id: number
|
||||
@@ -135,4 +190,160 @@ export type ParentAttendanceReportsListResponse = {
|
||||
}
|
||||
|
||||
/** `GET /api/v1/parents/authorized-users` — envelope from BaseApiController. */
|
||||
export type ParentAuthorizedUsersApiResponse = ApiEnvelope<unknown[]>
|
||||
export type ParentAuthorizedUserRow = {
|
||||
id?: number
|
||||
user_id?: number
|
||||
email?: string | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type ParentAuthorizedUsersApiResponse = ApiEnvelope<ParentAuthorizedUserRow[]>
|
||||
|
||||
export type ParentMessageRow = {
|
||||
id?: number | null
|
||||
message_number?: string | number | null
|
||||
sender_name?: string | null
|
||||
recipient_name?: string | null
|
||||
subject?: string | null
|
||||
message?: string | null
|
||||
sent_datetime?: string | null
|
||||
read_status?: boolean
|
||||
priority?: string | null
|
||||
}
|
||||
|
||||
export type ParentMessagesResponse = ApiEnvelope<{
|
||||
messages: ParentMessageRow[]
|
||||
meta?: Record<string, unknown> | null
|
||||
}>
|
||||
|
||||
export type SchoolCalendarEventRow = {
|
||||
id?: number | null
|
||||
title: string
|
||||
start: string
|
||||
description?: string
|
||||
extendedProps?: {
|
||||
event_type?: string
|
||||
backgroundColor?: string
|
||||
color?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type SchoolCalendarEventsResponse = ApiEnvelope<{
|
||||
events: SchoolCalendarEventRow[]
|
||||
}>
|
||||
|
||||
export type StudentScoreRow = {
|
||||
id?: number
|
||||
student_id?: number
|
||||
school_year?: string | null
|
||||
semester?: string | null
|
||||
class_section_id?: number | null
|
||||
homework_score?: number | string | null
|
||||
project_score?: number | string | null
|
||||
participation_score?: number | string | null
|
||||
quiz_score?: number | string | null
|
||||
attendance_score?: number | string | null
|
||||
ptap_score?: number | string | null
|
||||
midterm_exam_score?: number | string | null
|
||||
final_exam_score?: number | string | null
|
||||
semester_score?: number | string | null
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type StudentScoresResponse = {
|
||||
ok: true
|
||||
student_id: number
|
||||
rows: StudentScoreRow[]
|
||||
}
|
||||
|
||||
export type ReportCardStudentMetaRow = {
|
||||
id: number
|
||||
firstname: string
|
||||
lastname: string
|
||||
class_section_name: string
|
||||
}
|
||||
|
||||
export type ReportCardMetaResponse = ApiEnvelope<{
|
||||
schoolYears: string[]
|
||||
selectedYear: string | null
|
||||
semesters: string[]
|
||||
selectedSemester: string | null
|
||||
students: ReportCardStudentMetaRow[]
|
||||
}>
|
||||
|
||||
export type ReportCardAcknowledgementRow = {
|
||||
student_id: number
|
||||
school_year: string
|
||||
semester: string
|
||||
viewed_at?: string | null
|
||||
signed_at?: string | null
|
||||
signed_name?: string | null
|
||||
}
|
||||
|
||||
export type ReportCardAcknowledgementResponse = ApiEnvelope<ReportCardAcknowledgementRow>
|
||||
|
||||
export type ClassProgressReportRow = {
|
||||
id: number
|
||||
teacher_name?: string | null
|
||||
class_section_name?: string | null
|
||||
subject?: string | null
|
||||
unit_title?: string | null
|
||||
status?: string | null
|
||||
status_label?: string | null
|
||||
covered?: string | null
|
||||
homework?: string | null
|
||||
support_needed?: string | null
|
||||
week_start?: string | null
|
||||
week_end?: string | null
|
||||
attachments?: { id?: number; original_name?: string | null; url?: string | null }[]
|
||||
}
|
||||
|
||||
export type ClassProgressGroupRow = {
|
||||
week_start?: string | null
|
||||
week_end?: string | null
|
||||
class_section_id?: number | null
|
||||
class_section_name?: string | null
|
||||
reports?: Record<string, ClassProgressReportRow>
|
||||
}
|
||||
|
||||
export type ClassProgressGroupsResponse = ApiEnvelope<{
|
||||
items: ClassProgressGroupRow[]
|
||||
pagination?: Record<string, unknown>
|
||||
}>
|
||||
|
||||
export type ClassProgressShowResponse = ApiEnvelope<{
|
||||
report?: ClassProgressReportRow
|
||||
weekly_reports?: Record<string, ClassProgressReportRow>
|
||||
status_options?: Record<string, string>
|
||||
}>
|
||||
|
||||
export type ParentRegistrationOverviewResponse = {
|
||||
ok: true
|
||||
parent: ParentProfileRecord | null
|
||||
existingKids: ParentEnrollmentStudent[]
|
||||
emergencies: ParentEmergencyContactRow[]
|
||||
maxChilds?: number
|
||||
maxEmergency?: number
|
||||
lastDayOfRegistration?: string | null
|
||||
registrationAgeDeadline?: string | null
|
||||
}
|
||||
|
||||
export type ParentEventRow = {
|
||||
id?: number
|
||||
title?: string | null
|
||||
event_name?: string | null
|
||||
event_date?: string | null
|
||||
start_date?: string | null
|
||||
description?: string | null
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type ParentEventsOverviewResponse = {
|
||||
ok: true
|
||||
activeEvents?: ParentEventRow[]
|
||||
charges?: Record<string, unknown>[]
|
||||
yourStudents?: ParentEnrollmentStudent[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user