From fc4be718f7fee2aadeea1184d2e15c270491f695 Mon Sep 17 00:00:00 2001 From: Mitchell Magro Date: Wed, 9 Jul 2025 14:41:51 +0200 Subject: [PATCH] Added Edit Uder in Admin --- .../app/api/dashboard/admin/users/route.ts | 66 ++++++++++ payment-iq/app/api/transactions/route.ts | 30 ++--- payment-iq/app/components/test/test2.tsx | 117 +++++++++--------- payment-iq/app/dashboard/admin/users/page.tsx | 13 +- .../app/features/Pages/Admin/Users/users.tsx | 108 ++-------------- .../DashboardHomePage/DashboardHomePage.tsx | 46 +------ .../Pages/transactions/Transactions.tsx | 37 +++--- .../features/UserRoles/AddUser/AddUser.scss | 46 +++++++ .../features/UserRoles/AddUser/AddUser.tsx | 0 .../features/UserRoles/EditUser/EditUser.scss | 46 +++++++ .../features/UserRoles/EditUser/EditUser.tsx | 107 ++++++++++++++++ payment-iq/app/features/UserRoles/User.scss | 6 + .../app/features/UserRoles/userRoleCard.tsx | 18 ++- payment-iq/app/providers/msw-provider.tsx | 11 +- payment-iq/config/theme.ts | 34 ++--- payment-iq/mock/browser.ts | 9 +- payment-iq/mock/constants.ts | 61 +++++++++ payment-iq/mock/handlers.ts | 95 ++++++-------- payment-iq/next.config.ts | 4 +- payment-iq/styles/globals.scss | 2 + payment-iq/styles/variables.scss | 2 + 21 files changed, 521 insertions(+), 337 deletions(-) create mode 100644 payment-iq/app/api/dashboard/admin/users/route.ts create mode 100644 payment-iq/app/features/UserRoles/AddUser/AddUser.scss create mode 100644 payment-iq/app/features/UserRoles/AddUser/AddUser.tsx create mode 100644 payment-iq/app/features/UserRoles/EditUser/EditUser.scss create mode 100644 payment-iq/app/features/UserRoles/EditUser/EditUser.tsx create mode 100644 payment-iq/app/features/UserRoles/User.scss create mode 100644 payment-iq/mock/constants.ts diff --git a/payment-iq/app/api/dashboard/admin/users/route.ts b/payment-iq/app/api/dashboard/admin/users/route.ts new file mode 100644 index 0000000..594c580 --- /dev/null +++ b/payment-iq/app/api/dashboard/admin/users/route.ts @@ -0,0 +1,66 @@ +// app/api/user/route.ts +import { NextResponse } from "next/server"; + +export async function GET() { + return NextResponse.json([ + { + merchantId: 100987998, + id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9", + mame: "Jacob", + username: "lspaddy", + firstName: "Paddy", + lastName: "Man", + email: "patrick@omegasys.eu", + phone: "", + jobTitle: "", + enabled: true, + authorities: [ + "ROLE_IIN", + "ROLE_FIRST_APPROVER", + "ROLE_RULES_ADMIN", + "ROLE_TRANSACTION_VIEWER", + "ROLE_IIN_ADMIN", + "ROLE_USER_PSP_ACCOUNT", + ], + allowedMerchantIds: [100987998], + created: "2025-05-04T15:32:48.432Z", + disabledBy: null, + disabledDate: null, + disabledReason: null, + incidentNotes: false, + lastLogin: "", + lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", + marketingNewsletter: false, + releaseNotes: false, + requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], + twoFactorCondition: "required", + twoFactorCredentials: [], + }, + { + merchantId: 100987998, + mame: "Jacob", + id: "382eed15-1e21-41fa-b1f3-0c1adb3af714", + username: "lsterence", + firstName: "Terence", + lastName: "User", + email: "terence@omegasys.eu", + phone: "", + jobTitle: "", + enabled: true, + authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"], + allowedMerchantIds: [100987998], + created: "2025-05-04T15:32:48.432Z", + disabledBy: null, + disabledDate: null, + disabledReason: null, + incidentNotes: false, + lastLogin: "", + lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", + marketingNewsletter: false, + releaseNotes: false, + requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], + twoFactorCondition: "required", + twoFactorCredentials: [], + }, + ]); +} diff --git a/payment-iq/app/api/transactions/route.ts b/payment-iq/app/api/transactions/route.ts index 0d8f238..03bdd3d 100644 --- a/payment-iq/app/api/transactions/route.ts +++ b/payment-iq/app/api/transactions/route.ts @@ -1,25 +1,25 @@ -import { transactionDummyData } from '@/app/features/Pages/transactions/mockData'; -import { NextRequest, NextResponse } from 'next/server'; +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'); + const state = searchParams.get("state"); + const user = searchParams.get("user"); let filteredTransactions = [...transactionDummyData]; - if (user) { - filteredTransactions = filteredTransactions.filter( - tx => tx.user.toString() === user - ); - } + if (user) { + filteredTransactions = filteredTransactions.filter( + (tx) => tx.user.toString() === user + ); + } - if (state) { - filteredTransactions = filteredTransactions.filter( - tx => tx.state.toLowerCase() === state.toLowerCase() - ); - } + 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/test/test2.tsx b/payment-iq/app/components/test/test2.tsx index 93792b4..3db3076 100644 --- a/payment-iq/app/components/test/test2.tsx +++ b/payment-iq/app/components/test/test2.tsx @@ -1,28 +1,62 @@ // app/transactions/page.tsx -'use client'; +"use client"; -import { useState } from 'react'; +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 [userId, setUserId] = useState(""); + const [state, setState] = useState(""); + const [statusCode, setStatusCode] = useState(""); const [transactions, setTransactions] = useState([]); 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 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); + console.error("Error fetching transactions:", error); } finally { setLoading(false); } @@ -31,7 +65,7 @@ export default function TransactionsPage() { return (

