Skip to content

Commit d21f93c

Browse files
authored
Merge pull request #320 from El-swaggerito/main
refactor: enhance code documentation and component consistency
2 parents 0c75283 + 8860064 commit d21f93c

10 files changed

Lines changed: 408 additions & 105 deletions

File tree

src/app/api/pnl/route.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
1+
/**
2+
* Profit and Loss (PnL) API Route.
3+
* Generates synthetic historical performance data for the dashboard charts.
4+
* This is used for demonstrating portfolio tracking features.
5+
*/
6+
17
import { NextResponse } from 'next/server';
28

9+
/**
10+
* Historical data point for the PnL chart.
11+
*/
312
interface PnLData {
13+
/** Localized date string (e.g., "Jan 12") */
414
date: string;
15+
/** The portfolio value at that specific point in time */
516
value: number;
617
}
718

19+
/**
20+
* GET handler for the PnL endpoint.
21+
* Returns a 30-day series of simulated portfolio values.
22+
*/
823
export async function GET() {
9-
// Generate dummy PnL data for the last 30 days
24+
// Generate mock PnL data for the last 30 days
1025
const data: PnLData[] = [];
1126
const today = new Date();
12-
let currentValue = 10000; // Starting value
27+
28+
// Starting seed value for the simulation
29+
let currentValue = 10000;
1330

1431
for (let i = 29; i >= 0; i--) {
1532
const date = new Date(today);
1633
date.setDate(date.getDate() - i);
1734

18-
// Random walk with slight upward trend
35+
// Simulate a random walk with a slight positive bias (0.45 instead of 0.50)
36+
// and a volatility factor of 200
1937
const change = (Math.random() - 0.45) * 200;
2038
currentValue += change;
2139

@@ -25,6 +43,7 @@ export async function GET() {
2543
});
2644
}
2745

46+
// Return the series as a JSON response
2847
return NextResponse.json(data);
2948
}
3049

src/app/api/upload/route.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
1+
/**
2+
* Document Upload API Route.
3+
* Handles the secure uploading of invoice documents to IPFS/Pinata.
4+
* Currently disabled for maintenance or pending further security implementation.
5+
*/
6+
17
import { NextRequest, NextResponse } from 'next/server';
28

9+
/**
10+
* POST handler for the upload endpoint.
11+
* Currently returns a 503 Service Unavailable error as the feature is locked.
12+
*
13+
* @param {NextRequest} request - The incoming upload request.
14+
*/
315
export async function POST(request: NextRequest) {
16+
// 1. Log the attempt for security auditing
17+
const clientIp = request.headers.get('x-forwarded-for') || 'unknown';
18+
console.log(`[UploadAPI] Blocked upload attempt from ${clientIp}`);
19+
20+
// 2. Return a consistent error response
421
return NextResponse.json(
5-
{ error: 'Upload temporarily disabled' },
22+
{
23+
error: 'Upload service temporarily disabled',
24+
reason: 'Undergoing maintenance',
25+
retryAfter: 3600
26+
},
627
{ status: 503 }
728
);
829
}

src/app/page.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* TradeFlow Main Dashboard Page.
3+
* This is the primary entry point for the application, providing users with
4+
* a high-level overview of their assets, protocol status, and the RWA pipeline.
5+
*/
6+
17
"use client";
28

39
import React, { useState, useEffect, useRef } from "react";
@@ -29,15 +35,24 @@ import { useWalletConnection } from "../stores/useWeb3Store";
2935
import { showError, showSuccess } from "../lib/toast";
3036
import Icon from "../components/ui/Icon";
3137

38+
/**
39+
* The root component for the TradeFlow dashboard.
40+
* Manages high-level state for wallet connection, active tabs, and invoice data.
41+
*/
3242
export default function Page() {
3343
const router = useRouter();
3444
const searchParams = useSearchParams();
3545
const { isConnected, walletAddress, isConnecting } = useWalletConnection();
3646
const [invoices, setInvoices] = useState<InvoiceSummary[]>([]);
3747
const [loading, setLoading] = useState(false);
48+
/** Controls visibility of the Invoice Minting modal */
3849
const [showMintForm, setShowMintForm] = useState(false);
50+
/** Controls visibility of the Wallet Selection modal */
3951
const [isModalOpen, setIsModalOpen] = useState(false);
52+
/** Currently active navigation tab (dashboard or watchlist) */
4053
const [activeTab, setActiveTab] = useState("dashboard");
54+
55+
/** Watchlist management hook */
4156
const { toggleWatchlist, isInWatchlist } = useWatchlist();
4257
const riskSocketRef = useRef<RiskSocketClient | null>(null);
4358

@@ -77,6 +92,8 @@ export default function Page() {
7792
}
7893
};
7994

