build versiion
This commit is contained in:
parent
830606e1a7
commit
845913e94b
@ -1,11 +1,11 @@
|
||||
// app/api/user/route.ts
|
||||
// app/api/dashboard/admin/users/route.ts
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export const users = [
|
||||
const users = [
|
||||
{
|
||||
merchantId: 100987998,
|
||||
id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9",
|
||||
mame: "Jacob",
|
||||
name: "Jacob",
|
||||
username: "lspaddy",
|
||||
firstName: "Paddy",
|
||||
lastName: "Man",
|
||||
@ -46,9 +46,9 @@ export async function POST(request: NextRequest) {
|
||||
const { firstName, lastName, email, phone, role } = body;
|
||||
|
||||
// Add the new user to the existing users array (in-memory, not persistent)
|
||||
const bodytoAdd = {
|
||||
const newUser = {
|
||||
merchantId: 100987998,
|
||||
mame: "Jacob",
|
||||
name: "Jacob",
|
||||
id: "382eed15-1e21-41fa-b1f3-0c1adb3af714",
|
||||
username: "lsterence",
|
||||
firstName,
|
||||
@ -73,7 +73,7 @@ export async function POST(request: NextRequest) {
|
||||
twoFactorCondition: "required",
|
||||
twoFactorCredentials: [],
|
||||
};
|
||||
users.push(bodytoAdd);
|
||||
users.push(newUser);
|
||||
|
||||
return NextResponse.json(users, { status: 201 });
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { transactionDummyData } from "@/app/components/test/test2";
|
||||
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);
|
||||
}
|
||||
@ -1,103 +0,0 @@
|
||||
import * as React from "react";
|
||||
import Box from "@mui/material/Box";
|
||||
import Drawer from "@mui/material/Drawer";
|
||||
import Button from "@mui/material/Button";
|
||||
import List from "@mui/material/List";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import ListItem from "@mui/material/ListItem";
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import InboxIcon from "@mui/icons-material/MoveToInbox";
|
||||
import MailIcon from "@mui/icons-material/Mail";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
|
||||
export default function RightTemporaryDrawer() {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const toggleDrawer =
|
||||
(open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
|
||||
if (
|
||||
event.type === "keydown" &&
|
||||
((event as React.KeyboardEvent).key === "Tab" ||
|
||||
(event as React.KeyboardEvent).key === "Shift")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(open);
|
||||
};
|
||||
|
||||
const list = () => (
|
||||
<Box
|
||||
sx={{ width: 400 }}
|
||||
role="presentation"
|
||||
onClick={toggleDrawer(false)}
|
||||
onKeyDown={toggleDrawer(false)}
|
||||
>
|
||||
<List>
|
||||
{["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
|
||||
<ListItem key={text} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={text} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
<Divider />
|
||||
<List>
|
||||
{["All mail", "Trash", "Spam"].map((text, index) => (
|
||||
<ListItem key={text} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={text} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
sx={{
|
||||
borderRadius: "8px",
|
||||
textTransform: "none",
|
||||
backgroundColor: "#f5f5f5",
|
||||
color: "#555",
|
||||
padding: "6px 12px",
|
||||
boxShadow: "inset 0 0 0 1px #ddd",
|
||||
fontWeight: 400,
|
||||
fontSize: "16px",
|
||||
justifyContent: "flex-start",
|
||||
"& .MuiButton-startIcon": {
|
||||
marginRight: "12px",
|
||||
backgroundColor: "#eee",
|
||||
padding: "8px",
|
||||
borderRadius: "4px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
"&:hover": {
|
||||
backgroundColor: "#e0e0e0",
|
||||
},
|
||||
}}
|
||||
startIcon={<SearchIcon />}
|
||||
onClick={toggleDrawer(true)}
|
||||
>
|
||||
Advanced Search
|
||||
</Button>
|
||||
{/* <Button onClick={toggleDrawer(true)}>Open Right Drawer</Button> */}
|
||||
<Drawer anchor="right" open={open} onClose={toggleDrawer(false)}>
|
||||
{list()}
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,186 +0,0 @@
|
||||
// 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,
|
||||
});
|
||||
}),
|
||||
];
|
||||
@ -1,8 +1,5 @@
|
||||
// This ensures this component is rendered only on the client side
|
||||
"use client";
|
||||
|
||||
import { Approve } from "@/app/features/Pages/Approve/Approve";
|
||||
|
||||
export default function BackOfficeUsersPage() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import Users from "@/app/features/Pages/Admin/Users/users";
|
||||
import Users from "@/app/features/pages/Admin/Users/users";
|
||||
|
||||
export default async function BackOfficeUsersPage() {
|
||||
const baseUrl =
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// This ensures this component is rendered only on the client side
|
||||
"use client";
|
||||
|
||||
import { Approve } from "@/app/features/Pages/Approve/Approve";
|
||||
import { Approve } from "@/app/features/pages/Approve/Approve";
|
||||
|
||||
export default function ApprovePage() {
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { DashboardHomePage } from "../features/Pages/DashboardHomePage/DashboardHomePage";
|
||||
import { DashboardHomePage } from "../features/pages/DashboardHomePage/DashboardHomePage";
|
||||
|
||||
const DashboardPage = () => {
|
||||
return <DashboardHomePage />;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import TransactionsTable from "@/app/features/Pages/Transactions/TransactionsTable";
|
||||
|
||||
import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable";
|
||||
import { getTransactions } from "@/app/services/transactions";
|
||||
|
||||
export default async function DepositTransactionPage({
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import TransactionsTable from "@/app/features/Pages/Transactions/TransactionsTable";
|
||||
import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable";
|
||||
import { getTransactions } from "@/app/services/transactions";
|
||||
|
||||
export default async function DepositTransactionPage({
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import TransactionsTable from "@/app/features/Pages/Transactions/TransactionsTable";
|
||||
import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable";
|
||||
import { getTransactions } from "@/app/services/transactions";
|
||||
|
||||
export default async function DepositTransactionPage({
|
||||
export default async function WithdrawalTransactionPage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
||||
|
||||
@ -22,5 +22,6 @@ export interface IUser {
|
||||
releaseNotes: boolean;
|
||||
requiredActions: string[];
|
||||
twoFactorCondition: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
twoFactorCredentials: any[]; // Assuming this is an array that could contain any type of data
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { FetchReport } from "../../FetchReports/FetchReports";
|
||||
import { Documentation } from "../../Documentation/Documentation";
|
||||
import { AccountIQ } from "../../AccountIQ/AccountIQ";
|
||||
import { WhatsNew } from "../../WhatsNew/WhatsNew";
|
||||
import { TransactionsOverView } from "../../TransactionsOverview/TransactionsOverview";
|
||||
import { TransactionsOverView } from "../../TransactionsOverView/TransactionsOverview";
|
||||
|
||||
export const DashboardHomePage = () => {
|
||||
return (
|
||||
|
||||
@ -47,6 +47,7 @@ const EditUser = () => {
|
||||
try {
|
||||
await createRole(form);
|
||||
router.refresh(); // <- refreshes the page (SSR re-runs)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
console.log(err.message || "Error creating role");
|
||||
// setError(err.message || "Error creating role");
|
||||
|
||||
@ -38,8 +38,6 @@ export default function UserRoleCard({
|
||||
name,
|
||||
email,
|
||||
isAdmin,
|
||||
lastLogin,
|
||||
// merchants,
|
||||
roles,
|
||||
extraRolesCount,
|
||||
}: Props) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { AppBar, Toolbar, IconButton } from "@mui/material";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import Dropdown from "./dropDown/DropDown";
|
||||
@ -6,19 +6,19 @@ import AccountMenu from "./accountMenu/AccountMenu";
|
||||
import "./Header.scss";
|
||||
|
||||
const Header = () => {
|
||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
// const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
|
||||
// Handle menu open
|
||||
const handleMenuClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
// // Handle menu open
|
||||
// const handleMenuClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||
// setAnchorEl(event.currentTarget);
|
||||
// };
|
||||
|
||||
// Handle menu close
|
||||
const handleMenuClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
// // Handle menu close
|
||||
// const handleMenuClose = () => {
|
||||
// setAnchorEl(null);
|
||||
// };
|
||||
|
||||
const handleChange = (e: any) => {};
|
||||
const handleChange = () => {};
|
||||
|
||||
return (
|
||||
<AppBar
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import ThemeRegistry from "@/config/ThemeRegistry";
|
||||
import type { Metadata } from "next";
|
||||
import "../styles/globals.scss";
|
||||
import { Providers } from "./providers/providers";
|
||||
import { MSWProvider } from './providers/msw-provider';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Your App",
|
||||
@ -17,11 +15,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<Providers>
|
||||
<MSWProvider>
|
||||
<ThemeRegistry>{children}</ThemeRegistry>
|
||||
</MSWProvider>
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { DashboardHomePage } from "./features/Pages/DashboardHomePage/DashboardHomePage";
|
||||
import { DashboardHomePage } from "./features/pages/DashboardHomePage/DashboardHomePage";
|
||||
|
||||
const DashboardPage = () => {
|
||||
return <DashboardHomePage />;
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export function MSWProvider({ children }: { children: React.ReactNode }) {
|
||||
useEffect(() => {
|
||||
if (process.env.NEXT_PUBLIC_API_MOCKING === "enabled") {
|
||||
import("../../mock/browser").then(({ worker }) => {
|
||||
// worker.start();
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { store } from '../redux/store';
|
||||
|
||||
export function Providers({ children }: { children: ReactNode }) {
|
||||
return <Provider store={store}>{children}</Provider>;
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
// app/test/page.tsx
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export default function TestPage() {
|
||||
const [user, setUser] = useState(null);
|
||||
const [loginStatus, setLoginStatus] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// Test GET request
|
||||
fetch('https://api.example.com/user')
|
||||
.then(res => res.json())
|
||||
.then(data => setUser(data));
|
||||
}, []);
|
||||
|
||||
const handleLogin = async () => {
|
||||
// Test POST request
|
||||
const response = await fetch('https://api.example.com/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: 'admin',
|
||||
password: 'password123'
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
setLoginStatus(response.ok ? 'Login successful' : `Error: ${result.error}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>MSW Test Page</h1>
|
||||
|
||||
<section>
|
||||
<h2>User Data (GET)</h2>
|
||||
<pre>{JSON.stringify(user, null, 2)}</pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Login Test (POST)</h2>
|
||||
<button onClick={handleLogin}>Login as Admin</button>
|
||||
<p>{loginStatus}</p>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
'use client'
|
||||
import React, { useState } from 'react';
|
||||
import SearchFilters from '../components/searchFilter/SearchFilters';
|
||||
|
||||
export default function Home() {
|
||||
const [filters, setFilters] = useState({
|
||||
user: '42',
|
||||
state: 'FAILED',
|
||||
startDate: '2025-06-28 23:25',
|
||||
});
|
||||
|
||||
const handleDeleteFilter = (key) => {
|
||||
setFilters((prev) => ({ ...prev, [key]: null }));
|
||||
};
|
||||
|
||||
const handleClearAll = () => {
|
||||
setFilters({ user: null, state: null, startDate: null });
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SearchFilters
|
||||
filters={filters}
|
||||
onDeleteFilter={handleDeleteFilter}
|
||||
onClearAll={handleClearAll}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
// app/products/page.tsx
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function ProductsPage() {
|
||||
const [category, setCategory] = useState('');
|
||||
const [sort, setSort] = useState('price');
|
||||
const [limit, setLimit] = useState('10');
|
||||
const [products, setProducts] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const fetchProducts = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Construct URL with query parameters
|
||||
const url = new URL('https://api.example.com/products');
|
||||
if (category) url.searchParams.append('category', category);
|
||||
if (sort) url.searchParams.append('sort', sort);
|
||||
if (limit) url.searchParams.append('limit', limit);
|
||||
|
||||
const response = await fetch(url.toString());
|
||||
const data = await response.json();
|
||||
setProducts(data.products);
|
||||
} catch (error) {
|
||||
console.error('Error fetching products:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h1 className="text-2xl font-bold mb-4">Product Search</h1>
|
||||
|
||||
<div className="flex gap-4 mb-6">
|
||||
<div>
|
||||
<label className="block mb-1">Category</label>
|
||||
<input
|
||||
type="text"
|
||||
value={category}
|
||||
onChange={(e) => setCategory(e.target.value)}
|
||||
className="border p-2 rounded"
|
||||
placeholder="electronics, clothing, etc."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block mb-1">Sort By</label>
|
||||
<select
|
||||
value={sort}
|
||||
onChange={(e) => setSort(e.target.value)}
|
||||
className="border p-2 rounded"
|
||||
>
|
||||
<option value="price">Price</option>
|
||||
<option value="name">Name</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block mb-1">Items Per Page</label>
|
||||
<input
|
||||
type="number"
|
||||
value={limit}
|
||||
onChange={(e) => setLimit(e.target.value)}
|
||||
className="border p-2 rounded"
|
||||
min="1"
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={fetchProducts}
|
||||
disabled={loading}
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded self-end"
|
||||
>
|
||||
{loading ? 'Loading...' : 'Search'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{products.length > 0 && (
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold mb-2">Results</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{products.map((product) => (
|
||||
<div key={product.id} className="border p-4 rounded">
|
||||
<h3 className="font-medium">{product.name}</h3>
|
||||
<p>Category: {product.category}</p>
|
||||
<p>Price: ${product.price}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,9 +1,11 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
// @ts-nocheck
|
||||
import * as XLSX from "xlsx";
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
export type FileType = "csv" | "xls" | "xlsx";
|
||||
import { saveAs } from "file-saver";
|
||||
|
||||
import type { ITransaction } from "../features/Pages/Transactions/types";
|
||||
import type { ITransaction } from "../features/pages/transactions/types";
|
||||
|
||||
|
||||
export const exportData = (
|
||||
|
||||
@ -80,6 +80,8 @@ export const handlers = [
|
||||
const statusCode = url.searchParams.get("statusCode");
|
||||
|
||||
// Filter transactions based on query parameters
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
let filteredTransactions = [...transactionDummyData];
|
||||
|
||||
if (userId) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user