From 6b5a80b597392121231cc073bd7927e91d4d1c05 Mon Sep 17 00:00:00 2001 From: Stephanos A Date: Thu, 16 Jul 2026 15:18:01 +0300 Subject: [PATCH] Supplementary payments client pages --- .../payments/SupplementaryChargesModal.tsx | 294 +++--------------- .../backoffice/src/app/payments/page.tsx | 144 ++++++++- .../app/pay-balance/[token]/failed/page.tsx | 24 ++ .../src/app/pay-balance/[token]/page.tsx | 191 ++++++++++++ .../app/pay-balance/[token]/success/page.tsx | 21 ++ 5 files changed, 420 insertions(+), 254 deletions(-) create mode 100644 apps/edr-passenger-web/portal/src/app/pay-balance/[token]/failed/page.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/pay-balance/[token]/page.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/pay-balance/[token]/success/page.tsx diff --git a/apps/edr-passenger-web/backoffice/src/app/payments/SupplementaryChargesModal.tsx b/apps/edr-passenger-web/backoffice/src/app/payments/SupplementaryChargesModal.tsx index 9fb0de6bb..45941cea4 100644 --- a/apps/edr-passenger-web/backoffice/src/app/payments/SupplementaryChargesModal.tsx +++ b/apps/edr-passenger-web/backoffice/src/app/payments/SupplementaryChargesModal.tsx @@ -1,66 +1,30 @@ 'use client'; import { useState } from 'react'; -import { Send, CheckCircle, XCircle, RotateCcw, PlusCircle } from 'lucide-react'; +import { PlusCircle } from 'lucide-react'; import Modal from '@/components/ui/Modal'; import ActionButton from '@/components/ui/ActionButton'; -import Badge from '@/components/ui/Badge'; -import { formatCurrency, formatDateTime } from '@/lib/utils'; -import { - useSupplementaryCharges, - useCreateSupplementaryCharge, - useMarkSupplementaryPaid, - useWaiveSupplementaryCharge, - useResendSupplementaryLink, -} from './useSupplementaryCharges'; +import { useCreateSupplementaryCharge } from './useSupplementaryCharges'; -type Tab = 'create' | 'list'; +const REASONS = ['UNDERPAYMENT', 'FARE_CORRECTION', 'CURRENCY_ADJUSTMENT', 'OTHER']; interface Props { isOpen: boolean; onClose: () => void; } -const REASONS = ['UNDERPAYMENT', 'FARE_CORRECTION', 'CURRENCY_ADJUSTMENT', 'OTHER']; - -const STATUS_COLORS: Record = { - PENDING: 'warning', - PAID: 'success', - WAIVED: 'info', - EXPIRED: 'error', -}; - export default function SupplementaryChargesModal({ isOpen, onClose }: Props) { - const [tab, setTab] = useState('create'); - const [listFilters, setListFilters] = useState({ bookingRef: '', status: '' }); - - // Create form state const [form, setForm] = useState({ bookingRef: '', amountEtb: '', reason: 'UNDERPAYMENT', notes: '' }); const [formError, setFormError] = useState(null); const [createSuccess, setCreateSuccess] = useState(null); - const { data: chargesData, isLoading } = useSupplementaryCharges(listFilters); - const charges: any[] = (chargesData as any)?.items ?? (Array.isArray(chargesData) ? chargesData : []); - const createMutation = useCreateSupplementaryCharge(() => { - setCreateSuccess(`Charge created and payment link sent.`); + setCreateSuccess('Charge created and payment link sent.'); setForm({ bookingRef: '', amountEtb: '', reason: 'UNDERPAYMENT', notes: '' }); setFormError(null); - setTimeout(() => { setCreateSuccess(null); setTab('list'); }, 2000); + setTimeout(() => { setCreateSuccess(null); onClose(); }, 2000); }); - const markPaidMutation = useMarkSupplementaryPaid(); - const waiveMutation = useWaiveSupplementaryCharge(); - const resendMutation = useResendSupplementaryLink(); - - const [actionError, setActionError] = useState(null); - const [actionSuccess, setActionSuccess] = useState(null); - - const flash = (msg: string) => { - setActionSuccess(msg); - setTimeout(() => setActionSuccess(null), 3000); - }; - const handleCreate = async () => { setFormError(null); const amountMinor = Math.round(parseFloat(form.amountEtb) * 100); @@ -73,218 +37,46 @@ export default function SupplementaryChargesModal({ isOpen, onClose }: Props) { } }; - const handleMarkPaid = async (id: string) => { - setActionError(null); - try { - await markPaidMutation.mutateAsync({ id }); - flash('Marked as paid'); - } catch (e: any) { - setActionError(e?.response?.data?.message ?? e?.message ?? 'Failed'); - } - }; - - const handleWaive = async (id: string) => { - setActionError(null); - try { - await waiveMutation.mutateAsync({ id }); - flash('Charge waived'); - } catch (e: any) { - setActionError(e?.response?.data?.message ?? e?.message ?? 'Failed'); - } - }; - - const handleResend = async (id: string) => { - setActionError(null); - try { - await resendMutation.mutateAsync(id); - flash('Payment link resent'); - } catch (e: any) { - setActionError(e?.response?.data?.message ?? e?.message ?? 'Failed'); - } - }; - return ( - - {/* Tabs */} -
- {(['create', 'list'] as Tab[]).map((t) => ( - - ))} + +
+ {createSuccess && ( +
✓ {createSuccess}
+ )} + {formError && ( +
{formError}
+ )} + +
+
+ + setForm({ ...form, bookingRef: e.target.value })} /> +
+
+ + setForm({ ...form, amountEtb: e.target.value })} /> +
+
+ + +
+
+ +