feat(frontend): Comprehensive RBAC implementation across admin pages
**Option 3 Implementation (Latest):** - InviteStaffDialog: Use /admin/roles/assignable endpoint - AdminStaff: Enable admin users to see 'Invite Staff' button **Permission Checks Added (8 admin pages):** - AdminNewsletters: newsletters.create/edit/delete - AdminFinancials: financials.create/edit/delete - AdminBylaws: bylaws.create/edit/delete - AdminValidations: users.approve, subscriptions.activate - AdminSubscriptions: subscriptions.export/edit/cancel - AdminDonations: donations.export - AdminGallery: gallery.upload/edit/delete - AdminPlans: subscriptions.plans **Pattern Established:** All admin action buttons now wrapped with hasPermission() checks. UI hides what users can't access, backend enforces rules. **Files Modified:** 10 files, 100+ permission checks added
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import api from '../../utils/api';
|
||||
import { Card } from '../../components/ui/card';
|
||||
import { Button } from '../../components/ui/button';
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
|
||||
const AdminFinancials = () => {
|
||||
const { hasPermission } = useAuth();
|
||||
const [reports, setReports] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
@@ -162,13 +164,15 @@ const AdminFinancials = () => {
|
||||
Manage annual financial reports
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleCreate}
|
||||
className="bg-[#664fa3] text-white hover:bg-[#533a82] rounded-full flex items-center gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Add Report
|
||||
</Button>
|
||||
{hasPermission('financials.create') && (
|
||||
<Button
|
||||
onClick={handleCreate}
|
||||
className="bg-[#664fa3] text-white hover:bg-[#533a82] rounded-full flex items-center gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Add Report
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Reports List */}
|
||||
@@ -176,10 +180,12 @@ const AdminFinancials = () => {
|
||||
<Card className="p-12 text-center">
|
||||
<TrendingUp className="h-16 w-16 text-[#ddd8eb] mx-auto mb-4" />
|
||||
<p className="text-[#664fa3] text-lg mb-4">No financial reports yet</p>
|
||||
<Button onClick={handleCreate} className="bg-[#664fa3] text-white">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Create First Report
|
||||
</Button>
|
||||
{hasPermission('financials.create') && (
|
||||
<Button onClick={handleCreate} className="bg-[#664fa3] text-white">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Create First Report
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
@@ -209,24 +215,30 @@ const AdminFinancials = () => {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleEdit(report)}
|
||||
className="border-[#664fa3] text-[#664fa3]"
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleDelete(report)}
|
||||
className="border-red-500 text-red-500 hover:bg-red-50"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
{(hasPermission('financials.edit') || hasPermission('financials.delete')) && (
|
||||
<div className="flex gap-2">
|
||||
{hasPermission('financials.edit') && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleEdit(report)}
|
||||
className="border-[#664fa3] text-[#664fa3]"
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
{hasPermission('financials.delete') && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleDelete(report)}
|
||||
className="border-red-500 text-red-500 hover:bg-red-50"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user