Push with router.refresh
This commit is contained in:
parent
fc4be718f7
commit
16d51f30b5
@ -1,66 +1,127 @@
|
|||||||
// app/api/user/route.ts
|
// 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() {
|
export async function GET() {
|
||||||
return NextResponse.json([
|
return NextResponse.json(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 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";
|
import Users from "@/app/features/Pages/Admin/Users/users";
|
||||||
|
|
||||||
export default async function BackOfficeUsersPage() {
|
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
|
cache: "no-store", // 👈 disables caching for SSR freshness
|
||||||
});
|
});
|
||||||
const users = await res.json();
|
const users = await res.json();
|
||||||
|
|
||||||
console.log("[USERS]", users);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Users users={users} />
|
<Users users={users} />
|
||||||
|
|||||||
@ -1,23 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import "./editUser.scss";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { IEditUserForm, EditUserField } from "../User.interfaces";
|
||||||
// Union type for form field names
|
import { createRole } from "@/services/roles.services";
|
||||||
export type EditUserField =
|
import "./EditUser.scss";
|
||||||
| "firstName"
|
|
||||||
| "lastName"
|
|
||||||
| "email"
|
|
||||||
| "role"
|
|
||||||
| "phone";
|
|
||||||
|
|
||||||
interface IEditUserForm {
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
email: string;
|
|
||||||
role: string;
|
|
||||||
phone: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EditUser = () => {
|
const EditUser = () => {
|
||||||
|
const router = useRouter();
|
||||||
const [form, setForm] = React.useState<IEditUserForm>({
|
const [form, setForm] = React.useState<IEditUserForm>({
|
||||||
firstName: "",
|
firstName: "",
|
||||||
lastName: "",
|
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 (
|
return (
|
||||||
<form className="edit-user">
|
<form className="edit-user" onSubmit={handleSubmit}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="First Name"
|
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 {
|
.user-card {
|
||||||
display: flex;
|
&__edit {
|
||||||
justify-content: center;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
width: 100%;
|
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 {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@ -18,8 +19,8 @@ import {
|
|||||||
AdminPanelSettings,
|
AdminPanelSettings,
|
||||||
History,
|
History,
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { useState } from "react";
|
|
||||||
import EditUser from "./EditUser/EditUser";
|
import EditUser from "./EditUser/EditUser";
|
||||||
|
import "./User.scss";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
username: string;
|
username: string;
|
||||||
@ -99,7 +100,7 @@ export default function UserRoleCard({
|
|||||||
|
|
||||||
<Box mt={2}>
|
<Box mt={2}>
|
||||||
<Typography fontWeight="bold">
|
<Typography fontWeight="bold">
|
||||||
Roles{" "}
|
Roles
|
||||||
<Tooltip title="Roles assigned to this user">
|
<Tooltip title="Roles assigned to this user">
|
||||||
<InfoOutlined fontSize="small" />
|
<InfoOutlined fontSize="small" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -113,13 +114,13 @@ export default function UserRoleCard({
|
|||||||
{extraRolesCount && <Chip label={`+${extraRolesCount}`} />}
|
{extraRolesCount && <Chip label={`+${extraRolesCount}`} />}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
{isEditing && <EditUser />}
|
<div
|
||||||
{/* Footer */}
|
className={`user-card__edit-transition${
|
||||||
{/* <Box mt={2}>
|
isEditing ? " user-card__edit-transition--open" : ""
|
||||||
<Typography variant="caption" color="text.secondary">
|
}`}
|
||||||
{lastLogin}
|
>
|
||||||
</Typography>
|
{isEditing && <EditUser />}
|
||||||
</Box> */}
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</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