Implemented session and account lockout management
Enabled account sync control and session expiration management Applied some fixes to the govername page and project page
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
Search,
|
||||
Coins,
|
||||
Eye,
|
||||
RefreshCw,
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
getOrganisations,
|
||||
@@ -49,6 +50,7 @@ import {
|
||||
import {
|
||||
getOrganisationTypeLabel,
|
||||
getActivityStatusBadge,
|
||||
getOrganisationStatusBadge,
|
||||
getApprovalStatusBadge,
|
||||
formatDate,
|
||||
getUserEmail,
|
||||
@@ -192,7 +194,7 @@ export const GovernancePage: React.FC = () => {
|
||||
orgForm.reset();
|
||||
},
|
||||
onError: (err: unknown) => {
|
||||
toastError('Failed to save organisation', String(err));
|
||||
toastError('Failed to save organisation', err);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -217,7 +219,7 @@ export const GovernancePage: React.FC = () => {
|
||||
portfolioForm.reset();
|
||||
},
|
||||
onError: (err: unknown) => {
|
||||
toastError('Failed to save portfolio', String(err));
|
||||
toastError('Failed to save portfolio', err);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -242,7 +244,7 @@ export const GovernancePage: React.FC = () => {
|
||||
programmeForm.reset();
|
||||
},
|
||||
onError: (err: unknown) => {
|
||||
toastError('Failed to save programme', String(err));
|
||||
toastError('Failed to save programme', err);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -409,17 +411,31 @@ export const GovernancePage: React.FC = () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Search Bar */}
|
||||
{/* Search Bar & Actions */}
|
||||
{activeTab === 'organisations' && (
|
||||
<div className="relative max-w-md">
|
||||
<Search className="w-4 h-4 text-slate-500 absolute left-3 top-3" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search by organisation name, reg no, or email..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full pl-9 pr-4 py-2.5 text-xs bg-[#090d16] border border-slate-700/80 rounded-xl focus:outline-none focus:ring-1 focus:ring-blue-500 text-slate-200 placeholder:text-slate-500 transition shadow-xs"
|
||||
/>
|
||||
<div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3">
|
||||
<div className="relative max-w-md flex-1">
|
||||
<Search className="w-4 h-4 text-slate-500 absolute left-3 top-3" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search by organisation name, reg no, or email..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full pl-9 pr-4 py-2.5 text-xs bg-[#090d16] border border-slate-700/80 rounded-xl focus:outline-none focus:ring-1 focus:ring-blue-500 text-slate-200 placeholder:text-slate-500 transition shadow-xs"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
queryClient.invalidateQueries({ queryKey: ['organisations'] });
|
||||
success('Refreshed', 'Organisation directory refreshed from database.');
|
||||
}}
|
||||
className="inline-flex items-center justify-center gap-1.5 px-3.5 py-2 text-xs font-semibold text-slate-300 bg-[#0d121f] hover:bg-slate-800 border border-slate-700/80 rounded-xl transition cursor-pointer"
|
||||
title="Force refresh organisation directory from database"
|
||||
>
|
||||
<RefreshCw className="w-3.5 h-3.5 text-blue-400" />
|
||||
Refresh Directory
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -453,7 +469,7 @@ export const GovernancePage: React.FC = () => {
|
||||
</tr>
|
||||
) : (
|
||||
filteredOrgs.map((org) => {
|
||||
const statusBadge = getActivityStatusBadge(org.status);
|
||||
const statusBadge = getOrganisationStatusBadge(org);
|
||||
return (
|
||||
<tr key={org.id} className="hover:bg-slate-800/40 transition-colors">
|
||||
<td className="py-3.5 px-5">
|
||||
|
||||
Reference in New Issue
Block a user