Skip to content

Commit 274da0f

Browse files
authored
Merge pull request #405 from Marvy247/main
2 parents 4f4e279 + 1f4e023 commit 274da0f

4 files changed

Lines changed: 78 additions & 16 deletions

File tree

app/(merchant)/settlement/page.tsx

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ import { getStellarExplorerTxUrl } from '@/lib/utils/explorer';
2121
import { EmptyState } from '@/components/shared';
2222
import { ErrorDisplay } from '@/components/shared';
2323
import { useOfflineStore } from '@/lib/store/offlineStore';
24+
import { useAuthStore } from '@/lib/store/authStore';
2425
import { SettlementConfirmation } from '@/components/settlement/SettlementConfirmation';
2526
import { InvoiceDownloadButton, BatchInvoiceDownload } from '@/components/settlement/InvoiceGenerator';
2627
import { StatCard } from '@/components/shared';
2728
import { memo } from 'react';
28-
import { useSettlements, type ApiSettlement } from '@/lib/api/hooks';
29+
import { useSettlements, useMerchantBankAccount, type ApiSettlement } from '@/lib/api/hooks';
2930

3031
type Settlement = ApiSettlement;
3132

@@ -70,6 +71,8 @@ const SettlementItem = memo(function SettlementItem({ settlement: s }: Settlemen
7071
export default function SettlementPage() {
7172
const { data: settlements, isLoading, error: fetchError, refetch } = useSettlements();
7273
const [settlementsError, setSettlementsError] = useState(false);
74+
const { user } = useAuthStore();
75+
const { data: bankAccount, isLoading: bankLoading } = useMerchantBankAccount(user?.id);
7376
const isOnline = useOfflineStore((s) => s.isOnline);
7477
const [settlementOpen, setSettlementOpen] = useState(false);
7578

@@ -184,20 +187,35 @@ export default function SettlementPage() {
184187
</Card>
185188

186189
{/* Bank account config notice */}
187-
<Card className="border border-primary/30 bg-primary/10">
188-
<CardContent className="flex items-start gap-4 p-5">
189-
<AlertCircle className="w-5 h-5 text-primary mt-0.5 flex-shrink-0" />
190-
<div className="flex-1">
191-
<p className="text-sm font-semibold text-primary">Bank account not configured</p>
192-
<p className="text-xs text-primary mt-0.5">
193-
Add your Nigerian bank account in Settings to enable automatic settlements.
194-
</p>
195-
</div>
196-
<Button variant="ghost" className="text-primary hover:bg-primary/20 rounded-xl text-xs h-8 px-3 flex-shrink-0">
197-
Go to Settings <ChevronRight className="w-3 h-3 ml-1" />
198-
</Button>
199-
</CardContent>
200-
</Card>
190+
{!bankLoading && !bankAccount && (
191+
<Card className="border border-primary/30 bg-primary/10">
192+
<CardContent className="flex items-start gap-4 p-5">
193+
<AlertCircle className="w-5 h-5 text-primary mt-0.5 flex-shrink-0" />
194+
<div className="flex-1">
195+
<p className="text-sm font-semibold text-primary">Bank account not configured</p>
196+
<p className="text-xs text-primary mt-0.5">
197+
Add your Nigerian bank account in Settings to enable automatic settlements.
198+
</p>
199+
</div>
200+
<Button variant="ghost" className="text-primary hover:bg-primary/20 rounded-xl text-xs h-8 px-3 flex-shrink-0">
201+
Go to Settings <ChevronRight className="w-3 h-3 ml-1" />
202+
</Button>
203+
</CardContent>
204+
</Card>
205+
)}
206+
{!bankLoading && bankAccount && (
207+
<Card className="border border-success/30 bg-success/5">
208+
<CardContent className="flex items-start gap-4 p-5">
209+
<CheckCircle2 className="w-5 h-5 text-success mt-0.5 flex-shrink-0" />
210+
<div className="flex-1">
211+
<p className="text-sm font-semibold text-success">Bank account configured</p>
212+
<p className="text-xs text-muted-foreground mt-0.5">
213+
{bankAccount.bankName} · {'\u2022'.repeat(Math.max(0, bankAccount.accountNumber.length - 4))}{bankAccount.accountNumber.slice(-4)}
214+
</p>
215+
</div>
216+
</CardContent>
217+
</Card>
218+
)}
201219
</div>
202220
);
203221
}

components/shared/StatusBadge.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export const StatusBadge = ({ status, className }: StatusBadgeProps) => {
1717
icon: CheckCircle2,
1818
className: 'bg-success/10 text-success hover:bg-success/20 border-success/20',
1919
},
20+
completed: {
21+
label: 'Completed',
22+
icon: CheckCircle2,
23+
className: 'bg-success/10 text-success hover:bg-success/20 border-success/20',
24+
},
2025
[PAYMENT_STATUS.PENDING]: {
2126
label: 'Pending',
2227
icon: Clock,

lib/api/hooks.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
44
import { apiClient } from './axios';
5-
import type { MerchantProfile } from '../types';
5+
import type { MerchantProfile, MerchantBankAccount } from '../types';
66
import { getErrorMessage } from '../utils/apiError';
77

88
// ─── Types ────────────────────────────────────────────────────────────────────
@@ -207,6 +207,38 @@ export function useRates(): UseRatesResult {
207207
};
208208
}
209209

210+
// ─── useMerchantBankAccount ────────────────────────────────────────────────────
211+
212+
export function useMerchantBankAccount(
213+
merchantId: string | undefined,
214+
): HookShape<MerchantBankAccount | null> {
215+
const query = useQuery<MerchantBankAccount | null, Error>({
216+
queryKey: [...queryKeys.merchant(merchantId), 'bank-account'],
217+
enabled: Boolean(merchantId),
218+
queryFn: async () => {
219+
const res = await apiClient.get<
220+
ItemEnvelope<MerchantBankAccount> | MerchantBankAccount
221+
>(`/api/merchants/${merchantId}/bank-account`);
222+
const payload = res.data;
223+
if (payload && !Array.isArray(payload) && 'bankName' in payload) {
224+
return payload as MerchantBankAccount;
225+
}
226+
return (payload as ItemEnvelope<MerchantBankAccount> | undefined)?.data ?? null;
227+
},
228+
});
229+
230+
const isLoading = query.isLoading;
231+
232+
return {
233+
data: query.data ?? null,
234+
isLoading,
235+
error: query.isError ? getErrorMessage(query.error) : null,
236+
refetch: () => {
237+
void query.refetch();
238+
},
239+
};
240+
}
241+
210242
// ─── useMerchantProfile ───────────────────────────────────────────────────────
211243

212244
export function useMerchantProfile(

lib/types/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ export interface MerchantProfile {
2828
phoneNumber: string | null;
2929
logoUrl: string | null;
3030
}
31+
32+
export interface MerchantBankAccount {
33+
bankName: string;
34+
accountNumber: string;
35+
accountName: string;
36+
bankCode?: string;
37+
}

0 commit comments

Comments
 (0)