128 lines
4.0 KiB
TypeScript
128 lines
4.0 KiB
TypeScript
import { apiUrl } from '../lib/apiOrigin'
|
|
|
|
export type FullRegisterPayload = {
|
|
firstname: string
|
|
lastname: string
|
|
gender: string
|
|
cellphone: string
|
|
email: string
|
|
confirm_email: string
|
|
address_street: string
|
|
apt?: string
|
|
city: string
|
|
state: string
|
|
zip: string
|
|
is_parent: boolean
|
|
no_second_parent_info: boolean
|
|
second_firstname?: string
|
|
second_lastname?: string
|
|
second_gender?: string
|
|
second_email?: string
|
|
second_cellphone?: string
|
|
accept_school_policy: boolean
|
|
captcha: string
|
|
}
|
|
|
|
export async function fetchRegisterCaptcha(): Promise<{ challenge: string }> {
|
|
const res = await fetch(apiUrl('/api/v1/auth/register/captcha'), {
|
|
method: 'GET',
|
|
headers: { Accept: 'application/json' },
|
|
})
|
|
const body: unknown = await res.json().catch(() => null)
|
|
if (!res.ok || !body || typeof body !== 'object') {
|
|
throw new Error('Could not load CAPTCHA.')
|
|
}
|
|
const o = body as { ok?: boolean; captcha?: string }
|
|
if (!o.ok || typeof o.captcha !== 'string') {
|
|
throw new Error('Invalid CAPTCHA response.')
|
|
}
|
|
return { challenge: o.captcha }
|
|
}
|
|
|
|
export type FullRegisterSuccess = {
|
|
ok: true
|
|
message?: string
|
|
registration?: unknown
|
|
}
|
|
|
|
export type FullRegisterFailure = {
|
|
ok: false
|
|
message: string
|
|
errors?: Record<string, string[]>
|
|
}
|
|
|
|
export async function submitFullRegistration(
|
|
payload: FullRegisterPayload,
|
|
): Promise<FullRegisterSuccess | FullRegisterFailure> {
|
|
const body: Record<string, unknown> = {
|
|
firstname: payload.firstname.trim(),
|
|
lastname: payload.lastname.trim(),
|
|
gender: payload.gender,
|
|
cellphone: payload.cellphone.trim(),
|
|
email: payload.email.trim(),
|
|
confirm_email: payload.confirm_email.trim(),
|
|
address_street: payload.address_street.trim(),
|
|
apt: payload.apt?.trim() || '',
|
|
city: payload.city.trim(),
|
|
state: payload.state,
|
|
zip: payload.zip.trim(),
|
|
is_parent: payload.is_parent,
|
|
no_second_parent_info: payload.no_second_parent_info,
|
|
accept_school_policy: payload.accept_school_policy,
|
|
captcha: payload.captcha.trim(),
|
|
}
|
|
|
|
if (payload.is_parent && !payload.no_second_parent_info) {
|
|
body.second_firstname = payload.second_firstname?.trim() ?? ''
|
|
body.second_lastname = payload.second_lastname?.trim() ?? ''
|
|
body.second_gender = payload.second_gender ?? ''
|
|
body.second_email = payload.second_email?.trim() ?? ''
|
|
body.second_cellphone = payload.second_cellphone?.trim() ?? ''
|
|
}
|
|
|
|
const res = await fetch(apiUrl('/api/v1/auth/register'), {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(body),
|
|
})
|
|
|
|
const data: unknown = await res.json().catch(() => null)
|
|
|
|
if (res.ok && data && typeof data === 'object' && 'ok' in data && (data as { ok?: boolean }).ok === true) {
|
|
return { ok: true, message: (data as { message?: string }).message, registration: (data as { registration?: unknown }).registration }
|
|
}
|
|
|
|
let message = 'Registration failed.'
|
|
let errors: Record<string, string[]> | undefined
|
|
if (data && typeof data === 'object') {
|
|
const o = data as { message?: string; errors?: Record<string, string[] | string> }
|
|
if (typeof o.message === 'string') message = o.message
|
|
if (o.errors && typeof o.errors === 'object') {
|
|
errors = {}
|
|
for (const [k, v] of Object.entries(o.errors)) {
|
|
if (Array.isArray(v)) errors[k] = v.map(String)
|
|
else errors[k] = [String(v)]
|
|
}
|
|
}
|
|
}
|
|
|
|
return { ok: false, message, errors }
|
|
}
|
|
|
|
export async function fetchSchoolPolicyHtml(): Promise<string> {
|
|
const res = await fetch(apiUrl('/api/v1/policies/school'), {
|
|
headers: { Accept: 'application/json' },
|
|
})
|
|
const json = (await res.json().catch(() => null)) as {
|
|
data?: { policy?: { content?: string } }
|
|
}
|
|
const html = json?.data?.policy?.content
|
|
if (!res.ok || !html) {
|
|
return '<p>Unable to load policy. Please contact the school.</p>'
|
|
}
|
|
return html
|
|
}
|