import { useEffect, useMemo, useState } from 'react' import { Link, useSearchParams } from 'react-router-dom' import { ApiHttpError } from '../../api/http' import { applyDiscountVoucher, fetchDiscountApplyContext } from '../../api/session' import type { DiscountApplyParentRow, DiscountVoucherRow } from '../../api/types' import { AcademicFilterBar } from './AcademicFilterBar' export function DiscountApplyVoucherPage() { const [searchParams] = useSearchParams() const schoolYear = searchParams.get('school_year') ?? undefined const semester = searchParams.get('semester') ?? undefined const [vouchers, setVouchers] = useState([]) const [voucherId, setVoucherId] = useState('') const [allowAdditional, setAllowAdditional] = useState(true) const [parents, setParents] = useState([]) const [selected, setSelected] = useState>({}) const [checkAll, setCheckAll] = useState(false) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [msg, setMsg] = useState(null) const [busy, setBusy] = useState(false) useEffect(() => { let cancelled = false setLoading(true) fetchDiscountApplyContext({ school_year: schoolYear, semester }) .then((d) => { if (cancelled) return setParents(d.parents ?? []) setVouchers(d.vouchers ?? []) }) .catch((e: unknown) => { if (!cancelled) setError(e instanceof ApiHttpError ? e.message : 'Could not load parents or vouchers.') }) .finally(() => { if (!cancelled) setLoading(false) }) return () => { cancelled = true } }, [schoolYear, semester]) const selectableParents = useMemo( () => parents.filter((p) => { if (!p.has_discount) return true return allowAdditional }), [parents, allowAdditional], ) function toggleParent(id: string, enabled: boolean) { if (!enabled) return setSelected((s) => ({ ...s, [id]: !s[id] })) } function onCheckAll(checked: boolean) { setCheckAll(checked) const next: Record = {} if (checked) { for (const p of selectableParents) { next[String(p.id)] = true } } setSelected(next) } useEffect(() => { setSelected({}) setCheckAll(false) }, [allowAdditional, parents]) async function onSubmit(e: React.FormEvent) { e.preventDefault() if (!voucherId) return const ids = Object.entries(selected) .filter(([, on]) => on) .map(([id]) => id) if (ids.length === 0) { setMsg('Select at least one parent.') return } setBusy(true) setMsg(null) try { await applyDiscountVoucher({ voucher_id: voucherId, parent_ids: ids, allow_additional: allowAdditional, school_year: schoolYear, semester, }) setMsg('Voucher applied.') } catch (err: unknown) { setMsg(err instanceof ApiHttpError ? err.message : 'Apply failed.') } finally { setBusy(false) } } return (

Apply Discount Voucher

{loading ?

Loading…

: null} {error ?
{error}
: null} {msg ? (
{msg}
) : null}
Cancel
setAllowAdditional(ev.target.checked)} />
{parents.map((parent) => { const id = String(parent.id) const hasDisc = Boolean(parent.has_discount) const enabled = !hasDisc || allowAdditional return ( ) })}
onCheckAll(ev.target.checked)} aria-label="Select all" /> Parent ID Parent Name Email Has Discount? Total Discount Amount
toggleParent(id, enabled)} /> {parent.school_id ?? 'N/A'} {[parent.firstname, parent.lastname].filter(Boolean).join(' ') || '—'} {parent.email ?? '—'} {hasDisc ? 'Yes' : 'No'} ${Number(parent.total_discount ?? 0).toFixed(2)}
) }