From 940ebc16d5300d530e312742a2bde4c3714ae109 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 02:36:41 +0100 Subject: [PATCH 1/9] fix(backend): round owed amounts via half-even policy in loanController.ts roundToCents (#1372) --- backend/src/__tests__/loanConfig.test.ts | 1 + backend/src/__tests__/roundToCents.test.ts | 23 +++++++++++++++++++++ backend/src/controllers/loanController.ts | 3 ++- backend/src/money/__tests__/decimal.test.ts | 15 ++++++++++++++ backend/src/money/decimal.ts | 11 ++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 backend/src/__tests__/roundToCents.test.ts diff --git a/backend/src/__tests__/loanConfig.test.ts b/backend/src/__tests__/loanConfig.test.ts index b32c78ce..58b307bc 100644 --- a/backend/src/__tests__/loanConfig.test.ts +++ b/backend/src/__tests__/loanConfig.test.ts @@ -1,3 +1,4 @@ +import { jest } from '@jest/globals'; import { validateLoanConfig, validateLoanConfigOnStartup } from '../config/loanConfig.js'; describe('Loan config startup validation', () => { diff --git a/backend/src/__tests__/roundToCents.test.ts b/backend/src/__tests__/roundToCents.test.ts new file mode 100644 index 00000000..1b085c1c --- /dev/null +++ b/backend/src/__tests__/roundToCents.test.ts @@ -0,0 +1,23 @@ +import { roundToCents } from '../controllers/loanController.js'; + +describe('roundToCents half-even rounding', () => { + it('applies banker rounding (half-even) for .5 cent cases', () => { + expect(roundToCents(0.125)).toBe(0.12); + expect(roundToCents(0.135)).toBe(0.14); + expect(roundToCents(10.005)).toBe(10.0); + expect(roundToCents(10.015)).toBe(10.02); + }); + + it('handles negative half-even rounding symmetrically', () => { + expect(roundToCents(-0.125)).toBe(-0.12); + expect(roundToCents(-0.135)).toBe(-0.14); + }); + + it('rounds non-tie values to nearest cent', () => { + expect(roundToCents(10.004)).toBe(10.0); + expect(roundToCents(10.006)).toBe(10.01); + expect(roundToCents(12.3456)).toBe(12.35); + expect(roundToCents(12.3412)).toBe(12.34); + expect(roundToCents(0.0049)).toBe(0); + }); +}); diff --git a/backend/src/controllers/loanController.ts b/backend/src/controllers/loanController.ts index b79ba540..a11b2a8d 100644 --- a/backend/src/controllers/loanController.ts +++ b/backend/src/controllers/loanController.ts @@ -12,6 +12,7 @@ import logger from '../utils/logger.js'; import { cacheService } from '../services/cacheService.js'; import { notificationService } from '../services/notificationService.js'; import { invalidateOnRepay, invalidateOnLoanRequest } from '../utils/cacheKeys.js'; +import { roundToCents } from '../money/decimal.js'; // ─── Test/Dev Only ──────────────────────────────────────────────────────────── @@ -225,7 +226,7 @@ const getLatestLedger = async (): Promise => { return result.rows[0]?.last_indexed_ledger ?? 0; }; -const roundToCents = (value: number): number => Math.floor((value + Number.EPSILON) * 100) / 100; +export { roundToCents }; const addDays = (date: Date, days: number): Date => { const result = new Date(date); diff --git a/backend/src/money/__tests__/decimal.test.ts b/backend/src/money/__tests__/decimal.test.ts index 99448a00..7583255f 100644 --- a/backend/src/money/__tests__/decimal.test.ts +++ b/backend/src/money/__tests__/decimal.test.ts @@ -3,6 +3,7 @@ import { toStroops, fromStroops, splitProRata, + roundToCents, RoundingMode, MoneyError, STROOP_SCALE, @@ -168,3 +169,17 @@ describe('splitProRata', () => { expect(() => splitProRata(1n, [-1n])).toThrow(MoneyError); }); }); + +describe('roundToCents', () => { + it('rounds via half-even rounding mode (bankers rounding)', () => { + expect(roundToCents(0.125)).toBe(0.12); + expect(roundToCents(0.135)).toBe(0.14); + expect(roundToCents(10.005)).toBe(10.0); + expect(roundToCents(10.015)).toBe(10.02); + }); + + it('handles negative numbers symmetrically', () => { + expect(roundToCents(-0.125)).toBe(-0.12); + expect(roundToCents(-0.135)).toBe(-0.14); + }); +}); diff --git a/backend/src/money/decimal.ts b/backend/src/money/decimal.ts index 1ee9f5d8..6e45098e 100644 --- a/backend/src/money/decimal.ts +++ b/backend/src/money/decimal.ts @@ -154,6 +154,17 @@ export function fromStroops(value: bigint): string { return `${negative ? '-' : ''}${whole.toString()}.${fraction}`; } +/** + * Round a numeric amount to 2 decimal places (cents) using the policy's + * default half-even rounding mode. + */ +export function roundToCents(value: number, mode: RoundingMode = DEFAULT_MODE): number { + if (!Number.isFinite(value)) return value; + const stroops = toStroops(value.toFixed(7), mode); + const cents = roundDiv(stroops, 100_000n, mode); + return Number(cents) / 100; +} + /** * Split `total` stroops across `weights` proportionally using the * largest-remainder method, guaranteeing the returned parts sum *exactly* From 2852369de5c8f5994af492033bd1954f6627e595 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 02:41:28 +0100 Subject: [PATCH 2/9] style(frontend): fix Prettier formatting issues --- frontend/lib/money/format.ts | 2 +- frontend/src/app/[locale]/activity/page.tsx | 33 ++++++----- .../src/app/[locale]/lend/LendPageClient.tsx | 24 ++++---- .../app/[locale]/loans/LoansPageClient.tsx | 4 +- .../loans/[loanId]/LoanDetailsPageClient.tsx | 32 +++++------ frontend/src/app/[locale]/page.tsx | 4 +- frontend/src/app/[locale]/settings/page.tsx | 4 +- frontend/src/app/[locale]/wallet/page.tsx | 8 +-- .../borrower/ActiveLoansTracker.tsx | 4 +- .../src/app/components/borrower/LoanCard.tsx | 56 ++++++++++--------- .../FinancialPerformanceDashboard.tsx | 18 ++++-- .../src/app/components/global_ui/Header.tsx | 8 +-- .../loan-wizard/StepAmountAsset.tsx | 4 +- .../components/loan-wizard/WizardStepper.tsx | 4 +- .../src/app/components/loan/LoanHealth.tsx | 8 +-- .../components/providers/WalletProvider.tsx | 6 +- frontend/src/app/components/ui.tsx | 2 +- .../app/components/ui/OperationProgress.tsx | 5 +- frontend/src/app/components/ui/Toaster.tsx | 4 +- frontend/src/app/hooks/useApi.ts | 8 +-- .../src/app/utils/transactionFormatter.ts | 5 +- 21 files changed, 132 insertions(+), 111 deletions(-) diff --git a/frontend/lib/money/format.ts b/frontend/lib/money/format.ts index 24a6594a..c1c57f34 100644 --- a/frontend/lib/money/format.ts +++ b/frontend/lib/money/format.ts @@ -150,7 +150,7 @@ export function formatStroops(value: bigint, opts: FormatStroopsOptions = {}): s const fraction = scaledMagnitude % scale; const wholeStr = - (opts.grouped ?? false) ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); + opts.grouped ?? false ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); const sign = negative && scaledMagnitude !== ZERO ? "-" : ""; diff --git a/frontend/src/app/[locale]/activity/page.tsx b/frontend/src/app/[locale]/activity/page.tsx index 626f16e9..07507ada 100644 --- a/frontend/src/app/[locale]/activity/page.tsx +++ b/frontend/src/app/[locale]/activity/page.tsx @@ -64,16 +64,16 @@ export default function ActivityPage() { (loan as { latestEventType?: string }).latestEventType === "LoanExtended" ? "Loan Extended" : (loan as { latestEventType?: string }).latestEventType === "LoanRefinanced" - ? "Loan Refinanced" - : loan.status === "repaid" - ? "Loan Repaid" - : loan.status === "liquidated" - ? "Loan Liquidated" - : loan.status === "defaulted" - ? "Loan Defaulted" - : loan.status === "active" - ? "Loan Active" - : "Loan Request", + ? "Loan Refinanced" + : loan.status === "repaid" + ? "Loan Repaid" + : loan.status === "liquidated" + ? "Loan Liquidated" + : loan.status === "defaulted" + ? "Loan Defaulted" + : loan.status === "active" + ? "Loan Active" + : "Loan Request", description: `Loan #${loan.id} — ${loan.currency}`, amount: `${loan.status === "repaid" ? "+" : "-"}${formatCurrency(loan.amount)}`, timestamp: new Date(loan.createdAt).toISOString(), @@ -84,7 +84,10 @@ export default function ActivityPage() { const remittanceEvents: ActivityItem[] = remittances.map((remittance) => ({ id: `remittance-${remittance.id}`, type: "Remittance", - description: `To ${remittance.recipientAddress.slice(0, 6)}...${remittance.recipientAddress.slice(-4)}`, + description: `To ${remittance.recipientAddress.slice( + 0, + 6, + )}...${remittance.recipientAddress.slice(-4)}`, amount: `-${formatCurrency(remittance.amount)}`, timestamp: new Date(remittance.createdAt).toISOString(), status: remittance.status, @@ -226,10 +229,10 @@ export default function ActivityPage() { item.status === "completed" || item.status === "repaid" ? "bg-green-50 dark:bg-green-500/10" : item.status === "failed" || - item.status === "defaulted" || - item.status === "liquidated" - ? "bg-red-50 dark:bg-red-500/10" - : "bg-indigo-50 dark:bg-indigo-500/10" + item.status === "defaulted" || + item.status === "liquidated" + ? "bg-red-50 dark:bg-red-500/10" + : "bg-indigo-50 dark:bg-indigo-500/10" }`} aria-hidden="true" > diff --git a/frontend/src/app/[locale]/lend/LendPageClient.tsx b/frontend/src/app/[locale]/lend/LendPageClient.tsx index 455492d5..825b05dd 100644 --- a/frontend/src/app/[locale]/lend/LendPageClient.tsx +++ b/frontend/src/app/[locale]/lend/LendPageClient.tsx @@ -195,19 +195,19 @@ export function LendPageClient() { sseStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : sseStatus === "connecting" - ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" - : sseStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" + ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" + : sseStatus === "polling" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" }`} title={ sseStatus === "connected" ? "Live pool updates connected" : sseStatus === "connecting" - ? "Connecting to live updates…" - : sseStatus === "polling" - ? "Live updates dropped — polling while reconnecting" - : "Live updates disconnected — retrying" + ? "Connecting to live updates…" + : sseStatus === "polling" + ? "Live updates dropped — polling while reconnecting" + : "Live updates disconnected — retrying" } > {sseStatus === "connected" ? ( @@ -218,10 +218,10 @@ export function LendPageClient() { {sseStatus === "connected" ? "Live" : sseStatus === "connecting" - ? "Connecting…" - : sseStatus === "polling" - ? "Reconnecting…" - : "Offline"} + ? "Connecting…" + : sseStatus === "polling" + ? "Reconnecting…" + : "Offline"} )} diff --git a/frontend/src/app/[locale]/loans/LoansPageClient.tsx b/frontend/src/app/[locale]/loans/LoansPageClient.tsx index 4d18346c..bd902f40 100644 --- a/frontend/src/app/[locale]/loans/LoansPageClient.tsx +++ b/frontend/src/app/[locale]/loans/LoansPageClient.tsx @@ -71,8 +71,8 @@ export function LoansPageClient() { overdueCount === 0 ? t("health.strong") : overdueCount <= 2 - ? t("health.watch") - : t("health.atRisk"); + ? t("health.watch") + : t("health.atRisk"); if (isLoading) { return ; diff --git a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx index ee8cf095..57b43e9e 100644 --- a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx +++ b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx @@ -142,10 +142,10 @@ export function LoanDetailsPageClient() { realtimeStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : realtimeStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : realtimeStatus === "disconnected" - ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" - : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : realtimeStatus === "disconnected" + ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" + : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" }`} > {realtimeStatus === "connected" ? ( @@ -156,10 +156,10 @@ export function LoanDetailsPageClient() { {realtimeStatus === "connected" ? "Live loan updates" : realtimeStatus === "polling" - ? "Polling while reconnecting" - : realtimeStatus === "disconnected" - ? "Realtime temporarily unavailable" - : "Connecting to live updates"} + ? "Polling while reconnecting" + : realtimeStatus === "disconnected" + ? "Realtime temporarily unavailable" + : "Connecting to live updates"} diff --git a/frontend/src/app/[locale]/wallet/page.tsx b/frontend/src/app/[locale]/wallet/page.tsx index f6386772..12176a4e 100644 --- a/frontend/src/app/[locale]/wallet/page.tsx +++ b/frontend/src/app/[locale]/wallet/page.tsx @@ -123,7 +123,7 @@ function useHorizonPayments(address: string, horizonUrl: string, cursor: string return { records, nextCursor: - records.length === TRANSACTIONS_PER_PAGE ? (lastRecord?.paging_token ?? null) : null, + records.length === TRANSACTIONS_PER_PAGE ? lastRecord?.paging_token ?? null : null, }; }, staleTime: 30_000, @@ -190,7 +190,7 @@ function BalancesCard({ address, horizonUrl }: { address: string; horizonUrl: st } = useHorizonBalances(address, horizonUrl); function assetLabel(b: HorizonBalance): string { - return b.asset_type === "native" ? "XLM" : (b.asset_code ?? "Unknown"); + return b.asset_type === "native" ? "XLM" : b.asset_code ?? "Unknown"; } function formatBalance(b: HorizonBalance): string { @@ -314,14 +314,14 @@ function TransactionHistoryCard({ function paymentAmount(p: HorizonPayment): string { if (!p.amount) return "—"; - const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); + const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; return `${parseFloat(p.amount).toLocaleString("en-US", { maximumFractionDigits: 7 })} ${asset}`; } function exportCsv() { const today = new Date().toISOString().split("T")[0]; const rows = payments.map((p) => { - const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); + const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; return { date: p.created_at, type: paymentLabel(p), diff --git a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx index f9c96dd3..70a99910 100644 --- a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx +++ b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx @@ -38,8 +38,8 @@ export function ActiveLoansTracker({ borrowerAddress }: { borrowerAddress: strin filter === "overdue" ? loans.filter((l) => l.status === "active" && new Date(l.nextPaymentDeadline) < now) : filter === "active" - ? loans.filter((l) => l.status === "active") - : loans; + ? loans.filter((l) => l.status === "active") + : loans; const tabCounts: Record = { active: loans.filter((l) => l.status === "active").length, diff --git a/frontend/src/app/components/borrower/LoanCard.tsx b/frontend/src/app/components/borrower/LoanCard.tsx index f92ec65d..d991470e 100644 --- a/frontend/src/app/components/borrower/LoanCard.tsx +++ b/frontend/src/app/components/borrower/LoanCard.tsx @@ -34,19 +34,19 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { label: isLiquidated ? "Liquidated" : isDefaulted - ? "Defaulted" - : isOverdue - ? "Overdue" - : isUrgent - ? "Due Soon" - : "On Track", + ? "Defaulted" + : isOverdue + ? "Overdue" + : isUrgent + ? "Due Soon" + : "On Track", className: isTerminalDistressed ? "bg-red-900 text-white" : isOverdue - ? "bg-red-100 text-red-800" - : isUrgent - ? "bg-yellow-100 text-yellow-800" - : "bg-green-100 text-green-800", + ? "bg-red-100 text-red-800" + : isUrgent + ? "bg-yellow-100 text-yellow-800" + : "bg-green-100 text-green-800", } : null; @@ -54,31 +54,31 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { const deadlineBg = isTerminalDistressed ? "bg-red-900/20" : isOverdue - ? "bg-red-50" - : isUrgent - ? "bg-yellow-50" - : "bg-gray-50"; + ? "bg-red-50" + : isUrgent + ? "bg-yellow-50" + : "bg-gray-50"; const deadlineTextColor = isTerminalDistressed ? "text-red-900" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-900"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-900"; const deadlineSubColor = isTerminalDistressed ? "text-red-700" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-600"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-600"; const deadlineLabel = isLiquidated ? "Collateral was liquidated" : isDefaulted - ? "Contact support to recover" - : isOverdue - ? `${Math.abs(daysUntil)} days overdue` - : `${daysUntil} days remaining`; + ? "Contact support to recover" + : isOverdue + ? `${Math.abs(daysUntil)} days overdue` + : `${daysUntil} days remaining`; // ── Progress (detailed only) ─────────────────────────────────────────────── const totalForProgress = loan.principal + loan.accruedInterest; @@ -150,7 +150,9 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) {

Next Payment

{formatDate(loan.nextPaymentDeadline)}

diff --git a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx index c6862d79..aa074e43 100644 --- a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx +++ b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx @@ -215,8 +215,8 @@ export function FinancialPerformanceDashboard({ // ── Derived display data ── const displayCreditScoreData = useMockData ? generateMockCreditScoreData() - : (creditScoreData ?? []); - const displayYieldData = useMockData ? generateMockYieldData() : (yieldData ?? []); + : creditScoreData ?? []; + const displayYieldData = useMockData ? generateMockYieldData() : yieldData ?? []; const displayLoanStats = useMemo(() => { if (useMockData) return generateMockLoanStats(); @@ -302,8 +302,8 @@ export function FinancialPerformanceDashboard({ {userType === "both" ? "credit score and yield" : userType === "borrower" - ? "credit score" - : "yield"}{" "} + ? "credit score" + : "yield"}{" "} performance over time

@@ -354,7 +354,9 @@ export function FinancialPerformanceDashboard({ @@ -417,7 +419,11 @@ export function FinancialPerformanceDashboard({ value={fmt(displayDepositorStats.currentValue)} sub={ displayDepositorStats.depositAmount > 0 - ? `+${(((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / displayDepositorStats.depositAmount) * 100).toFixed(2)}% growth` + ? `+${( + ((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / + displayDepositorStats.depositAmount) * + 100 + ).toFixed(2)}% growth` : undefined } colorClass="bg-blue-50 text-blue-900 dark:bg-blue-950/30 dark:text-blue-200" diff --git a/frontend/src/app/components/global_ui/Header.tsx b/frontend/src/app/components/global_ui/Header.tsx index 3b8fa256..7ebb5343 100644 --- a/frontend/src/app/components/global_ui/Header.tsx +++ b/frontend/src/app/components/global_ui/Header.tsx @@ -239,10 +239,10 @@ export function Header({ onMenuClick, className }: HeaderProps) { const profileLabel = user?.email ? user.email : user?.walletAddress - ? truncateWalletAddress(user.walletAddress) - : walletAddress - ? truncateWalletAddress(walletAddress) - : "Connect Wallet"; + ? truncateWalletAddress(user.walletAddress) + : walletAddress + ? truncateWalletAddress(walletAddress) + : "Connect Wallet"; return (
diff --git a/frontend/src/app/components/loan-wizard/WizardStepper.tsx b/frontend/src/app/components/loan-wizard/WizardStepper.tsx index f92c3ff3..85b9d311 100644 --- a/frontend/src/app/components/loan-wizard/WizardStepper.tsx +++ b/frontend/src/app/components/loan-wizard/WizardStepper.tsx @@ -98,8 +98,8 @@ export function WizardStepper({ steps, currentStep, onStepSelect }: WizardSteppe isCurrent ? "text-indigo-600 dark:text-indigo-400" : isCompleted - ? "text-zinc-700 dark:text-zinc-300" - : "text-zinc-400 dark:text-zinc-500", + ? "text-zinc-700 dark:text-zinc-300" + : "text-zinc-400 dark:text-zinc-500", )} > {step.label} diff --git a/frontend/src/app/components/loan/LoanHealth.tsx b/frontend/src/app/components/loan/LoanHealth.tsx index 3fd1c821..430c1f61 100644 --- a/frontend/src/app/components/loan/LoanHealth.tsx +++ b/frontend/src/app/components/loan/LoanHealth.tsx @@ -99,16 +99,16 @@ export function LoanHealth({ loan, isLoading, isError, topUpHref, labels }: Loan state === "atRisk" ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200" : state === "watch" - ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" - : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; + ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" + : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; const barTone = state === "atRisk" ? "bg-red-500" : state === "watch" ? "bg-amber-500" : "bg-emerald-500"; const source = loan?.healthSource === "contract" ? labels.sourceContract : loan?.healthSource === "backend" || backendRatio || backendHealthFactor - ? labels.sourceBackend - : labels.sourceDerived; + ? labels.sourceBackend + : labels.sourceDerived; const barWidth = `${Math.min(100, Math.max(6, (ratio / (threshold + 0.5)) * 100))}%`; return ( diff --git a/frontend/src/app/components/providers/WalletProvider.tsx b/frontend/src/app/components/providers/WalletProvider.tsx index 9eeb192b..1a4536bd 100644 --- a/frontend/src/app/components/providers/WalletProvider.tsx +++ b/frontend/src/app/components/providers/WalletProvider.tsx @@ -98,7 +98,7 @@ function getFallbackHorizonUrl(networkName: string | undefined): string { function mapBalances(balances: HorizonBalance[] | undefined): TokenBalance[] { return (balances ?? []).map((balance) => ({ - symbol: balance.asset_type === "native" ? "XLM" : (balance.asset_code ?? "ASSET"), + symbol: balance.asset_type === "native" ? "XLM" : balance.asset_code ?? "ASSET", amount: balance.balance, usdValue: null, })); @@ -181,8 +181,8 @@ export function WalletProvider({ children }: WalletProviderProps) { const networkResult: FreighterNetworkResult = api.getNetworkDetails ? await api.getNetworkDetails() : api.getNetwork - ? await api.getNetwork() - : { error: "Network info not available." }; + ? await api.getNetwork() + : { error: "Network info not available." }; if (networkResult.error) { throw new Error(normalizeWalletError(networkResult.error)); diff --git a/frontend/src/app/components/ui.tsx b/frontend/src/app/components/ui.tsx index 489fdddd..540c805b 100644 --- a/frontend/src/app/components/ui.tsx +++ b/frontend/src/app/components/ui.tsx @@ -1 +1 @@ -export { COPY_FEEDBACK_RESET_MS } from './ui/CopyButton'; +export { COPY_FEEDBACK_RESET_MS } from "./ui/CopyButton"; diff --git a/frontend/src/app/components/ui/OperationProgress.tsx b/frontend/src/app/components/ui/OperationProgress.tsx index 2df7d230..09eb4dca 100644 --- a/frontend/src/app/components/ui/OperationProgress.tsx +++ b/frontend/src/app/components/ui/OperationProgress.tsx @@ -88,7 +88,10 @@ export function OperationProgress({ transaction, type = "generic" }: OperationPr href={`https://stellar.expert/explorer/testnet/tx/${txHash}`} target="_blank" rel="noopener noreferrer" - aria-label={`View transaction ${txHash.slice(0, 8)}… on Stellar Explorer (opens in new tab)`} + aria-label={`View transaction ${txHash.slice( + 0, + 8, + )}… on Stellar Explorer (opens in new tab)`} className="text-xs text-blue-600 hover:text-blue-700 dark:text-blue-400 hover:underline flex items-center gap-1" > diff --git a/frontend/src/app/components/ui/Toaster.tsx b/frontend/src/app/components/ui/Toaster.tsx index adeab47d..52e9f45b 100644 --- a/frontend/src/app/components/ui/Toaster.tsx +++ b/frontend/src/app/components/ui/Toaster.tsx @@ -57,7 +57,9 @@ function ToastCard({ toast }: { toast: ToastItem }) { animate={{ opacity: 1, x: 0, scale: 1 }} exit={{ opacity: 0, x: 20, scale: 0.96 }} transition={{ duration: 0.2, ease: "easeOut" }} - className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles(toast.type)}`} + className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles( + toast.type, + )}`} role="alert" >
diff --git a/frontend/src/app/hooks/useApi.ts b/frontend/src/app/hooks/useApi.ts index 5f7509f0..87ca8038 100644 --- a/frontend/src/app/hooks/useApi.ts +++ b/frontend/src/app/hooks/useApi.ts @@ -797,8 +797,8 @@ export function useLiquidatableLoans( const loans = Array.isArray(response) ? response : "loans" in response - ? response.loans - : response.data; + ? response.loans + : response.data; const fallbackSource = Array.isArray(response) ? undefined : response.source; return loans.map((loan) => @@ -1493,8 +1493,8 @@ export function useAdminDisputes( const disputes = Array.isArray(response) ? response : "disputes" in response - ? response.disputes - : response.data; + ? response.disputes + : response.data; return disputes.map(normalizeDispute); }, diff --git a/frontend/src/app/utils/transactionFormatter.ts b/frontend/src/app/utils/transactionFormatter.ts index 84a9898d..9aa8fe34 100644 --- a/frontend/src/app/utils/transactionFormatter.ts +++ b/frontend/src/app/utils/transactionFormatter.ts @@ -186,7 +186,10 @@ export function formatRemittanceSend(params: { const operations: TransactionOperation[] = [ { type: "Send Remittance", - description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice(0, 8)}...${params.recipient.slice(-6)}`, + description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice( + 0, + 8, + )}...${params.recipient.slice(-6)}`, amount: params.amount.toString(), token: params.token, details: { From 336bad4c0f99b560328796dd7856b7d477233fe4 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 02:45:34 +0100 Subject: [PATCH 3/9] style(frontend): enforce LF endOfLine in frontend/.prettierrc --- frontend/.prettierrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.prettierrc b/frontend/.prettierrc index f47f903b..39a725eb 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -4,5 +4,5 @@ "trailingComma": "all", "tabWidth": 2, "printWidth": 100, - "endOfLine": "auto" + "endOfLine": "lf" } From 98c4fb05501efd8dbbdfe206165c44a82d7ad5b0 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 02:48:29 +0100 Subject: [PATCH 4/9] build: add .gitattributes to enforce LF line endings across environments --- .gitattributes | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fa27750c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto eol=lf +*.ts text eol=lf +*.tsx text eol=lf +*.js text eol=lf +*.jsx text eol=lf +*.json text eol=lf +*.md text eol=lf +*.css text eol=lf From d96ef59fc5d133bf11038820bbd362771717778d Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 03:05:06 +0100 Subject: [PATCH 5/9] revert(frontend): restore frontend files to original main state --- frontend/.prettierrc | 2 +- frontend/lib/money/format.ts | 2 +- frontend/src/app/[locale]/activity/page.tsx | 33 +++++------ .../src/app/[locale]/lend/LendPageClient.tsx | 24 ++++---- .../app/[locale]/loans/LoansPageClient.tsx | 4 +- .../loans/[loanId]/LoanDetailsPageClient.tsx | 32 +++++------ frontend/src/app/[locale]/page.tsx | 4 +- frontend/src/app/[locale]/settings/page.tsx | 4 +- frontend/src/app/[locale]/wallet/page.tsx | 8 +-- .../borrower/ActiveLoansTracker.tsx | 4 +- .../src/app/components/borrower/LoanCard.tsx | 56 +++++++++---------- .../FinancialPerformanceDashboard.tsx | 18 ++---- .../src/app/components/global_ui/Header.tsx | 8 +-- .../loan-wizard/StepAmountAsset.tsx | 4 +- .../components/loan-wizard/WizardStepper.tsx | 4 +- .../src/app/components/loan/LoanHealth.tsx | 8 +-- .../components/providers/WalletProvider.tsx | 6 +- frontend/src/app/components/ui.tsx | 2 +- .../app/components/ui/OperationProgress.tsx | 5 +- frontend/src/app/components/ui/Toaster.tsx | 4 +- frontend/src/app/hooks/useApi.ts | 8 +-- .../src/app/utils/transactionFormatter.ts | 5 +- 22 files changed, 112 insertions(+), 133 deletions(-) diff --git a/frontend/.prettierrc b/frontend/.prettierrc index 39a725eb..f47f903b 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -4,5 +4,5 @@ "trailingComma": "all", "tabWidth": 2, "printWidth": 100, - "endOfLine": "lf" + "endOfLine": "auto" } diff --git a/frontend/lib/money/format.ts b/frontend/lib/money/format.ts index c1c57f34..24a6594a 100644 --- a/frontend/lib/money/format.ts +++ b/frontend/lib/money/format.ts @@ -150,7 +150,7 @@ export function formatStroops(value: bigint, opts: FormatStroopsOptions = {}): s const fraction = scaledMagnitude % scale; const wholeStr = - opts.grouped ?? false ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); + (opts.grouped ?? false) ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); const sign = negative && scaledMagnitude !== ZERO ? "-" : ""; diff --git a/frontend/src/app/[locale]/activity/page.tsx b/frontend/src/app/[locale]/activity/page.tsx index 07507ada..626f16e9 100644 --- a/frontend/src/app/[locale]/activity/page.tsx +++ b/frontend/src/app/[locale]/activity/page.tsx @@ -64,16 +64,16 @@ export default function ActivityPage() { (loan as { latestEventType?: string }).latestEventType === "LoanExtended" ? "Loan Extended" : (loan as { latestEventType?: string }).latestEventType === "LoanRefinanced" - ? "Loan Refinanced" - : loan.status === "repaid" - ? "Loan Repaid" - : loan.status === "liquidated" - ? "Loan Liquidated" - : loan.status === "defaulted" - ? "Loan Defaulted" - : loan.status === "active" - ? "Loan Active" - : "Loan Request", + ? "Loan Refinanced" + : loan.status === "repaid" + ? "Loan Repaid" + : loan.status === "liquidated" + ? "Loan Liquidated" + : loan.status === "defaulted" + ? "Loan Defaulted" + : loan.status === "active" + ? "Loan Active" + : "Loan Request", description: `Loan #${loan.id} — ${loan.currency}`, amount: `${loan.status === "repaid" ? "+" : "-"}${formatCurrency(loan.amount)}`, timestamp: new Date(loan.createdAt).toISOString(), @@ -84,10 +84,7 @@ export default function ActivityPage() { const remittanceEvents: ActivityItem[] = remittances.map((remittance) => ({ id: `remittance-${remittance.id}`, type: "Remittance", - description: `To ${remittance.recipientAddress.slice( - 0, - 6, - )}...${remittance.recipientAddress.slice(-4)}`, + description: `To ${remittance.recipientAddress.slice(0, 6)}...${remittance.recipientAddress.slice(-4)}`, amount: `-${formatCurrency(remittance.amount)}`, timestamp: new Date(remittance.createdAt).toISOString(), status: remittance.status, @@ -229,10 +226,10 @@ export default function ActivityPage() { item.status === "completed" || item.status === "repaid" ? "bg-green-50 dark:bg-green-500/10" : item.status === "failed" || - item.status === "defaulted" || - item.status === "liquidated" - ? "bg-red-50 dark:bg-red-500/10" - : "bg-indigo-50 dark:bg-indigo-500/10" + item.status === "defaulted" || + item.status === "liquidated" + ? "bg-red-50 dark:bg-red-500/10" + : "bg-indigo-50 dark:bg-indigo-500/10" }`} aria-hidden="true" > diff --git a/frontend/src/app/[locale]/lend/LendPageClient.tsx b/frontend/src/app/[locale]/lend/LendPageClient.tsx index 825b05dd..455492d5 100644 --- a/frontend/src/app/[locale]/lend/LendPageClient.tsx +++ b/frontend/src/app/[locale]/lend/LendPageClient.tsx @@ -195,19 +195,19 @@ export function LendPageClient() { sseStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : sseStatus === "connecting" - ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" - : sseStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" + ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" + : sseStatus === "polling" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" }`} title={ sseStatus === "connected" ? "Live pool updates connected" : sseStatus === "connecting" - ? "Connecting to live updates…" - : sseStatus === "polling" - ? "Live updates dropped — polling while reconnecting" - : "Live updates disconnected — retrying" + ? "Connecting to live updates…" + : sseStatus === "polling" + ? "Live updates dropped — polling while reconnecting" + : "Live updates disconnected — retrying" } > {sseStatus === "connected" ? ( @@ -218,10 +218,10 @@ export function LendPageClient() { {sseStatus === "connected" ? "Live" : sseStatus === "connecting" - ? "Connecting…" - : sseStatus === "polling" - ? "Reconnecting…" - : "Offline"} + ? "Connecting…" + : sseStatus === "polling" + ? "Reconnecting…" + : "Offline"}
)}
diff --git a/frontend/src/app/[locale]/loans/LoansPageClient.tsx b/frontend/src/app/[locale]/loans/LoansPageClient.tsx index bd902f40..4d18346c 100644 --- a/frontend/src/app/[locale]/loans/LoansPageClient.tsx +++ b/frontend/src/app/[locale]/loans/LoansPageClient.tsx @@ -71,8 +71,8 @@ export function LoansPageClient() { overdueCount === 0 ? t("health.strong") : overdueCount <= 2 - ? t("health.watch") - : t("health.atRisk"); + ? t("health.watch") + : t("health.atRisk"); if (isLoading) { return ; diff --git a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx index 57b43e9e..ee8cf095 100644 --- a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx +++ b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx @@ -142,10 +142,10 @@ export function LoanDetailsPageClient() { realtimeStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : realtimeStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : realtimeStatus === "disconnected" - ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" - : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : realtimeStatus === "disconnected" + ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" + : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" }`} > {realtimeStatus === "connected" ? ( @@ -156,10 +156,10 @@ export function LoanDetailsPageClient() { {realtimeStatus === "connected" ? "Live loan updates" : realtimeStatus === "polling" - ? "Polling while reconnecting" - : realtimeStatus === "disconnected" - ? "Realtime temporarily unavailable" - : "Connecting to live updates"} + ? "Polling while reconnecting" + : realtimeStatus === "disconnected" + ? "Realtime temporarily unavailable" + : "Connecting to live updates"} diff --git a/frontend/src/app/[locale]/wallet/page.tsx b/frontend/src/app/[locale]/wallet/page.tsx index 12176a4e..f6386772 100644 --- a/frontend/src/app/[locale]/wallet/page.tsx +++ b/frontend/src/app/[locale]/wallet/page.tsx @@ -123,7 +123,7 @@ function useHorizonPayments(address: string, horizonUrl: string, cursor: string return { records, nextCursor: - records.length === TRANSACTIONS_PER_PAGE ? lastRecord?.paging_token ?? null : null, + records.length === TRANSACTIONS_PER_PAGE ? (lastRecord?.paging_token ?? null) : null, }; }, staleTime: 30_000, @@ -190,7 +190,7 @@ function BalancesCard({ address, horizonUrl }: { address: string; horizonUrl: st } = useHorizonBalances(address, horizonUrl); function assetLabel(b: HorizonBalance): string { - return b.asset_type === "native" ? "XLM" : b.asset_code ?? "Unknown"; + return b.asset_type === "native" ? "XLM" : (b.asset_code ?? "Unknown"); } function formatBalance(b: HorizonBalance): string { @@ -314,14 +314,14 @@ function TransactionHistoryCard({ function paymentAmount(p: HorizonPayment): string { if (!p.amount) return "—"; - const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; + const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); return `${parseFloat(p.amount).toLocaleString("en-US", { maximumFractionDigits: 7 })} ${asset}`; } function exportCsv() { const today = new Date().toISOString().split("T")[0]; const rows = payments.map((p) => { - const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; + const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); return { date: p.created_at, type: paymentLabel(p), diff --git a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx index 70a99910..f9c96dd3 100644 --- a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx +++ b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx @@ -38,8 +38,8 @@ export function ActiveLoansTracker({ borrowerAddress }: { borrowerAddress: strin filter === "overdue" ? loans.filter((l) => l.status === "active" && new Date(l.nextPaymentDeadline) < now) : filter === "active" - ? loans.filter((l) => l.status === "active") - : loans; + ? loans.filter((l) => l.status === "active") + : loans; const tabCounts: Record = { active: loans.filter((l) => l.status === "active").length, diff --git a/frontend/src/app/components/borrower/LoanCard.tsx b/frontend/src/app/components/borrower/LoanCard.tsx index d991470e..f92ec65d 100644 --- a/frontend/src/app/components/borrower/LoanCard.tsx +++ b/frontend/src/app/components/borrower/LoanCard.tsx @@ -34,19 +34,19 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { label: isLiquidated ? "Liquidated" : isDefaulted - ? "Defaulted" - : isOverdue - ? "Overdue" - : isUrgent - ? "Due Soon" - : "On Track", + ? "Defaulted" + : isOverdue + ? "Overdue" + : isUrgent + ? "Due Soon" + : "On Track", className: isTerminalDistressed ? "bg-red-900 text-white" : isOverdue - ? "bg-red-100 text-red-800" - : isUrgent - ? "bg-yellow-100 text-yellow-800" - : "bg-green-100 text-green-800", + ? "bg-red-100 text-red-800" + : isUrgent + ? "bg-yellow-100 text-yellow-800" + : "bg-green-100 text-green-800", } : null; @@ -54,31 +54,31 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { const deadlineBg = isTerminalDistressed ? "bg-red-900/20" : isOverdue - ? "bg-red-50" - : isUrgent - ? "bg-yellow-50" - : "bg-gray-50"; + ? "bg-red-50" + : isUrgent + ? "bg-yellow-50" + : "bg-gray-50"; const deadlineTextColor = isTerminalDistressed ? "text-red-900" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-900"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-900"; const deadlineSubColor = isTerminalDistressed ? "text-red-700" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-600"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-600"; const deadlineLabel = isLiquidated ? "Collateral was liquidated" : isDefaulted - ? "Contact support to recover" - : isOverdue - ? `${Math.abs(daysUntil)} days overdue` - : `${daysUntil} days remaining`; + ? "Contact support to recover" + : isOverdue + ? `${Math.abs(daysUntil)} days overdue` + : `${daysUntil} days remaining`; // ── Progress (detailed only) ─────────────────────────────────────────────── const totalForProgress = loan.principal + loan.accruedInterest; @@ -150,9 +150,7 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) {

Next Payment

{formatDate(loan.nextPaymentDeadline)}

diff --git a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx index aa074e43..c6862d79 100644 --- a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx +++ b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx @@ -215,8 +215,8 @@ export function FinancialPerformanceDashboard({ // ── Derived display data ── const displayCreditScoreData = useMockData ? generateMockCreditScoreData() - : creditScoreData ?? []; - const displayYieldData = useMockData ? generateMockYieldData() : yieldData ?? []; + : (creditScoreData ?? []); + const displayYieldData = useMockData ? generateMockYieldData() : (yieldData ?? []); const displayLoanStats = useMemo(() => { if (useMockData) return generateMockLoanStats(); @@ -302,8 +302,8 @@ export function FinancialPerformanceDashboard({ {userType === "both" ? "credit score and yield" : userType === "borrower" - ? "credit score" - : "yield"}{" "} + ? "credit score" + : "yield"}{" "} performance over time

@@ -354,9 +354,7 @@ export function FinancialPerformanceDashboard({ @@ -419,11 +417,7 @@ export function FinancialPerformanceDashboard({ value={fmt(displayDepositorStats.currentValue)} sub={ displayDepositorStats.depositAmount > 0 - ? `+${( - ((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / - displayDepositorStats.depositAmount) * - 100 - ).toFixed(2)}% growth` + ? `+${(((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / displayDepositorStats.depositAmount) * 100).toFixed(2)}% growth` : undefined } colorClass="bg-blue-50 text-blue-900 dark:bg-blue-950/30 dark:text-blue-200" diff --git a/frontend/src/app/components/global_ui/Header.tsx b/frontend/src/app/components/global_ui/Header.tsx index 7ebb5343..3b8fa256 100644 --- a/frontend/src/app/components/global_ui/Header.tsx +++ b/frontend/src/app/components/global_ui/Header.tsx @@ -239,10 +239,10 @@ export function Header({ onMenuClick, className }: HeaderProps) { const profileLabel = user?.email ? user.email : user?.walletAddress - ? truncateWalletAddress(user.walletAddress) - : walletAddress - ? truncateWalletAddress(walletAddress) - : "Connect Wallet"; + ? truncateWalletAddress(user.walletAddress) + : walletAddress + ? truncateWalletAddress(walletAddress) + : "Connect Wallet"; return (
diff --git a/frontend/src/app/components/loan-wizard/WizardStepper.tsx b/frontend/src/app/components/loan-wizard/WizardStepper.tsx index 85b9d311..f92c3ff3 100644 --- a/frontend/src/app/components/loan-wizard/WizardStepper.tsx +++ b/frontend/src/app/components/loan-wizard/WizardStepper.tsx @@ -98,8 +98,8 @@ export function WizardStepper({ steps, currentStep, onStepSelect }: WizardSteppe isCurrent ? "text-indigo-600 dark:text-indigo-400" : isCompleted - ? "text-zinc-700 dark:text-zinc-300" - : "text-zinc-400 dark:text-zinc-500", + ? "text-zinc-700 dark:text-zinc-300" + : "text-zinc-400 dark:text-zinc-500", )} > {step.label} diff --git a/frontend/src/app/components/loan/LoanHealth.tsx b/frontend/src/app/components/loan/LoanHealth.tsx index 430c1f61..3fd1c821 100644 --- a/frontend/src/app/components/loan/LoanHealth.tsx +++ b/frontend/src/app/components/loan/LoanHealth.tsx @@ -99,16 +99,16 @@ export function LoanHealth({ loan, isLoading, isError, topUpHref, labels }: Loan state === "atRisk" ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200" : state === "watch" - ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" - : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; + ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" + : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; const barTone = state === "atRisk" ? "bg-red-500" : state === "watch" ? "bg-amber-500" : "bg-emerald-500"; const source = loan?.healthSource === "contract" ? labels.sourceContract : loan?.healthSource === "backend" || backendRatio || backendHealthFactor - ? labels.sourceBackend - : labels.sourceDerived; + ? labels.sourceBackend + : labels.sourceDerived; const barWidth = `${Math.min(100, Math.max(6, (ratio / (threshold + 0.5)) * 100))}%`; return ( diff --git a/frontend/src/app/components/providers/WalletProvider.tsx b/frontend/src/app/components/providers/WalletProvider.tsx index 1a4536bd..9eeb192b 100644 --- a/frontend/src/app/components/providers/WalletProvider.tsx +++ b/frontend/src/app/components/providers/WalletProvider.tsx @@ -98,7 +98,7 @@ function getFallbackHorizonUrl(networkName: string | undefined): string { function mapBalances(balances: HorizonBalance[] | undefined): TokenBalance[] { return (balances ?? []).map((balance) => ({ - symbol: balance.asset_type === "native" ? "XLM" : balance.asset_code ?? "ASSET", + symbol: balance.asset_type === "native" ? "XLM" : (balance.asset_code ?? "ASSET"), amount: balance.balance, usdValue: null, })); @@ -181,8 +181,8 @@ export function WalletProvider({ children }: WalletProviderProps) { const networkResult: FreighterNetworkResult = api.getNetworkDetails ? await api.getNetworkDetails() : api.getNetwork - ? await api.getNetwork() - : { error: "Network info not available." }; + ? await api.getNetwork() + : { error: "Network info not available." }; if (networkResult.error) { throw new Error(normalizeWalletError(networkResult.error)); diff --git a/frontend/src/app/components/ui.tsx b/frontend/src/app/components/ui.tsx index 540c805b..489fdddd 100644 --- a/frontend/src/app/components/ui.tsx +++ b/frontend/src/app/components/ui.tsx @@ -1 +1 @@ -export { COPY_FEEDBACK_RESET_MS } from "./ui/CopyButton"; +export { COPY_FEEDBACK_RESET_MS } from './ui/CopyButton'; diff --git a/frontend/src/app/components/ui/OperationProgress.tsx b/frontend/src/app/components/ui/OperationProgress.tsx index 09eb4dca..2df7d230 100644 --- a/frontend/src/app/components/ui/OperationProgress.tsx +++ b/frontend/src/app/components/ui/OperationProgress.tsx @@ -88,10 +88,7 @@ export function OperationProgress({ transaction, type = "generic" }: OperationPr href={`https://stellar.expert/explorer/testnet/tx/${txHash}`} target="_blank" rel="noopener noreferrer" - aria-label={`View transaction ${txHash.slice( - 0, - 8, - )}… on Stellar Explorer (opens in new tab)`} + aria-label={`View transaction ${txHash.slice(0, 8)}… on Stellar Explorer (opens in new tab)`} className="text-xs text-blue-600 hover:text-blue-700 dark:text-blue-400 hover:underline flex items-center gap-1" > diff --git a/frontend/src/app/components/ui/Toaster.tsx b/frontend/src/app/components/ui/Toaster.tsx index 52e9f45b..adeab47d 100644 --- a/frontend/src/app/components/ui/Toaster.tsx +++ b/frontend/src/app/components/ui/Toaster.tsx @@ -57,9 +57,7 @@ function ToastCard({ toast }: { toast: ToastItem }) { animate={{ opacity: 1, x: 0, scale: 1 }} exit={{ opacity: 0, x: 20, scale: 0.96 }} transition={{ duration: 0.2, ease: "easeOut" }} - className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles( - toast.type, - )}`} + className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles(toast.type)}`} role="alert" >
diff --git a/frontend/src/app/hooks/useApi.ts b/frontend/src/app/hooks/useApi.ts index 87ca8038..5f7509f0 100644 --- a/frontend/src/app/hooks/useApi.ts +++ b/frontend/src/app/hooks/useApi.ts @@ -797,8 +797,8 @@ export function useLiquidatableLoans( const loans = Array.isArray(response) ? response : "loans" in response - ? response.loans - : response.data; + ? response.loans + : response.data; const fallbackSource = Array.isArray(response) ? undefined : response.source; return loans.map((loan) => @@ -1493,8 +1493,8 @@ export function useAdminDisputes( const disputes = Array.isArray(response) ? response : "disputes" in response - ? response.disputes - : response.data; + ? response.disputes + : response.data; return disputes.map(normalizeDispute); }, diff --git a/frontend/src/app/utils/transactionFormatter.ts b/frontend/src/app/utils/transactionFormatter.ts index 9aa8fe34..84a9898d 100644 --- a/frontend/src/app/utils/transactionFormatter.ts +++ b/frontend/src/app/utils/transactionFormatter.ts @@ -186,10 +186,7 @@ export function formatRemittanceSend(params: { const operations: TransactionOperation[] = [ { type: "Send Remittance", - description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice( - 0, - 8, - )}...${params.recipient.slice(-6)}`, + description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice(0, 8)}...${params.recipient.slice(-6)}`, amount: params.amount.toString(), token: params.token, details: { From 33387bb5a13729e6cacb8d26e38a9a3cbb9bfff2 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 03:11:50 +0100 Subject: [PATCH 6/9] style(frontend): format all frontend files with Prettier LF line endings --- frontend/lib/money/format.ts | 2 +- frontend/src/app/[locale]/activity/page.tsx | 33 ++++++----- .../src/app/[locale]/lend/LendPageClient.tsx | 24 ++++---- .../app/[locale]/loans/LoansPageClient.tsx | 4 +- .../loans/[loanId]/LoanDetailsPageClient.tsx | 32 +++++------ frontend/src/app/[locale]/page.tsx | 4 +- frontend/src/app/[locale]/settings/page.tsx | 4 +- frontend/src/app/[locale]/wallet/page.tsx | 8 +-- .../borrower/ActiveLoansTracker.tsx | 4 +- .../src/app/components/borrower/LoanCard.tsx | 56 ++++++++++--------- .../FinancialPerformanceDashboard.tsx | 18 ++++-- .../src/app/components/global_ui/Header.tsx | 8 +-- .../loan-wizard/StepAmountAsset.tsx | 4 +- .../components/loan-wizard/WizardStepper.tsx | 4 +- .../src/app/components/loan/LoanHealth.tsx | 8 +-- .../components/providers/WalletProvider.tsx | 6 +- frontend/src/app/components/ui.tsx | 2 +- .../app/components/ui/OperationProgress.tsx | 5 +- frontend/src/app/components/ui/Toaster.tsx | 4 +- frontend/src/app/hooks/useApi.ts | 8 +-- .../src/app/utils/transactionFormatter.ts | 5 +- 21 files changed, 132 insertions(+), 111 deletions(-) diff --git a/frontend/lib/money/format.ts b/frontend/lib/money/format.ts index 24a6594a..c1c57f34 100644 --- a/frontend/lib/money/format.ts +++ b/frontend/lib/money/format.ts @@ -150,7 +150,7 @@ export function formatStroops(value: bigint, opts: FormatStroopsOptions = {}): s const fraction = scaledMagnitude % scale; const wholeStr = - (opts.grouped ?? false) ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); + opts.grouped ?? false ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); const sign = negative && scaledMagnitude !== ZERO ? "-" : ""; diff --git a/frontend/src/app/[locale]/activity/page.tsx b/frontend/src/app/[locale]/activity/page.tsx index 626f16e9..07507ada 100644 --- a/frontend/src/app/[locale]/activity/page.tsx +++ b/frontend/src/app/[locale]/activity/page.tsx @@ -64,16 +64,16 @@ export default function ActivityPage() { (loan as { latestEventType?: string }).latestEventType === "LoanExtended" ? "Loan Extended" : (loan as { latestEventType?: string }).latestEventType === "LoanRefinanced" - ? "Loan Refinanced" - : loan.status === "repaid" - ? "Loan Repaid" - : loan.status === "liquidated" - ? "Loan Liquidated" - : loan.status === "defaulted" - ? "Loan Defaulted" - : loan.status === "active" - ? "Loan Active" - : "Loan Request", + ? "Loan Refinanced" + : loan.status === "repaid" + ? "Loan Repaid" + : loan.status === "liquidated" + ? "Loan Liquidated" + : loan.status === "defaulted" + ? "Loan Defaulted" + : loan.status === "active" + ? "Loan Active" + : "Loan Request", description: `Loan #${loan.id} — ${loan.currency}`, amount: `${loan.status === "repaid" ? "+" : "-"}${formatCurrency(loan.amount)}`, timestamp: new Date(loan.createdAt).toISOString(), @@ -84,7 +84,10 @@ export default function ActivityPage() { const remittanceEvents: ActivityItem[] = remittances.map((remittance) => ({ id: `remittance-${remittance.id}`, type: "Remittance", - description: `To ${remittance.recipientAddress.slice(0, 6)}...${remittance.recipientAddress.slice(-4)}`, + description: `To ${remittance.recipientAddress.slice( + 0, + 6, + )}...${remittance.recipientAddress.slice(-4)}`, amount: `-${formatCurrency(remittance.amount)}`, timestamp: new Date(remittance.createdAt).toISOString(), status: remittance.status, @@ -226,10 +229,10 @@ export default function ActivityPage() { item.status === "completed" || item.status === "repaid" ? "bg-green-50 dark:bg-green-500/10" : item.status === "failed" || - item.status === "defaulted" || - item.status === "liquidated" - ? "bg-red-50 dark:bg-red-500/10" - : "bg-indigo-50 dark:bg-indigo-500/10" + item.status === "defaulted" || + item.status === "liquidated" + ? "bg-red-50 dark:bg-red-500/10" + : "bg-indigo-50 dark:bg-indigo-500/10" }`} aria-hidden="true" > diff --git a/frontend/src/app/[locale]/lend/LendPageClient.tsx b/frontend/src/app/[locale]/lend/LendPageClient.tsx index 455492d5..825b05dd 100644 --- a/frontend/src/app/[locale]/lend/LendPageClient.tsx +++ b/frontend/src/app/[locale]/lend/LendPageClient.tsx @@ -195,19 +195,19 @@ export function LendPageClient() { sseStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : sseStatus === "connecting" - ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" - : sseStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" + ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" + : sseStatus === "polling" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" }`} title={ sseStatus === "connected" ? "Live pool updates connected" : sseStatus === "connecting" - ? "Connecting to live updates…" - : sseStatus === "polling" - ? "Live updates dropped — polling while reconnecting" - : "Live updates disconnected — retrying" + ? "Connecting to live updates…" + : sseStatus === "polling" + ? "Live updates dropped — polling while reconnecting" + : "Live updates disconnected — retrying" } > {sseStatus === "connected" ? ( @@ -218,10 +218,10 @@ export function LendPageClient() { {sseStatus === "connected" ? "Live" : sseStatus === "connecting" - ? "Connecting…" - : sseStatus === "polling" - ? "Reconnecting…" - : "Offline"} + ? "Connecting…" + : sseStatus === "polling" + ? "Reconnecting…" + : "Offline"}
)}
diff --git a/frontend/src/app/[locale]/loans/LoansPageClient.tsx b/frontend/src/app/[locale]/loans/LoansPageClient.tsx index 4d18346c..bd902f40 100644 --- a/frontend/src/app/[locale]/loans/LoansPageClient.tsx +++ b/frontend/src/app/[locale]/loans/LoansPageClient.tsx @@ -71,8 +71,8 @@ export function LoansPageClient() { overdueCount === 0 ? t("health.strong") : overdueCount <= 2 - ? t("health.watch") - : t("health.atRisk"); + ? t("health.watch") + : t("health.atRisk"); if (isLoading) { return ; diff --git a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx index ee8cf095..57b43e9e 100644 --- a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx +++ b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx @@ -142,10 +142,10 @@ export function LoanDetailsPageClient() { realtimeStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : realtimeStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : realtimeStatus === "disconnected" - ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" - : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : realtimeStatus === "disconnected" + ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" + : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" }`} > {realtimeStatus === "connected" ? ( @@ -156,10 +156,10 @@ export function LoanDetailsPageClient() { {realtimeStatus === "connected" ? "Live loan updates" : realtimeStatus === "polling" - ? "Polling while reconnecting" - : realtimeStatus === "disconnected" - ? "Realtime temporarily unavailable" - : "Connecting to live updates"} + ? "Polling while reconnecting" + : realtimeStatus === "disconnected" + ? "Realtime temporarily unavailable" + : "Connecting to live updates"} diff --git a/frontend/src/app/[locale]/wallet/page.tsx b/frontend/src/app/[locale]/wallet/page.tsx index f6386772..12176a4e 100644 --- a/frontend/src/app/[locale]/wallet/page.tsx +++ b/frontend/src/app/[locale]/wallet/page.tsx @@ -123,7 +123,7 @@ function useHorizonPayments(address: string, horizonUrl: string, cursor: string return { records, nextCursor: - records.length === TRANSACTIONS_PER_PAGE ? (lastRecord?.paging_token ?? null) : null, + records.length === TRANSACTIONS_PER_PAGE ? lastRecord?.paging_token ?? null : null, }; }, staleTime: 30_000, @@ -190,7 +190,7 @@ function BalancesCard({ address, horizonUrl }: { address: string; horizonUrl: st } = useHorizonBalances(address, horizonUrl); function assetLabel(b: HorizonBalance): string { - return b.asset_type === "native" ? "XLM" : (b.asset_code ?? "Unknown"); + return b.asset_type === "native" ? "XLM" : b.asset_code ?? "Unknown"; } function formatBalance(b: HorizonBalance): string { @@ -314,14 +314,14 @@ function TransactionHistoryCard({ function paymentAmount(p: HorizonPayment): string { if (!p.amount) return "—"; - const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); + const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; return `${parseFloat(p.amount).toLocaleString("en-US", { maximumFractionDigits: 7 })} ${asset}`; } function exportCsv() { const today = new Date().toISOString().split("T")[0]; const rows = payments.map((p) => { - const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); + const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; return { date: p.created_at, type: paymentLabel(p), diff --git a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx index f9c96dd3..70a99910 100644 --- a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx +++ b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx @@ -38,8 +38,8 @@ export function ActiveLoansTracker({ borrowerAddress }: { borrowerAddress: strin filter === "overdue" ? loans.filter((l) => l.status === "active" && new Date(l.nextPaymentDeadline) < now) : filter === "active" - ? loans.filter((l) => l.status === "active") - : loans; + ? loans.filter((l) => l.status === "active") + : loans; const tabCounts: Record = { active: loans.filter((l) => l.status === "active").length, diff --git a/frontend/src/app/components/borrower/LoanCard.tsx b/frontend/src/app/components/borrower/LoanCard.tsx index f92ec65d..d991470e 100644 --- a/frontend/src/app/components/borrower/LoanCard.tsx +++ b/frontend/src/app/components/borrower/LoanCard.tsx @@ -34,19 +34,19 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { label: isLiquidated ? "Liquidated" : isDefaulted - ? "Defaulted" - : isOverdue - ? "Overdue" - : isUrgent - ? "Due Soon" - : "On Track", + ? "Defaulted" + : isOverdue + ? "Overdue" + : isUrgent + ? "Due Soon" + : "On Track", className: isTerminalDistressed ? "bg-red-900 text-white" : isOverdue - ? "bg-red-100 text-red-800" - : isUrgent - ? "bg-yellow-100 text-yellow-800" - : "bg-green-100 text-green-800", + ? "bg-red-100 text-red-800" + : isUrgent + ? "bg-yellow-100 text-yellow-800" + : "bg-green-100 text-green-800", } : null; @@ -54,31 +54,31 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { const deadlineBg = isTerminalDistressed ? "bg-red-900/20" : isOverdue - ? "bg-red-50" - : isUrgent - ? "bg-yellow-50" - : "bg-gray-50"; + ? "bg-red-50" + : isUrgent + ? "bg-yellow-50" + : "bg-gray-50"; const deadlineTextColor = isTerminalDistressed ? "text-red-900" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-900"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-900"; const deadlineSubColor = isTerminalDistressed ? "text-red-700" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-600"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-600"; const deadlineLabel = isLiquidated ? "Collateral was liquidated" : isDefaulted - ? "Contact support to recover" - : isOverdue - ? `${Math.abs(daysUntil)} days overdue` - : `${daysUntil} days remaining`; + ? "Contact support to recover" + : isOverdue + ? `${Math.abs(daysUntil)} days overdue` + : `${daysUntil} days remaining`; // ── Progress (detailed only) ─────────────────────────────────────────────── const totalForProgress = loan.principal + loan.accruedInterest; @@ -150,7 +150,9 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) {

Next Payment

{formatDate(loan.nextPaymentDeadline)}

diff --git a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx index c6862d79..aa074e43 100644 --- a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx +++ b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx @@ -215,8 +215,8 @@ export function FinancialPerformanceDashboard({ // ── Derived display data ── const displayCreditScoreData = useMockData ? generateMockCreditScoreData() - : (creditScoreData ?? []); - const displayYieldData = useMockData ? generateMockYieldData() : (yieldData ?? []); + : creditScoreData ?? []; + const displayYieldData = useMockData ? generateMockYieldData() : yieldData ?? []; const displayLoanStats = useMemo(() => { if (useMockData) return generateMockLoanStats(); @@ -302,8 +302,8 @@ export function FinancialPerformanceDashboard({ {userType === "both" ? "credit score and yield" : userType === "borrower" - ? "credit score" - : "yield"}{" "} + ? "credit score" + : "yield"}{" "} performance over time

@@ -354,7 +354,9 @@ export function FinancialPerformanceDashboard({ @@ -417,7 +419,11 @@ export function FinancialPerformanceDashboard({ value={fmt(displayDepositorStats.currentValue)} sub={ displayDepositorStats.depositAmount > 0 - ? `+${(((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / displayDepositorStats.depositAmount) * 100).toFixed(2)}% growth` + ? `+${( + ((displayDepositorStats.currentValue - displayDepositorStats.depositAmount) / + displayDepositorStats.depositAmount) * + 100 + ).toFixed(2)}% growth` : undefined } colorClass="bg-blue-50 text-blue-900 dark:bg-blue-950/30 dark:text-blue-200" diff --git a/frontend/src/app/components/global_ui/Header.tsx b/frontend/src/app/components/global_ui/Header.tsx index 3b8fa256..7ebb5343 100644 --- a/frontend/src/app/components/global_ui/Header.tsx +++ b/frontend/src/app/components/global_ui/Header.tsx @@ -239,10 +239,10 @@ export function Header({ onMenuClick, className }: HeaderProps) { const profileLabel = user?.email ? user.email : user?.walletAddress - ? truncateWalletAddress(user.walletAddress) - : walletAddress - ? truncateWalletAddress(walletAddress) - : "Connect Wallet"; + ? truncateWalletAddress(user.walletAddress) + : walletAddress + ? truncateWalletAddress(walletAddress) + : "Connect Wallet"; return (
diff --git a/frontend/src/app/components/loan-wizard/WizardStepper.tsx b/frontend/src/app/components/loan-wizard/WizardStepper.tsx index f92c3ff3..85b9d311 100644 --- a/frontend/src/app/components/loan-wizard/WizardStepper.tsx +++ b/frontend/src/app/components/loan-wizard/WizardStepper.tsx @@ -98,8 +98,8 @@ export function WizardStepper({ steps, currentStep, onStepSelect }: WizardSteppe isCurrent ? "text-indigo-600 dark:text-indigo-400" : isCompleted - ? "text-zinc-700 dark:text-zinc-300" - : "text-zinc-400 dark:text-zinc-500", + ? "text-zinc-700 dark:text-zinc-300" + : "text-zinc-400 dark:text-zinc-500", )} > {step.label} diff --git a/frontend/src/app/components/loan/LoanHealth.tsx b/frontend/src/app/components/loan/LoanHealth.tsx index 3fd1c821..430c1f61 100644 --- a/frontend/src/app/components/loan/LoanHealth.tsx +++ b/frontend/src/app/components/loan/LoanHealth.tsx @@ -99,16 +99,16 @@ export function LoanHealth({ loan, isLoading, isError, topUpHref, labels }: Loan state === "atRisk" ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200" : state === "watch" - ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" - : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; + ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" + : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; const barTone = state === "atRisk" ? "bg-red-500" : state === "watch" ? "bg-amber-500" : "bg-emerald-500"; const source = loan?.healthSource === "contract" ? labels.sourceContract : loan?.healthSource === "backend" || backendRatio || backendHealthFactor - ? labels.sourceBackend - : labels.sourceDerived; + ? labels.sourceBackend + : labels.sourceDerived; const barWidth = `${Math.min(100, Math.max(6, (ratio / (threshold + 0.5)) * 100))}%`; return ( diff --git a/frontend/src/app/components/providers/WalletProvider.tsx b/frontend/src/app/components/providers/WalletProvider.tsx index 9eeb192b..1a4536bd 100644 --- a/frontend/src/app/components/providers/WalletProvider.tsx +++ b/frontend/src/app/components/providers/WalletProvider.tsx @@ -98,7 +98,7 @@ function getFallbackHorizonUrl(networkName: string | undefined): string { function mapBalances(balances: HorizonBalance[] | undefined): TokenBalance[] { return (balances ?? []).map((balance) => ({ - symbol: balance.asset_type === "native" ? "XLM" : (balance.asset_code ?? "ASSET"), + symbol: balance.asset_type === "native" ? "XLM" : balance.asset_code ?? "ASSET", amount: balance.balance, usdValue: null, })); @@ -181,8 +181,8 @@ export function WalletProvider({ children }: WalletProviderProps) { const networkResult: FreighterNetworkResult = api.getNetworkDetails ? await api.getNetworkDetails() : api.getNetwork - ? await api.getNetwork() - : { error: "Network info not available." }; + ? await api.getNetwork() + : { error: "Network info not available." }; if (networkResult.error) { throw new Error(normalizeWalletError(networkResult.error)); diff --git a/frontend/src/app/components/ui.tsx b/frontend/src/app/components/ui.tsx index 489fdddd..540c805b 100644 --- a/frontend/src/app/components/ui.tsx +++ b/frontend/src/app/components/ui.tsx @@ -1 +1 @@ -export { COPY_FEEDBACK_RESET_MS } from './ui/CopyButton'; +export { COPY_FEEDBACK_RESET_MS } from "./ui/CopyButton"; diff --git a/frontend/src/app/components/ui/OperationProgress.tsx b/frontend/src/app/components/ui/OperationProgress.tsx index 2df7d230..09eb4dca 100644 --- a/frontend/src/app/components/ui/OperationProgress.tsx +++ b/frontend/src/app/components/ui/OperationProgress.tsx @@ -88,7 +88,10 @@ export function OperationProgress({ transaction, type = "generic" }: OperationPr href={`https://stellar.expert/explorer/testnet/tx/${txHash}`} target="_blank" rel="noopener noreferrer" - aria-label={`View transaction ${txHash.slice(0, 8)}… on Stellar Explorer (opens in new tab)`} + aria-label={`View transaction ${txHash.slice( + 0, + 8, + )}… on Stellar Explorer (opens in new tab)`} className="text-xs text-blue-600 hover:text-blue-700 dark:text-blue-400 hover:underline flex items-center gap-1" > diff --git a/frontend/src/app/components/ui/Toaster.tsx b/frontend/src/app/components/ui/Toaster.tsx index adeab47d..52e9f45b 100644 --- a/frontend/src/app/components/ui/Toaster.tsx +++ b/frontend/src/app/components/ui/Toaster.tsx @@ -57,7 +57,9 @@ function ToastCard({ toast }: { toast: ToastItem }) { animate={{ opacity: 1, x: 0, scale: 1 }} exit={{ opacity: 0, x: 20, scale: 0.96 }} transition={{ duration: 0.2, ease: "easeOut" }} - className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles(toast.type)}`} + className={`w-full rounded-xl border p-4 shadow-lg shadow-zinc-900/5 ${getToastStyles( + toast.type, + )}`} role="alert" >
diff --git a/frontend/src/app/hooks/useApi.ts b/frontend/src/app/hooks/useApi.ts index 5f7509f0..87ca8038 100644 --- a/frontend/src/app/hooks/useApi.ts +++ b/frontend/src/app/hooks/useApi.ts @@ -797,8 +797,8 @@ export function useLiquidatableLoans( const loans = Array.isArray(response) ? response : "loans" in response - ? response.loans - : response.data; + ? response.loans + : response.data; const fallbackSource = Array.isArray(response) ? undefined : response.source; return loans.map((loan) => @@ -1493,8 +1493,8 @@ export function useAdminDisputes( const disputes = Array.isArray(response) ? response : "disputes" in response - ? response.disputes - : response.data; + ? response.disputes + : response.data; return disputes.map(normalizeDispute); }, diff --git a/frontend/src/app/utils/transactionFormatter.ts b/frontend/src/app/utils/transactionFormatter.ts index 84a9898d..9aa8fe34 100644 --- a/frontend/src/app/utils/transactionFormatter.ts +++ b/frontend/src/app/utils/transactionFormatter.ts @@ -186,7 +186,10 @@ export function formatRemittanceSend(params: { const operations: TransactionOperation[] = [ { type: "Send Remittance", - description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice(0, 8)}...${params.recipient.slice(-6)}`, + description: `You are sending ${params.amount} ${params.token} to ${params.recipient.slice( + 0, + 8, + )}...${params.recipient.slice(-6)}`, amount: params.amount.toString(), token: params.token, details: { From 4896283f3476d888c9ab5632dcbb8380efb7b694 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 03:34:55 +0100 Subject: [PATCH 7/9] build(frontend): update frontend package-lock.json --- frontend/package-lock.json | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f12306c6..26e69e1c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11965,7 +11965,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, From 2f42e9651a9a287006927da66316ab6d6b2f1f60 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 03:35:43 +0100 Subject: [PATCH 8/9] style(frontend): format 16 frontend files with local Prettier 3 --- frontend/lib/money/format.ts | 2 +- frontend/src/app/[locale]/activity/page.tsx | 28 +++++----- .../src/app/[locale]/lend/LendPageClient.tsx | 24 ++++----- .../app/[locale]/loans/LoansPageClient.tsx | 4 +- .../loans/[loanId]/LoanDetailsPageClient.tsx | 32 ++++++------ frontend/src/app/[locale]/page.tsx | 4 +- frontend/src/app/[locale]/settings/page.tsx | 4 +- frontend/src/app/[locale]/wallet/page.tsx | 8 +-- .../borrower/ActiveLoansTracker.tsx | 4 +- .../src/app/components/borrower/LoanCard.tsx | 52 +++++++++---------- .../FinancialPerformanceDashboard.tsx | 8 +-- .../src/app/components/global_ui/Header.tsx | 8 +-- .../components/loan-wizard/WizardStepper.tsx | 4 +- .../src/app/components/loan/LoanHealth.tsx | 8 +-- .../components/providers/WalletProvider.tsx | 6 +-- frontend/src/app/hooks/useApi.ts | 8 +-- 16 files changed, 102 insertions(+), 102 deletions(-) diff --git a/frontend/lib/money/format.ts b/frontend/lib/money/format.ts index c1c57f34..24a6594a 100644 --- a/frontend/lib/money/format.ts +++ b/frontend/lib/money/format.ts @@ -150,7 +150,7 @@ export function formatStroops(value: bigint, opts: FormatStroopsOptions = {}): s const fraction = scaledMagnitude % scale; const wholeStr = - opts.grouped ?? false ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); + (opts.grouped ?? false) ? whole.toLocaleString(opts.locale ?? "en-US") : whole.toString(); const sign = negative && scaledMagnitude !== ZERO ? "-" : ""; diff --git a/frontend/src/app/[locale]/activity/page.tsx b/frontend/src/app/[locale]/activity/page.tsx index 07507ada..cbf2deaf 100644 --- a/frontend/src/app/[locale]/activity/page.tsx +++ b/frontend/src/app/[locale]/activity/page.tsx @@ -64,16 +64,16 @@ export default function ActivityPage() { (loan as { latestEventType?: string }).latestEventType === "LoanExtended" ? "Loan Extended" : (loan as { latestEventType?: string }).latestEventType === "LoanRefinanced" - ? "Loan Refinanced" - : loan.status === "repaid" - ? "Loan Repaid" - : loan.status === "liquidated" - ? "Loan Liquidated" - : loan.status === "defaulted" - ? "Loan Defaulted" - : loan.status === "active" - ? "Loan Active" - : "Loan Request", + ? "Loan Refinanced" + : loan.status === "repaid" + ? "Loan Repaid" + : loan.status === "liquidated" + ? "Loan Liquidated" + : loan.status === "defaulted" + ? "Loan Defaulted" + : loan.status === "active" + ? "Loan Active" + : "Loan Request", description: `Loan #${loan.id} — ${loan.currency}`, amount: `${loan.status === "repaid" ? "+" : "-"}${formatCurrency(loan.amount)}`, timestamp: new Date(loan.createdAt).toISOString(), @@ -229,10 +229,10 @@ export default function ActivityPage() { item.status === "completed" || item.status === "repaid" ? "bg-green-50 dark:bg-green-500/10" : item.status === "failed" || - item.status === "defaulted" || - item.status === "liquidated" - ? "bg-red-50 dark:bg-red-500/10" - : "bg-indigo-50 dark:bg-indigo-500/10" + item.status === "defaulted" || + item.status === "liquidated" + ? "bg-red-50 dark:bg-red-500/10" + : "bg-indigo-50 dark:bg-indigo-500/10" }`} aria-hidden="true" > diff --git a/frontend/src/app/[locale]/lend/LendPageClient.tsx b/frontend/src/app/[locale]/lend/LendPageClient.tsx index 825b05dd..455492d5 100644 --- a/frontend/src/app/[locale]/lend/LendPageClient.tsx +++ b/frontend/src/app/[locale]/lend/LendPageClient.tsx @@ -195,19 +195,19 @@ export function LendPageClient() { sseStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : sseStatus === "connecting" - ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" - : sseStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" + ? "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400" + : sseStatus === "polling" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : "bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400" }`} title={ sseStatus === "connected" ? "Live pool updates connected" : sseStatus === "connecting" - ? "Connecting to live updates…" - : sseStatus === "polling" - ? "Live updates dropped — polling while reconnecting" - : "Live updates disconnected — retrying" + ? "Connecting to live updates…" + : sseStatus === "polling" + ? "Live updates dropped — polling while reconnecting" + : "Live updates disconnected — retrying" } > {sseStatus === "connected" ? ( @@ -218,10 +218,10 @@ export function LendPageClient() { {sseStatus === "connected" ? "Live" : sseStatus === "connecting" - ? "Connecting…" - : sseStatus === "polling" - ? "Reconnecting…" - : "Offline"} + ? "Connecting…" + : sseStatus === "polling" + ? "Reconnecting…" + : "Offline"}
)}
diff --git a/frontend/src/app/[locale]/loans/LoansPageClient.tsx b/frontend/src/app/[locale]/loans/LoansPageClient.tsx index bd902f40..4d18346c 100644 --- a/frontend/src/app/[locale]/loans/LoansPageClient.tsx +++ b/frontend/src/app/[locale]/loans/LoansPageClient.tsx @@ -71,8 +71,8 @@ export function LoansPageClient() { overdueCount === 0 ? t("health.strong") : overdueCount <= 2 - ? t("health.watch") - : t("health.atRisk"); + ? t("health.watch") + : t("health.atRisk"); if (isLoading) { return ; diff --git a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx index 57b43e9e..ee8cf095 100644 --- a/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx +++ b/frontend/src/app/[locale]/loans/[loanId]/LoanDetailsPageClient.tsx @@ -142,10 +142,10 @@ export function LoanDetailsPageClient() { realtimeStatus === "connected" ? "bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400" : realtimeStatus === "polling" - ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" - : realtimeStatus === "disconnected" - ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" - : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" + ? "bg-amber-50 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" + : realtimeStatus === "disconnected" + ? "bg-red-50 text-red-700 dark:bg-red-500/10 dark:text-red-300" + : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300" }`} > {realtimeStatus === "connected" ? ( @@ -156,10 +156,10 @@ export function LoanDetailsPageClient() { {realtimeStatus === "connected" ? "Live loan updates" : realtimeStatus === "polling" - ? "Polling while reconnecting" - : realtimeStatus === "disconnected" - ? "Realtime temporarily unavailable" - : "Connecting to live updates"} + ? "Polling while reconnecting" + : realtimeStatus === "disconnected" + ? "Realtime temporarily unavailable" + : "Connecting to live updates"} diff --git a/frontend/src/app/[locale]/wallet/page.tsx b/frontend/src/app/[locale]/wallet/page.tsx index 12176a4e..f6386772 100644 --- a/frontend/src/app/[locale]/wallet/page.tsx +++ b/frontend/src/app/[locale]/wallet/page.tsx @@ -123,7 +123,7 @@ function useHorizonPayments(address: string, horizonUrl: string, cursor: string return { records, nextCursor: - records.length === TRANSACTIONS_PER_PAGE ? lastRecord?.paging_token ?? null : null, + records.length === TRANSACTIONS_PER_PAGE ? (lastRecord?.paging_token ?? null) : null, }; }, staleTime: 30_000, @@ -190,7 +190,7 @@ function BalancesCard({ address, horizonUrl }: { address: string; horizonUrl: st } = useHorizonBalances(address, horizonUrl); function assetLabel(b: HorizonBalance): string { - return b.asset_type === "native" ? "XLM" : b.asset_code ?? "Unknown"; + return b.asset_type === "native" ? "XLM" : (b.asset_code ?? "Unknown"); } function formatBalance(b: HorizonBalance): string { @@ -314,14 +314,14 @@ function TransactionHistoryCard({ function paymentAmount(p: HorizonPayment): string { if (!p.amount) return "—"; - const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; + const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); return `${parseFloat(p.amount).toLocaleString("en-US", { maximumFractionDigits: 7 })} ${asset}`; } function exportCsv() { const today = new Date().toISOString().split("T")[0]; const rows = payments.map((p) => { - const asset = p.asset_type === "native" ? "XLM" : p.asset_code ?? ""; + const asset = p.asset_type === "native" ? "XLM" : (p.asset_code ?? ""); return { date: p.created_at, type: paymentLabel(p), diff --git a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx index 70a99910..f9c96dd3 100644 --- a/frontend/src/app/components/borrower/ActiveLoansTracker.tsx +++ b/frontend/src/app/components/borrower/ActiveLoansTracker.tsx @@ -38,8 +38,8 @@ export function ActiveLoansTracker({ borrowerAddress }: { borrowerAddress: strin filter === "overdue" ? loans.filter((l) => l.status === "active" && new Date(l.nextPaymentDeadline) < now) : filter === "active" - ? loans.filter((l) => l.status === "active") - : loans; + ? loans.filter((l) => l.status === "active") + : loans; const tabCounts: Record = { active: loans.filter((l) => l.status === "active").length, diff --git a/frontend/src/app/components/borrower/LoanCard.tsx b/frontend/src/app/components/borrower/LoanCard.tsx index d991470e..4e172b46 100644 --- a/frontend/src/app/components/borrower/LoanCard.tsx +++ b/frontend/src/app/components/borrower/LoanCard.tsx @@ -34,19 +34,19 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { label: isLiquidated ? "Liquidated" : isDefaulted - ? "Defaulted" - : isOverdue - ? "Overdue" - : isUrgent - ? "Due Soon" - : "On Track", + ? "Defaulted" + : isOverdue + ? "Overdue" + : isUrgent + ? "Due Soon" + : "On Track", className: isTerminalDistressed ? "bg-red-900 text-white" : isOverdue - ? "bg-red-100 text-red-800" - : isUrgent - ? "bg-yellow-100 text-yellow-800" - : "bg-green-100 text-green-800", + ? "bg-red-100 text-red-800" + : isUrgent + ? "bg-yellow-100 text-yellow-800" + : "bg-green-100 text-green-800", } : null; @@ -54,31 +54,31 @@ export function LoanCard({ loan, variant = "compact" }: LoanCardProps) { const deadlineBg = isTerminalDistressed ? "bg-red-900/20" : isOverdue - ? "bg-red-50" - : isUrgent - ? "bg-yellow-50" - : "bg-gray-50"; + ? "bg-red-50" + : isUrgent + ? "bg-yellow-50" + : "bg-gray-50"; const deadlineTextColor = isTerminalDistressed ? "text-red-900" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-900"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-900"; const deadlineSubColor = isTerminalDistressed ? "text-red-700" : isOverdue - ? "text-red-600" - : isUrgent - ? "text-yellow-600" - : "text-gray-600"; + ? "text-red-600" + : isUrgent + ? "text-yellow-600" + : "text-gray-600"; const deadlineLabel = isLiquidated ? "Collateral was liquidated" : isDefaulted - ? "Contact support to recover" - : isOverdue - ? `${Math.abs(daysUntil)} days overdue` - : `${daysUntil} days remaining`; + ? "Contact support to recover" + : isOverdue + ? `${Math.abs(daysUntil)} days overdue` + : `${daysUntil} days remaining`; // ── Progress (detailed only) ─────────────────────────────────────────────── const totalForProgress = loan.principal + loan.accruedInterest; diff --git a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx index aa074e43..c25a1368 100644 --- a/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx +++ b/frontend/src/app/components/dashboards/FinancialPerformanceDashboard.tsx @@ -215,8 +215,8 @@ export function FinancialPerformanceDashboard({ // ── Derived display data ── const displayCreditScoreData = useMockData ? generateMockCreditScoreData() - : creditScoreData ?? []; - const displayYieldData = useMockData ? generateMockYieldData() : yieldData ?? []; + : (creditScoreData ?? []); + const displayYieldData = useMockData ? generateMockYieldData() : (yieldData ?? []); const displayLoanStats = useMemo(() => { if (useMockData) return generateMockLoanStats(); @@ -302,8 +302,8 @@ export function FinancialPerformanceDashboard({ {userType === "both" ? "credit score and yield" : userType === "borrower" - ? "credit score" - : "yield"}{" "} + ? "credit score" + : "yield"}{" "} performance over time

diff --git a/frontend/src/app/components/global_ui/Header.tsx b/frontend/src/app/components/global_ui/Header.tsx index 7ebb5343..3b8fa256 100644 --- a/frontend/src/app/components/global_ui/Header.tsx +++ b/frontend/src/app/components/global_ui/Header.tsx @@ -239,10 +239,10 @@ export function Header({ onMenuClick, className }: HeaderProps) { const profileLabel = user?.email ? user.email : user?.walletAddress - ? truncateWalletAddress(user.walletAddress) - : walletAddress - ? truncateWalletAddress(walletAddress) - : "Connect Wallet"; + ? truncateWalletAddress(user.walletAddress) + : walletAddress + ? truncateWalletAddress(walletAddress) + : "Connect Wallet"; return (
{step.label} diff --git a/frontend/src/app/components/loan/LoanHealth.tsx b/frontend/src/app/components/loan/LoanHealth.tsx index 430c1f61..3fd1c821 100644 --- a/frontend/src/app/components/loan/LoanHealth.tsx +++ b/frontend/src/app/components/loan/LoanHealth.tsx @@ -99,16 +99,16 @@ export function LoanHealth({ loan, isLoading, isError, topUpHref, labels }: Loan state === "atRisk" ? "border-red-200 bg-red-50 text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200" : state === "watch" - ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" - : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; + ? "border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200" + : "border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200"; const barTone = state === "atRisk" ? "bg-red-500" : state === "watch" ? "bg-amber-500" : "bg-emerald-500"; const source = loan?.healthSource === "contract" ? labels.sourceContract : loan?.healthSource === "backend" || backendRatio || backendHealthFactor - ? labels.sourceBackend - : labels.sourceDerived; + ? labels.sourceBackend + : labels.sourceDerived; const barWidth = `${Math.min(100, Math.max(6, (ratio / (threshold + 0.5)) * 100))}%`; return ( diff --git a/frontend/src/app/components/providers/WalletProvider.tsx b/frontend/src/app/components/providers/WalletProvider.tsx index 1a4536bd..9eeb192b 100644 --- a/frontend/src/app/components/providers/WalletProvider.tsx +++ b/frontend/src/app/components/providers/WalletProvider.tsx @@ -98,7 +98,7 @@ function getFallbackHorizonUrl(networkName: string | undefined): string { function mapBalances(balances: HorizonBalance[] | undefined): TokenBalance[] { return (balances ?? []).map((balance) => ({ - symbol: balance.asset_type === "native" ? "XLM" : balance.asset_code ?? "ASSET", + symbol: balance.asset_type === "native" ? "XLM" : (balance.asset_code ?? "ASSET"), amount: balance.balance, usdValue: null, })); @@ -181,8 +181,8 @@ export function WalletProvider({ children }: WalletProviderProps) { const networkResult: FreighterNetworkResult = api.getNetworkDetails ? await api.getNetworkDetails() : api.getNetwork - ? await api.getNetwork() - : { error: "Network info not available." }; + ? await api.getNetwork() + : { error: "Network info not available." }; if (networkResult.error) { throw new Error(normalizeWalletError(networkResult.error)); diff --git a/frontend/src/app/hooks/useApi.ts b/frontend/src/app/hooks/useApi.ts index 87ca8038..5f7509f0 100644 --- a/frontend/src/app/hooks/useApi.ts +++ b/frontend/src/app/hooks/useApi.ts @@ -797,8 +797,8 @@ export function useLiquidatableLoans( const loans = Array.isArray(response) ? response : "loans" in response - ? response.loans - : response.data; + ? response.loans + : response.data; const fallbackSource = Array.isArray(response) ? undefined : response.source; return loans.map((loan) => @@ -1493,8 +1493,8 @@ export function useAdminDisputes( const disputes = Array.isArray(response) ? response : "disputes" in response - ? response.disputes - : response.data; + ? response.disputes + : response.data; return disputes.map(normalizeDispute); }, From f0fb129acbb1caa5b147faa9e1f38a380159bf51 Mon Sep 17 00:00:00 2001 From: Ogunmodede Joel Taiwo Date: Mon, 10 Aug 2026 03:39:53 +0100 Subject: [PATCH 9/9] fix(frontend): resolve promise initialization in useReveal.test.tsx --- frontend/src/app/hooks/useReveal.test.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/hooks/useReveal.test.tsx b/frontend/src/app/hooks/useReveal.test.tsx index 3feac3ab..454acc39 100644 --- a/frontend/src/app/hooks/useReveal.test.tsx +++ b/frontend/src/app/hooks/useReveal.test.tsx @@ -125,12 +125,10 @@ describe("useReveal", () => { it("does not expose the value before the request resolves", async () => { let resolveFetch!: (val: unknown) => void; - global.fetch = jest.fn( - () => - new Promise((resolve) => { - resolveFetch = resolve; - }), - ) as unknown as typeof fetch; + const fetchPromise = new Promise((resolve) => { + resolveFetch = resolve; + }); + global.fetch = jest.fn(() => fetchPromise) as unknown as typeof fetch; const { result } = renderHook(() => useReveal(), { wrapper: createWrapper() });