feat: app permissions admin page
This commit is contained in:
@ -27,6 +27,7 @@ import VerifyAvatarPage from "./pages/Verify/Avatar";
|
|||||||
import VerifyReviewPage from "./pages/Verify/Review";
|
import VerifyReviewPage from "./pages/Verify/Review";
|
||||||
import AdminUserSessionsPage from "./pages/Admin/UserSessions";
|
import AdminUserSessionsPage from "./pages/Admin/UserSessions";
|
||||||
import AdminServiceSessionsPage from "./pages/Admin/ServiceSessions";
|
import AdminServiceSessionsPage from "./pages/Admin/ServiceSessions";
|
||||||
|
import AdminAppPermissionsPage from "./pages/Admin/AppPermissions";
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@ -93,6 +94,12 @@ const router = createBrowserRouter([
|
|||||||
{ index: true, element: <AdminServiceSessionsPage /> },
|
{ index: true, element: <AdminServiceSessionsPage /> },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "app-permissions",
|
||||||
|
children: [
|
||||||
|
{ index: true, element: <AdminAppPermissionsPage /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
130
web/src/pages/Admin/AppPermissions/index.tsx
Normal file
130
web/src/pages/Admin/AppPermissions/index.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import { useEffect, type FC } from "react";
|
||||||
|
import Breadcrumbs from "@/components/ui/breadcrumbs";
|
||||||
|
import { usePermissions } from "@/store/admin/permissions";
|
||||||
|
|
||||||
|
interface DisplayPermission {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPermissionGroupProps {
|
||||||
|
scope: string;
|
||||||
|
permissions?: DisplayPermission[] | null | undefined;
|
||||||
|
generatedPermissions?: DisplayPermission[] | null | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PermissionGroup: FC<IPermissionGroupProps> = ({
|
||||||
|
scope,
|
||||||
|
permissions,
|
||||||
|
generatedPermissions,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="border dark:border-gray-800 border-gray-300 p-4 rounded mb-4">
|
||||||
|
<h2 className="dark:text-gray-300 text-gray-800 text-lg font-semibold">
|
||||||
|
{scope}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{(generatedPermissions?.length ?? 0) > 0 && (
|
||||||
|
<>
|
||||||
|
<p className="text-gray-500 text-sm mt-2 mb-4">Generated by Guard</p>
|
||||||
|
|
||||||
|
<ol
|
||||||
|
className={`grid gap-4 gap-y-3 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 text-gray-800 dark:text-gray-300 font-medium mb-${permissions && permissions.length > 0 ? "6" : "2"}`}
|
||||||
|
>
|
||||||
|
{generatedPermissions!.map(({ name, description }) => (
|
||||||
|
<li className="before:w-2 before:h-2 before:block before:translate-y-2 before:bg-gray-400 dark:before:bg-gray-700 before:rounded-xs flex flex-row items-start gap-2">
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<label>{name}</label>
|
||||||
|
<p className="text-xs text-gray-400 dark:text-gray-500">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(permissions?.length ?? 0) > 0 && (
|
||||||
|
<>
|
||||||
|
<p className="text-gray-500 text-sm mt-2 mb-4">Manually Created</p>
|
||||||
|
|
||||||
|
<ol className="grid gap-4 gap-y-3 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 text-gray-800 dark:text-gray-300 font-medium">
|
||||||
|
{permissions!.map(({ name, description }) => (
|
||||||
|
<li className="before:w-2 before:h-2 before:block before:translate-y-2 before:bg-gray-400 dark:before:bg-gray-700 before:rounded-xs flex flex-row items-start gap-2">
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<label>{name}</label>
|
||||||
|
<p className="text-xs text-gray-400 dark:text-gray-500">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const AdminAppPermissionsPage: FC = () => {
|
||||||
|
const permissions = usePermissions((s) => s.permissions);
|
||||||
|
const fetch = usePermissions((s) => s.fetch);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch();
|
||||||
|
}, [fetch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative flex flex-col items-stretch w-full">
|
||||||
|
<div className="p-4">
|
||||||
|
<Breadcrumbs
|
||||||
|
className="pb-2"
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
href: "/admin",
|
||||||
|
label: "Admin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "App Permissions",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="px-7">
|
||||||
|
{Object.keys(permissions).map((scope) => (
|
||||||
|
<PermissionGroup
|
||||||
|
scope={scope.toUpperCase()}
|
||||||
|
generatedPermissions={permissions[scope].map((p) => ({
|
||||||
|
name: p.name
|
||||||
|
.split("_")
|
||||||
|
.map((s) => s[0].toUpperCase() + s.slice(1))
|
||||||
|
.join(" "),
|
||||||
|
description: p.description,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{/* <PermissionGroup
|
||||||
|
scope="Open Chat"
|
||||||
|
generatedPermissions={["Access Open Chat"].map((name) => ({
|
||||||
|
name,
|
||||||
|
description: `You can ${name.toLowerCase()}`,
|
||||||
|
}))}
|
||||||
|
permissions={[
|
||||||
|
"Receive Messages",
|
||||||
|
"Send Messages",
|
||||||
|
"View Status",
|
||||||
|
"Post Status",
|
||||||
|
"Use Ghost Mode",
|
||||||
|
"Send Large Media",
|
||||||
|
].map((name) => ({
|
||||||
|
name,
|
||||||
|
description: `You can ${name.toLowerCase()}`,
|
||||||
|
}))}
|
||||||
|
/> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AdminAppPermissionsPage;
|
Reference in New Issue
Block a user