Refactor: Implement permission notice for admin role
This commit is contained in:
@@ -1,14 +1,15 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Settings, Mail } from "lucide-react";
|
import { Settings, Mail, ShieldAlert } from "lucide-react";
|
||||||
import { Form } from "@/components/ui/form";
|
import { Form } from "@/components/ui/form";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useLanguage } from "@/contexts/LanguageContext";
|
import { useLanguage } from "@/contexts/LanguageContext";
|
||||||
import { useSystemSettings } from "@/hooks/useSystemSettings";
|
import { useSystemSettings } from "@/hooks/useSystemSettings";
|
||||||
import { GeneralSettings } from "@/services/settingsService";
|
import { GeneralSettings } from "@/services/settingsService";
|
||||||
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
|
import { authService } from "@/services/authService";
|
||||||
import SystemSettingsTab from './SystemSettingsTab';
|
import SystemSettingsTab from './SystemSettingsTab';
|
||||||
import MailSettingsTab from './MailSettingsTab';
|
import MailSettingsTab from './MailSettingsTab';
|
||||||
import { GeneralSettingsPanelProps } from './types';
|
import { GeneralSettingsPanelProps } from './types';
|
||||||
@@ -18,6 +19,10 @@ const GeneralSettingsPanel: React.FC<GeneralSettingsPanelProps> = () => {
|
|||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState("system");
|
const [activeTab, setActiveTab] = useState("system");
|
||||||
|
|
||||||
|
// Get current user to check permissions
|
||||||
|
const currentUser = authService.getCurrentUser();
|
||||||
|
const isSuperAdmin = currentUser?.role === "superadmin";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
settings,
|
settings,
|
||||||
isLoading,
|
isLoading,
|
||||||
@@ -50,7 +55,7 @@ const GeneralSettingsPanel: React.FC<GeneralSettingsPanelProps> = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (settings) {
|
if (settings && isSuperAdmin) {
|
||||||
// Initialize form with existing settings, using system_name for appName if meta.appName is not set
|
// Initialize form with existing settings, using system_name for appName if meta.appName is not set
|
||||||
const appName = settings.meta?.appName || settings.system_name || '';
|
const appName = settings.meta?.appName || settings.system_name || '';
|
||||||
|
|
||||||
@@ -74,7 +79,7 @@ const GeneralSettingsPanel: React.FC<GeneralSettingsPanelProps> = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [settings, form]);
|
}, [settings, form, isSuperAdmin]);
|
||||||
|
|
||||||
const handleSave = async (formData: GeneralSettings) => {
|
const handleSave = async (formData: GeneralSettings) => {
|
||||||
try {
|
try {
|
||||||
@@ -134,6 +139,27 @@ const GeneralSettingsPanel: React.FC<GeneralSettingsPanelProps> = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Show permission notice for admin users
|
||||||
|
if (!isSuperAdmin) {
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>{t("generalSettings", "menu")}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-4">
|
||||||
|
<Alert className="border-blue-200 bg-blue-50 dark:bg-blue-950 dark:border-blue-800">
|
||||||
|
<ShieldAlert className="h-5 w-5 text-blue-600 dark:text-blue-400" />
|
||||||
|
<AlertDescription className="text-blue-700 dark:text-blue-300">
|
||||||
|
<span className="font-medium">Permission Notice:</span> As an admin user, you do not have access to view or modify system and mail settings. These settings can only be accessed and modified by Super Admins. Contact your Super Admin if you need to make changes to system configuration or mail settings.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <div className="p-4">Loading settings...</div>;
|
return <div className="p-4">Loading settings...</div>;
|
||||||
}
|
}
|
||||||
@@ -147,9 +173,6 @@ const GeneralSettingsPanel: React.FC<GeneralSettingsPanelProps> = () => {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>{t("generalSettings", "menu")}</CardTitle>
|
<CardTitle>{t("generalSettings", "menu")}</CardTitle>
|
||||||
<CardDescription>
|
|
||||||
{t("monitorSSLCertificates", "ssl")}
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const SystemSettingsTab: React.FC<SettingsTabProps> = ({ form, isEditing, settin
|
|||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
disabled={!isEditing}
|
disabled={!isEditing}
|
||||||
placeholder="https://pb-api.k8sops.asia"
|
placeholder="https://localhost:8090"
|
||||||
className="bg-background border-input text-foreground placeholder:text-muted-foreground disabled:bg-muted disabled:text-muted-foreground"
|
className="bg-background border-input text-foreground placeholder:text-muted-foreground disabled:bg-muted disabled:text-muted-foreground"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -5,15 +5,11 @@ import AddUserDialog from "./AddUserDialog";
|
|||||||
import EditUserDialog from "./EditUserDialog";
|
import EditUserDialog from "./EditUserDialog";
|
||||||
import DeleteUserDialog from "./DeleteUserDialog";
|
import DeleteUserDialog from "./DeleteUserDialog";
|
||||||
import { useUserManagement } from "./hooks";
|
import { useUserManagement } from "./hooks";
|
||||||
import {
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||||
Accordion,
|
import { UserCog, Loader2, AlertCircle, Info, Users, ShieldAlert } from "lucide-react";
|
||||||
AccordionContent,
|
|
||||||
AccordionItem,
|
|
||||||
AccordionTrigger
|
|
||||||
} from "@/components/ui/accordion";
|
|
||||||
import { UserCog, Loader2, AlertCircle } from "lucide-react";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
|
import { authService } from "@/services/authService";
|
||||||
const UserManagement = () => {
|
const UserManagement = () => {
|
||||||
const {
|
const {
|
||||||
users,
|
users,
|
||||||
@@ -39,8 +35,10 @@ const UserManagement = () => {
|
|||||||
fetchUsers
|
fetchUsers
|
||||||
} = useUserManagement();
|
} = useUserManagement();
|
||||||
|
|
||||||
return (
|
// Get the current logged in user to check their role
|
||||||
<div className="space-y-4">
|
const loggedInUser = authService.getCurrentUser();
|
||||||
|
const isSuperAdmin = loggedInUser?.role === "superadmin";
|
||||||
|
return <div className="space-y-4">
|
||||||
<Accordion type="single" collapsible className="w-full" defaultValue="user-management">
|
<Accordion type="single" collapsible className="w-full" defaultValue="user-management">
|
||||||
<AccordionItem value="user-management">
|
<AccordionItem value="user-management">
|
||||||
<AccordionTrigger className="py-4 px-5 bg-card hover:bg-card/90 hover:no-underline rounded-lg text-lg font-medium flex items-center w-full">
|
<AccordionTrigger className="py-4 px-5 bg-card hover:bg-card/90 hover:no-underline rounded-lg text-lg font-medium flex items-center w-full">
|
||||||
@@ -52,66 +50,39 @@ const UserManagement = () => {
|
|||||||
<AccordionContent className="p-4 pt-6 bg-background rounded-b-lg">
|
<AccordionContent className="p-4 pt-6 bg-background rounded-b-lg">
|
||||||
<div className="flex justify-between items-center mb-6">
|
<div className="flex justify-between items-center mb-6">
|
||||||
<h2 className="text-2xl font-bold">User Management</h2>
|
<h2 className="text-2xl font-bold">User Management</h2>
|
||||||
<button
|
{isSuperAdmin && <button onClick={() => setIsAddUserDialogOpen(true)} className="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-md flex items-center">
|
||||||
onClick={() => setIsAddUserDialogOpen(true)}
|
|
||||||
className="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-md flex items-center"
|
|
||||||
>
|
|
||||||
<span className="mr-1">+</span> Add User
|
<span className="mr-1">+</span> Add User
|
||||||
</button>
|
</button>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{loading ? (
|
{!isSuperAdmin && <Alert className="mb-6 border-blue-200 bg-blue-50 dark:bg-blue-950 dark:border-blue-800">
|
||||||
<div className="p-8 flex flex-col items-center justify-center text-center">
|
<ShieldAlert className="h-5 w-5 text-blue-600 dark:text-blue-400" />
|
||||||
|
<AlertDescription className="text-blue-700 dark:text-blue-300">
|
||||||
|
<span className="font-medium">Permission Notice:</span> As an admin user, you have access to view and modify existing user details. However, only Super Admins have permission to create new user accounts. Contact your Super Admin if you need to add a new user.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>}
|
||||||
|
|
||||||
|
{loading ? <div className="p-8 flex flex-col items-center justify-center text-center">
|
||||||
<Loader2 className="h-8 w-8 animate-spin mb-2 text-primary" />
|
<Loader2 className="h-8 w-8 animate-spin mb-2 text-primary" />
|
||||||
<p className="text-muted-foreground">Loading users...</p>
|
<p className="text-muted-foreground">Loading users...</p>
|
||||||
</div>
|
</div> : error ? <div className="p-8 flex flex-col items-center justify-center text-center">
|
||||||
) : error ? (
|
|
||||||
<div className="p-8 flex flex-col items-center justify-center text-center">
|
|
||||||
<AlertCircle className="h-8 w-8 text-destructive mb-2" />
|
<AlertCircle className="h-8 w-8 text-destructive mb-2" />
|
||||||
<p className="text-destructive font-medium mb-2">Failed to load users</p>
|
<p className="text-destructive font-medium mb-2">Failed to load users</p>
|
||||||
<p className="text-muted-foreground mb-4">{error}</p>
|
<p className="text-muted-foreground mb-4">{error}</p>
|
||||||
<Button onClick={fetchUsers} variant="outline">
|
<Button onClick={fetchUsers} variant="outline">
|
||||||
Retry
|
Retry
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div> : <UserTable users={users} onUserUpdate={handleEditUser} onUserDelete={handleDeletePrompt} />}
|
||||||
) : (
|
|
||||||
<UserTable
|
|
||||||
users={users}
|
|
||||||
onUserUpdate={handleEditUser}
|
|
||||||
onUserDelete={handleDeletePrompt}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<AddUserDialog
|
<AddUserDialog isOpen={isAddUserDialogOpen && isSuperAdmin} setIsOpen={setIsAddUserDialogOpen} form={newUserForm} onSubmit={onAddUser} isSubmitting={isSubmitting} />
|
||||||
isOpen={isAddUserDialogOpen}
|
|
||||||
setIsOpen={setIsAddUserDialogOpen}
|
|
||||||
form={newUserForm}
|
|
||||||
onSubmit={onAddUser}
|
|
||||||
isSubmitting={isSubmitting}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EditUserDialog
|
<EditUserDialog isOpen={isDialogOpen} setIsOpen={setIsDialogOpen} form={form} user={currentUser} onSubmit={onSubmit} isSubmitting={isSubmitting} error={updateError} />
|
||||||
isOpen={isDialogOpen}
|
|
||||||
setIsOpen={setIsDialogOpen}
|
|
||||||
form={form}
|
|
||||||
user={currentUser}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
isSubmitting={isSubmitting}
|
|
||||||
error={updateError}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DeleteUserDialog
|
<DeleteUserDialog isOpen={isDeleting} setIsOpen={setIsDeleting} user={userToDelete} onDelete={handleDeleteUser} isDeleting={isSubmitting} />
|
||||||
isOpen={isDeleting}
|
|
||||||
setIsOpen={setIsDeleting}
|
|
||||||
user={userToDelete}
|
|
||||||
onDelete={handleDeleteUser}
|
|
||||||
isDeleting={isSubmitting}
|
|
||||||
/>
|
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>;
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UserManagement;
|
export default UserManagement;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { toast } from "@/components/ui/use-toast";
|
import { toast } from "@/components/ui/use-toast";
|
||||||
import { useLanguage } from "@/contexts/LanguageContext";
|
import { useLanguage } from "@/contexts/LanguageContext";
|
||||||
|
import { authService } from "@/services/authService";
|
||||||
import { GeneralSettings } from "@/services/settingsService";
|
import { GeneralSettings } from "@/services/settingsService";
|
||||||
|
|
||||||
interface ApiResponse {
|
interface ApiResponse {
|
||||||
@@ -14,7 +15,11 @@ export function useSystemSettings() {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { t } = useLanguage();
|
const { t } = useLanguage();
|
||||||
|
|
||||||
// Fetch settings from API
|
// Check if user is super admin
|
||||||
|
const currentUser = authService.getCurrentUser();
|
||||||
|
const isSuperAdmin = currentUser?.role === "superadmin";
|
||||||
|
|
||||||
|
// Fetch settings from API - only if user is super admin
|
||||||
const {
|
const {
|
||||||
data: settings,
|
data: settings,
|
||||||
isLoading,
|
isLoading,
|
||||||
@@ -56,7 +61,8 @@ export function useSystemSettings() {
|
|||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
enabled: isSuperAdmin, // Only run query if user is super admin
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update settings mutation
|
// Update settings mutation
|
||||||
|
|||||||
Reference in New Issue
Block a user