diff --git a/payment-iq/app/api/transactions/route.ts b/payment-iq/app/api/transactions/route.ts new file mode 100644 index 0000000..0d8f238 --- /dev/null +++ b/payment-iq/app/api/transactions/route.ts @@ -0,0 +1,25 @@ +import { transactionDummyData } from '@/app/features/Pages/transactions/mockData'; +import { NextRequest, NextResponse } from 'next/server'; + +export async function GET(request: NextRequest) { + const { searchParams } = new URL(request.url); + + const state = searchParams.get('state'); + const user = searchParams.get('user'); + + let filteredTransactions = [...transactionDummyData]; + + if (user) { + filteredTransactions = filteredTransactions.filter( + tx => tx.user.toString() === user + ); + } + + if (state) { + filteredTransactions = filteredTransactions.filter( + tx => tx.state.toLowerCase() === state.toLowerCase() + ); + } + + return NextResponse.json(filteredTransactions); +} \ No newline at end of file diff --git a/payment-iq/app/components/searchFilter/SearchFilters.tsx b/payment-iq/app/components/searchFilter/SearchFilters.tsx new file mode 100644 index 0000000..82f5692 --- /dev/null +++ b/payment-iq/app/components/searchFilter/SearchFilters.tsx @@ -0,0 +1,37 @@ +// components/SearchFilters.js +import React from 'react'; +import { Box, Chip, Typography, Button } from '@mui/material'; + +const SearchFilters = ({ filters, onDeleteFilter, onClearAll }) => { + const renderChip = (label, value, key) => ( + + {label} {value} + + } + onDelete={() => onDeleteFilter(key)} + sx={{ mr: 1, mb: 1 }} + /> + ); + + return ( + + {filters.user && renderChip('User', filters.user, 'user')} + {filters.state && renderChip('State', filters.state, 'state')} + {filters.startDate && renderChip('Start Date', filters.startDate, 'startDate')} + + {Object.values(filters).some(Boolean) && ( + + )} + + ); +}; + +export default SearchFilters; diff --git a/payment-iq/app/components/test/test2.tsx b/payment-iq/app/components/test/test2.tsx index 631ba38..93792b4 100644 --- a/payment-iq/app/components/test/test2.tsx +++ b/payment-iq/app/components/test/test2.tsx @@ -1,207 +1,189 @@ -import React, { useState } from "react"; -import { - Box, - Grid, - TextField, - MenuItem, - Button, - InputLabel, - FormControl, - Select, - Typography, -} from "@mui/material"; -import { DatePicker } from "@mui/x-date-pickers/DatePicker"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; -import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; -import SearchIcon from "@mui/icons-material/Search"; -import RefreshIcon from "@mui/icons-material/Refresh"; +// app/transactions/page.tsx +'use client'; -const currencies = ["USD", "EUR", "GBP"]; -const states = ["Pending", "Completed", "Failed"]; -const transactionTypes = ["Credit", "Debit"]; -const paymentMethods = ["Card", "Bank Transfer"]; -const psps = ["Stripe", "PayPal"]; -const merchants = ["Amazon", "eBay"]; +import { useState } from 'react'; -export default function SearchFilterForm() { - const [form, setForm] = useState({ - keyword: "", - transactionId: "", - transactionReferenceId: "", - user: "", - currency: "", - state: "", - statusDescription: "", - transactionType: "", - paymentMethod: "", - psps: "", - initialPsps: "", - merchants: "", - startDate: null, - endDate: null, - lastUpdatedFrom: null, - lastUpdatedTo: null, - minAmount: "", - maxAmount: "", - channel: "", - }); +export default function TransactionsPage() { + const [userId, setUserId] = useState(''); + const [state, setState] = useState(''); + const [statusCode, setStatusCode] = useState(''); + const [transactions, setTransactions] = useState([]); + const [loading, setLoading] = useState(false); - const handleChange = (field: string, value: any) => { - setForm((prev) => ({ ...prev, [field]: value })); - }; + 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 resetForm = () => { - setForm({ - keyword: "", - transactionId: "", - transactionReferenceId: "", - user: "", - currency: "", - state: "", - statusDescription: "", - transactionType: "", - paymentMethod: "", - psps: "", - initialPsps: "", - merchants: "", - startDate: null, - endDate: null, - lastUpdatedFrom: null, - lastUpdatedTo: null, - minAmount: "", - maxAmount: "", - channel: "", - }); + 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 ( - - - - Search - +
+

