Applied UI rendering fixes

This commit is contained in:
2026-10-22 06:23:22 +02:00
parent 87f597c091
commit c24e809b88
11 changed files with 261 additions and 154 deletions
@@ -533,7 +533,7 @@ export const SettingsPage: React.FC = () => {
};
return (
<div className="space-y-6 max-w-7xl mx-auto">
<div className="space-y-6 max-w-7xl mx-auto min-w-0 w-full">
{/* Header Banner */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 bg-gradient-to-r from-[#0d1322] via-[#0f172a] to-[#0d1322] p-6 sm:p-8 rounded-3xl border border-slate-800/80 shadow-2xl relative overflow-hidden">
<div className="absolute -right-10 -bottom-10 w-60 h-60 bg-blue-600/10 rounded-full blur-3xl pointer-events-none" />
@@ -819,8 +819,8 @@ export const SettingsPage: React.FC = () => {
/>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-xs border-collapse">
<div className="overflow-x-auto min-w-0 w-full">
<table className="w-full text-left text-xs border-collapse min-w-[850px]">
<thead>
<tr className="bg-slate-900/60 border-b border-slate-800/80 text-slate-400 uppercase tracking-wider font-semibold">
<SortableTh column="email" currentColumn={userSortCol} direction={userSortDir} onSort={handleUserSort} className="py-3.5 px-5">
@@ -1096,8 +1096,8 @@ export const SettingsPage: React.FC = () => {
/>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-xs border-collapse">
<div className="overflow-x-auto min-w-0 w-full">
<table className="w-full text-left text-xs border-collapse min-w-[850px]">
<thead>
<tr className="bg-slate-900/60 border-b border-slate-800/80 text-slate-400 uppercase tracking-wider font-semibold">
<SortableTh column="recipient" currentColumn={inviteSortCol} direction={inviteSortDir} onSort={handleInviteSort} className="py-3.5 px-5">
@@ -1372,8 +1372,8 @@ export const SettingsPage: React.FC = () => {
</span>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse text-xs">
<div className="overflow-x-auto min-w-0 w-full">
<table className="w-full text-left border-collapse text-xs min-w-[900px]">
<thead>
<tr className="border-b border-slate-800 bg-slate-900/40 text-slate-400 font-medium">
<SortableTh column="id" currentColumn={notifSortCol} direction={notifSortDir} onSort={handleNotifSort} className="py-3.5 px-4">
@@ -1639,8 +1639,8 @@ export const SettingsPage: React.FC = () => {
</span>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-xs border-collapse">
<div className="overflow-x-auto min-w-0 w-full">
<table className="w-full text-left text-xs border-collapse min-w-[850px]">
<thead>
<tr className="bg-slate-900/60 border-b border-slate-800/80 text-slate-400 uppercase tracking-wider font-semibold">
<th className="py-3.5 px-3 w-10 text-center"></th>
@@ -1800,28 +1800,28 @@ export const SettingsPage: React.FC = () => {
<tr className="bg-[#080c14] border-b border-slate-800/80">
<td colSpan={8} className="p-4 sm:p-5 bg-gradient-to-r from-[#0d121f] via-[#090d16] to-[#0d121f]">
<div className="rounded-xl border border-slate-800/90 bg-[#070a12]/90 p-4 space-y-3 shadow-inner">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 border-b border-slate-800/80 pb-3">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 border-b border-slate-800/80 pb-3 flex-wrap">
<div className="flex items-center gap-2">
<Layers className="w-4 h-4 text-blue-400" />
<Layers className="w-4 h-4 text-blue-400 shrink-0" />
<h4 className="text-xs font-bold text-white uppercase tracking-wider">
Recorded Changes Content (Event #{log.id})
</h4>
<span className="text-[10px] font-mono px-2 py-0.5 rounded-full bg-blue-500/10 text-blue-400 border border-blue-500/20 font-semibold">
<span className="text-[10px] font-mono px-2 py-0.5 rounded-full bg-blue-500/10 text-blue-400 border border-blue-500/20 font-semibold shrink-0">
{changesCount} {changesCount === 1 ? 'Entry' : 'Entries'}
</span>
</div>
<div className="flex items-center gap-3 text-xs text-slate-400">
<span>
<div className="flex items-center gap-2 sm:gap-3 text-xs text-slate-400 flex-wrap min-w-0">
<span className="truncate max-w-[260px] sm:max-w-none">
Entity: <strong className="text-white">{log.entityName || 'General'}</strong> {log.entityId ? `(#${log.entityId})` : ''}
</span>
<span>•</span>
<span className="flex items-center gap-1">
Performer: <strong className="text-slate-200 font-mono text-[11px]">{displayEmail}</strong>
<span className="flex items-center gap-1 min-w-0">
Performer: <strong className="text-slate-200 font-mono text-[11px] truncate max-w-[220px] sm:max-w-none">{displayEmail}</strong>
{log.performedBy && (
<button
type="button"
onClick={(e) => handleCopyUserId(log.performedBy, e)}
className="p-1 rounded hover:bg-slate-800 text-slate-400 hover:text-white transition cursor-pointer"
className="p-1 rounded hover:bg-slate-800 text-slate-400 hover:text-white transition cursor-pointer shrink-0"
title={`Copy User ID: ${log.performedBy}`}
>
{copiedUserId === log.performedBy ? (
@@ -1884,10 +1884,11 @@ export const SettingsPage: React.FC = () => {
}}
title={`Audit Event: #${selectedAuditLog?.id || ''}`}
subtitle="Authoritative event payload and activity ledger"
maxWidth="xl"
>
{selectedAuditLog && (
<div className="space-y-4 text-xs">
<div className="p-4 bg-[#0d121f] rounded-xl border border-slate-800 space-y-3">
<div className="space-y-4 text-xs min-w-0">
<div className="p-4 bg-[#0d121f] rounded-xl border border-slate-800 space-y-3 min-w-0">
<div className="flex justify-between items-center border-b border-slate-800/80 pb-2">
<span className="text-slate-400 font-semibold uppercase text-[11px]">Action Type:</span>
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold border ${getActionBadge(selectedAuditLog.action).className}`}>
@@ -1895,22 +1896,22 @@ export const SettingsPage: React.FC = () => {
</span>
</div>
<div className="grid grid-cols-2 gap-3">
<div>
<div className="grid grid-cols-2 gap-3 min-w-0">
<div className="min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase">Entity Name:</span>
<span className="text-white font-semibold">{selectedAuditLog.entityName || '—'}</span>
<span className="text-white font-semibold truncate block">{selectedAuditLog.entityName || '—'}</span>
</div>
<div>
<div className="min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase">Entity ID:</span>
<span className="font-mono text-slate-300">{selectedAuditLog.entityId || '—'}</span>
<span className="font-mono text-slate-300 break-all block">{selectedAuditLog.entityId || '—'}</span>
</div>
</div>
<div className="grid grid-cols-2 gap-3 border-t border-slate-800/80 pt-2">
<div>
<div className="grid grid-cols-2 gap-3 border-t border-slate-800/80 pt-2 min-w-0">
<div className="min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase">Performed By:</span>
<div className="flex items-center gap-1.5 mt-0.5">
<span className="font-mono text-slate-200 text-[11px] truncate">
<div className="flex items-center gap-1.5 mt-0.5 min-w-0">
<span className="font-mono text-slate-200 text-[11px] truncate block" title={selectedAuditLog.performedBy || 'System'}>
{getUserEmail(selectedAuditLog.performedBy) !== '—'
? getUserEmail(selectedAuditLog.performedBy)
: (selectedAuditLog.performedBy || 'System')}
@@ -1931,32 +1932,34 @@ export const SettingsPage: React.FC = () => {
)}
</div>
{selectedAuditLog.performedBy && (
<span className="text-[10px] text-slate-500 font-mono block mt-0.5 truncate">
<span className="text-[10px] text-slate-500 font-mono block mt-0.5 truncate" title={`ID: ${selectedAuditLog.performedBy}`}>
ID: {selectedAuditLog.performedBy}
</span>
)}
</div>
<div>
<div className="min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase">Logged Timestamp:</span>
<span className="font-mono text-slate-300 block mt-0.5">{formatDate(selectedAuditLog.timestamp)}</span>
</div>
</div>
{selectedAuditLog.tenantId && (
<div className="border-t border-slate-800/80 pt-2">
<div className="border-t border-slate-800/80 pt-2 min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase">Tenant Scope:</span>
<span className="font-mono text-slate-300">Tenant #{selectedAuditLog.tenantId}</span>
</div>
)}
<div className="border-t border-slate-800/80 pt-2 space-y-1">
<div className="border-t border-slate-800/80 pt-2 space-y-1 min-w-0">
<span className="text-slate-400 font-semibold block text-[11px] uppercase mb-1">State Changes / Delta:</span>
{Array.isArray(selectedAuditLog.changes) && selectedAuditLog.changes.length > 0 ? (
<ul className="space-y-1 p-2 rounded-lg bg-slate-900 border border-slate-800">
<ul className="space-y-1.5 p-2.5 rounded-lg bg-slate-900 border border-slate-800 min-w-0 max-h-56 overflow-y-auto">
{selectedAuditLog.changes.map((ch, idx) => (
<li key={idx} className="font-mono text-emerald-400/90 text-[11px] flex items-center gap-1.5">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
{ch}
<li key={idx} className="font-mono text-emerald-400/90 text-[11px] flex items-start gap-2 min-w-0">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 shrink-0 mt-1.5" />
<span className="break-all whitespace-pre-wrap min-w-0 flex-1 leading-relaxed">
{ch}
</span>
</li>
))}
</ul>
@@ -1968,7 +1971,7 @@ export const SettingsPage: React.FC = () => {
</div>
{/* Raw JSON Data Viewer */}
<div className="border-t border-slate-800/80 pt-2.5 space-y-1.5">
<div className="border-t border-slate-800/80 pt-2.5 space-y-1.5 min-w-0">
<div className="flex items-center justify-between">
<span className="text-slate-400 font-semibold text-[11px] uppercase">
Raw Audit Record (JSON):
@@ -1994,7 +1997,7 @@ export const SettingsPage: React.FC = () => {
)}
</button>
</div>
<pre className="p-3 rounded-lg bg-[#070a12] border border-slate-800/80 text-emerald-300/90 font-mono text-[10.5px] overflow-x-auto max-h-48">
<pre className="p-3 rounded-lg bg-[#070a12] border border-slate-800/80 text-emerald-300/90 font-mono text-[10.5px] overflow-x-auto whitespace-pre-wrap break-all max-h-48 min-w-0">
{JSON.stringify(selectedAuditLog, null, 2)}
</pre>
</div>
@@ -2216,14 +2219,16 @@ export const SettingsPage: React.FC = () => {
{/* ============================================================== */}
{/* Modal: User Administration & Role/Claim/Session Control */}
{/* ============================================================== */}
<UserSecurityModal
isOpen={isUserDetailModalOpen}
onClose={() => {
setIsUserDetailModalOpen(false);
setSelectedUserForDetail(null);
}}
user={selectedUserForDetail}
/>
{isUserDetailModalOpen && selectedUserForDetail && (
<UserSecurityModal
isOpen={isUserDetailModalOpen}
onClose={() => {
setIsUserDetailModalOpen(false);
setSelectedUserForDetail(null);
}}
user={selectedUserForDetail}
/>
)}
{/* ============================================================== */}
{/* Modal: Provision Tenant User */}
@@ -309,8 +309,8 @@ const TenantUsersSubList: React.FC<{
</div>
</div>
<div className="overflow-x-auto rounded-lg border border-slate-800/80 bg-slate-900/40">
<table className="w-full text-left text-xs border-collapse">
<div className="overflow-x-auto rounded-lg border border-slate-800/80 bg-slate-900/40 min-w-0 w-full">
<table className="w-full text-left text-xs border-collapse min-w-[700px]">
<thead>
<tr className="bg-slate-900/80 border-b border-slate-800/80 text-slate-400 text-[11px] uppercase tracking-wider font-semibold">
<th className="py-2 px-3">Email Address</th>
@@ -351,13 +351,14 @@ const TenantUsersSubList: React.FC<{
<td className="py-2 px-3 text-right">
<button
onClick={() => {
const userToManage: User = u || {
id: tu.userId,
email: null,
role: null,
idNumber: null,
status: tu.status,
lastLoginAt: null,
const userToManage: User = {
...(u || {}),
id: u?.id || tu.userId,
status: u?.status ?? tu.status,
email: u?.email || null,
role: u?.role || null,
idNumber: u?.idNumber || null,
lastLoginAt: u?.lastLoginAt || null,
};
onManageUser(userToManage);
}}
@@ -782,9 +783,9 @@ export const TenantManagementPage: React.FC = () => {
</div>
{/* Tenants Table */}
<div className="bg-[#0f1523]/80 rounded-2xl border border-slate-800/80 overflow-hidden shadow-xl backdrop-blur-md">
<div className="overflow-x-auto">
<table className="w-full text-left text-xs border-collapse">
<div className="bg-[#0f1523]/80 rounded-2xl border border-slate-800/80 overflow-hidden shadow-xl backdrop-blur-md min-w-0 w-full">
<div className="overflow-x-auto min-w-0 w-full">
<table className="w-full text-left text-xs border-collapse min-w-[800px]">
<thead>
<tr className="bg-slate-900/60 border-b border-slate-800/80 text-slate-400 font-semibold uppercase tracking-wider">
<th className="py-3.5 px-3 w-10 text-center">
@@ -1198,14 +1199,16 @@ export const TenantManagementPage: React.FC = () => {
/>
{/* User Security & Administration Modal */}
<UserSecurityModal
isOpen={isSecurityModalOpen}
onClose={() => {
setIsSecurityModalOpen(false);
setSecurityUser(null);
}}
user={securityUser}
/>
{isSecurityModalOpen && securityUser && (
<UserSecurityModal
isOpen={isSecurityModalOpen}
onClose={() => {
setIsSecurityModalOpen(false);
setSecurityUser(null);
}}
user={securityUser}
/>
)}
</div>
);
};