From f0ddb809d72d7cb9d0d61c66f6be2aa4b39083d5 Mon Sep 17 00:00:00 2001 From: Mitchell Magro Date: Mon, 14 Jul 2025 18:56:59 +0200 Subject: [PATCH] Added more to add user --- .../app/api/dashboard/admin/users/route.ts | 86 ++++--------------- payment-iq/app/components/Modal/Modal.scss | 53 ++++++++++++ payment-iq/app/components/Modal/Modal.tsx | 48 +++++++++++ .../app/features/Pages/Admin/Users/users.tsx | 16 +++- .../features/UserRoles/AddUser/AddUser.scss | 64 ++++++-------- .../features/UserRoles/AddUser/AddUser.tsx | 32 +++++++ 6 files changed, 193 insertions(+), 106 deletions(-) create mode 100644 payment-iq/app/components/Modal/Modal.scss create mode 100644 payment-iq/app/components/Modal/Modal.tsx diff --git a/payment-iq/app/api/dashboard/admin/users/route.ts b/payment-iq/app/api/dashboard/admin/users/route.ts index b64d0f0..6352b69 100644 --- a/payment-iq/app/api/dashboard/admin/users/route.ts +++ b/payment-iq/app/api/dashboard/admin/users/route.ts @@ -35,16 +35,28 @@ export const users = [ twoFactorCondition: "required", twoFactorCredentials: [], }, - { +]; + +export async function GET() { + return NextResponse.json(users); +} + +export async function POST(request: NextRequest) { + const body = await request.json(); + const { firstName, lastName, email, phone, role } = body; + + // Add the new user to the existing users array (in-memory, not persistent) + const bodytoAdd = { merchantId: 100987998, mame: "Jacob", id: "382eed15-1e21-41fa-b1f3-0c1adb3af714", username: "lsterence", - firstName: "Terence", - lastName: "User", - email: "terence@omegasys.eu", - phone: "", + firstName, + lastName, + email, + phone, jobTitle: "", + role, enabled: true, authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"], allowedMerchantIds: [100987998], @@ -60,68 +72,8 @@ export const users = [ requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], twoFactorCondition: "required", twoFactorCredentials: [], - }, -]; - -export async function GET() { - return NextResponse.json(users); -} - -export async function POST(request: NextRequest) { - const body = await request.json(); - - // Use the first user as a template - const templateUser = users[0]; - - // Create the new user by spreading the template and then the body (body fields override template) - const newUser = { - ...templateUser, - ...body, - id: - typeof crypto !== "undefined" && crypto.randomUUID - ? crypto.randomUUID() - : Math.random().toString(36).substring(2, 15), - created: new Date().toISOString(), }; + users.push(bodytoAdd); - users.push(newUser); - - return NextResponse.json(newUser, { status: 201 }); + return NextResponse.json(users, { status: 201 }); } - -// To call the POST function from the client side, you can use fetch like this: - -/* -Example usage in a React component or any client-side JS: - -const createUser = async (userData) => { - const res = await fetch('/api/dashboard/admin/users', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(userData), - }); - - if (!res.ok) { - // handle error - throw new Error('Failed to create user'); - } - - const newUser = await res.json(); - return newUser; -}; - -// Usage: -createUser({ - username: "newuser", - firstName: "New", - lastName: "User", - email: "newuser@example.com", - // ...other fields as needed -}).then(user => { - console.log('Created user:', user); -}).catch(err => { - console.error(err); -}); -*/ diff --git a/payment-iq/app/components/Modal/Modal.scss b/payment-iq/app/components/Modal/Modal.scss new file mode 100644 index 0000000..8dedc7f --- /dev/null +++ b/payment-iq/app/components/Modal/Modal.scss @@ -0,0 +1,53 @@ +.modal__overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.5); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; +} + +.modal { + background: #fff; + border-radius: 8px; + box-shadow: 0 2px 16px rgba(0, 0, 0, 0.2); + position: relative; + min-width: 320px; + max-width: 90vw; + max-height: 90vh; + overflow: auto; + padding: 2rem 1.5rem 1.5rem 1.5rem; + display: flex; + flex-direction: column; +} + +.modal__close { + position: absolute; + top: 1rem; + right: 1rem; + background: transparent; + border: none; + font-size: 2rem; + line-height: 1; + cursor: pointer; + color: #888; + transition: color 0.2s; + + &:hover, + &:focus { + color: #333; + outline: none; + } +} + +.modal__body { + // Example element block for modal content + margin-top: 1rem; + font-size: 1rem; + color: #222; + width: 500px; +} diff --git a/payment-iq/app/components/Modal/Modal.tsx b/payment-iq/app/components/Modal/Modal.tsx new file mode 100644 index 0000000..7a5a2c6 --- /dev/null +++ b/payment-iq/app/components/Modal/Modal.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import "./Modal.scss"; + +interface ModalProps { + open: boolean; + onClose: () => void; + children: React.ReactNode; + className?: string; + overlayClassName?: string; + title?: string; +} + +const Modal: React.FC = ({ + open, + onClose, + children, + title, + className = "", +}) => { + if (!open) return null; + + return ( +
+
e.stopPropagation()} + data-testid="modal-content" + > + + {title &&

{title}

} +
{children}
+
+
+ ); +}; + +export default Modal; diff --git a/payment-iq/app/features/Pages/Admin/Users/users.tsx b/payment-iq/app/features/Pages/Admin/Users/users.tsx index e829d7d..df5dc8e 100644 --- a/payment-iq/app/features/Pages/Admin/Users/users.tsx +++ b/payment-iq/app/features/Pages/Admin/Users/users.tsx @@ -1,16 +1,22 @@ "use client"; -import React from "react"; +import React, { useState } from "react"; import { Card, CardContent, Typography, Stack } from "@mui/material"; import { IUser } from "./interfaces"; import UserRoleCard from "@/app/features/UserRoles/UserRoleCard"; +import UserTopBar from "@/app/features/UserRoles/AddUser/AddUser"; +import EditUser from "@/app/features/UserRoles/EditUser/EditUser"; +import Modal from "@/app/components/Modal/Modal"; interface UsersProps { users: IUser[]; } const Users: React.FC = ({ users }) => { + const [showAddUser, setShowAddUser] = useState(false); + return (
+ setShowAddUser(true)} /> {users.map((user: IUser) => ( @@ -35,6 +41,14 @@ const Users: React.FC = ({ users }) => { ))} + + setShowAddUser(false)} + title="Add User" + > + +
); }; diff --git a/payment-iq/app/features/UserRoles/AddUser/AddUser.scss b/payment-iq/app/features/UserRoles/AddUser/AddUser.scss index 7e2e617..d6fc563 100644 --- a/payment-iq/app/features/UserRoles/AddUser/AddUser.scss +++ b/payment-iq/app/features/UserRoles/AddUser/AddUser.scss @@ -1,46 +1,34 @@ -.edit-user { - margin-top: 30px; +.add-user { + position: sticky; + top: 40px; + width: 100%; + background: #fff; + z-index: 10; display: flex; - flex-wrap: wrap; - gap: 16px; + justify-content: flex-end; + align-items: center; + gap: 1rem; + padding: 1rem 0.5rem; + border-bottom: 1px solid #eee; - input { - flex: 1 1 20%; - min-width: 150px; - box-sizing: border-box; - padding: 8px; - font-size: 1rem; + &__button { + padding: 0.5rem 1rem; + border: none; border-radius: 4px; - border: 1px solid #ccc; - outline: none; - transition: border-color 0.3s ease; - - &:focus { - border-color: #0070f3; - } + cursor: pointer; + font-size: 1rem; + display: flex; + align-items: center; + gap: 0.5rem; } - &__button-container { - flex-basis: 100%; - width: 100%; - button { - flex-basis: 100%; - margin-top: 16px; - padding: 10px 0; - font-size: 1rem; - border-radius: 4px; - width: 100px; - cursor: pointer; - } + &__button--primary { + background: #1976d2; + color: #fff; + } - button:first-child { - color: var(--button-primary); - border-color: var(--button-primary); - } - button:last-child { - color: var(--button-secondary); - border-color: var(--button-secondary); - margin-left: 8; - } + &__button--secondary { + background: #e0e0e0; + color: #333; } } diff --git a/payment-iq/app/features/UserRoles/AddUser/AddUser.tsx b/payment-iq/app/features/UserRoles/AddUser/AddUser.tsx index e69de29..9f79eb7 100644 --- a/payment-iq/app/features/UserRoles/AddUser/AddUser.tsx +++ b/payment-iq/app/features/UserRoles/AddUser/AddUser.tsx @@ -0,0 +1,32 @@ +import { Add } from "@mui/icons-material"; +import React from "react"; +import "./AddUser.scss"; + +const AddUser: React.FC<{ + onAddUser?: () => void; + onExport?: () => void; +}> = ({ onAddUser, onExport }) => { + return ( +
+ + +
+ ); +}; + +export default AddUser;