feat: add year filtering and search functionality to Bylaws and Financials pages; enhance report grouping by year
This commit is contained in:
@@ -350,44 +350,83 @@ const AdminRoles = () => {
|
||||
Select permissions for this role. You can also add permissions later.
|
||||
</p>
|
||||
<div className="border rounded-lg p-4 max-h-64 overflow-y-auto scrollbar-dashboard">
|
||||
{Object.entries(groupedPermissions).map(([module, perms]) => (
|
||||
<div key={module} className="mb-4">
|
||||
<button
|
||||
onClick={() => toggleModule(module)}
|
||||
className="flex items-center w-full text-left font-medium mb-2 hover:text-blue-600"
|
||||
>
|
||||
{expandedModules[module] ? (
|
||||
<ChevronUp className="w-4 h-4 mr-1" />
|
||||
) : (
|
||||
<ChevronDown className="w-4 h-4 mr-1" />
|
||||
)}
|
||||
{module.charAt(0).toUpperCase() + module.slice(1)} ({perms.length})
|
||||
</button>
|
||||
{expandedModules[module] && (
|
||||
<div className="space-y-2 ml-5">
|
||||
{perms.map(perm => (
|
||||
<div key={perm.code} className="flex items-center">
|
||||
<Checkbox
|
||||
checked={formData.permissions.includes(perm.code)}
|
||||
onCheckedChange={() => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
permissions: prev.permissions.includes(perm.code)
|
||||
? prev.permissions.filter(p => p !== perm.code)
|
||||
: [...prev.permissions, perm.code]
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
<label className="ml-2 text-sm">
|
||||
<span className="font-medium">{perm.name}</span>
|
||||
<span className="text-gray-500 ml-2">({perm.code})</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
{Object.entries(groupedPermissions).map(([module, perms]) => {
|
||||
const moduleCodes = perms.map(perm => perm.code);
|
||||
const selectedCount = moduleCodes.filter(code => formData.permissions.includes(code)).length;
|
||||
const hasPermissions = moduleCodes.length > 0;
|
||||
const isAllSelected = hasPermissions && selectedCount === moduleCodes.length;
|
||||
const isNoneSelected = selectedCount === 0;
|
||||
|
||||
return (
|
||||
<div key={module} className="mb-4">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleModule(module)}
|
||||
className="flex items-center text-left font-medium hover:text-blue-600"
|
||||
>
|
||||
{expandedModules[module] ? (
|
||||
<ChevronUp className="w-4 h-4 mr-1" />
|
||||
) : (
|
||||
<ChevronDown className="w-4 h-4 mr-1" />
|
||||
)}
|
||||
{module.charAt(0).toUpperCase() + module.slice(1)} ({perms.length})
|
||||
</button>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
permissions: [...new Set([...prev.permissions, ...moduleCodes])]
|
||||
}));
|
||||
}}
|
||||
disabled={!hasPermissions || isAllSelected}
|
||||
className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Select all
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
permissions: prev.permissions.filter(code => !moduleCodes.includes(code))
|
||||
}));
|
||||
}}
|
||||
disabled={!hasPermissions || isNoneSelected}
|
||||
className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Deselect all
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{expandedModules[module] && (
|
||||
<div className="space-y-2 ml-5">
|
||||
{perms.map(perm => (
|
||||
<div key={perm.code} className="flex items-center">
|
||||
<Checkbox
|
||||
checked={formData.permissions.includes(perm.code)}
|
||||
onCheckedChange={() => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
permissions: prev.permissions.includes(perm.code)
|
||||
? prev.permissions.filter(p => p !== perm.code)
|
||||
: [...prev.permissions, perm.code]
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
<label className="ml-2 text-sm">
|
||||
<span className="font-medium">{perm.name}</span>
|
||||
<span className="text-gray-500 ml-2">({perm.code})</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user