build versiion

This commit is contained in:
Petropoulos Evangelos 2025-07-17 20:31:45 +03:00
parent 830606e1a7
commit 845913e94b
25 changed files with 35 additions and 553 deletions

View File

@ -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 });
}
}

View File

@ -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);
}

View File

@ -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>
);
}

View File

@ -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,
});
}),
];

View File

@ -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>

View File

@ -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 =

View File

@ -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 (

View File

@ -1,6 +1,6 @@
"use client";
import { DashboardHomePage } from "../features/Pages/DashboardHomePage/DashboardHomePage";
import { DashboardHomePage } from "../features/pages/DashboardHomePage/DashboardHomePage";
const DashboardPage = () => {
return <DashboardHomePage />;

View File

@ -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({

View File

@ -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({

View File

@ -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>>;

View File

@ -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
}

View File

@ -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 (

View File

@ -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");

View File

@ -38,8 +38,6 @@ export default function UserRoleCard({
name,
email,
isAdmin,
lastLogin,
// merchants,
roles,
extraRolesCount,
}: Props) {

View File

@ -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

View File

@ -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>
);

View File

@ -1,6 +1,6 @@
"use client";
import { DashboardHomePage } from "./features/Pages/DashboardHomePage/DashboardHomePage";
import { DashboardHomePage } from "./features/pages/DashboardHomePage/DashboardHomePage";
const DashboardPage = () => {
return <DashboardHomePage />;

View File

@ -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}</>;
}

View File

@ -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>;
}

View File

@ -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>
);
}

View File

@ -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>
);
}

View File

@ -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>
);
}

View File

@ -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 = (

View File

@ -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) {