Overhauled lockout process

This commit is contained in:
2026-10-24 17:36:30 +02:00
parent a731c979bb
commit 25e251aa79
12 changed files with 574 additions and 527 deletions
@@ -87,7 +87,7 @@ export const SessionExpiredModal: React.FC<SessionExpiredModalProps> = ({
const modalContent = (
<div
id="session-expired-modal-backdrop"
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/85 backdrop-blur-md p-4 animate-in fade-in duration-200 overflow-y-auto"
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-md p-4 animate-in fade-in duration-150 overflow-y-auto"
onMouseEnter={() => setIsPaused(true)}
onMouseLeave={() => setIsPaused(false)}
role="dialog"
@@ -96,27 +96,20 @@ export const SessionExpiredModal: React.FC<SessionExpiredModalProps> = ({
>
<div
id="session-expired-modal-content"
className="relative w-full max-w-md bg-[#0c121e] border border-amber-500/40 rounded-2xl shadow-2xl shadow-black/90 p-6 overflow-hidden text-slate-200 space-y-5 my-auto"
className="relative w-full max-w-md bg-[#0d1322] border border-slate-800 rounded-2xl shadow-2xl p-5 overflow-hidden text-slate-200 space-y-4 my-auto"
>
{/* Subtle decorative top accent bar */}
<div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-amber-500 via-orange-500 to-rose-500" />
<div className="absolute top-0 left-0 right-0 h-1 bg-amber-500" />
{/* Top bar with close button */}
<div className="flex items-start justify-between pt-1">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-2xl bg-amber-500/10 border border-amber-500/30 flex items-center justify-center text-amber-400 shrink-0 shadow-lg shadow-amber-500/10">
<ShieldAlert className="w-6 h-6" />
<div className="w-10 h-10 rounded-xl bg-amber-500/10 border border-amber-500/20 flex items-center justify-center text-amber-400 shrink-0">
<ShieldAlert className="w-5 h-5" />
</div>
<div>
<div className="flex items-center gap-2">
<h3 id="session-expired-title" className="text-base font-bold text-white tracking-tight">
Session Expired
</h3>
<span className="text-[10px] font-mono font-semibold px-2 py-0.5 rounded bg-rose-950/60 text-rose-300 border border-rose-800/60">
HTTP 401
</span>
</div>
<p className="text-xs text-slate-400 mt-0.5">Authorization token invalidated</p>
<h3 id="session-expired-title" className="text-base font-bold text-white tracking-tight">
Session Expired
</h3>
<p className="text-xs text-slate-400">Authorization credentials expired</p>
</div>
</div>
@@ -125,60 +118,46 @@ export const SessionExpiredModal: React.FC<SessionExpiredModalProps> = ({
type="button"
onClick={handleAction}
aria-label="Dismiss and return to landing page"
className="p-1.5 text-slate-400 hover:text-white rounded-lg hover:bg-slate-800/80 transition-colors"
className="p-1.5 text-slate-400 hover:text-white rounded-lg hover:bg-slate-800 transition-colors cursor-pointer"
>
<X className="w-4 h-4" />
</button>
</div>
{/* Informative Explanation (non-technical and clear) */}
<div className="space-y-2.5 text-xs text-slate-300 leading-relaxed bg-slate-900/60 p-4 rounded-xl border border-slate-800/80">
<div className="text-xs text-slate-300 leading-relaxed bg-slate-900/60 p-3.5 rounded-xl border border-slate-800/80 space-y-1.5">
<p>
Your active working session has ended or your security credentials have expired. To protect your data and prevent unauthorized changes, your session has been closed.
Your active session has ended to protect account security. Please sign in again to continue working.
</p>
{reason && (
<div className="flex items-start gap-2 pt-1 text-[11px] text-amber-300/90 font-mono">
<div className="flex items-start gap-1.5 pt-1 text-[11px] text-amber-300/90 font-mono">
<AlertTriangle className="w-3.5 h-3.5 shrink-0 mt-0.5 text-amber-400" />
<span className="break-words">{reason}</span>
</div>
)}
</div>
{/* Progress Bar Countdown */}
<div className="space-y-2">
<div className="flex items-center justify-between text-xs">
<span className="text-slate-400 flex items-center gap-1.5">
<Clock className="w-3.5 h-3.5 text-amber-400" />
Returning to landing page in{' '}
<strong className="text-white font-mono">{secondsRemaining}s</strong>
<div className="flex items-center justify-between text-xs text-slate-400">
<span className="flex items-center gap-1.5">
<Clock className="w-3.5 h-3.5 text-amber-400" />
Redirecting in <strong className="text-white font-mono">{secondsRemaining}s</strong>
</span>
{isPaused && (
<span className="text-[10px] text-amber-400/80 px-1.5 py-0.5 rounded bg-amber-500/10 border border-amber-500/20">
Paused
</span>
{isPaused && (
<span className="text-[10px] text-amber-400/80 font-medium px-1.5 py-0.2 rounded bg-amber-950/40 border border-amber-900/60">
Paused on hover
</span>
)}
</div>
{/* Progress bar line */}
<div className="w-full h-2 bg-slate-800/90 rounded-full overflow-hidden border border-slate-700/60 p-0.5">
<div
className="h-full rounded-full bg-gradient-to-r from-amber-500 via-orange-500 to-rose-500 transition-all duration-75 ease-linear"
style={{ width: `${progressPercent}%` }}
/>
</div>
)}
</div>
{/* Actions */}
<div className="pt-2 flex flex-col sm:flex-row items-center gap-2.5">
<div className="pt-1">
<button
id="session-expired-return-btn"
type="button"
onClick={handleAction}
className="w-full py-2.5 px-4 text-xs font-semibold text-white bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-500 hover:to-indigo-500 rounded-xl shadow-lg shadow-blue-500/20 transition-all flex items-center justify-center gap-2"
className="w-full py-2.5 px-4 text-xs font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-xl shadow-md transition-all flex items-center justify-center gap-2 cursor-pointer"
>
<LogOut className="w-4 h-4" />
<span>Return to Landing Page Now</span>
<ArrowRight className="w-3.5 h-3.5 ml-0.5" />
<span>Return to Landing Page</span>
<ArrowRight className="w-3.5 h-3.5" />
</button>
</div>
</div>