add certificate

This commit is contained in:
root
2026-05-18 00:07:40 -04:00
parent dc7acf2536
commit 0d3cdd3857
13 changed files with 869 additions and 44 deletions
+65
View File
@@ -0,0 +1,65 @@
import { apiUrl } from '../lib/apiOrigin'
import { ApiHttpError, apiFetch, getStoredToken } from './http'
import type { ApiEnvelope } from './types'
export type CertClassSection = {
class_section_id: number
class_section_name: string
}
export type CertStudent = {
id: number
firstname: string
lastname: string
grade: string
}
export type CertFormOptions = {
class_sections: CertClassSection[]
students: CertStudent[]
school_year: string
selected_class_id: string | null
}
export async function fetchCertFormOptions(params?: {
school_year?: string
class_section_id?: string | number
}): Promise<ApiEnvelope<CertFormOptions>> {
const qs = new URLSearchParams()
if (params?.school_year) qs.set('school_year', params.school_year)
if (params?.class_section_id != null && String(params.class_section_id) !== '')
qs.set('class_section_id', String(params.class_section_id))
const suffix = qs.toString() ? `?${qs}` : ''
return apiFetch<ApiEnvelope<CertFormOptions>>(`/api/v1/administrator/certificates/form-options${suffix}`)
}
export async function postCertificateGenerate(payload: {
student_ids: number[]
cert_date: string
class_section_id?: number | string | null
}): Promise<Blob> {
const headers = new Headers({
Accept: 'application/pdf,*/*',
'Content-Type': 'application/json',
})
const token = getStoredToken()
if (token) headers.set('Authorization', `Bearer ${token}`)
const res = await fetch(apiUrl('/api/v1/administrator/certificates/generate'), {
method: 'POST',
headers,
body: JSON.stringify(payload),
})
if (!res.ok) {
const errBody: unknown = await res.json().catch(() => null)
const msg =
typeof errBody === 'object' && errBody !== null && 'message' in errBody
? String((errBody as { message?: unknown }).message ?? '')
: ''
throw new ApiHttpError(msg || `HTTP ${res.status}`, res.status, errBody)
}
const raw = await res.blob()
return new Blob([await raw.arrayBuffer()], { type: 'application/pdf' })
}
+1 -1
View File
@@ -43,7 +43,7 @@ export async function apiFetch<T>(
res = await fetch(url, { ...init, headers })
} catch (e) {
const hint = import.meta.env.DEV
? ' Start the API and ensure Vite can reach it (see vite.config.ts; default proxy is http://192.168.3.100:8000).'
? ' Start the API and ensure Vite can reach it (see vite.config.ts; default proxy is http://localhost:8080 unless VITE_PROXY_API is set).'
: ''
const reason = e instanceof Error ? e.message : 'Failed to fetch'
throw new ApiHttpError(`Network error: ${reason}.${hint}`, 0, null)