Push with router.refresh
This commit is contained in:
parent
fc4be718f7
commit
16d51f30b5
@ -1,66 +1,127 @@
|
||||
// app/api/user/route.ts
|
||||
import { NextResponse } from "next/server";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
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: [],
|
||||
},
|
||||
];
|
||||
|
||||
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: [],
|
||||
},
|
||||
]);
|
||||
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(newUser);
|
||||
|
||||
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);
|
||||
});
|
||||
*/
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
import Users from "@/app/features/Pages/Admin/Users/users";
|
||||
|
||||
export default async function BackOfficeUsersPage() {
|
||||
const res = await fetch("http://localhost:3000/api/dashboard/admin/users", {
|
||||
const baseUrl =
|
||||
process.env.NEXT_PUBLIC_BASE_URL || process.env.VERCEL_URL
|
||||
? `https://${process.env.VERCEL_URL}`
|
||||
: "http://localhost:3000";
|
||||
const res = await fetch(`${baseUrl}/api/dashboard/admin/users`, {
|
||||
cache: "no-store", // 👈 disables caching for SSR freshness
|
||||
});
|
||||
const users = await res.json();
|
||||
|
||||
console.log("[USERS]", users);
|
||||
return (
|
||||
<div>
|
||||
<Users users={users} />
|
||||
|
||||
@ -1,23 +1,11 @@
|
||||
import React from "react";
|
||||
import "./editUser.scss";
|
||||
|
||||
// Union type for form field names
|
||||
export type EditUserField =
|
||||
| "firstName"
|
||||
| "lastName"
|
||||
| "email"
|
||||
| "role"
|
||||
| "phone";
|
||||
|
||||
interface IEditUserForm {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
role: string;
|
||||
phone: string;
|
||||
}
|
||||
import { useRouter } from "next/navigation";
|
||||
import { IEditUserForm, EditUserField } from "../User.interfaces";
|
||||
import { createRole } from "@/services/roles.services";
|
||||
import "./EditUser.scss";
|
||||
|
||||
const EditUser = () => {
|
||||
const router = useRouter();
|
||||
const [form, setForm] = React.useState<IEditUserForm>({
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
@ -53,8 +41,20 @@ const EditUser = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
await createRole(form);
|
||||
router.refresh(); // <- refreshes the page (SSR re-runs)
|
||||
} catch (err: any) {
|
||||
console.log(err.message || "Error creating role");
|
||||
// setError(err.message || "Error creating role");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form className="edit-user">
|
||||
<form className="edit-user" onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="First Name"
|
||||
|
||||
14
payment-iq/app/features/UserRoles/User.interfaces.ts
Normal file
14
payment-iq/app/features/UserRoles/User.interfaces.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export interface IEditUserForm {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
role: string;
|
||||
phone: string;
|
||||
}
|
||||
|
||||
export type EditUserField =
|
||||
| "firstName"
|
||||
| "lastName"
|
||||
| "email"
|
||||
| "role"
|
||||
| "phone";
|
||||
@ -1,6 +1,17 @@
|
||||
.edit-user {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.user-card {
|
||||
&__edit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__edit-transition {
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
|
||||
&--open {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
payment-iq/app/features/UserRoles/User.types.ts
Normal file
0
payment-iq/app/features/UserRoles/User.types.ts
Normal file
@ -1,3 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@ -18,8 +19,8 @@ import {
|
||||
AdminPanelSettings,
|
||||
History,
|
||||
} from "@mui/icons-material";
|
||||
import { useState } from "react";
|
||||
import EditUser from "./EditUser/EditUser";
|
||||
import "./User.scss";
|
||||
|
||||
interface Props {
|
||||
username: string;
|
||||
@ -99,7 +100,7 @@ export default function UserRoleCard({
|
||||
|
||||
<Box mt={2}>
|
||||
<Typography fontWeight="bold">
|
||||
Roles{" "}
|
||||
Roles
|
||||
<Tooltip title="Roles assigned to this user">
|
||||
<InfoOutlined fontSize="small" />
|
||||
</Tooltip>
|
||||
@ -113,13 +114,13 @@ export default function UserRoleCard({
|
||||
{extraRolesCount && <Chip label={`+${extraRolesCount}`} />}
|
||||
</Stack>
|
||||
</Box>
|
||||
{isEditing && <EditUser />}
|
||||
{/* Footer */}
|
||||
{/* <Box mt={2}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{lastLogin}
|
||||
</Typography>
|
||||
</Box> */}
|
||||
<div
|
||||
className={`user-card__edit-transition${
|
||||
isEditing ? " user-card__edit-transition--open" : ""
|
||||
}`}
|
||||
>
|
||||
{isEditing && <EditUser />}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
15
payment-iq/services/roles.services.ts
Normal file
15
payment-iq/services/roles.services.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { IEditUserForm } from "@/app/features/UserRoles/User.interfaces";
|
||||
|
||||
export async function createRole(data: IEditUserForm) {
|
||||
const res = await fetch("/api/dashboard/admin/users", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to create role");
|
||||
}
|
||||
|
||||
return res.json(); // or return type depending on your backend
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user