Switch payment method filter to a static list with an "other" bucket

Per feedback, drop the dynamic /mypayments/methods lookup (wasn't
loading reliably) in favor of a static cash/card/eft/voucher/other
dropdown. Server-side normalization now folds any gateway-reported
method outside those four manual-entry values (apple_pay, google_pay,
yoco, etc.) into "other" instead of "card", both in the returned data
and in the filter query.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 09:24:53 +02:00
co-authored by Claude Sonnet 5
parent 7f074e43a6
commit 325ab87729
7 changed files with 18 additions and 63 deletions
@@ -19,12 +19,13 @@ interface PaymentItem {
const formatRand = (n: number) => `R ${Math.abs(n).toFixed(2)}`;
// The API normalizes Payment.method to this set before it ever reaches the dashboard — any
// gateway-reported wallet type (apple_pay, google_pay, yoco, ...) is folded into "card".
// gateway-reported wallet type (apple_pay, google_pay, yoco, ...) is folded into "other".
const METHOD_LABELS: Record<string, string> = {
cash: "Cash",
card: "Card",
eft: "EFT",
voucher: "Voucher",
other: "Other",
};
const formatMethod = (method: string | null | undefined) => {
@@ -54,17 +55,6 @@ export default function UserPaymentsPage() {
const [method, setMethod] = useState("");
const [kind, setKind] = useState<"" | "payment" | "refund">("");
// Method is free-text (gateways can report values like apple_pay/google_pay beyond the
// manual-entry set), so the filter options come from what's actually in the user's payments
// rather than a hardcoded guess.
const [availableMethods, setAvailableMethods] = useState<string[]>([]);
useEffect(() => {
if (!token) return;
apiFetch<any>("/api/payments/mypayments/methods", { authToken: token })
.then(res => setAvailableMethods(Array.isArray(res?.methods) ? res.methods : []))
.catch(() => {});
}, [token]);
const buildQuery = useCallback((p: number) => {
const qs = new URLSearchParams({ page: String(p), limit: "25" });
if (startDate) qs.set("startDate", startDate);
@@ -131,9 +121,11 @@ export default function UserPaymentsPage() {
<label className="block text-xs text-gray-600 mb-1">Method</label>
<select className="border rounded px-2 py-1.5 text-sm" value={method} onChange={e => setMethod(e.target.value)}>
<option value="">All methods</option>
{availableMethods.map(m => (
<option key={m} value={m}>{formatMethod(m)}</option>
))}
<option value="cash">Cash</option>
<option value="card">Card</option>
<option value="eft">EFT</option>
<option value="voucher">Voucher</option>
<option value="other">Other</option>
</select>
</div>
<div>