|
|
<!DOCTYPE html> |
|
|
<html lang="ar" dir="rtl"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Auto-Guardian Dashboard</title> |
|
|
<meta name="google-site-verification" content="google7cceda004d653872" /> |
|
|
<meta name="description" content="Auto-Guardian: A comprehensive security and monitoring system dashboard for modern infrastructure. Automated security monitoring and protection core system." /> |
|
|
<meta name="keywords" content="security, monitoring, automation, guardian, dashboard, infrastructure, protection" /> |
|
|
<meta name="author" content="Abdulelah Othman Gwaith" /> |
|
|
<meta property="og:title" content="Auto-Guardian Dashboard" /> |
|
|
<meta property="og:description" content="Automated security monitoring and protection core system." /> |
|
|
<meta property="og:url" content="https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/" /> |
|
|
<meta property="og:type" content="website" /> |
|
|
<script type="application/ld+json"> |
|
|
{ |
|
|
"@context": "https://schema.org", |
|
|
"@type": "SoftwareApplication", |
|
|
"name": "Auto-Guardian-Core", |
|
|
"operatingSystem": "Linux, Windows, macOS", |
|
|
"applicationCategory": "SecurityApplication", |
|
|
"offers": { |
|
|
"@type": "Offer", |
|
|
"price": "0", |
|
|
"priceCurrency": "USD" |
|
|
}, |
|
|
"author": { |
|
|
"@type": "Person", |
|
|
"name": "Abdulelah Othman Gwaith" |
|
|
}, |
|
|
"description": "An automated security monitoring and protection core system designed for modern infrastructure.", |
|
|
"url": "https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/" |
|
|
} |
|
|
</script> |
|
|
<style> |
|
|
* { |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
|
|
|
:root { |
|
|
--primary: #0F172A; |
|
|
--secondary: #3B82F6; |
|
|
--success: #10B981; |
|
|
--danger: #EF4444; |
|
|
--warning: #F59E0B; |
|
|
--bg: #F8FAFC; |
|
|
--card-bg: #FFFFFF; |
|
|
--text: #1E293B; |
|
|
--text-muted: #64748B; |
|
|
--border: #E2E8F0; |
|
|
} |
|
|
|
|
|
body { |
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
|
background-color: var(--bg); |
|
|
color: var(--text); |
|
|
min-height: 100vh; |
|
|
overflow-x: hidden; |
|
|
} |
|
|
|
|
|
.dashboard { |
|
|
display: flex; |
|
|
flex-direction: row; |
|
|
min-height: 100vh; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
|
|
|
.sidebar { |
|
|
background: var(--primary); |
|
|
color: white; |
|
|
padding: 20px 0; |
|
|
width: 240px; |
|
|
height: 100vh; |
|
|
overflow-y: auto; |
|
|
flex-shrink: 0; |
|
|
position: sticky; |
|
|
top: 0; |
|
|
} |
|
|
|
|
|
.logo { |
|
|
padding: 20px; |
|
|
text-align: center; |
|
|
border-bottom: 1px solid rgba(255,255,255,0.1); |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
|
|
|
.logo h1 { |
|
|
font-size: 20px; |
|
|
font-weight: 700; |
|
|
color: var(--secondary); |
|
|
} |
|
|
|
|
|
.logo span { |
|
|
font-size: 12px; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
.nav-menu { |
|
|
list-style: none; |
|
|
} |
|
|
|
|
|
.nav-item { |
|
|
padding: 12px 20px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 12px; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
border-right: 3px solid transparent; |
|
|
} |
|
|
|
|
|
.nav-item:hover, .nav-item.active { |
|
|
background: rgba(59, 130, 246, 0.1); |
|
|
border-right-color: var(--secondary); |
|
|
} |
|
|
|
|
|
.nav-item svg { |
|
|
width: 20px; |
|
|
height: 20px; |
|
|
} |
|
|
|
|
|
.nav-item span { |
|
|
font-size: 14px; |
|
|
} |
|
|
|
|
|
|
|
|
.main-content { |
|
|
flex: 1; |
|
|
padding: 20px 30px; |
|
|
min-width: 0; |
|
|
overflow-x: hidden; |
|
|
} |
|
|
|
|
|
|
|
|
.header { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
margin-bottom: 30px; |
|
|
flex-wrap: wrap; |
|
|
gap: 15px; |
|
|
} |
|
|
|
|
|
.header h2 { |
|
|
font-size: 24px; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.header-actions { |
|
|
display: flex; |
|
|
gap: 12px; |
|
|
align-items: center; |
|
|
} |
|
|
|
|
|
.search-box { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
background: var(--card-bg); |
|
|
border: 1px solid var(--border); |
|
|
border-radius: 8px; |
|
|
padding: 8px 16px; |
|
|
gap: 8px; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.search-box:hover { |
|
|
border-color: var(--secondary); |
|
|
} |
|
|
|
|
|
.search-box input { |
|
|
border: none; |
|
|
outline: none; |
|
|
font-size: 14px; |
|
|
width: 150px; |
|
|
background: transparent; |
|
|
flex: 1; |
|
|
min-width: 100px; |
|
|
} |
|
|
|
|
|
.search-results { |
|
|
display: none; |
|
|
position: absolute; |
|
|
top: 100%; |
|
|
left: 0; |
|
|
right: 0; |
|
|
background: white; |
|
|
border: 1px solid var(--border); |
|
|
border-radius: 8px; |
|
|
margin-top: 8px; |
|
|
max-height: 300px; |
|
|
overflow-y: auto; |
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.1); |
|
|
z-index: 100; |
|
|
} |
|
|
|
|
|
.search-results.active { |
|
|
display: block; |
|
|
} |
|
|
|
|
|
.search-result-item { |
|
|
padding: 12px 16px; |
|
|
border-bottom: 1px solid var(--border); |
|
|
cursor: pointer; |
|
|
transition: background 0.3s ease; |
|
|
} |
|
|
|
|
|
.search-result-item:hover { |
|
|
background: var(--bg); |
|
|
} |
|
|
|
|
|
.search-result-item:last-child { |
|
|
border-bottom: none; |
|
|
} |
|
|
|
|
|
.notification-btn { |
|
|
position: relative; |
|
|
background: var(--card-bg); |
|
|
border: 1px solid var(--border); |
|
|
border-radius: 8px; |
|
|
padding: 8px 12px; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.notification-btn:hover { |
|
|
border-color: var(--secondary); |
|
|
} |
|
|
|
|
|
.notification-badge { |
|
|
position: absolute; |
|
|
top: -5px; |
|
|
right: -5px; |
|
|
background: var(--danger); |
|
|
color: white; |
|
|
font-size: 10px; |
|
|
padding: 2px 6px; |
|
|
border-radius: 10px; |
|
|
} |
|
|
|
|
|
|
|
|
.settings-panel { |
|
|
display: none; |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0,0,0,0.5); |
|
|
z-index: 1000; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
} |
|
|
|
|
|
.settings-panel.active { |
|
|
display: flex; |
|
|
} |
|
|
|
|
|
.settings-content { |
|
|
background: white; |
|
|
border-radius: 16px; |
|
|
padding: 30px; |
|
|
width: 90%; |
|
|
max-width: 500px; |
|
|
max-height: 80vh; |
|
|
overflow-y: auto; |
|
|
} |
|
|
|
|
|
.settings-header { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
margin-bottom: 24px; |
|
|
} |
|
|
|
|
|
.settings-header h3 { |
|
|
font-size: 20px; |
|
|
} |
|
|
|
|
|
.close-btn { |
|
|
background: none; |
|
|
border: none; |
|
|
font-size: 24px; |
|
|
cursor: pointer; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
.setting-item { |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
|
|
|
.setting-label { |
|
|
display: block; |
|
|
font-size: 14px; |
|
|
font-weight: 500; |
|
|
margin-bottom: 8px; |
|
|
} |
|
|
|
|
|
.setting-description { |
|
|
font-size: 12px; |
|
|
color: var(--text-muted); |
|
|
margin-bottom: 8px; |
|
|
} |
|
|
|
|
|
.setting-input { |
|
|
width: 100%; |
|
|
padding: 10px 14px; |
|
|
border: 1px solid var(--border); |
|
|
border-radius: 8px; |
|
|
font-size: 14px; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.setting-input:focus { |
|
|
outline: none; |
|
|
border-color: var(--secondary); |
|
|
} |
|
|
|
|
|
.setting-select { |
|
|
width: 100%; |
|
|
padding: 10px 14px; |
|
|
border: 1px solid var(--border); |
|
|
border-radius: 8px; |
|
|
font-size: 14px; |
|
|
background: white; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.setting-toggle { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 12px; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.toggle-switch { |
|
|
position: relative; |
|
|
width: 50px; |
|
|
height: 26px; |
|
|
background: var(--border); |
|
|
border-radius: 13px; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.toggle-switch.active { |
|
|
background: var(--secondary); |
|
|
} |
|
|
|
|
|
.toggle-switch::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
width: 22px; |
|
|
height: 22px; |
|
|
background: white; |
|
|
border-radius: 50%; |
|
|
top: 2px; |
|
|
left: 2px; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.toggle-switch.active::after { |
|
|
left: 26px; |
|
|
} |
|
|
|
|
|
.save-btn { |
|
|
width: 100%; |
|
|
padding: 12px; |
|
|
background: var(--secondary); |
|
|
color: white; |
|
|
border: none; |
|
|
border-radius: 8px; |
|
|
font-size: 14px; |
|
|
font-weight: 500; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.save-btn:hover { |
|
|
background: var(--primary); |
|
|
} |
|
|
|
|
|
|
|
|
.stats-grid { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(4, 1fr); |
|
|
gap: 20px; |
|
|
margin-bottom: 30px; |
|
|
} |
|
|
|
|
|
.stat-card { |
|
|
background: var(--card-bg); |
|
|
border-radius: 12px; |
|
|
padding: 20px; |
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1); |
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.stat-card:hover { |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15); |
|
|
} |
|
|
|
|
|
.stat-header { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: flex-start; |
|
|
margin-bottom: 12px; |
|
|
} |
|
|
|
|
|
.stat-icon { |
|
|
width: 40px; |
|
|
height: 40px; |
|
|
border-radius: 10px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
.stat-icon.blue { background: rgba(59, 130, 246, 0.1); color: var(--secondary); } |
|
|
.stat-icon.green { background: rgba(16, 185, 129, 0.1); color: var(--success); } |
|
|
.stat-icon.red { background: rgba(239, 68, 68, 0.1); color: var(--danger); } |
|
|
.stat-icon.yellow { background: rgba(245, 158, 11, 0.1); color: var(--warning); } |
|
|
|
|
|
.stat-trend { |
|
|
font-size: 12px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 4px; |
|
|
} |
|
|
|
|
|
.stat-trend.up { color: var(--success); } |
|
|
.stat-trend.down { color: var(--danger); } |
|
|
|
|
|
.stat-value { |
|
|
font-size: 28px; |
|
|
font-weight: 700; |
|
|
margin-bottom: 4px; |
|
|
} |
|
|
|
|
|
.stat-label { |
|
|
font-size: 13px; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
|
|
|
.charts-section { |
|
|
display: grid; |
|
|
grid-template-columns: 2fr 1fr; |
|
|
gap: 20px; |
|
|
margin-bottom: 30px; |
|
|
} |
|
|
|
|
|
.chart-card { |
|
|
background: var(--card-bg); |
|
|
border-radius: 12px; |
|
|
padding: 20px; |
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1); |
|
|
} |
|
|
|
|
|
.chart-header { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
|
|
|
.chart-title { |
|
|
font-size: 16px; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.chart-tabs { |
|
|
display: flex; |
|
|
gap: 8px; |
|
|
} |
|
|
|
|
|
.chart-tab { |
|
|
padding: 6px 12px; |
|
|
border-radius: 6px; |
|
|
font-size: 12px; |
|
|
cursor: pointer; |
|
|
background: var(--bg); |
|
|
border: none; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.chart-tab.active { |
|
|
background: var(--secondary); |
|
|
color: white; |
|
|
} |
|
|
|
|
|
.chart-tab:hover:not(.active) { |
|
|
background: var(--border); |
|
|
} |
|
|
|
|
|
|
|
|
.area-chart { |
|
|
height: 250px; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.chart-svg { |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
} |
|
|
|
|
|
|
|
|
.donut-chart { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
gap: 30px; |
|
|
} |
|
|
|
|
|
.donut-svg { |
|
|
width: 180px; |
|
|
height: 180px; |
|
|
} |
|
|
|
|
|
.donut-legend { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 12px; |
|
|
} |
|
|
|
|
|
.legend-item { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 8px; |
|
|
} |
|
|
|
|
|
.legend-color { |
|
|
width: 12px; |
|
|
height: 12px; |
|
|
border-radius: 3px; |
|
|
} |
|
|
|
|
|
.legend-label { |
|
|
font-size: 13px; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
.legend-value { |
|
|
font-size: 14px; |
|
|
font-weight: 600; |
|
|
margin-right: auto; |
|
|
} |
|
|
|
|
|
|
|
|
.activity-section { |
|
|
display: grid; |
|
|
grid-template-columns: 1fr 1fr; |
|
|
gap: 20px; |
|
|
} |
|
|
|
|
|
.activity-card { |
|
|
background: var(--card-bg); |
|
|
border-radius: 12px; |
|
|
padding: 20px; |
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1); |
|
|
} |
|
|
|
|
|
.activity-header { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
margin-bottom: 16px; |
|
|
} |
|
|
|
|
|
.activity-title { |
|
|
font-size: 16px; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.view-all { |
|
|
font-size: 13px; |
|
|
color: var(--secondary); |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.view-all:hover { |
|
|
text-decoration: underline; |
|
|
} |
|
|
|
|
|
|
|
|
.issues-list { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 12px; |
|
|
} |
|
|
|
|
|
.issue-item { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 12px; |
|
|
padding: 12px; |
|
|
background: var(--bg); |
|
|
border-radius: 8px; |
|
|
transition: all 0.3s ease; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.issue-item:hover { |
|
|
background: rgba(59, 130, 246, 0.05); |
|
|
} |
|
|
|
|
|
.issue-icon { |
|
|
width: 32px; |
|
|
height: 32px; |
|
|
border-radius: 8px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
.issue-content { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
.issue-title { |
|
|
font-size: 13px; |
|
|
font-weight: 500; |
|
|
margin-bottom: 2px; |
|
|
} |
|
|
|
|
|
.issue-meta { |
|
|
font-size: 11px; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
.issue-badge { |
|
|
padding: 4px 10px; |
|
|
border-radius: 20px; |
|
|
font-size: 11px; |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
.badge-critical { background: rgba(239, 68, 68, 0.1); color: var(--danger); } |
|
|
.badge-warning { background: rgba(245, 158, 11, 0.1); color: var(--warning); } |
|
|
.badge-info { background: rgba(59, 130, 246, 0.1); color: var(--secondary); } |
|
|
.badge-success { background: rgba(16, 185, 129, 0.1); color: var(--success); } |
|
|
|
|
|
|
|
|
.repos-list { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 12px; |
|
|
} |
|
|
|
|
|
.repo-item { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 12px; |
|
|
padding: 12px; |
|
|
background: var(--bg); |
|
|
border-radius: 8px; |
|
|
transition: all 0.3s ease; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.repo-item:hover { |
|
|
background: rgba(59, 130, 246, 0.05); |
|
|
} |
|
|
|
|
|
.repo-icon { |
|
|
width: 36px; |
|
|
height: 36px; |
|
|
border-radius: 8px; |
|
|
background: var(--primary); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
color: white; |
|
|
} |
|
|
|
|
|
.repo-content { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
.repo-name { |
|
|
font-size: 13px; |
|
|
font-weight: 500; |
|
|
margin-bottom: 2px; |
|
|
} |
|
|
|
|
|
.repo-stats { |
|
|
display: flex; |
|
|
gap: 12px; |
|
|
font-size: 11px; |
|
|
color: var(--text-muted); |
|
|
} |
|
|
|
|
|
.repo-status { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 4px; |
|
|
font-size: 12px; |
|
|
} |
|
|
|
|
|
.status-dot { |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
border-radius: 50%; |
|
|
} |
|
|
|
|
|
.status-dot.active { background: var(--success); } |
|
|
.status-dot.warning { background: var(--warning); } |
|
|
.status-dot.error { background: var(--danger); } |
|
|
|
|
|
|
|
|
.toast-container { |
|
|
position: fixed; |
|
|
top: 20px; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
z-index: 2000; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 10px; |
|
|
} |
|
|
|
|
|
.toast { |
|
|
padding: 14px 20px; |
|
|
background: var(--primary); |
|
|
color: white; |
|
|
border-radius: 10px; |
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.2); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 10px; |
|
|
animation: slideIn 0.3s ease, fadeOut 0.3s ease 2.7s; |
|
|
} |
|
|
|
|
|
.toast.success { background: var(--success); } |
|
|
.toast.error { background: var(--danger); } |
|
|
.toast.warning { background: var(--warning); } |
|
|
.toast.info { background: var(--secondary); } |
|
|
|
|
|
@keyframes slideIn { |
|
|
from { transform: translateY(-20px); opacity: 0; } |
|
|
to { transform: translateY(0); opacity: 1; } |
|
|
} |
|
|
|
|
|
@keyframes fadeOut { |
|
|
from { opacity: 1; } |
|
|
to { opacity: 0; } |
|
|
} |
|
|
|
|
|
|
|
|
@media (max-width: 1200px) { |
|
|
.stats-grid { |
|
|
grid-template-columns: repeat(2, 1fr); |
|
|
} |
|
|
.charts-section { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
.activity-section { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
} |
|
|
|
|
|
@media (max-width: 992px) { |
|
|
.sidebar { |
|
|
position: fixed; |
|
|
right: -240px; |
|
|
top: 0; |
|
|
z-index: 1000; |
|
|
transition: right 0.3s ease; |
|
|
box-shadow: -4px 0 20px rgba(0,0,0,0.1); |
|
|
} |
|
|
|
|
|
.sidebar.active { |
|
|
right: 0; |
|
|
} |
|
|
|
|
|
.sidebar-overlay { |
|
|
display: none; |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0,0,0,0.5); |
|
|
z-index: 999; |
|
|
} |
|
|
|
|
|
.sidebar-overlay.active { |
|
|
display: block; |
|
|
} |
|
|
|
|
|
.main-content { |
|
|
width: 100%; |
|
|
padding: 15px 20px; |
|
|
} |
|
|
|
|
|
.mobile-menu-btn { |
|
|
display: flex !important; |
|
|
} |
|
|
|
|
|
.header-actions { |
|
|
gap: 8px; |
|
|
} |
|
|
|
|
|
.search-box { |
|
|
min-width: 120px; |
|
|
} |
|
|
|
|
|
.search-box input { |
|
|
width: 80px; |
|
|
} |
|
|
} |
|
|
|
|
|
@media (max-width: 768px) { |
|
|
.dashboard { |
|
|
flex-direction: column; |
|
|
} |
|
|
|
|
|
.stats-grid { |
|
|
grid-template-columns: 1fr; |
|
|
gap: 12px; |
|
|
} |
|
|
|
|
|
.stat-card { |
|
|
padding: 15px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: space-between; |
|
|
flex-wrap: wrap; |
|
|
} |
|
|
|
|
|
.stat-header { |
|
|
margin-bottom: 0; |
|
|
width: auto; |
|
|
} |
|
|
|
|
|
.stat-value { |
|
|
font-size: 24px; |
|
|
text-align: left; |
|
|
} |
|
|
|
|
|
.stat-label { |
|
|
text-align: left; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.charts-section { |
|
|
gap: 15px; |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
|
|
|
.chart-card { |
|
|
padding: 15px; |
|
|
} |
|
|
|
|
|
.area-chart { |
|
|
height: 200px; |
|
|
} |
|
|
|
|
|
.donut-chart { |
|
|
flex-direction: column; |
|
|
gap: 15px; |
|
|
} |
|
|
|
|
|
.donut-svg { |
|
|
width: 150px; |
|
|
height: 150px; |
|
|
} |
|
|
|
|
|
.activity-section { |
|
|
gap: 15px; |
|
|
} |
|
|
|
|
|
.activity-card { |
|
|
padding: 15px; |
|
|
} |
|
|
|
|
|
.header { |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
|
|
|
.header h2 { |
|
|
font-size: 20px; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.header-actions { |
|
|
width: 100%; |
|
|
justify-content: space-between; |
|
|
} |
|
|
|
|
|
.search-box { |
|
|
flex: 1; |
|
|
min-width: 0; |
|
|
} |
|
|
|
|
|
.search-box input { |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.notification-btn { |
|
|
padding: 8px; |
|
|
} |
|
|
} |
|
|
|
|
|
@media (max-width: 480px) { |
|
|
.stat-card { |
|
|
padding: 12px; |
|
|
} |
|
|
|
|
|
.stat-icon { |
|
|
width: 36px; |
|
|
height: 36px; |
|
|
} |
|
|
|
|
|
.stat-value { |
|
|
font-size: 20px; |
|
|
} |
|
|
|
|
|
.stat-label { |
|
|
font-size: 12px; |
|
|
} |
|
|
|
|
|
.chart-title { |
|
|
font-size: 14px; |
|
|
} |
|
|
|
|
|
.chart-tabs { |
|
|
gap: 4px; |
|
|
} |
|
|
|
|
|
.chart-tab { |
|
|
padding: 4px 8px; |
|
|
font-size: 11px; |
|
|
} |
|
|
|
|
|
.issue-item, .repo-item { |
|
|
padding: 10px; |
|
|
} |
|
|
|
|
|
.issue-icon { |
|
|
width: 28px; |
|
|
height: 28px; |
|
|
} |
|
|
|
|
|
.issue-title { |
|
|
font-size: 12px; |
|
|
} |
|
|
|
|
|
.issue-meta { |
|
|
font-size: 10px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.mobile-menu-btn { |
|
|
display: none; |
|
|
position: fixed; |
|
|
bottom: 20px; |
|
|
left: 20px; |
|
|
width: 50px; |
|
|
height: 50px; |
|
|
border-radius: 50%; |
|
|
background: var(--secondary); |
|
|
color: white; |
|
|
border: none; |
|
|
cursor: pointer; |
|
|
z-index: 1001; |
|
|
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4); |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.mobile-menu-btn:hover { |
|
|
transform: scale(1.1); |
|
|
background: var(--primary); |
|
|
} |
|
|
|
|
|
.mobile-menu-btn svg { |
|
|
width: 24px; |
|
|
height: 24px; |
|
|
} |
|
|
|
|
|
|
|
|
.sidebar-overlay { |
|
|
display: none; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="dashboard"> |
|
|
|
|
|
<div class="sidebar-overlay" id="sidebarOverlay" onclick="toggleMobileMenu()"></div> |
|
|
|
|
|
|
|
|
<aside class="sidebar" id="sidebar"> |
|
|
<div class="logo"> |
|
|
<h1>Auto-Guardian</h1> |
|
|
<span>Security Dashboard</span> |
|
|
</div> |
|
|
<ul class="nav-menu"> |
|
|
<li class="nav-item active" data-view="dashboard"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/> |
|
|
</svg> |
|
|
<span>لوحة التحكم</span> |
|
|
</li> |
|
|
<li class="nav-item" data-view="protection"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/> |
|
|
</svg> |
|
|
<span>الحماية</span> |
|
|
</li> |
|
|
<li class="nav-item" data-view="analysis"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/> |
|
|
</svg> |
|
|
<span>الفحص والتحليل</span> |
|
|
</li> |
|
|
<li class="nav-item" data-view="reports"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/> |
|
|
</svg> |
|
|
<span>التقارير</span> |
|
|
</li> |
|
|
<li class="nav-item" data-view="settings" id="settingsNavItem"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/> |
|
|
</svg> |
|
|
<span>الإعدادات</span> |
|
|
</li> |
|
|
<li class="nav-item" data-view="help"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> |
|
|
</svg> |
|
|
<span>المساعدة</span> |
|
|
</li> |
|
|
</ul> |
|
|
</aside> |
|
|
|
|
|
|
|
|
<button class="mobile-menu-btn" id="mobileMenuBtn" onclick="toggleMobileMenu()"> |
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/> |
|
|
</svg> |
|
|
</button> |
|
|
|
|
|
|
|
|
<main class="main-content"> |
|
|
|
|
|
<header class="header"> |
|
|
<h2>لوحة تحكم Auto-Guardian</h2> |
|
|
<div class="header-actions"> |
|
|
<div class="search-box" id="searchBox"> |
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/> |
|
|
</svg> |
|
|
<input type="text" placeholder="بحث..." id="searchInput"> |
|
|
<div class="search-results" id="searchResults"></div> |
|
|
</div> |
|
|
<button class="notification-btn" id="notificationBtn"> |
|
|
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/> |
|
|
</svg> |
|
|
<span class="notification-badge" id="notificationBadge">5</span> |
|
|
</button> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
|
|
|
<div class="stats-grid"> |
|
|
<div class="stat-card" onclick="filterIssues('critical')"> |
|
|
<div class="stat-header"> |
|
|
<div class="stat-icon blue"> |
|
|
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/> |
|
|
</svg> |
|
|
</div> |
|
|
<span class="stat-trend up" id="trendCritical">↑ 12%</span> |
|
|
</div> |
|
|
<div class="stat-value" id="statThreats">1,247</div> |
|
|
<div class="stat-label">التهديدات المحظورة</div> |
|
|
</div> |
|
|
|
|
|
<div class="stat-card"> |
|
|
<div class="stat-header"> |
|
|
<div class="stat-icon green"> |
|
|
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> |
|
|
</svg> |
|
|
</div> |
|
|
<span class="stat-trend up" id="trendSuccess">↑ 8%</span> |
|
|
</div> |
|
|
<div class="stat-value" id="statSuccess">99.9%</div> |
|
|
<div class="stat-label">معدل النجاح</div> |
|
|
</div> |
|
|
|
|
|
<div class="stat-card" onclick="filterIssues('open')"> |
|
|
<div class="stat-header"> |
|
|
<div class="stat-icon red"> |
|
|
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> |
|
|
</svg> |
|
|
</div> |
|
|
<span class="stat-trend down" id="trendOpen">↓ 3%</span> |
|
|
</div> |
|
|
<div class="stat-value" id="statOpen">23</div> |
|
|
<div class="stat-label">المشكلات المفتوحة</div> |
|
|
</div> |
|
|
|
|
|
<div class="stat-card"> |
|
|
<div class="stat-header"> |
|
|
<div class="stat-icon yellow"> |
|
|
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/> |
|
|
</svg> |
|
|
</div> |
|
|
<span class="stat-trend up" id="trendResponse">↑ 15%</span> |
|
|
</div> |
|
|
<div class="stat-value" id="statResponse">0.3s</div> |
|
|
<div class="stat-label">زمن الاستجابة</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="charts-section"> |
|
|
<div class="chart-card"> |
|
|
<div class="chart-header"> |
|
|
<h3 class="chart-title">نشاط الفحص والأمان</h3> |
|
|
<div class="chart-tabs"> |
|
|
<button class="chart-tab" data-period="day" onclick="changePeriod('day')">24 ساعة</button> |
|
|
<button class="chart-tab active" data-period="week" onclick="changePeriod('week')">أسبوع</button> |
|
|
<button class="chart-tab" data-period="month" onclick="changePeriod('month')">شهر</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="area-chart"> |
|
|
<svg class="chart-svg" viewBox="0 0 800 250" id="mainChart"> |
|
|
|
|
|
<line x1="50" y1="30" x2="750" y2="30" stroke="#E2E8F0" stroke-width="1"/> |
|
|
<line x1="50" y1="80" x2="750" y2="80" stroke="#E2E8F0" stroke-width="1"/> |
|
|
<line x1="50" y1="130" x2="750" y2="130" stroke="#E2E8F0" stroke-width="1"/> |
|
|
<line x1="50" y1="180" x2="750" y2="180" stroke="#E2E8F0" stroke-width="1"/> |
|
|
|
|
|
|
|
|
<defs> |
|
|
<linearGradient id="areaGradient" x1="0%" y1="0%" x2="0%" y2="100%"> |
|
|
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3"/> |
|
|
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.05"/> |
|
|
</linearGradient> |
|
|
</defs> |
|
|
|
|
|
|
|
|
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55 L750,180 Z" fill="url(#areaGradient)"/> |
|
|
|
|
|
|
|
|
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55" fill="none" stroke="#3B82F6" stroke-width="3" stroke-linecap="round"/> |
|
|
|
|
|
|
|
|
<circle cx="100" cy="150" r="5" fill="#3B82F6" class="chart-point" data-value="45"/> |
|
|
<circle cx="200" cy="120" r="5" fill="#3B82F6" class="chart-point" data-value="60"/> |
|
|
<circle cx="300" cy="100" r="5" fill="#3B82F6" class="chart-point" data-value="70"/> |
|
|
<circle cx="400" cy="70" r="5" fill="#3B82F6" class="chart-point" data-value="85"/> |
|
|
<circle cx="500" cy="60" r="5" fill="#3B82F6" class="chart-point" data-value="90"/> |
|
|
<circle cx="600" cy="50" r="5" fill="#3B82F6" class="chart-point" data-value="95"/> |
|
|
<circle cx="700" cy="40" r="5" fill="#3B82F6" class="chart-point" data-value="100"/> |
|
|
|
|
|
|
|
|
<text x="50" y="200" fill="#64748B" font-size="11">السبت</text> |
|
|
<text x="150" y="200" fill="#64748B" font-size="11">الأحد</text> |
|
|
<text x="250" y="200" fill="#64748B" font-size="11">الاثنين</text> |
|
|
<text x="350" y="200" fill="#64748B" font-size="11">الثلاثاء</text> |
|
|
<text x="450" y="200" fill="#64748B" font-size="11">الأربعاء</text> |
|
|
<text x="550" y="200" fill="#64748B" font-size="11">الخميس</text> |
|
|
<text x="650" y="200" fill="#64748B" font-size="11">الجمعة</text> |
|
|
|
|
|
|
|
|
<text x="45" y="35" text-anchor="end" fill="#64748B" font-size="10">100</text> |
|
|
<text x="45" y="85" text-anchor="end" fill="#64748B" font-size="10">75</text> |
|
|
<text x="45" y="135" text-anchor="end" fill="#64748B" font-size="10">50</text> |
|
|
<text x="45" y="185" text-anchor="end" fill="#64748B" font-size="10">25</text> |
|
|
</svg> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="chart-card"> |
|
|
<div class="chart-header"> |
|
|
<h3 class="chart-title">توزيع المشكلات</h3> |
|
|
</div> |
|
|
<div class="donut-chart"> |
|
|
<svg class="donut-svg" viewBox="0 0 180 180"> |
|
|
<circle cx="90" cy="90" r="70" fill="none" stroke="#E2E8F0" stroke-width="25"/> |
|
|
<circle cx="90" cy="90" r="70" fill="none" stroke="#EF4444" stroke-width="25" stroke-dasharray="110 308" stroke-dashoffset="0" transform="rotate(-90 90 90)"/> |
|
|
<circle cx="90" cy="90" r="70" fill="none" stroke="#F59E0B" stroke-width="25" stroke-dasharray="88 308" stroke-dashoffset="-110" transform="rotate(-90 90 90)"/> |
|
|
<circle cx="90" cy="90" r="70" fill="none" stroke="#3B82F6" stroke-width="25" stroke-dasharray="66 308" stroke-dashoffset="-198" transform="rotate(-90 90 90)"/> |
|
|
<circle cx="90" cy="90" r="70" fill="none" stroke="#10B981" stroke-width="25" stroke-dasharray="44 308" stroke-dashoffset="-264" transform="rotate(-90 90 90)"/> |
|
|
<text x="90" y="85" text-anchor="middle" font-size="24" font-weight="bold" fill="#0F172A" id="donutTotal">23</text> |
|
|
<text x="90" y="105" text-anchor="middle" font-size="12" fill="#64748B">إجمالي</text> |
|
|
</svg> |
|
|
<div class="donut-legend"> |
|
|
<div class="legend-item"> |
|
|
<div class="legend-color" style="background:#EF4444"></div> |
|
|
<span class="legend-label">حرجة</span> |
|
|
<span class="legend-value" id="legendCritical">5</span> |
|
|
</div> |
|
|
<div class="legend-item"> |
|
|
<div class="legend-color" style="background:#F59E0B"></div> |
|
|
<span class="legend-label">عالية</span> |
|
|
<span class="legend-value" id="legendHigh">7</span> |
|
|
</div> |
|
|
<div class="legend-item"> |
|
|
<div class="legend-color" style="background:#3B82F6"></div> |
|
|
<span class="legend-label">متوسطة</span> |
|
|
<span class="legend-value" id="legendMedium">6</span> |
|
|
</div> |
|
|
<div class="legend-item"> |
|
|
<div class="legend-color" style="background:#10B981"></div> |
|
|
<span class="legend-label">منخفضة</span> |
|
|
<span class="legend-value" id="legendLow">5</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="activity-section"> |
|
|
<div class="activity-card"> |
|
|
<div class="activity-header"> |
|
|
<h3 class="activity-title">أحدث المشكلات</h3> |
|
|
<span class="view-all" onclick="filterIssues('all')">عرض الكل →</span> |
|
|
</div> |
|
|
<div class="issues-list" id="issuesList"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="activity-card"> |
|
|
<div class="activity-header"> |
|
|
<h3 class="activity-title">المستودعات النشطة</h3> |
|
|
<span class="view-all">عرض الكل →</span> |
|
|
</div> |
|
|
<div class="repos-list" id="reposList"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</main> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="settings-panel" id="settingsPanel"> |
|
|
<div class="settings-content"> |
|
|
<div class="settings-header"> |
|
|
<h3>⚙️ الإعدادات</h3> |
|
|
<button class="close-btn" onclick="closeSettings()">×</button> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">اسم المستخدم</label> |
|
|
<input type="text" class="setting-input" id="settingUsername" placeholder="أدخل اسم المستخدم"> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">البريد الإلكتروني</label> |
|
|
<input type="email" class="setting-input" id="settingEmail" placeholder="أدخل البريد الإلكتروني"> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">لغة الواجهة</label> |
|
|
<select class="setting-select" id="settingLanguage"> |
|
|
<option value="ar">العربية</option> |
|
|
<option value="en">English</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">السمة</label> |
|
|
<select class="setting-select" id="settingTheme"> |
|
|
<option value="light">فاتحة</option> |
|
|
<option value="dark">داكنة</option> |
|
|
<option value="auto">تلقائي</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">فحص تلقائي عند الحفظ</label> |
|
|
<div class="setting-toggle" onclick="toggleSetting('autoScan')"> |
|
|
<div class="toggle-switch" id="toggleAutoScan"></div> |
|
|
<span>تشغيل</span> |
|
|
</div> |
|
|
<p class="setting-description">إجراء فحص تلقائي للكود عند حفظ الملفات</p> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">إشعارات المشاكل الحرجة</label> |
|
|
<div class="setting-toggle" onclick="toggleSetting('criticalAlerts')"> |
|
|
<div class="toggle-switch" id="toggleCriticalAlerts"></div> |
|
|
<span>تشغيل</span> |
|
|
</div> |
|
|
<p class="setting-description">إرسال إشعارات فورية للمشاكل الأمنية الحرجة</p> |
|
|
</div> |
|
|
|
|
|
<div class="setting-item"> |
|
|
<label class="setting-label">الإصلاح التلقائي الآمن</label> |
|
|
<div class="setting-toggle" onclick="toggleSetting('autoFix')"> |
|
|
<div class="toggle-switch" id="toggleAutoFix"></div> |
|
|
<span>تشغيل</span> |
|
|
</div> |
|
|
<p class="setting-description">إصلاح المشاكل الآمنة تلقائياً دون تدخل</p> |
|
|
</div> |
|
|
|
|
|
<button class="save-btn" onclick="saveSettings()">💾 حفظ الإعدادات</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="toast-container" id="toastContainer"></div> |
|
|
|
|
|
<script> |
|
|
|
|
|
let currentData = { |
|
|
threats: 1247, |
|
|
successRate: 99.9, |
|
|
openIssues: 23, |
|
|
responseTime: 0.3, |
|
|
issues: [], |
|
|
repos: [] |
|
|
}; |
|
|
|
|
|
let settings = { |
|
|
username: '', |
|
|
email: '', |
|
|
language: 'ar', |
|
|
theme: 'light', |
|
|
autoScan: true, |
|
|
criticalAlerts: true, |
|
|
autoFix: true |
|
|
}; |
|
|
|
|
|
|
|
|
const sampleIssues = [ |
|
|
{ id: 1, title: 'ثغرة أمنية في وحدة المصادقة', file: 'auth-module.py', time: 'قبل 5 دقائق', severity: 'critical' }, |
|
|
{ id: 2, title: 'فشل في اختبارات الأداء', file: 'performance_test.py', time: 'قبل 23 دقيقة', severity: 'warning' }, |
|
|
{ id: 3, title: 'تحذير في تنسيق الكود', file: 'main_controller.dart', time: 'قبل ساعة', severity: 'info' }, |
|
|
{ id: 4, title: 'تم إصلاح مشكلة التنسيق تلقائياً', file: 'utils_helper.js', time: 'قبل ساعتين', severity: 'success' }, |
|
|
{ id: 5, title: 'مشكلة في اتصال قاعدة البيانات', file: 'db_connection.java', time: 'قبل ساعتين', severity: 'critical' }, |
|
|
{ id: 6, title: 'تحذير: استخدام دالة قديمة', file: 'legacy_code.py', time: 'قبل 3 ساعات', severity: 'warning' } |
|
|
]; |
|
|
|
|
|
const sampleRepos = [ |
|
|
{ id: 1, name: 'auto-guardian-system', stars: 124, pullRequests: 45, bugs: 3, status: 'active' }, |
|
|
{ id: 2, name: 'payment-gateway-api', stars: 89, pullRequests: 32, bugs: 5, status: 'warning' }, |
|
|
{ id: 3, name: 'user-management-service', stars: 56, pullRequests: 18, bugs: 1, status: 'active' }, |
|
|
{ id: 4, name: 'data-analytics-platform', stars: 234, pullRequests: 67, bugs: 8, status: 'error' } |
|
|
]; |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
loadSettings(); |
|
|
loadData(); |
|
|
renderIssues(); |
|
|
renderRepos(); |
|
|
setupEventListeners(); |
|
|
setupMobileMenu(); |
|
|
showToast('🎉 مرحباً بك في Auto-Guardian!', 'success'); |
|
|
}); |
|
|
|
|
|
|
|
|
function setupMobileMenu() { |
|
|
const mobileMenuBtn = document.getElementById('mobileMenuBtn'); |
|
|
if (mobileMenuBtn) { |
|
|
|
|
|
const checkScreenSize = () => { |
|
|
if (window.innerWidth <= 992) { |
|
|
mobileMenuBtn.style.display = 'flex'; |
|
|
} else { |
|
|
mobileMenuBtn.style.display = 'none'; |
|
|
closeMobileMenu(); |
|
|
} |
|
|
}; |
|
|
|
|
|
checkScreenSize(); |
|
|
window.addEventListener('resize', checkScreenSize); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function toggleMobileMenu() { |
|
|
const sidebar = document.getElementById('sidebar'); |
|
|
const overlay = document.getElementById('sidebarOverlay'); |
|
|
|
|
|
if (sidebar && overlay) { |
|
|
sidebar.classList.toggle('active'); |
|
|
overlay.classList.toggle('active'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function closeMobileMenu() { |
|
|
const sidebar = document.getElementById('sidebar'); |
|
|
const overlay = document.getElementById('sidebarOverlay'); |
|
|
|
|
|
if (sidebar) { |
|
|
sidebar.classList.remove('active'); |
|
|
} |
|
|
if (overlay) { |
|
|
overlay.classList.remove('active'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function loadSettings() { |
|
|
const saved = localStorage.getItem('autoGuardianSettings'); |
|
|
if (saved) { |
|
|
settings = JSON.parse(saved); |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('settingUsername').value = settings.username || ''; |
|
|
document.getElementById('settingEmail').value = settings.email || ''; |
|
|
document.getElementById('settingLanguage').value = settings.language || 'ar'; |
|
|
document.getElementById('settingTheme').value = settings.theme || 'light'; |
|
|
updateToggle('toggleAutoScan', settings.autoScan); |
|
|
updateToggle('toggleCriticalAlerts', settings.criticalAlerts); |
|
|
updateToggle('toggleAutoFix', settings.autoFix); |
|
|
} |
|
|
|
|
|
|
|
|
function saveSettings() { |
|
|
settings.username = document.getElementById('settingUsername').value; |
|
|
settings.email = document.getElementById('settingEmail').value; |
|
|
settings.language = document.getElementById('settingLanguage').value; |
|
|
settings.theme = document.getElementById('settingTheme').value; |
|
|
|
|
|
localStorage.setItem('autoGuardianSettings', JSON.stringify(settings)); |
|
|
closeSettings(); |
|
|
showToast('✅ تم حفظ الإعدادات بنجاح!', 'success'); |
|
|
} |
|
|
|
|
|
|
|
|
function updateToggle(id, value) { |
|
|
const toggle = document.getElementById(id); |
|
|
if (value) { |
|
|
toggle.classList.add('active'); |
|
|
} else { |
|
|
toggle.classList.remove('active'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function toggleSetting(setting) { |
|
|
settings[setting] = !settings[setting]; |
|
|
updateToggle('toggle' + setting.charAt(0).toUpperCase() + setting.slice(1), settings[setting]); |
|
|
showToast(`⚙️ تم ${settings[setting] ? 'تفعيل' : 'تعطيل'} ${setting}`, 'info'); |
|
|
} |
|
|
|
|
|
|
|
|
function loadData() { |
|
|
currentData.issues = sampleIssues; |
|
|
currentData.repos = sampleRepos; |
|
|
|
|
|
|
|
|
currentData.threats = Math.floor(Math.random() * 2000) + 500; |
|
|
currentData.openIssues = Math.floor(Math.random() * 30) + 10; |
|
|
currentData.responseTime = (Math.random() * 0.5 + 0.1).toFixed(1); |
|
|
|
|
|
updateStatsUI(); |
|
|
} |
|
|
|
|
|
|
|
|
function updateStatsUI() { |
|
|
document.getElementById('statThreats').textContent = currentData.threats.toLocaleString(); |
|
|
document.getElementById('statSuccess').textContent = currentData.successRate + '%'; |
|
|
document.getElementById('statOpen').textContent = currentData.openIssues; |
|
|
document.getElementById('statResponse').textContent = currentData.responseTime + 's'; |
|
|
|
|
|
|
|
|
const critical = currentData.issues.filter(i => i.severity === 'critical').length; |
|
|
const warning = currentData.issues.filter(i => i.severity === 'warning').length; |
|
|
const info = currentData.issues.filter(i => i.severity === 'info').length; |
|
|
const success = currentData.issues.filter(i => i.severity === 'success').length; |
|
|
|
|
|
document.getElementById('legendCritical').textContent = critical; |
|
|
document.getElementById('legendHigh').textContent = warning; |
|
|
document.getElementById('legendMedium').textContent = info; |
|
|
document.getElementById('legendLow').textContent = success; |
|
|
document.getElementById('donutTotal').textContent = currentData.issues.length; |
|
|
} |
|
|
|
|
|
|
|
|
function renderIssues(issues = currentData.issues) { |
|
|
const container = document.getElementById('issuesList'); |
|
|
container.innerHTML = ''; |
|
|
|
|
|
issues.forEach(issue => { |
|
|
const severityClass = issue.severity === 'critical' ? 'badge-critical' : |
|
|
issue.severity === 'warning' ? 'badge-warning' : |
|
|
issue.severity === 'info' ? 'badge-info' : 'badge-success'; |
|
|
|
|
|
const severityLabel = issue.severity === 'critical' ? 'حرجة' : |
|
|
issue.severity === 'warning' ? 'عالية' : |
|
|
issue.severity === 'info' ? 'متوسطة' : 'تم الإصلاح'; |
|
|
|
|
|
const iconSvg = issue.severity === 'critical' ? |
|
|
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>' : |
|
|
issue.severity === 'warning' ? |
|
|
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' : |
|
|
issue.severity === 'success' ? |
|
|
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' : |
|
|
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>'; |
|
|
|
|
|
const html = ` |
|
|
<div class="issue-item" onclick="showIssueDetails(${issue.id})"> |
|
|
<div class="issue-icon" style="background: rgba(${issue.severity === 'critical' ? '239, 68, 68' : issue.severity === 'warning' ? '245, 158, 11' : issue.severity === 'success' ? '16, 185, 129' : '59, 130, 246'}, 0.1); color: ${issue.severity === 'critical' ? '#EF4444' : issue.severity === 'warning' ? '#F59E0B' : issue.severity === 'success' ? '#10B981' : '#3B82F6'};"> |
|
|
${iconSvg} |
|
|
</div> |
|
|
<div class="issue-content"> |
|
|
<div class="issue-title">${issue.title}</div> |
|
|
<div class="issue-meta">${issue.file} • ${issue.time}</div> |
|
|
</div> |
|
|
<span class="issue-badge ${severityClass}">${severityLabel}</span> |
|
|
</div> |
|
|
`; |
|
|
container.innerHTML += html; |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function renderRepos(repos = currentData.repos) { |
|
|
const container = document.getElementById('reposList'); |
|
|
container.innerHTML = ''; |
|
|
|
|
|
repos.forEach(repo => { |
|
|
const statusClass = repo.status === 'active' ? 'active' : repo.status === 'warning' ? 'warning' : 'error'; |
|
|
const statusLabel = repo.status === 'active' ? 'نشط' : repo.status === 'warning' ? 'يحتاج مراجعة' : 'مشاكل'; |
|
|
const statusColor = repo.status === 'active' ? '#10B981' : repo.status === 'warning' ? '#F59E0B' : '#EF4444'; |
|
|
|
|
|
const html = ` |
|
|
<div class="repo-item"> |
|
|
<div class="repo-icon"> |
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/> |
|
|
</svg> |
|
|
</div> |
|
|
<div class="repo-content"> |
|
|
<div class="repo-name">${repo.name}</div> |
|
|
<div class="repo-stats"> |
|
|
<span>⭐ ${repo.stars}</span> |
|
|
<span>🔀 ${repo.pullRequests}</span> |
|
|
<span>🐛 ${repo.bugs}</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="repo-status"> |
|
|
<span class="status-dot ${statusClass}"></span> |
|
|
<span style="color: ${statusColor};">${statusLabel}</span> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
container.innerHTML += html; |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function filterIssues(type) { |
|
|
let filtered = currentData.issues; |
|
|
|
|
|
if (type === 'critical') { |
|
|
filtered = currentData.issues.filter(i => i.severity === 'critical'); |
|
|
showToast(`🔍 عرض ${filtered.length} مشكلة حرجة`, 'info'); |
|
|
} else if (type === 'open') { |
|
|
filtered = currentData.issues.filter(i => i.severity !== 'success'); |
|
|
showToast(`🔍 عرض ${filtered.length} مشكلة مفتوحة`, 'info'); |
|
|
} else if (type === 'all') { |
|
|
showToast(`🔍 عرض ${filtered.length} مشكلة`, 'info'); |
|
|
} |
|
|
|
|
|
renderIssues(filtered); |
|
|
} |
|
|
|
|
|
|
|
|
function showIssueDetails(id) { |
|
|
const issue = currentData.issues.find(i => i.id === id); |
|
|
if (issue) { |
|
|
showToast(`📋 ${issue.title} - ${issue.file}`, 'info'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function changePeriod(period) { |
|
|
|
|
|
document.querySelectorAll('.chart-tab').forEach(tab => { |
|
|
tab.classList.remove('active'); |
|
|
if (tab.dataset.period === period) { |
|
|
tab.classList.add('active'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
showToast(`📊 عرض بيانات ${period === 'day' ? '24 ساعة' : period === 'week' ? 'أسبوع' : 'شهر'}`, 'info'); |
|
|
|
|
|
|
|
|
const randomFactor = period === 'day' ? 1 : period === 'week' ? 7 : 30; |
|
|
currentData.threats = Math.floor(Math.random() * 2000 * randomFactor) + 500; |
|
|
updateStatsUI(); |
|
|
} |
|
|
|
|
|
|
|
|
function setupEventListeners() { |
|
|
|
|
|
document.querySelectorAll('.nav-item').forEach(item => { |
|
|
item.addEventListener('click', function() { |
|
|
const view = this.dataset.view; |
|
|
|
|
|
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active')); |
|
|
this.classList.add('active'); |
|
|
|
|
|
|
|
|
closeMobileMenu(); |
|
|
|
|
|
if (view === 'settings') { |
|
|
openSettings(); |
|
|
} else if (view === 'help') { |
|
|
showToast('📖 المساعدة: استخدم القائمة للتنقل بين الأقسام', 'info'); |
|
|
} else { |
|
|
showToast(`📂 الانتقال إلى ${this.querySelector('span').textContent}`, 'info'); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const searchInput = document.getElementById('searchInput'); |
|
|
const searchResults = document.getElementById('searchResults'); |
|
|
|
|
|
searchInput.addEventListener('input', function() { |
|
|
const query = this.value.toLowerCase(); |
|
|
|
|
|
if (query.length < 2) { |
|
|
searchResults.classList.remove('active'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const results = []; |
|
|
|
|
|
currentData.issues.forEach(issue => { |
|
|
if (issue.title.toLowerCase().includes(query) || issue.file.toLowerCase().includes(query)) { |
|
|
results.push({ type: 'issue', title: issue.title, subtitle: issue.file }); |
|
|
} |
|
|
}); |
|
|
|
|
|
currentData.repos.forEach(repo => { |
|
|
if (repo.name.toLowerCase().includes(query)) { |
|
|
results.push({ type: 'repo', title: repo.name, subtitle: `⭐ ${repo.stars} | 🔀 ${repo.pullRequests}` }); |
|
|
} |
|
|
}); |
|
|
|
|
|
if (results.length > 0) { |
|
|
searchResults.innerHTML = results.map(r => ` |
|
|
<div class="search-result-item"> |
|
|
<div style="font-weight: 500;">${r.title}</div> |
|
|
<div style="font-size: 12px; color: var(--text-muted);">${r.subtitle}</div> |
|
|
</div> |
|
|
`).join(''); |
|
|
searchResults.classList.add('active'); |
|
|
} else { |
|
|
searchResults.innerHTML = '<div class="search-result-item">لا توجد نتائج</div>'; |
|
|
searchResults.classList.add('active'); |
|
|
} |
|
|
}); |
|
|
|
|
|
searchInput.addEventListener('blur', function() { |
|
|
setTimeout(() => { |
|
|
searchResults.classList.remove('active'); |
|
|
}, 200); |
|
|
}); |
|
|
|
|
|
searchInput.addEventListener('focus', function() { |
|
|
if (this.value.length >= 2) { |
|
|
searchResults.classList.add('active'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('notificationBtn').addEventListener('click', function() { |
|
|
showToast('🔔 الإشعارات: 5 إشعارات جديدة', 'info'); |
|
|
document.getElementById('notificationBadge').textContent = '0'; |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function openSettings() { |
|
|
document.getElementById('settingsPanel').classList.add('active'); |
|
|
} |
|
|
|
|
|
function closeSettings() { |
|
|
document.getElementById('settingsPanel').classList.remove('active'); |
|
|
} |
|
|
|
|
|
|
|
|
function showToast(message, type = 'info') { |
|
|
const container = document.getElementById('toastContainer'); |
|
|
const toast = document.createElement('div'); |
|
|
toast.className = `toast ${type}`; |
|
|
toast.innerHTML = message; |
|
|
container.appendChild(toast); |
|
|
|
|
|
setTimeout(() => { |
|
|
toast.remove(); |
|
|
}, 3000); |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('settingsPanel').addEventListener('click', function(e) { |
|
|
if (e.target === this) { |
|
|
closeSettings(); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|