Added admin user roles

This commit is contained in:
Mitchell Magro 2025-07-03 22:23:30 +02:00
parent 7f6f603103
commit a2cfede9b9
8 changed files with 357 additions and 8 deletions

View File

@ -1,13 +1,12 @@
// This ensures this component is rendered only on the client side // This ensures this component is rendered only on the client side
"use client"; "use client";
import { Approve } from "@/app/features/Pages/Approve/Approve"; import Users from "@/app/features/Pages/Admin/Users/users";
export default function BackOfficeUsersPage() { export default function BackOfficeUsersPage() {
return ( return (
<div> <div>
{/* This page will now be rendered on the client-side */} <Users />
<Approve />
</div> </div>
); );
} }

View File

@ -1,7 +1,7 @@
// This ensures this component is rendered only on the client side // This ensures this component is rendered only on the client side
"use client"; "use client";
import TransactionTable from "@/app/features/Pages/transactions/Transactions"; import TransactionTable from "@/app/features/Pages/Transactions/Transactions";
export default function TransactionPage() { export default function TransactionPage() {
return ( return (

View File

@ -0,0 +1,26 @@
export interface IUser {
merchantId: number;
name?: string;
id: string;
username: string;
firstName: string;
lastName: string;
email: string;
phone: string;
jobTitle: string;
enabled: boolean;
authorities: string[];
allowedMerchantIds: number[];
created: string;
disabledBy: string | null;
disabledDate: string | null;
disabledReason: string | null;
incidentNotes: boolean;
lastLogin: string;
lastMandatoryUpdated: string;
marketingNewsletter: boolean;
releaseNotes: boolean;
requiredActions: string[];
twoFactorCondition: string;
twoFactorCredentials: any[]; // Assuming this is an array that could contain any type of data
}

View File

@ -0,0 +1,131 @@
"use client";
import React, { useEffect, useState } from "react";
import { Card, CardContent, Typography, Chip, Stack } from "@mui/material";
import { IUser } from "./interfaces";
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();
}
}, []);
return (
<div>
{data.map((user: IUser) => (
<Card key={user.id} sx={{ mb: 2 }}>
<CardContent>
<Typography variant="h6">{user.username}</Typography>
<Typography variant="body2">
Merchant ID: {user.merchantId}
</Typography>
{/* You can render more UI here for additional properties */}
<Stack direction="row" spacing={1} mt={1}>
<UserRoleCard
username={user.lastName}
name={user.name || ""}
email={user.email}
isAdmin={true}
lastLogin="small"
roles={user.authorities}
// merchants={Numberuser.allowedMerchantIds}
/>
{/* Add more chips or UI elements for other data */}
</Stack>
</CardContent>
</Card>
))}
</div>
);
};
// 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;

View File

@ -0,0 +1,118 @@
import {
Card,
CardContent,
Avatar,
Typography,
Chip,
IconButton,
Tooltip,
Stack,
Box,
} from "@mui/material";
import {
Edit,
Delete,
Visibility,
VpnKey,
InfoOutlined,
AdminPanelSettings,
History,
} from "@mui/icons-material";
interface Props {
username: string;
name: string;
email: string;
isAdmin: boolean;
lastLogin: string;
merchants: string[];
roles: string[];
extraRolesCount?: number;
}
export default function UserRoleCard({
username,
name,
email,
isAdmin,
lastLogin,
// merchants,
roles,
extraRolesCount,
}: Props) {
return (
<Card sx={{ mb: 2, minWidth: "100%" }}>
<CardContent>
{/* Header */}
<Stack direction="row" alignItems="center" spacing={2}>
<Avatar>{username.slice(0, 2).toUpperCase()}</Avatar>
<Box flexGrow={1}>
<Typography fontWeight="bold">{username}</Typography>
<Typography variant="body2">{name}</Typography>
<Typography variant="caption">{email}</Typography>
</Box>
{isAdmin && (
<Chip icon={<AdminPanelSettings />} label="Admin" size="small" />
)}
<IconButton>
<History />
</IconButton>
<Tooltip title="Edit">
<IconButton>
<Edit />
</IconButton>
</Tooltip>
<Tooltip title="View">
<IconButton>
<Visibility />
</IconButton>
</Tooltip>
<Tooltip title="Reset Password">
<IconButton>
<VpnKey />
</IconButton>
</Tooltip>
<Tooltip title="Delete">
<IconButton>
<Delete />
</IconButton>
</Tooltip>
</Stack>
{/* Merchants + Roles */}
<Box mt={2}>
<Typography fontWeight="bold">Merchants</Typography>
{/* <Stack direction="row" spacing={1} mt={1}>
{merchants.map((m) => (
<Chip key={m} label={m} size="small" />
))}
</Stack> */}
</Box>
<Box mt={2}>
<Typography fontWeight="bold">
Roles{" "}
<Tooltip title="Roles assigned to this user">
<InfoOutlined fontSize="small" />
</Tooltip>
</Typography>
<Stack direction="row" spacing={1} mt={1} flexWrap="wrap">
<Stack direction="row" spacing={1}>
{roles.map((role) => (
<Chip key={role} label={role} size="small" />
))}
</Stack>
{extraRolesCount && <Chip label={`+${extraRolesCount}`} />}
</Stack>
</Box>
{/* Footer */}
<Box mt={2}>
<Typography variant="caption" color="text.secondary">
{lastLogin}
</Typography>
</Box>
</CardContent>
</Card>
);
}

View File

@ -19,7 +19,7 @@ const SideBar = () => {
<aside className="sidebar"> <aside className="sidebar">
<div className="sidebar__header"> <div className="sidebar__header">
<span> <span>
Betrise cashir{" "} Betrise cashir
<DashboardIcon fontSize="small" className="sidebar__icon-spacing" /> <DashboardIcon fontSize="small" className="sidebar__icon-spacing" />
</span> </span>
</div> </div>

View File

@ -37,17 +37,17 @@ export const PAGE_LINKS: ISidebarLink[] = [
children: [ children: [
{ {
title: "Manage Users", title: "Manage Users",
path: "/admin/users", path: "/dashboard/admin/users",
icon: PeopleIcon, icon: PeopleIcon,
}, },
{ {
title: "Transactions", title: "Transactions",
path: "/admin/transactions", path: "/dashboard/admin/transactions",
icon: ListAltIcon, icon: ListAltIcon,
}, },
{ {
title: "Settings", title: "Settings",
path: "/admin/settings", path: "dashboard/admin/settings",
icon: SettingsIcon, icon: SettingsIcon,
}, },
], ],

View File

@ -18,4 +18,79 @@ export const handlers = [
}); });
} }
), ),
http.get(
"https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/users/",
(req, _res, _ctx) => {
// Mock data for merchantId = 100987998
if (true) {
return HttpResponse.json({
result: [
{
merchantId: 100987998,
id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9",
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,
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
],
total: 4,
});
}
}
),
]; ];