Spaces:
Running
Running
assafvayner HF Staff
fix(photos,forms): own-property content types, dimension bounds, VP8L signature, trimmed inputs
fa363c5 | import { isValidDate } from '../../domain/schemas'; | |
| import { centsToInput, parseAmountToCents } from '../../domain/money'; | |
| import type { Settlement, SettlementBody } from '../../domain/types'; | |
| import type { BuildResult, SettlementField, SettlementFormValues } from '../../forms/types'; | |
| import { str } from './form-utils'; | |
| export type { SettlementField, SettlementFormValues }; | |
| export function readSettlementForm(form: FormData): SettlementFormValues { | |
| return { from: str(form, 'from'), to: str(form, 'to'), amount: str(form, 'amount').trim(), date: str(form, 'date').trim(), note: str(form, 'note').trim() }; | |
| } | |
| export function settlementToFormValues(s: Settlement): SettlementFormValues { | |
| return { from: s.from, to: s.to, amount: centsToInput(s.amountCents), date: s.date, note: s.note ?? '' }; | |
| } | |
| /** Prefill from `/balances` "Settle up" links: ?from=&to=&amount=. */ | |
| export function settlementFormFromQuery(q: URLSearchParams, viewerId: string, today: string): SettlementFormValues { | |
| const clip = (v: string): string => v.trim().slice(0, 64); | |
| return { from: clip(q.get('from') ?? viewerId), to: clip(q.get('to') ?? ''), amount: clip(q.get('amount') ?? ''), date: today, note: '' }; | |
| } | |
| export function buildSettlementBody(v: SettlementFormValues, activeMemberIds: string[]): BuildResult<SettlementBody, SettlementField> { | |
| const errors: Partial<Record<SettlementField, string>> = {}; | |
| const active = new Set(activeMemberIds); | |
| if (!active.has(v.from)) errors.from = 'Choose who paid'; | |
| if (!active.has(v.to)) errors.to = 'Choose who received the money'; | |
| else if (v.to === v.from) errors.to = 'Payer and receiver must differ'; | |
| const amountCents = parseAmountToCents(v.amount); | |
| if (amountCents === null) errors.amount = 'Enter a positive amount with at most 2 decimals'; | |
| if (!isValidDate(v.date)) errors.date = 'Enter a valid date'; | |
| if (v.note.length > 2000) errors.form = 'Note is too long'; | |
| if (Object.keys(errors).length > 0 || amountCents === null) return { ok: false, errors }; | |
| const body: SettlementBody = { from: v.from, to: v.to, amountCents, date: v.date }; | |
| if (v.note.length > 0) body.note = v.note; | |
| return { ok: true, body }; | |
| } | |