Files
saas_frontend/src/application/modules/admin/components/ModulePermissions.tsx
T
2026-04-25 08:34:57 +03:00

102 lines
3.9 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, RefreshCw, Shield } from 'lucide-react';
import { useModuleApi } from '../hooks/useModuleApi';
import Loader from '../../../../components/custom/CustomLoader';
import type { ModulePermission, Module } from '../AdminModuleTypes';
import CustomButton from '../../../../components/custom/CustomButton';
import { NodeGroupAccessViewer } from '../../../roles/components/NodeGroupAccessViewer';
import type { RoleAccess } from '../../../roles/RolesTypes';
const ModulePermissions = () => {
const { moduleId } = useParams<{ moduleId: string }>();
const navigate = useNavigate();
const { getModule, getPermissions, syncPermissions, loading } = useModuleApi();
const [module, setModule] = useState<Module | null>(null);
const [permissions, setPermissions] = useState<ModulePermission[]>([]);
const [syncing, setSyncing] = useState(false);
const fetchData = async () => {
if (!moduleId) return;
const [moduleData, permsData] = await Promise.all([
getModule(moduleId),
getPermissions(moduleId)
]);
if (moduleData) setModule(moduleData);
if (permsData) setPermissions(permsData);
};
useEffect(() => {
fetchData();
}, [moduleId]);
const handleSync = async () => {
if (!moduleId) return;
setSyncing(true);
const result = await syncPermissions(moduleId);
if (result) {
fetchData();
}
setSyncing(false);
};
const viewerAccesses: RoleAccess[] = permissions.map(p => ({
id: p.id,
access_code: p.access_code,
name: p.name,
category: p.category || 'General',
parent_id: p.parent_id
}));
return (
<div className="space-y-6">
<div className="flex items-center gap-4">
<button
onClick={() => navigate('/admin/modules')}
className="p-2 hover:bg-(--background) rounded-lg transition-colors text-(--text-secondary) hover:text-(--text-primary)"
>
<ArrowLeft size={20} />
</button>
<div className="flex flex-col gap-1">
<h1 className="text-2xl font-bold text-(--text-primary)">
{module?.module_name || 'Loading...'} - Permissions
</h1>
<p className="text-sm text-(--text-secondary)">View and sync permissions from module</p>
</div>
<div className="ml-auto">
<CustomButton
onClick={handleSync}
loading={syncing}
leftIcon={!syncing && <RefreshCw size={20} />}
>
{syncing ? 'Syncing...' : 'Sync Permissions'}
</CustomButton>
</div>
</div>
{loading ? (
<div className=" p-12 flex flex-col items-center justify-center min-h-[300px]">
<Loader size="md" />
</div>
) : permissions.length > 0 ? (
<div className="bg-(--card-bg) border border-(--card-border) rounded-lg p-6">
<NodeGroupAccessViewer accesses={viewerAccesses} />
</div>
) : (
<div className="bg-(--card-bg) border border-(--card-border) rounded-lg p-12 text-center">
<Shield className="w-16 h-16 text-(--text-secondary) mx-auto mb-4" />
<h3 className="text-lg font-semibold text-(--text-primary) mb-2">No Permissions Synced</h3>
<p className="text-(--text-secondary) mb-4">Click "Sync Permissions" to fetch from the module</p>
</div>
)}
</div>
);
};
export default ModulePermissions;