Initial commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { FrappeError, METHODS, frappeCall, registrationEnabled } from '@/lib/lukenya-api'
|
||||
|
||||
// The browser posts the form here; this route forwards it to Frappe. The backend
|
||||
// re-validates everything and decides the price, so nothing here is trusted for money.
|
||||
|
||||
const ALLOWED = [
|
||||
'event_edition', 'race_category', 'residency', 'first_name', 'last_name', 'id_number',
|
||||
'date_of_birth', 'gender', 'nationality', 'email', 'phone', 'whatsapp', 'shirt_size',
|
||||
'emergency_contact_name', 'emergency_contact_phone', 'guardian_name', 'guardian_phone',
|
||||
'indemnity_accepted', 'communication_consent', 'preferred_payment', 'emergency_contact_relationship',
|
||||
'support_request', 'consents',
|
||||
] as const
|
||||
|
||||
const REQUIRED = [
|
||||
'race_category', 'first_name', 'last_name', 'email', 'phone',
|
||||
'emergency_contact_name', 'emergency_contact_phone',
|
||||
] as const
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (!registrationEnabled()) {
|
||||
return NextResponse.json({ error: 'Online registration is not open yet.' }, { status: 403 })
|
||||
}
|
||||
|
||||
let body: Record<string, unknown>
|
||||
try {
|
||||
body = await req.json()
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'The form data could not be read.' }, { status: 400 })
|
||||
}
|
||||
|
||||
const payload: Record<string, unknown> = {}
|
||||
for (const key of ALLOWED) {
|
||||
const value = body[key]
|
||||
if (value === undefined || value === null) continue
|
||||
payload[key] = typeof value === 'string' ? value.trim().slice(0, key === 'support_request' ? 1000 : 500) : value
|
||||
}
|
||||
payload.event_edition = payload.event_edition || process.env.FRAPPE_EDITION
|
||||
|
||||
const missing = REQUIRED.filter((k) => !payload[k])
|
||||
if (!payload.event_edition) missing.unshift('race edition' as never)
|
||||
if (payload.indemnity_accepted !== true) missing.push('indemnity acceptance' as never)
|
||||
if (missing.length) {
|
||||
return NextResponse.json({ error: `Please complete: ${missing.join(', ').replace(/_/g, ' ')}.` }, { status: 400 })
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await frappeCall<{
|
||||
registration: string
|
||||
amount_due: number
|
||||
currency: string
|
||||
payment_token?: string
|
||||
}>(METHODS.createRegistration, { args: { payload }, post: true })
|
||||
return NextResponse.json({
|
||||
registration: result.registration,
|
||||
amount_due: result.amount_due,
|
||||
currency: result.currency,
|
||||
payment_token: result.payment_token,
|
||||
})
|
||||
} catch (err) {
|
||||
const status = err instanceof FrappeError && err.status < 500 ? 400 : 502
|
||||
return NextResponse.json({ error: (err as Error).message }, { status })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user