Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Account Security Dashboard</title> | |
| <!-- Importing Phosphor Icons for modern iconography --> | |
| <script src="https://unpkg.com/@phosphor-icons/web"></script> | |
| <style> | |
| :root { | |
| --bg-dark: #0f172a; | |
| --bg-card: #1e293b; | |
| --primary: #3b82f6; | |
| --primary-glow: rgba(59, 130, 246, 0.5); | |
| --success: #10b981; | |
| --warning: #f59e0b; | |
| --danger: #ef4444; | |
| --text-main: #f8fafc; | |
| --text-muted: #94a3b8; | |
| --border: #334155; | |
| --font-family: 'Inter', system-ui, -apple-system, sans-serif; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background-color: var(--bg-dark); | |
| color: var(--text-main); | |
| font-family: var(--font-family); | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow-x: hidden; | |
| } | |
| /* --- Header --- */ | |
| header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1.5rem 2rem; | |
| border-bottom: 1px solid var(--border); | |
| background: rgba(15, 23, 42, 0.8); | |
| backdrop-filter: blur(10px); | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: 1.25rem; | |
| font-weight: 700; | |
| color: var(--primary); | |
| } | |
| .anycoder-link { | |
| color: var(--text-muted); | |
| text-decoration: none; | |
| font-size: 0.875rem; | |
| transition: color 0.3s; | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .anycoder-link:hover { | |
| color: var(--primary); | |
| } | |
| /* --- Main Layout --- */ | |
| main { | |
| flex: 1; | |
| padding: 2rem; | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| width: 100%; | |
| display: grid; | |
| grid-template-columns: 300px 1fr; | |
| gap: 2rem; | |
| } | |
| /* --- Sidebar / Profile --- */ | |
| .profile-card { | |
| background: var(--bg-card); | |
| border-radius: 16px; | |
| padding: 2rem; | |
| text-align: center; | |
| border: 1px solid var(--border); | |
| height: fit-content; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .profile-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100px; | |
| background: linear-gradient(180deg, rgba(59, 130, 246, 0.2) 0%, transparent 100%); | |
| } | |
| .avatar-container { | |
| width: 100px; | |
| height: 100px; | |
| margin: 0 auto 1rem; | |
| border-radius: 50%; | |
| background: var(--border); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 3rem; | |
| color: var(--text-muted); | |
| border: 4px solid var(--bg-card); | |
| box-shadow: 0 0 20px rgba(0,0,0,0.3); | |
| position: relative; | |
| z-index: 1; | |
| } | |
| .security-score-circle { | |
| width: 120px; | |
| height: 120px; | |
| border-radius: 50%; | |
| background: conic-gradient(var(--success) 0% 75%, var(--border) 75% 100%); | |
| margin: 0 auto 1.5rem; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| position: relative; | |
| transition: background 1s ease-out; | |
| } | |
| .score-inner { | |
| width: 100px; | |
| height: 100px; | |
| background: var(--bg-card); | |
| border-radius: 50%; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .score-value { | |
| font-size: 2rem; | |
| font-weight: 800; | |
| color: var(--success); | |
| } | |
| .score-label { | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| } | |
| /* --- Dashboard Grid --- */ | |
| .dashboard-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 1.5rem; | |
| } | |
| .card { | |
| background: var(--bg-card); | |
| border-radius: 16px; | |
| padding: 1.5rem; | |
| border: 1px solid var(--border); | |
| transition: transform 0.2s, box-shadow 0.2s; | |
| } | |
| .card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 30px -10px rgba(0,0,0,0.5); | |
| border-color: var(--primary); | |
| } | |
| .card-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1.5rem; | |
| } | |
| .card-title { | |
| font-size: 1.1rem; | |
| font-weight: 600; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .status-badge { | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 20px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| } | |
| .status-active { background: rgba(16, 185, 129, 0.1); color: var(--success); } | |
| .status-warning { background: rgba(245, 158, 11, 0.1); color: var(--warning); } | |
| .status-danger { background: rgba(239, 68, 68, 0.1); color: var(--danger); } | |
| /* --- Interactive Elements --- */ | |
| .password-input-group { | |
| position: relative; | |
| margin-bottom: 1rem; | |
| } | |
| .password-input { | |
| width: 100%; | |
| padding: 1rem; | |
| background: rgba(0,0,0,0.2); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| color: var(--text-main); | |
| font-family: monospace; | |
| font-size: 1rem; | |
| outline: none; | |
| transition: border-color 0.3s; | |
| } | |
| .password-input:focus { | |
| border-color: var(--primary); | |
| } | |
| .strength-meter { | |
| height: 4px; | |
| background: var(--border); | |
| border-radius: 2px; | |
| margin-top: 0.5rem; | |
| overflow: hidden; | |
| display: flex; | |
| } | |
| .strength-bar { | |
| height: 100%; | |
| width: 0%; | |
| transition: width 0.3s, background-color 0.3s; | |
| } | |
| .login-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| padding: 1rem 0; | |
| border-bottom: 1px solid rgba(255,255,255,0.05); | |
| } | |
| .login-item:last-child { border-bottom: none; } | |
| .device-icon { | |
| width: 40px; | |
| height: 40px; | |
| background: rgba(255,255,255,0.05); | |
| border-radius: 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.25rem; | |
| color: var(--primary); | |
| } | |
| .login-details { flex: 1; } | |
| .login-location { font-size: 0.875rem; color: var(--text-muted); } | |
| .login-time { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem; } | |
| .btn-action { | |
| padding: 0.5rem 1rem; | |
| border-radius: 6px; | |
| border: none; | |
| cursor: pointer; | |
| font-weight: 600; | |
| transition: all 0.2s; | |
| font-size: 0.875rem; | |
| } | |
| .btn-secure { | |
| background: var(--primary); | |
| color: white; | |
| } | |
| .btn-secure:hover { background: #2563eb; } | |
| .btn-danger { | |
| background: rgba(239, 68, 68, 0.1); | |
| color: var(--danger); | |
| } | |
| .btn-danger:hover { background: rgba(239, 68, 68, 0.2); } | |
| /* --- Responsive --- */ | |
| @media (max-width: 900px) { | |
| main { | |
| grid-template-columns: 1fr; | |
| } | |
| .profile-card { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="logo"> | |
| <i class="ph ph-shield-check"></i> | |
| <span>Securify</span> | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link"> | |
| <i class="ph ph-code"></i> | |
| Built with anycoder | |
| </a> | |
| </header> | |
| <main> | |
| <!-- Sidebar / Profile Summary --> | |
| <aside class="profile-card"> | |
| <div class="avatar-container"> | |
| <i class="ph ph-user"></i> | |
| </div> | |
| <h2 style="margin-bottom: 0.5rem;">Admin User</h2> | |
| <p style="color: var(--text-muted); margin-bottom: 2rem;">admin@example.com</p> | |
| <div class="security-score-circle" id="scoreCircle"> | |
| <div class="score-inner"> | |
| <span class="score-value" id="scoreValue">0</span> | |
| <span class="score-label">Security</span> | |
| </div> | |
| </div> | |
| <div style="text-align: left; width: 100%;"> | |
| <h4 style="margin-bottom: 1rem; font-size: 0.9rem; text-transform: uppercase; color: var(--text-muted);">Recommendations</h4> | |
| <div style="display: flex; flex-direction: column; gap: 0.75rem;"> | |
| <div style="display: flex; align-items: center; gap: 0.75rem; color: var(--success);"> | |
| <i class="ph ph-check-circle"></i> | |
| <span style="font-size: 0.9rem;">Login Alerts Enabled</span> | |
| </div> | |
| <div style="display: flex; align-items: center; gap: 0.75rem; color: var(--warning);"> | |
| <i class="ph ph-warning"></i> | |
| <span style="font-size: 0.9rem;">Update Recovery Email</span> | |
| </div> | |
| <div style="display: flex; align-items: center; gap: 0.75rem; color: var(--danger);"> | |
| <i class="ph ph-x-circle"></i> | |
| <span style="font-size: 0.9rem;">Password Strength Low</span> | |
| </div> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Main Dashboard Content --> | |
| <section class="dashboard-grid"> | |
| <!-- Password Health Card --> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <div class="card-title"> | |
| <i class="ph ph-key" style="color: var(--primary);"></i> | |
| Password Health | |
| </div> | |
| <span class="status-badge status-danger" id="pwdStatus">Weak</span> | |
| </div> | |
| <p style="color: var(--text-muted); margin-bottom: 1rem; font-size: 0.9rem;"> | |
| Test your password strength locally. This data is not sent to any server. | |
| </p> | |
| <div class="password-input-group"> | |
| <input type="password" class="password-input" id="passwordInput" placeholder="Enter a password to test..."> | |
| <div class="strength-meter"> | |
| <div class="strength-bar" id="strengthBar"></div> | |
| </div> | |
| </div> | |
| <button class="btn-action btn-secure" style="width: 100%; margin-top: 1rem;"> | |
| <i class="ph ph-arrows-clockwise"></i> Generate Strong Password | |
| </button> | |
| </div> | |
| <!-- 2FA Status Card --> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <div class="card-title"> | |
| <i class="ph ph-device-mobile-camera" style="color: var(--success);"></i> | |
| Two-Factor Auth | |
| </div> | |
| <span class="status-badge status-warning">Not Active</span> | |
| </div> | |
| <div style="display: flex; align-items: center; justify-content: center; height: 150px; background: rgba(0,0,0,0.2); border-radius: 8px; margin-bottom: 1rem;"> | |
| <i class="ph ph-qr-code" style="font-size: 4rem; color: var(--text-muted); opacity: 0.5;"></i> | |
| </div> | |
| <p style="color: var(--text-muted); margin-bottom: 1rem; font-size: 0.9rem;"> | |
| Secure your account by requiring a code from your phone when logging in. | |
| </p> | |
| <button class="btn-action btn-secure" style="width: 100%;"> | |
| Setup 2FA | |
| </button> | |
| </div> | |
| <!-- Active Sessions Card --> | |
| <div class="card" style="grid-column: 1 / -1;"> | |
| <div class="card-header"> | |
| <div class="card-title"> | |
| <i class="ph ph-globe" style="color: var(--warning);"></i> | |
| Active Sessions | |
| </div> | |
| <button class="btn-action btn-danger" style="padding: 0.25rem 0.5rem;">Log out all</button> | |
| </div> | |
| <div class="login-list" id="loginList"> | |
| <!-- Javascript will populate this --> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <script> | |
| // --- Password Strength Logic --- | |
| const passwordInput = document.getElementById('passwordInput'); | |
| const strengthBar = document.getElementById('strengthBar'); | |
| const pwdStatus = document.getElementById('pwdStatus'); | |
| const scoreValue = document.getElementById('scoreValue'); | |
| const scoreCircle = document.getElementById('scoreCircle'); | |
| passwordInput.addEventListener('input', (e) => { | |
| const val = e.target.value; | |
| let strength = 0; | |
| if (val.length > 5) strength += 20; | |
| if (val.length > 10) strength += 20; | |
| if (/[A-Z]/.test(val)) strength += 20; | |
| if (/[0-9]/.test(val)) strength += 20; | |
| if (/[^A-Za-z0-9]/.test(val)) strength += 20; | |
| // Update UI | |
| strengthBar.style.width = `${strength}%`; | |
| if (strength < 40) { | |
| strengthBar.style.backgroundColor = 'var(--danger)'; | |
| pwdStatus.textContent = 'Weak'; | |
| pwdStatus.className = 'status-badge status-danger'; | |
| updateScore(40); | |
| } else if (strength < 80) { | |
| strengthBar.style.backgroundColor = 'var(--warning)'; | |
| pwdStatus.textContent = 'Medium'; | |
| pwdStatus.className = 'status-badge status-warning'; | |
| updateScore(75); | |
| } else { | |
| strengthBar.style.backgroundColor = 'var(--success)'; | |
| pwdStatus.textContent = 'Strong'; | |
| pwdStatus.className = 'status-badge status-active'; | |
| updateScore(100); | |
| } | |
| }); | |
| function updateScore(target) { | |
| // Animate score circle | |
| scoreCircle.style.background = `conic-gradient(var(--success) 0% ${target}%, var(--border) ${target}% 100%)`; | |
| // Animate number | |
| let current = parseInt(scoreValue.innerText); | |
| const step = (target - current) / 20; | |
| const timer = setInterval(() => { | |
| current += step; | |
| if ((step > 0 && current >= target) || (step < 0 && current <= target)) { | |
| current = target; | |
| clearInterval(timer); | |
| } | |
| scoreValue.innerText = Math.round(current); | |
| }, 30); | |
| } | |
| // --- Mock Login Data --- | |
| const sessions = [ | |
| { device: 'Windows PC', location: 'New York, USA', time: 'Active Now', icon: 'ph-desktop' }, | |
| { device: 'iPhone 13', location: 'San Francisco, USA', time: '2 hours ago', icon: 'ph-device-mobile' }, | |
| { device: 'Chrome Browser', location: 'London, UK', time: '1 day ago', icon: 'ph-globe' }, | |
| ]; | |
| const loginList = document.getElementById('loginList'); | |
| sessions.forEach(session => { | |
| const item = document.createElement('div'); | |
| item.className = 'login-item'; | |
| item.innerHTML = ` | |
| <div class="device-icon"> | |
| <i class="ph ${session.icon}"></i> | |
| </div> | |
| <div class="login-details"> | |
| <div style="font-weight: 600;">${session.device}</div> | |
| <div class="login-location">${session.location}</div> | |
| <div class="login-time">${session.time}</div> | |
| </div> | |
| ${session.time === 'Active Now' ? '<span class="status-badge status-active">Current</span>' : '<button class="btn-action btn-danger">End</button>'} | |
| `; | |
| loginList.appendChild(item); | |
| }); | |
| // Initialize score | |
| updateScore(75); | |
| </script> | |
| </body> | |
| </html> |