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:
2026-09-18 10:19:24 +02:00
parent 41bf9b63bf
commit ec777fabf8
24 changed files with 3888 additions and 500 deletions
@@ -307,7 +307,52 @@ export const getContractStatusBadge = (status: ContractStatus | number) => {
}
};
export const getActivityStatusBadge = (status: ActivityStatus | number) => {
export const getActivityStatusBadge = (status: ActivityStatus | number | string | boolean | null | undefined) => {
if (status === null || status === undefined) {
return {
label: 'Active',
className: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30 font-semibold',
};
}
if (typeof status === 'boolean') {
return status
? { label: 'Active', className: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30 font-semibold' }
: { label: 'Inactive', className: 'bg-slate-800/80 text-slate-400 border-slate-700/80 font-semibold' };
}
const str = String(status).trim().toLowerCase();
if (str === '1' || str === 'active' || str === 'enabled') {
return {
label: 'Active',
className: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30 font-semibold',
};
}
if (str === '2' || str === 'inactive') {
return {
label: 'Inactive',
className: 'bg-slate-800/80 text-slate-400 border-slate-700/80 font-semibold',
};
}
if (str === '3' || str === 'disabled' || str === 'suspended' || str === 'terminated') {
return {
label: str === 'suspended' ? 'Suspended' : 'Disabled',
className: 'bg-rose-500/10 text-rose-400 border-rose-500/30 font-semibold',
};
}
if (str === 'approved') {
return {
label: 'Approved',
className: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30 font-semibold',
};
}
if (str === 'pending' || str === 'review') {
return {
label: 'Pending',
className: 'bg-amber-500/10 text-amber-400 border-amber-500/30 font-semibold',
};
}
const s = Number(status);
switch (s) {
case ActivityStatus.Active:
@@ -321,14 +366,44 @@ export const getActivityStatusBadge = (status: ActivityStatus | number) => {
className: 'bg-slate-800/80 text-slate-400 border-slate-700/80 font-semibold',
};
case ActivityStatus.Disabled:
default:
return {
label: 'Disabled',
className: 'bg-rose-500/10 text-rose-400 border-rose-500/30 font-semibold',
};
default:
return {
label: String(status),
className: 'bg-slate-800/80 text-slate-300 border-slate-700/80 font-semibold',
};
}
};
/**
* Robust Status Badge resolver for Organisation Directory.
* Inspects status, Status, activityStatus, approvalStatus, statusId, isActive, or state,
* parsing string, boolean, or numeric database representations.
*/
export const getOrganisationStatusBadge = (statusOrOrg: any) => {
let val: any = statusOrOrg;
if (statusOrOrg !== null && typeof statusOrOrg === 'object') {
val =
statusOrOrg.status ??
statusOrOrg.Status ??
statusOrOrg.activityStatus ??
statusOrOrg.ActivityStatus ??
statusOrOrg.approvalStatus ??
statusOrOrg.ApprovalStatus ??
statusOrOrg.statusId ??
statusOrOrg.StatusId ??
statusOrOrg.state ??
statusOrOrg.State ??
(statusOrOrg.isActive !== undefined ? (statusOrOrg.isActive ? 1 : 2) : undefined) ??
(statusOrOrg.IsActive !== undefined ? (statusOrOrg.IsActive ? 1 : 2) : undefined);
}
return getActivityStatusBadge(val);
};
export const getPriorityBadge = (priority: Priority | number) => {
const p = Number(priority);
switch (p) {
@@ -419,14 +494,17 @@ export const getNotificationStatusBadge = (status?: NotificationStatus | number
};
export const getRiskScoreColor = (likelihood: RiskLikelihood | number, impact: RiskImpact | number) => {
const score = Number(likelihood) * Number(impact);
const score = (Number(likelihood) || 1) * (Number(impact) || 1);
if (score >= 15) {
return { level: 'High', color: 'bg-rose-600 text-white', badge: 'bg-rose-50 text-rose-800 border-rose-300 font-semibold' };
return { level: 'Critical', color: 'bg-rose-600 text-white', badge: 'bg-rose-500/20 text-rose-300 border border-rose-500/40 font-bold' };
}
if (score >= 8) {
return { level: 'Medium', color: 'bg-amber-500 text-white', badge: 'bg-amber-50 text-amber-900 border-amber-300 font-semibold' };
if (score >= 10) {
return { level: 'High', color: 'bg-orange-500 text-white', badge: 'bg-orange-500/20 text-orange-300 border border-orange-500/40 font-bold' };
}
return { level: 'Low', color: 'bg-emerald-600 text-white', badge: 'bg-emerald-50 text-emerald-800 border-emerald-300 font-semibold' };
if (score >= 5) {
return { level: 'Moderate', color: 'bg-amber-500 text-white', badge: 'bg-amber-500/20 text-amber-300 border border-amber-500/40 font-semibold' };
}
return { level: 'Low', color: 'bg-emerald-600 text-white', badge: 'bg-emerald-500/20 text-emerald-300 border border-emerald-500/40 font-semibold' };
};
// ==========================================
@@ -435,15 +513,30 @@ export const getRiskScoreColor = (likelihood: RiskLikelihood | number, impact: R
const USER_EMAIL_CACHE: Record<string, string> = {};
export const registerUserEmail = (userId: string, email: string) => {
if (userId && email) {
USER_EMAIL_CACHE[userId] = email;
export const registerUserEmail = (userId: string | number, email: string) => {
if (userId && email && typeof email === 'string' && email.trim()) {
const cleanId = String(userId).trim();
const cleanEmail = email.trim();
USER_EMAIL_CACHE[cleanId] = cleanEmail;
USER_EMAIL_CACHE[cleanId.toLowerCase()] = cleanEmail;
}
};
export const getUserEmail = (userIdOrEmail?: string | null): string => {
if (!userIdOrEmail) return '—';
if (userIdOrEmail.includes('@')) return userIdOrEmail;
if (USER_EMAIL_CACHE[userIdOrEmail]) return USER_EMAIL_CACHE[userIdOrEmail];
return userIdOrEmail;
export const registerUserEmails = (users: Array<{ id: string | number; email?: string | null }>) => {
if (!Array.isArray(users)) return;
for (const u of users) {
if (u && u.id && u.email) {
registerUserEmail(u.id, u.email);
}
}
};
export const getUserEmail = (userIdOrEmail?: string | number | null): string => {
if (!userIdOrEmail) return '—';
const str = String(userIdOrEmail).trim();
if (!str) return '—';
if (str.includes('@')) return str;
if (USER_EMAIL_CACHE[str]) return USER_EMAIL_CACHE[str];
if (USER_EMAIL_CACHE[str.toLowerCase()]) return USER_EMAIL_CACHE[str.toLowerCase()];
return str;
};