fix financial and certificates

This commit is contained in:
root
2026-06-05 01:51:12 -04:00
parent 647b96cafc
commit c4d7a06a17
16 changed files with 1689 additions and 374 deletions
+144
View File
@@ -0,0 +1,144 @@
import { apiFetch } from './http'
type TrophyApiEnvelope<T> = {
ok?: boolean
data?: T
}
export type TrophyStudent = {
student_id?: number
class_section_id?: number
name?: string
firstname?: string | null
lastname?: string | null
school_id?: string | null
gender?: string | null
fall_score?: number | null
spring_score?: number | null
year_score?: number | null
projected_trophy?: boolean
predicted?: boolean
actual?: boolean
status?: string
}
export type TrophyProjectionClassResult = {
section_id: number
section_name: string
students: TrophyStudent[]
threshold: number | null
trophy_count: number
student_count: number
scored_count: number
method: string
boys: number
girls: number
trophy_boys: number
trophy_girls: number
pct_boys: number
pct_girls: number
pct_trophy_boys: number
pct_trophy_girls: number
pct_trophy_total: number
}
export type TrophyProjectionPayload = {
selected_year: string
selected_percentile: number
years: string[]
class_results: TrophyProjectionClassResult[]
summary: Record<string, number>
}
export type TrophyWinnersClassResult = {
section_id: number
section_name: string
threshold: number | null
winners: TrophyStudent[]
student_count: number
boys: number
girls: number
trophy_boys: number
trophy_girls: number
pct_boys: number
pct_girls: number
pct_trophy_boys: number
pct_trophy_girls: number
pct_trophy_total: number
}
export type TrophyWinnersPayload = {
selected_year: string
selected_percentile: number
years: string[]
class_results: TrophyWinnersClassResult[]
summary: Record<string, number>
}
export type TrophyFinalClassResult = {
section_id: number
section_name: string
students: TrophyStudent[]
student_count: number
fall_threshold: number | null
year_threshold: number | null
predicted_count: number
actual_count: number
confirmed: number
surprises: number
missed: number
accuracy: number
}
export type TrophyGenderSummary = {
total: number
boys: number
girls: number
other: number
pct_boys: number
pct_girls: number
pct_other: number
}
export type TrophyFinalPayload = {
selected_year: string
selected_percentile: number
years: string[]
class_results: TrophyFinalClassResult[]
summary: Record<string, number>
winner_gender_summary: TrophyGenderSummary
all_gender_summary: TrophyGenderSummary
pass_gender_summary: TrophyGenderSummary
winner_stickers: Array<{ name: string; section: string }>
}
type TrophyFilters = {
school_year?: string
percentile?: string | number
}
function withQuery(path: string, params?: TrophyFilters) {
const qs = new URLSearchParams()
if (params?.school_year) qs.set('school_year', String(params.school_year))
if (params?.percentile !== undefined && String(params.percentile).trim() !== '') {
qs.set('percentile', String(params.percentile))
}
return qs.size > 0 ? `${path}?${qs.toString()}` : path
}
async function fetchTrophyPayload<T>(path: string, params?: TrophyFilters): Promise<T> {
const res = await apiFetch<TrophyApiEnvelope<T>>(withQuery(path, params))
return (res.data ?? {}) as T
}
export function fetchTrophyProjection(params?: TrophyFilters) {
return fetchTrophyPayload<TrophyProjectionPayload>('/api/v1/administrator/trophy', params)
}
export function fetchTrophyWinners(params?: TrophyFilters) {
return fetchTrophyPayload<TrophyWinnersPayload>('/api/v1/administrator/trophy/winners', params)
}
export function fetchTrophyFinal(params?: TrophyFilters) {
return fetchTrophyPayload<TrophyFinalPayload>('/api/v1/administrator/trophy/final', params)
}