Transaction Search

- +
@@ -72,7 +106,7 @@ export default function TransactionsPage() { disabled={loading} className="bg-blue-500 text-white px-4 py-2 rounded text-sm" > - {loading ? 'Loading...' : 'Search'} + {loading ? "Loading..." : "Search"}
@@ -104,86 +138,49 @@ export default function TransactionsPage() {
) : (
- {loading ? 'Loading transactions...' : 'No transactions found'} + {loading ? "Loading transactions..." : "No transactions found"}
)} ); } - // mocks/handlers.ts -import { http, HttpResponse } from 'msw'; -import { transactionDummyData } from './transactionData'; +import { http, HttpResponse } from "msw"; export const handlers = [ - http.get('https://api.example.com/transactions', ({ request }) => { + 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'); + 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 + (tx) => tx.user.toString() === userId ); } if (state) { filteredTransactions = filteredTransactions.filter( - tx => tx.state.toLowerCase() === state.toLowerCase() + (tx) => tx.state.toLowerCase() === state.toLowerCase() ); } if (statusCode) { filteredTransactions = filteredTransactions.filter( - tx => tx.pspStatusCode.toString() === statusCode + (tx) => tx.pspStatusCode.toString() === statusCode ); } return HttpResponse.json({ transactions: filteredTransactions, - count: filteredTransactions.length + 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/admin/users/page.tsx b/payment-iq/app/dashboard/admin/users/page.tsx index 9a8be75..c5625e4 100644 --- a/payment-iq/app/dashboard/admin/users/page.tsx +++ b/payment-iq/app/dashboard/admin/users/page.tsx @@ -1,12 +1,15 @@ -// This ensures this component is rendered only on the client side -"use client"; - import Users from "@/app/features/Pages/Admin/Users/users"; -export default function BackOfficeUsersPage() { +export default async function BackOfficeUsersPage() { + const res = await fetch("http://localhost:3000/api/dashboard/admin/users", { + cache: "no-store", // 👈 disables caching for SSR freshness + }); + const users = await res.json(); + + console.log("[USERS]", users); return (
- +
); } diff --git a/payment-iq/app/features/Pages/Admin/Users/users.tsx b/payment-iq/app/features/Pages/Admin/Users/users.tsx index 7e00e63..e829d7d 100644 --- a/payment-iq/app/features/Pages/Admin/Users/users.tsx +++ b/payment-iq/app/features/Pages/Admin/Users/users.tsx @@ -1,92 +1,17 @@ "use client"; -import React, { useEffect, useState } from "react"; -import { Card, CardContent, Typography, Chip, Stack } from "@mui/material"; +import React from "react"; +import { Card, CardContent, Typography, Stack } from "@mui/material"; import { IUser } from "./interfaces"; -import UserRoleCard from "@/app/features/UserRoles/userRoleCard"; +import UserRoleCard from "@/app/features/UserRoles/UserRoleCard"; -const Users = () => { - const [data, setData] = useState([ - { - merchantId: 100987998, - id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9", - mame: "Jacob", - username: "lspaddy", - firstName: "Paddy", - lastName: "Man", - email: "patrick@omegasys.eu", - phone: "", - jobTitle: "", - enabled: true, - authorities: [ - "ROLE_IIN", - "ROLE_FIRST_APPROVER", - "ROLE_RULES_ADMIN", - "ROLE_TRANSACTION_VIEWER", - "ROLE_IIN_ADMIN", - "ROLE_USER_PSP_ACCOUNT", - ], - allowedMerchantIds: [100987998], - created: "2025-05-04T15:32:48.432Z", - disabledBy: null, - disabledDate: null, - disabledReason: null, - incidentNotes: false, - lastLogin: "", - lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", - marketingNewsletter: false, - releaseNotes: false, - requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], - twoFactorCondition: "required", - twoFactorCredentials: [], - }, - { - merchantId: 100987998, - mame: "Jacob", - id: "382eed15-1e21-41fa-b1f3-0c1adb3af714", - username: "lsterence", - firstName: "Terence", - lastName: "User", - email: "terence@omegasys.eu", - phone: "", - jobTitle: "", - enabled: true, - authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"], - allowedMerchantIds: [100987998], - created: "2025-05-04T15:32:48.432Z", - disabledBy: null, - disabledDate: null, - disabledReason: null, - incidentNotes: false, - lastLogin: "", - lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", - marketingNewsletter: false, - releaseNotes: false, - requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], - twoFactorCondition: "required", - twoFactorCredentials: [], - }, - // Add more users if needed - ]); - - useEffect(() => { - // Only run MSW in the browser environment - if (typeof window !== "undefined") { - const fetchData = async () => { - const response = await fetch( - "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/users/?includeSubMids=false&size=20&page=0&merchantId=100987998" - ); // This would be intercepted by MSW in the browser - const data = await response.json(); - console.log("[DATA]", data); - // setData(data); - }; - - fetchData(); - } - }, []); +interface UsersProps { + users: IUser[]; +} +const Users: React.FC = ({ users }) => { return (
- {data.map((user: IUser) => ( + {users.map((user: IUser) => ( {user.username} @@ -103,7 +28,7 @@ const Users = () => { isAdmin={true} lastLogin="small" roles={user.authorities} - // merchants={Numberuser.allowedMerchantIds} + merchants={[]} // merchants={Numberuser.allowedMerchantIds} /> {/* Add more chips or UI elements for other data */} @@ -113,19 +38,4 @@ const Users = () => {
); }; - -// Fetch data server-side using getServerSideProps -// export async function getServerSideProps() { -// // Replace this with your actual API call -// const res = await fetch("https://api.example.com/users"); -// const data = await res.json(); - -// // Return the fetched data as props -// return { -// props: { -// result: data, // Assuming data is an array of users -// }, -// }; -// } - export default Users; diff --git a/payment-iq/app/features/Pages/DashboardHomePage/DashboardHomePage.tsx b/payment-iq/app/features/Pages/DashboardHomePage/DashboardHomePage.tsx index 4eaf208..d36e1ad 100644 --- a/payment-iq/app/features/Pages/DashboardHomePage/DashboardHomePage.tsx +++ b/payment-iq/app/features/Pages/DashboardHomePage/DashboardHomePage.tsx @@ -1,3 +1,4 @@ +"use client"; import { Box } from "@mui/material"; import { GeneralHealthCard } from "../../GeneralHealthCard/GeneralHealthCard"; import { TransactionsWaitingApproval } from "../../TransactionsWaitingApproval/TransactionsWaitingApproval"; @@ -6,53 +7,8 @@ import { Documentation } from "../../Documentation/Documentation"; import { AccountIQ } from "../../AccountIQ/AccountIQ"; import { WhatsNew } from "../../WhatsNew/WhatsNew"; import { TransactionsOverView } from "../../TransactionsOverview/TransactionsOverview"; -import { useEffect } from "react"; export const DashboardHomePage = () => { - // useEffect to fetch data when the component mounts - useEffect(() => { - // Construct the URL with query parameters - const url = - "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/metrics/txsummary?merchantId=100987998&fromDate=2025-06-29+19%3A10&toDate=2025-07-01+19%3A09"; - - // Perform the fetch request inside useEffect - const fetchData = async () => { - try { - // Start loading - - // Make the API request - const response = await fetch(url, { - method: "GET", // You can change this to 'POST' if necessary - headers: { - "Content-Type": "application/json", - // Add any other headers you need here - }, - }); - - // Check if the response is OK (status code 200-299) - if (!response.ok) { - throw new Error(`Failed to fetch: ${response.status}`); - } - - // Parse the JSON response - const data = await response.json(); - console.log("[DATA]", data); - - // Update the state with the fetched data - // setTransactions(data.result || []); - } catch (err) { - // Handle any errors that occurred during the fetch - // setError("Failed to load data, please try again."); - console.error("Fetch error:", err); - } finally { - // Set loading to false when the request is complete - // setLoading(false); - } - }; - - // Call the fetch function - fetchData(); - }, []); // Empty dependency return ( <> diff --git a/payment-iq/app/features/Pages/transactions/Transactions.tsx b/payment-iq/app/features/Pages/transactions/Transactions.tsx index 473908d..fe594ab 100644 --- a/payment-iq/app/features/Pages/transactions/Transactions.tsx +++ b/payment-iq/app/features/Pages/transactions/Transactions.tsx @@ -28,7 +28,6 @@ import SearchFilters from "@/app/components/searchFilter/SearchFilters"; const paginationModel = { page: 0, pageSize: 50 }; export default function TransactionTable() { - const [form, setForm] = useState({ keyword: "", transactionID: "", @@ -80,7 +79,9 @@ export default function TransactionTable() { const [onlyCurrentTable, setOnlyCurrentTable] = useState(false); const handleExport = () => { - const exportRows = onlyCurrentTable ? transactions.slice(0, 5) : transactions; + const exportRows = onlyCurrentTable + ? transactions.slice(0, 5) + : transactions; const exportData = [ columns.map((col) => col.headerName), ...exportRows.map((row) => columns.map((col) => row[col.field] ?? "")), @@ -103,7 +104,6 @@ export default function TransactionTable() { setOpen(false); }; - const [transactions, setTransactions] = useState([]); const fetchTransactions = async () => { @@ -113,33 +113,27 @@ export default function TransactionTable() { const data = await res.json(); setTransactions(data); } catch (error) { - console.error('Error fetching transactions:', error); + console.error("Error fetching transactions:", error); } }; - - useEffect(() => { fetchTransactions(); }, [form]); const handleDeleteFilter = (key) => { - setForm((prev) => ({ ...prev, [key]: '' })); + setForm((prev) => ({ ...prev, [key]: "" })); }; const handleClearAll = () => { - resetForm() - fetchTransactions() + resetForm(); + fetchTransactions(); }; - const handleClickField = (field: string, value: any) => { setForm((prev) => ({ ...prev, [field]: value })); }; - - - return ( - + {/* */} {/* */} + + + + ); +}; + +export default EditUser; diff --git a/payment-iq/app/features/UserRoles/User.scss b/payment-iq/app/features/UserRoles/User.scss new file mode 100644 index 0000000..5e0384d --- /dev/null +++ b/payment-iq/app/features/UserRoles/User.scss @@ -0,0 +1,6 @@ +.edit-user { + display: flex; + justify-content: center; + align-items: center; + width: 100%; +} diff --git a/payment-iq/app/features/UserRoles/userRoleCard.tsx b/payment-iq/app/features/UserRoles/userRoleCard.tsx index 43828bb..a6dfc5e 100644 --- a/payment-iq/app/features/UserRoles/userRoleCard.tsx +++ b/payment-iq/app/features/UserRoles/userRoleCard.tsx @@ -18,6 +18,8 @@ import { AdminPanelSettings, History, } from "@mui/icons-material"; +import { useState } from "react"; +import EditUser from "./EditUser/EditUser"; interface Props { username: string; @@ -40,12 +42,18 @@ export default function UserRoleCard({ roles, extraRolesCount, }: Props) { + const [isEditing, setIsEditing] = useState(false); + + const handleEditClick = () => { + setIsEditing(!isEditing); + }; + return ( {/* Header */} - {username.slice(0, 2).toUpperCase()} + {username?.slice(0, 2).toUpperCase()} {username} {name} @@ -58,7 +66,7 @@ export default function UserRoleCard({ - + @@ -105,13 +113,13 @@ export default function UserRoleCard({ {extraRolesCount && } - + {isEditing && } {/* Footer */} - + {/* {lastLogin} - + */} ); diff --git a/payment-iq/app/providers/msw-provider.tsx b/payment-iq/app/providers/msw-provider.tsx index 9f3bf55..d186b21 100644 --- a/payment-iq/app/providers/msw-provider.tsx +++ b/payment-iq/app/providers/msw-provider.tsx @@ -1,11 +1,12 @@ -'use client'; -import { useEffect } from 'react'; +"use client"; +import { useEffect } from "react"; export function MSWProvider({ children }: { children: React.ReactNode }) { useEffect(() => { - if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') { - const { worker } = require('../../mock/browser.ts'); - worker.start(); + if (process.env.NEXT_PUBLIC_API_MOCKING === "enabled") { + import("../../mock/browser").then(({ worker }) => { + // worker.start(); + }); } }, []); diff --git a/payment-iq/config/theme.ts b/payment-iq/config/theme.ts index c1b46e5..2d17df3 100644 --- a/payment-iq/config/theme.ts +++ b/payment-iq/config/theme.ts @@ -1,39 +1,43 @@ -import { createTheme } from '@mui/material/styles'; +import { createTheme } from "@mui/material/styles"; const palette = { primary: { - main: '#1976d2', + main: "#1976d2", }, secondary: { - main: '#d32f2f', + main: "#d32f2f", }, background: { - default: '#fafafa', - paper: '#ffffff', - primary: 'rgb(69, 190, 171)', + default: "#fafafa", + paper: "#ffffff", + primary: "rgb(69, 190, 171)", }, text: { - primary: '#000000', - secondary: '#555555', - tertiary: '#fff', + primary: "#000000", + secondary: "#555555", + tertiary: "#fff", + }, + button: { + primary: "#0070f3", + secondary: "##FF00FF", }, action: { - hover: 'rgba(0, 0, 0, 0.08)', + hover: "rgba(0, 0, 0, 0.08)", }, }; const typography = { fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', h1: { - fontSize: '3rem', + fontSize: "3rem", fontWeight: 700, }, h2: { - fontSize: '2.5rem', + fontSize: "2.5rem", fontWeight: 700, }, body1: { - fontSize: '1rem', + fontSize: "1rem", fontWeight: 400, }, }; @@ -41,8 +45,8 @@ const typography = { // Create the theme based on the light or dark mode preference const theme = createTheme({ palette: { - mode: 'light', // Change this to 'dark' for dark mode - ...palette + mode: "light", // Change this to 'dark' for dark mode + ...palette, }, // typography, breakpoints: { diff --git a/payment-iq/mock/browser.ts b/payment-iq/mock/browser.ts index 2845183..bcd82e4 100644 --- a/payment-iq/mock/browser.ts +++ b/payment-iq/mock/browser.ts @@ -1,9 +1,4 @@ -// // mocks/browser.ts import { setupWorker } from "msw/browser"; -// import { handlers } from "./handlers"; -// -// export const worker = setupWorker(...handlers); - -import { setupWorker } from 'msw/browser'; -import { handlers } from './handlers'; +import { setupWorker } from "msw/browser"; +import { handlers } from "./handlers"; export const worker = setupWorker(...handlers); diff --git a/payment-iq/mock/constants.ts b/payment-iq/mock/constants.ts new file mode 100644 index 0000000..5e64ec5 --- /dev/null +++ b/payment-iq/mock/constants.ts @@ -0,0 +1,61 @@ +export const users = [ + { + merchantId: 100987998, + id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9", + mame: "Jacob", + username: "lspaddy", + firstName: "Paddy", + lastName: "Man", + email: "patrick@omegasys.eu", + phone: "", + jobTitle: "", + enabled: true, + authorities: [ + "ROLE_IIN", + "ROLE_FIRST_APPROVER", + "ROLE_RULES_ADMIN", + "ROLE_TRANSACTION_VIEWER", + "ROLE_IIN_ADMIN", + "ROLE_USER_PSP_ACCOUNT", + ], + allowedMerchantIds: [100987998], + created: "2025-05-04T15:32:48.432Z", + disabledBy: null, + disabledDate: null, + disabledReason: null, + incidentNotes: false, + lastLogin: "", + lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", + marketingNewsletter: false, + releaseNotes: false, + requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], + twoFactorCondition: "required", + twoFactorCredentials: [], + }, + { + merchantId: 100987998, + mame: "Jacob", + id: "382eed15-1e21-41fa-b1f3-0c1adb3af714", + username: "lsterence", + firstName: "Terence", + lastName: "User", + email: "terence@omegasys.eu", + phone: "", + jobTitle: "", + enabled: true, + authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"], + allowedMerchantIds: [100987998], + created: "2025-05-04T15:32:48.432Z", + disabledBy: null, + disabledDate: null, + disabledReason: null, + incidentNotes: false, + lastLogin: "", + lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", + marketingNewsletter: false, + releaseNotes: false, + requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], + twoFactorCondition: "required", + twoFactorCredentials: [], + }, +]; diff --git a/payment-iq/mock/handlers.ts b/payment-iq/mock/handlers.ts index d80ae73..b67318f 100644 --- a/payment-iq/mock/handlers.ts +++ b/payment-iq/mock/handlers.ts @@ -1,72 +1,49 @@ -// import { http, HttpResponse } from "msw"; -// -// export const handlers = [ -// http.get( -// "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/metrics/txsummary", -// (req, _res, _ctx) => { -// const merchantId = req.url.searchParams.get("merchantId"); -// const fromDate = req.url.searchParams.get("fromDate"); -// const toDate = req.url.searchParams.get("toDate"); -// -// console.log(merchantId, fromDate, toDate); -// -// return HttpResponse.json({ -// result: { -// txCount: { total: 0, successful: 0 }, -// amount: { value: "0", currency: "EUR" }, -// }, -// }); -// } -// ), -// ]; - - -import { transactionDummyData } from '@/app/features/Pages/transactions/mockData'; -import { http, HttpResponse } from 'msw'; +import { http, HttpResponse } from "msw"; export const handlers = [ // Simple GET endpoint - http.get('https://api.example.com/user', () => { - return HttpResponse.json({ - id: 'usr_123', - name: 'John Doe', - email: 'john@example.com' - }); + http.get("https://api.example.com/user", () => { + return HttpResponse.json([ + { + id: "usr_123", + name: "John Doe", + email: "john@example.com", + }, + ]); }), // POST endpoint with request validation - http.post('https://api.example.com/login', async ({ request }) => { - const { username, password } = await request.json() as { username: string; password: string }; + http.post("https://api.example.com/login", async ({ request }) => { + const { username, password } = (await request.json()) as { + username: string; + password: string; + }; - if (username === 'admin' && password === 'password123') { + if (username === "admin" && password === "password123") { return HttpResponse.json({ - token: 'mock-jwt-token', - user: { id: 'usr_123', name: 'Admin User' } + token: "mock-jwt-token", + user: { id: "usr_123", name: "Admin User" }, }); } - return HttpResponse.json( - { error: 'Invalid credentials' }, - { status: 401 } - ); + return HttpResponse.json({ error: "Invalid credentials" }, { status: 401 }); }), - // Example with query parameters - http.get('https://api.example.com/products', ({ request }) => { + http.get("https://api.example.com/products", ({ request }) => { // Parse the URL to access query parameters const url = new URL(request.url); // Get query parameters - const category = url.searchParams.get('category'); - const sort = url.searchParams.get('sort') || 'price'; - const page = url.searchParams.get('page') || '1'; - const limit = url.searchParams.get('limit') || '10'; + const category = url.searchParams.get("category"); + const sort = url.searchParams.get("sort") || "price"; + const page = url.searchParams.get("page") || "1"; + const limit = url.searchParams.get("limit") || "10"; // Validate parameters if (limit && parseInt(limit) > 100) { return HttpResponse.json( - { error: 'Limit cannot exceed 100' }, + { error: "Limit cannot exceed 100" }, { status: 400 } ); } @@ -74,15 +51,15 @@ export const handlers = [ // Generate mock response based on parameters const mockProducts = Array.from({ length: parseInt(limit) }, (_, i) => ({ id: i + 1, - name: `Product ${i + 1}${category ? ` in ${category}` : ''}`, + name: `Product ${i + 1}${category ? ` in ${category}` : ""}`, price: Math.floor(Math.random() * 100), - category: category || 'general', + category: category || "general", })); // Sort products if sort parameter provided - if (sort === 'price') { + if (sort === "price") { mockProducts.sort((a, b) => a.price - b.price); - } else if (sort === 'name') { + } else if (sort === "name") { mockProducts.sort((a, b) => a.name.localeCompare(b.name)); } @@ -94,38 +71,38 @@ export const handlers = [ sortBy: sort, }); }), - http.get('https://api.example.com/transactions', ({ request }) => { + 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'); + 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 + (tx) => tx.user.toString() === userId ); } if (state) { filteredTransactions = filteredTransactions.filter( - tx => tx.state.toLowerCase() === state.toLowerCase() + (tx) => tx.state.toLowerCase() === state.toLowerCase() ); } if (statusCode) { filteredTransactions = filteredTransactions.filter( - tx => tx.pspStatusCode.toString() === statusCode + (tx) => tx.pspStatusCode.toString() === statusCode ); } return HttpResponse.json({ transactions: filteredTransactions, - count: filteredTransactions.length + count: filteredTransactions.length, }); }), ]; diff --git a/payment-iq/next.config.ts b/payment-iq/next.config.ts index b9172f5..0030107 100644 --- a/payment-iq/next.config.ts +++ b/payment-iq/next.config.ts @@ -3,8 +3,8 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ webpack: (config) => { - if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') { - config.resolve.alias['@mswjs/interceptors'] = false; + if (process.env.NEXT_PUBLIC_API_MOCKING === "enabled") { + config.resolve.alias["@mswjs/interceptors"] = false; } return config; }, diff --git a/payment-iq/styles/globals.scss b/payment-iq/styles/globals.scss index 366294f..940adbe 100644 --- a/payment-iq/styles/globals.scss +++ b/payment-iq/styles/globals.scss @@ -11,6 +11,8 @@ --text-tertiary: #{$text-tertiary}; --hover-color: #{$hover-color}; --font-family-base: #{$font-family-base}; + --button-primary: #{$button-primary}; + --button-secondary: #{$button-secondary}; } @media (prefers-color-scheme: dark) { diff --git a/payment-iq/styles/variables.scss b/payment-iq/styles/variables.scss index d8311d9..5b4eca0 100644 --- a/payment-iq/styles/variables.scss +++ b/payment-iq/styles/variables.scss @@ -5,6 +5,8 @@ $background-primary: rgb(69, 190, 171); $text-primary: #000000; $text-secondary: #555555; $text-tertiary: #ffffff; +$button-primary: #0070f3; +$button-secondary: #ff00ff; $hover-color: rgba(0, 0, 0, 0.08); $font-family-base: "Roboto", "Helvetica", "Arial", sans-serif;