187 lines
5.4 KiB
TypeScript
187 lines
5.4 KiB
TypeScript
// app/transactions/page.tsx
|
|
"use client";
|
|
|
|
import { useState } from "react";
|
|
|
|
// mocks/transactionData.ts
|
|
export const transactionDummyData = [
|
|
{
|
|
id: 1,
|
|
merchandId: 100987998,
|
|
transactionID: 1049131973,
|
|
user: 1,
|
|
created: "2025-06-18 10:10:30",
|
|
state: "FAILED",
|
|
statusDescription: "ERR_ABOVE_LIMIT",
|
|
pspStatusCode: 100501,
|
|
},
|
|
{
|
|
id: 2,
|
|
merchandId: 100987998,
|
|
transactionID: 1049131973,
|
|
user: 2,
|
|
created: "2025-06-18 10:10:30",
|
|
state: "FAILED",
|
|
statusDescription: "ERR_ABOVE_LIMIT",
|
|
pspStatusCode: 100501,
|
|
},
|
|
{
|
|
id: 3,
|
|
merchandId: 100987998,
|
|
transactionID: 1049131973,
|
|
user: 3,
|
|
created: "2025-06-18 10:10:30",
|
|
state: "FAILED",
|
|
statusDescription: "ERR_ABOVE_LIMIT",
|
|
pspStatusCode: 100501,
|
|
},
|
|
];
|
|
|
|
export default function TransactionsPage() {
|
|
const [userId, setUserId] = useState("");
|
|
const [state, setState] = useState("");
|
|
const [statusCode, setStatusCode] = useState("");
|
|
const [transactions, setTransactions] = useState<any[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const fetchTransactions = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const url = new URL("https://api.example.com/transactions");
|
|
if (userId) url.searchParams.append("userId", userId);
|
|
if (state) url.searchParams.append("state", state);
|
|
if (statusCode) url.searchParams.append("statusCode", statusCode);
|
|
|
|
const response = await fetch(url.toString());
|
|
const data = await response.json();
|
|
setTransactions(data.transactions);
|
|
} catch (error) {
|
|
console.error("Error fetching transactions:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="p-4">
|
|
<h1 className="text-xl font-bold mb-4">Transaction Search</h1>
|
|
|
|
<div className="flex gap-4 mb-4">
|
|
<div>
|
|
<label className="block text-sm mb-1">User ID</label>
|
|
<input
|
|
type="text"
|
|
value={userId}
|
|
onChange={(e) => setUserId(e.target.value)}
|
|
className="border p-2 rounded text-sm"
|
|
placeholder="Filter by user ID"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm mb-1">State</label>
|
|
<input
|
|
type="text"
|
|
value={state}
|
|
onChange={(e) => setState(e.target.value)}
|
|
className="border p-2 rounded text-sm"
|
|
placeholder="Filter by state"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm mb-1">Status Code</label>
|
|
<input
|
|
type="text"
|
|
value={statusCode}
|
|
onChange={(e) => setStatusCode(e.target.value)}
|
|
className="border p-2 rounded text-sm"
|
|
placeholder="Filter by status code"
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-end">
|
|
<button
|
|
onClick={fetchTransactions}
|
|
disabled={loading}
|
|
className="bg-blue-500 text-white px-4 py-2 rounded text-sm"
|
|
>
|
|
{loading ? "Loading..." : "Search"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{transactions.length > 0 ? (
|
|
<div className="border rounded overflow-hidden">
|
|
<table className="min-w-full">
|
|
<thead className="bg-gray-100">
|
|
<tr>
|
|
<th className="py-2 px-4 text-left text-sm">ID</th>
|
|
<th className="py-2 px-4 text-left text-sm">User</th>
|
|
<th className="py-2 px-4 text-left text-sm">State</th>
|
|
<th className="py-2 px-4 text-left text-sm">Status Code</th>
|
|
<th className="py-2 px-4 text-left text-sm">Created</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{transactions.map((tx) => (
|
|
<tr key={tx.id} className="border-t">
|
|
<td className="py-2 px-4 text-sm">{tx.id}</td>
|
|
<td className="py-2 px-4 text-sm">{tx.user}</td>
|
|
<td className="py-2 px-4 text-sm">{tx.state}</td>
|
|
<td className="py-2 px-4 text-sm">{tx.pspStatusCode}</td>
|
|
<td className="py-2 px-4 text-sm">{tx.created}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
) : (
|
|
<div className="text-center py-4 text-sm">
|
|
{loading ? "Loading transactions..." : "No transactions found"}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// mocks/handlers.ts
|
|
import { http, HttpResponse } from "msw";
|
|
|
|
export const handlers = [
|
|
http.get("https://api.example.com/transactions", ({ request }) => {
|
|
const url = new URL(request.url);
|
|
|
|
// Get query parameters
|
|
const userId = url.searchParams.get("userId");
|
|
const state = url.searchParams.get("state");
|
|
const statusCode = url.searchParams.get("statusCode");
|
|
|
|
// Filter transactions based on query parameters
|
|
let filteredTransactions = [...transactionDummyData];
|
|
|
|
if (userId) {
|
|
filteredTransactions = filteredTransactions.filter(
|
|
(tx) => tx.user.toString() === userId
|
|
);
|
|
}
|
|
|
|
if (state) {
|
|
filteredTransactions = filteredTransactions.filter(
|
|
(tx) => tx.state.toLowerCase() === state.toLowerCase()
|
|
);
|
|
}
|
|
|
|
if (statusCode) {
|
|
filteredTransactions = filteredTransactions.filter(
|
|
(tx) => tx.pspStatusCode.toString() === statusCode
|
|
);
|
|
}
|
|
|
|
return HttpResponse.json({
|
|
transactions: filteredTransactions,
|
|
count: filteredTransactions.length,
|
|
});
|
|
}),
|
|
];
|