95+
// --- Lifecycle Hooks ---
96+
8097
useEffect(() => {
8198
const controller = new AbortController();
8299

@@ -147,14 +164,18 @@ export default function Page() {
147164
const handleInvoiceMint = (data: Record<string, unknown>) => {
148165
console.log("Invoice data received:", data);
149166
setShowMintForm(false);
150-
// TODO: Chain integration will be handled separately
167+
// TODO: Initiate Soroban contract call for minting the NFT
151168
};
152169

170+
// --- Configuration ---
171+
172+
/** Tab definitions for the main navigation */
153173
const tabs = [
154174
{ id: "dashboard", label: "Dashboard" },
155175
{ id: "watchlist", label: "Watchlist", icon: <Icon icon={Star} dense /> },
156176
];
157177

178+
158179
return (
159180
<div className="min-h-screen bg-slate-900 text-white font-sans flex flex-col">
160181
{/* Header */}

src/components/SwapInterface.tsx

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,25 @@ import { dismissToast, showError, showLoading, showSuccess } from "../lib/toast"
77
import { useSigningActions } from "../stores/signatureStore";
88
import Icon from "./ui/Icon";
99

10+
/**
11+
* Main component for the token swap functionality.
12+
*/
1013
export default function SwapInterface() {
14+
// --- Token Selection State ---
15+
/** The asset code of the token being sold */
1116
const [fromToken, setFromToken] = useState("XLM");
17+
/** The asset code of the token being bought */
1218
const [toToken, setToToken] = useState("USDC");
19+
20+
// --- UI Visibility State ---
1321
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
1422
const [isProMode, setIsProMode] = useState(false);
1523

1624
const { deadline } = useSettings();
1725

26+
/**
27+
* Swaps the 'from' and 'to' tokens and their amounts.
28+
*/
1829
const handleSwap = () => {
1930
const temp = fromToken;
2031
setFromToken(toToken);
@@ -23,19 +34,28 @@ export default function SwapInterface() {
2334
setToAmount(fromAmount);
2435
};
2536

37+
/**
38+
* Updates the source amount and recalculates the destination amount and price impact.
39+
*
40+
* @param {string} value - The new input amount.
41+
*/
2642
const handleFromAmountChange = (value: string) => {
2743
setFromAmount(value);
2844
const impact = calculatePriceImpact(value);
2945
setPriceImpact(impact);
3046

3147
if (value && parseFloat(value) > 0) {
48+
// Mock exchange rate logic
3249
const mockRate = fromToken === "XLM" ? 0.15 : 6.67;
3350
setToAmount((parseFloat(value) * mockRate * (1 - impact / 100)).toFixed(6));
3451
} else {
3552
setToAmount("");
3653
}
3754
};
3855

56+
/**
57+
* Initiates the swap flow, validating inputs and checking for high slippage.
58+
*/
3959
const handleSwapClick = async () => {
4060
if (!fromAmount || parseFloat(fromAmount) <= 0) {
4161
showError("Please enter an amount to swap");
@@ -45,41 +65,43 @@ export default function SwapInterface() {
4565
const loadingToast = showLoading("Processing swap...");
4666

4767
try {
68+
// Threshold check for high slippage warning
4869
if (priceImpact > 5) {
4970
setIsHighSlippageWarningOpen(true);
5071
dismissToast(loadingToast);
5172
return;
5273
}
5374

54-
await new Promise((resolve) => setTimeout(resolve, 1800));
75+
// Simulate network delay
76+
await new Promise((resolve) => setTimeout(resolve, 1500));
5577

5678
showSuccess(`Swapped ${fromAmount} ${fromToken}${toAmount} ${toToken}`, {
5779
id: loadingToast,
5880
});
5981

60-
if (priceImpact > 5) {
61-
setIsHighSlippageWarningOpen(true);
62-
} else {
63-
setIsTradeReviewOpen(true);
64-
}
82+
setIsTradeReviewOpen(true);
6583
} catch (error) {
6684
showError("Failed to process swap", {
6785
id: loadingToast,
6886
});
6987
}
7088
};
7189

90+
/**
91+
* Confirms the trade and prepares the transaction for signing.
92+
*/
7293
const handleTradeConfirm = async () => {
7394
setIsTradeReviewOpen(false);
7495
setIsSubmitting(true);
7596
setSubmissionStartTime(Date.now());
7697

7798
try {
99+
// Simulate transaction building time
78100
await new Promise(resolve => setTimeout(resolve, 2000));
79101

80-
// Generate mock transaction XDR
102+
// Mock transaction XDR for demonstration
81103
const mockTransactionXDR = "AAAAAK/eFzA7Jf5Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3Xf3XAAAABQAAAAAAAAAAA==";
82-
console.log("Mock XDR generated:", mockTransactionXDR);
104+
console.log("[SwapInterface] Mock XDR generated:", mockTransactionXDR);
83105

84106
setIsTransactionSignatureOpen(true);
85107
} catch (error) {
@@ -89,6 +111,9 @@ export default function SwapInterface() {
89111
}
90112
};
91113

114+
/**
115+
* Handles confirmation from the high slippage warning modal.
116+
*/
92117
const handleHighSlippageConfirm = async () => {
93118
const loadingToast = showLoading("Processing high slippage swap...");
94119

@@ -105,9 +130,13 @@ export default function SwapInterface() {
105130
}
106131
};
107132

108-
/* ISSUE #87: Trigger the success modal when the transaction is signed */
133+
/**
134+
* Callback for when the user successfully signs the transaction.
135+
*
136+
* @param {string} signedXDR - The base64 signed transaction XDR.
137+
*/
109138
const handleTransactionSuccess = (signedXDR: string) => {
110-
console.log("Transaction signed:", signedXDR);
139+
console.log("[SwapInterface] Transaction signed:", signedXDR);
111140

112141
showSuccess("Transaction signed successfully!", {
113142
icon: "✅",
@@ -117,16 +146,18 @@ export default function SwapInterface() {
117146
setIsSubmitting(false);
118147
setSubmissionStartTime(null);
119148

120-
// Show the Growth/Share modal
149+
// Show the post-trade share/growth modal
121150
setIsSuccessModalOpen(true);
122151

152+
// Reset form after a short delay
123153
setTimeout(() => {
124154
setFromAmount("");
125155
setToAmount("");
126156
setPriceImpact(0);
127157
}, 1500);
128158
};
129159

160+
130161
const isAnyModalOpen = isSettingsOpen || isHighSlippageWarningOpen || isTradeReviewOpen || isSuccessModalOpen;
131162
const isSwapValid = fromAmount && parseFloat(fromAmount) > 0 && !isSubmitting;
132163

0 commit comments

Comments
 (0)