Added more to add user
This commit is contained in:
parent
7dd4323ebe
commit
f0ddb809d7
@ -35,16 +35,28 @@ export const users = [
|
|||||||
twoFactorCondition: "required",
|
twoFactorCondition: "required",
|
||||||
twoFactorCredentials: [],
|
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,
|
merchantId: 100987998,
|
||||||
mame: "Jacob",
|
mame: "Jacob",
|
||||||
id: "382eed15-1e21-41fa-b1f3-0c1adb3af714",
|
id: "382eed15-1e21-41fa-b1f3-0c1adb3af714",
|
||||||
username: "lsterence",
|
username: "lsterence",
|
||||||
firstName: "Terence",
|
firstName,
|
||||||
lastName: "User",
|
lastName,
|
||||||
email: "terence@omegasys.eu",
|
email,
|
||||||
phone: "",
|
phone,
|
||||||
jobTitle: "",
|
jobTitle: "",
|
||||||
|
role,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"],
|
authorities: ["ROLE_IIN", "ROLE_FIRST_APPROVER", "ROLE_RULES_ADMIN"],
|
||||||
allowedMerchantIds: [100987998],
|
allowedMerchantIds: [100987998],
|
||||||
@ -60,68 +72,8 @@ export const users = [
|
|||||||
requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"],
|
requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"],
|
||||||
twoFactorCondition: "required",
|
twoFactorCondition: "required",
|
||||||
twoFactorCredentials: [],
|
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(users, { status: 201 });
|
||||||
|
|
||||||
return NextResponse.json(newUser, { 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);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|||||||
53
payment-iq/app/components/Modal/Modal.scss
Normal file
53
payment-iq/app/components/Modal/Modal.scss
Normal file
@ -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;
|
||||||
|
}
|
||||||
48
payment-iq/app/components/Modal/Modal.tsx
Normal file
48
payment-iq/app/components/Modal/Modal.tsx
Normal file
@ -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<ModalProps> = ({
|
||||||
|
open,
|
||||||
|
onClose,
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
className = "",
|
||||||
|
}) => {
|
||||||
|
if (!open) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={"modal__overlay"}
|
||||||
|
onClick={onClose}
|
||||||
|
data-testid="modal-overlay"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`modal${className ? " " + className : ""}`}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
data-testid="modal-content"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="modal__close"
|
||||||
|
onClick={onClose}
|
||||||
|
aria-label="Close"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
{title && <h2 className="modal__title">{title}</h2>}
|
||||||
|
<div className={"modal__body"}>{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
||||||
@ -1,16 +1,22 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { Card, CardContent, Typography, Stack } from "@mui/material";
|
import { Card, CardContent, Typography, Stack } from "@mui/material";
|
||||||
import { IUser } from "./interfaces";
|
import { IUser } from "./interfaces";
|
||||||
import UserRoleCard from "@/app/features/UserRoles/UserRoleCard";
|
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 {
|
interface UsersProps {
|
||||||
users: IUser[];
|
users: IUser[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Users: React.FC<UsersProps> = ({ users }) => {
|
const Users: React.FC<UsersProps> = ({ users }) => {
|
||||||
|
const [showAddUser, setShowAddUser] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<UserTopBar onAddUser={() => setShowAddUser(true)} />
|
||||||
{users.map((user: IUser) => (
|
{users.map((user: IUser) => (
|
||||||
<Card key={user.id} sx={{ mb: 2 }}>
|
<Card key={user.id} sx={{ mb: 2 }}>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
@ -35,6 +41,14 @@ const Users: React.FC<UsersProps> = ({ users }) => {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
open={showAddUser}
|
||||||
|
onClose={() => setShowAddUser(false)}
|
||||||
|
title="Add User"
|
||||||
|
>
|
||||||
|
<EditUser />
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,46 +1,34 @@
|
|||||||
.edit-user {
|
.add-user {
|
||||||
margin-top: 30px;
|
position: sticky;
|
||||||
|
top: 40px;
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
justify-content: flex-end;
|
||||||
gap: 16px;
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
input {
|
&__button {
|
||||||
flex: 1 1 20%;
|
padding: 0.5rem 1rem;
|
||||||
min-width: 150px;
|
border: none;
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 8px;
|
|
||||||
font-size: 1rem;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #ccc;
|
cursor: pointer;
|
||||||
outline: none;
|
font-size: 1rem;
|
||||||
transition: border-color 0.3s ease;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
&:focus {
|
gap: 0.5rem;
|
||||||
border-color: #0070f3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&__button-container {
|
|
||||||
flex-basis: 100%;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
button {
|
&__button--primary {
|
||||||
flex-basis: 100%;
|
background: #1976d2;
|
||||||
margin-top: 16px;
|
color: #fff;
|
||||||
padding: 10px 0;
|
}
|
||||||
font-size: 1rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
width: 100px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:first-child {
|
&__button--secondary {
|
||||||
color: var(--button-primary);
|
background: #e0e0e0;
|
||||||
border-color: var(--button-primary);
|
color: #333;
|
||||||
}
|
|
||||||
button:last-child {
|
|
||||||
color: var(--button-secondary);
|
|
||||||
border-color: var(--button-secondary);
|
|
||||||
margin-left: 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 (
|
||||||
|
<div className="add-user">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={onAddUser}
|
||||||
|
className="add-user__button add-user__button--primary"
|
||||||
|
>
|
||||||
|
<Add />
|
||||||
|
Add User
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={onExport}
|
||||||
|
className="add-user__button add-user__button--secondary"
|
||||||
|
disabled
|
||||||
|
title="Export to Excel (coming soon)"
|
||||||
|
>
|
||||||
|
Export to Excel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddUser;
|
||||||
Loading…
x
Reference in New Issue
Block a user