Transaction Search

+ +
+
+ + setUserId(e.target.value)} + className="border p-2 rounded text-sm" + placeholder="Filter by user ID" + /> +
- - {[ - { label: "Keyword", field: "keyword", type: "text" }, - { label: "Transaction ID", field: "transactionId", type: "text" }, - { - label: "Transaction Reference ID", - field: "transactionReferenceId", - type: "text", - }, - { label: "User", field: "user", type: "text" }, - { - label: "Currency", - field: "currency", - type: "select", - options: currencies, - }, - { label: "State", field: "state", type: "select", options: states }, - { - label: "Status Description", - field: "statusDescription", - type: "text", - }, - { - label: "Transaction Type", - field: "transactionType", - type: "select", - options: transactionTypes, - }, - { - label: "Payment Method", - field: "paymentMethod", - type: "select", - options: paymentMethods, - }, - { label: "PSPs", field: "psps", type: "text" }, - { label: "Initial PSPs", field: "initialPsps", type: "text" }, - { label: "Merchants", field: "merchants", type: "text" }, - { label: "Start Date", field: "startDate", type: "date" }, - { label: "End Date", field: "endDate", type: "date" }, - { - label: "Last Updated From", - field: "lastUpdatedFrom", - type: "date", - }, - { label: "Last Updated To", field: "lastUpdatedTo", type: "date" }, - { label: "Min Amount", field: "minAmount", type: "text" }, - { label: "Max Amount", field: "maxAmount", type: "text" }, - { label: "Channel", field: "channel", type: "text" }, - ].map(({ label, field, type, options }) => ( - - - - {label} - - - - {type === "text" && ( - handleChange(field, e.target.value)} - /> - )} - {type === "select" && ( - - - - )} - {type === "date" && ( - handleChange(field, newValue)} - renderInput={(params) => ( - - )} - /> - )} - - - ))} +
+ + setState(e.target.value)} + className="border p-2 rounded text-sm" + placeholder="Filter by state" + /> +
- {/* Buttons */} - - - - -
- - +
+ + setStatusCode(e.target.value)} + className="border p-2 rounded text-sm" + placeholder="Filter by status code" + /> +
+ +
+ +
+
+ + {transactions.length > 0 ? ( +
+ + + + + + + + + + + + {transactions.map((tx) => ( + + + + + + + + ))} + +
IDUserStateStatus CodeCreated
{tx.id}{tx.user}{tx.state}{tx.pspStatusCode}{tx.created}
+
+ ) : ( +
+ {loading ? 'Loading transactions...' : 'No transactions found'} +
+ )} +
); } + + +// mocks/handlers.ts +import { http, HttpResponse } from 'msw'; +import { transactionDummyData } from './transactionData'; + +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 + }); + }), +]; + + +// 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, + } +]; diff --git a/payment-iq/app/dashboard/transactions/page.tsx b/payment-iq/app/dashboard/transactions/page.tsx index f2059f1..64e0f47 100644 --- a/payment-iq/app/dashboard/transactions/page.tsx +++ b/payment-iq/app/dashboard/transactions/page.tsx @@ -1,11 +1,11 @@ // This ensures this component is rendered only on the client side -"use client"; import TransactionTable from "@/app/features/Pages/Transactions/Transactions"; + export default function TransactionPage() { return ( -
+
{/* This page will now be rendered on the client-side */}
diff --git a/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx index a51dd10..9c03417 100644 --- a/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx +++ b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx @@ -21,7 +21,7 @@ const states = ["Pending", "Completed", "Failed"]; const transactionTypes = ["Credit", "Debit"]; const paymentMethods = ["Card", "Bank Transfer"]; -export default function AdvancedSearch({setForm, form, resetForm}) { +export default function AdvancedSearch({ setForm, form, resetForm }) { const [open, setOpen] = useState(false); const handleChange = (field: string, value: any) => { @@ -172,7 +172,7 @@ export default function AdvancedSearch({setForm, form, resetForm}) { ); return ( - +