|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>DashX - Modern API Dashboard</title> |
|
|
<meta name="description" content="DashX is a modern REST API dashboard platform that allows you to manage, monitor, and utilize various API tools with ease. Fully featured for developers with an intuitive interface and powerful analytics."> |
|
|
<meta name="keywords" content="API Dashboard, REST API, DashX, API Management, Developer Tools, API Analytics"> |
|
|
<meta name="author" content="DashX Team"> |
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> |
|
|
<link rel="icon" type="image/webp" href="/icon.webp"> |
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.10.8/sweetalert2.min.css" rel="stylesheet"> |
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet"> |
|
|
<link href="styles.css" rel="stylesheet"> |
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script> |
|
|
<style> |
|
|
i.fas, i.fa, i.far, i.fab, i.fal, |
|
|
.fas, .fa, .far, .fab, .fal, |
|
|
i[class*="fa-"] { |
|
|
font-family: "Font Awesome 6 Free", "Font Awesome 6 Pro", "FontAwesome" !important; |
|
|
font-weight: 900 !important; |
|
|
font-style: normal !important; |
|
|
font-variant: normal !important; |
|
|
text-rendering: auto !important; |
|
|
line-height: 1 !important; |
|
|
-webkit-font-smoothing: antialiased !important; |
|
|
-moz-osx-font-smoothing: grayscale !important; |
|
|
display: inline-block !important; |
|
|
} |
|
|
|
|
|
.stat-item { |
|
|
text-align: center; |
|
|
padding: 1.5rem; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 12px; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.stat-item .stat-value { |
|
|
display: block; |
|
|
font-size: 1.8rem; |
|
|
font-weight: 700; |
|
|
color: rgba(133, 48, 48, 0.9); |
|
|
margin-bottom: 0.5rem; |
|
|
} |
|
|
|
|
|
.stat-item .stat-label { |
|
|
display: block; |
|
|
font-size: 0.9rem; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
} |
|
|
|
|
|
.stat-icon { |
|
|
font-size: 3rem !important; |
|
|
color: rgba(255, 168, 168, 0.9) !important; |
|
|
min-width: 80px !important; |
|
|
text-align: center !important; |
|
|
display: flex !important; |
|
|
align-items: center !important; |
|
|
justify-content: center !important; |
|
|
} |
|
|
|
|
|
.stat-icon i { |
|
|
font-size: 3rem !important; |
|
|
display: block !important; |
|
|
} |
|
|
|
|
|
.stat-info { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
.stat-number { |
|
|
font-size: 2rem; |
|
|
font-weight: 700; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
margin-bottom: 0.25rem; |
|
|
word-break: break-all; |
|
|
} |
|
|
|
|
|
.stat-label { |
|
|
font-size: 0.9rem; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
} |
|
|
|
|
|
.section h2 i { |
|
|
color: #e74c3c !important; |
|
|
} |
|
|
|
|
|
.navbar { |
|
|
background: rgba(44, 62, 80, 0.95) !important; |
|
|
backdrop-filter: blur(10px); |
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.2); |
|
|
} |
|
|
|
|
|
.navbar-brand { |
|
|
font-size: 1.5rem; |
|
|
font-weight: 700; |
|
|
color: #fff !important; |
|
|
} |
|
|
|
|
|
.navbar-brand i { |
|
|
color: #e74c3c; |
|
|
font-size: 1.8rem; |
|
|
margin-right: 0.5rem; |
|
|
} |
|
|
|
|
|
.nav-link { |
|
|
color: #ecf0f1 !important; |
|
|
font-weight: 500; |
|
|
transition: all 0.3s ease; |
|
|
padding: 0.5rem 1rem !important; |
|
|
border-radius: 8px; |
|
|
margin: 0 0.25rem; |
|
|
} |
|
|
|
|
|
.nav-link:hover { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
transform: translateY(-1px); |
|
|
} |
|
|
|
|
|
.nav-link.text-danger { |
|
|
color: #e74c3c !important; |
|
|
} |
|
|
|
|
|
.nav-link.text-danger:hover { |
|
|
background: rgba(231, 76, 60, 0.1); |
|
|
color: #ff6b6b !important; |
|
|
} |
|
|
|
|
|
.glassmorphism { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
border-radius: 16px; |
|
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); |
|
|
} |
|
|
|
|
|
.reset-timer-card { |
|
|
margin-top: 2rem; |
|
|
padding: 1.5rem; |
|
|
border-radius: 12px; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); |
|
|
} |
|
|
|
|
|
.timer-header { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 1rem; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
|
|
|
.timer-header i { |
|
|
font-size: 1.5rem; |
|
|
color: #853030; |
|
|
} |
|
|
|
|
|
.timer-header h3 { |
|
|
margin: 0; |
|
|
font-size: 1.2rem; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
} |
|
|
|
|
|
.timer-header p { |
|
|
margin: 0; |
|
|
opacity: 0.7; |
|
|
font-size: 0.9rem; |
|
|
} |
|
|
|
|
|
.countdown-display { |
|
|
text-align: center; |
|
|
padding: 2rem 1rem; |
|
|
} |
|
|
|
|
|
.countdown-time { |
|
|
font-size: 3rem; |
|
|
font-weight: bold; |
|
|
color: #853030; |
|
|
font-family: 'Courier New', monospace; |
|
|
letter-spacing: 0.1em; |
|
|
text-shadow: 0 0 20px rgba(133, 48, 48, 0.3); |
|
|
} |
|
|
|
|
|
.countdown-label { |
|
|
margin-top: 0.5rem; |
|
|
opacity: 0.6; |
|
|
font-size: 0.9rem; |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
} |
|
|
|
|
|
.reset-progress-container { |
|
|
width: 100%; |
|
|
height: 8px; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-radius: 4px; |
|
|
overflow: hidden; |
|
|
margin-top: 1rem; |
|
|
} |
|
|
|
|
|
.reset-progress { |
|
|
height: 100%; |
|
|
background: linear-gradient(90deg, #853030, #ff6b6b); |
|
|
transition: width 1s linear; |
|
|
width: 0%; |
|
|
box-shadow: 0 0 10px rgba(133, 48, 48, 0.5); |
|
|
} |
|
|
|
|
|
.reset-info { |
|
|
margin-top: 1rem; |
|
|
padding: 1rem; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 8px; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
} |
|
|
|
|
|
.reset-info i { |
|
|
color: #853030; |
|
|
margin-right: 0.5rem; |
|
|
} |
|
|
|
|
|
.reset-info span { |
|
|
font-size: 0.9rem; |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
} |
|
|
|
|
|
.reset-info div:last-child { |
|
|
font-weight: bold; |
|
|
color: #853030; |
|
|
} |
|
|
|
|
|
@keyframes pulse { |
|
|
0%, 100% { opacity: 1; } |
|
|
50% { opacity: 0.7; } |
|
|
} |
|
|
|
|
|
.reset-countdown { |
|
|
animation: pulse 2s ease-in-out infinite; |
|
|
} |
|
|
|
|
|
.usage-overview { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); |
|
|
gap: 1.5rem; |
|
|
margin-top: 1rem; |
|
|
} |
|
|
|
|
|
.usage-section { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
padding: 1.5rem; |
|
|
border-radius: 16px; |
|
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2); |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.usage-section:hover { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.3); |
|
|
} |
|
|
|
|
|
.usage-section h4 { |
|
|
margin-bottom: 1rem; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
font-size: 1.1rem; |
|
|
font-weight: 600; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.usage-section h4 i { |
|
|
color: rgba(133, 48, 48, 0.8); |
|
|
} |
|
|
|
|
|
.endpoint-list, .ip-list { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.endpoint-item, .ip-item { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
padding: 0.75rem; |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
backdrop-filter: blur(5px); |
|
|
border-radius: 8px; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.endpoint-item:hover, .ip-item:hover { |
|
|
background: rgba(255, 255, 255, 0.12); |
|
|
transform: translateX(4px); |
|
|
} |
|
|
|
|
|
.endpoint-name, .ip-address { |
|
|
font-family: 'Courier New', monospace; |
|
|
font-weight: 500; |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
font-size: 0.9rem; |
|
|
} |
|
|
|
|
|
.endpoint-count, .ip-count { |
|
|
color: rgba(133, 48, 48, 0.9); |
|
|
font-weight: 600; |
|
|
background: rgba(133, 48, 48, 0.1); |
|
|
padding: 0.25rem 0.5rem; |
|
|
border-radius: 12px; |
|
|
font-size: 0.8rem; |
|
|
} |
|
|
|
|
|
.ip-time { |
|
|
font-size: 0.75rem; |
|
|
color: rgba(255, 255, 255, 0.6); |
|
|
font-style: italic; |
|
|
} |
|
|
|
|
|
.daily-usage { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.75rem; |
|
|
} |
|
|
|
|
|
.usage-day { |
|
|
display: grid; |
|
|
grid-template-columns: 70px 1fr 50px; |
|
|
align-items: center; |
|
|
gap: 1rem; |
|
|
padding: 0.5rem; |
|
|
border-radius: 8px; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.usage-day:hover { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
} |
|
|
|
|
|
.usage-date { |
|
|
font-size: 0.85rem; |
|
|
font-weight: 500; |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
} |
|
|
|
|
|
.usage-bar-container { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-radius: 10px; |
|
|
height: 8px; |
|
|
overflow: hidden; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.usage-bar { |
|
|
height: 100%; |
|
|
background: linear-gradient(90deg, rgba(133, 48, 48, 0.8), rgba(166, 69, 69, 0.9)); |
|
|
border-radius: 10px; |
|
|
transition: width 0.6s ease; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.usage-bar::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
right: 0; |
|
|
bottom: 0; |
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); |
|
|
animation: shimmer 2s infinite; |
|
|
} |
|
|
|
|
|
@keyframes shimmer { |
|
|
0% { transform: translateX(-100%); } |
|
|
100% { transform: translateX(100%); } |
|
|
} |
|
|
|
|
|
.usage-count { |
|
|
font-size: 0.85rem; |
|
|
font-weight: 600; |
|
|
color: rgba(133, 48, 48, 0.9); |
|
|
text-align: center; |
|
|
} |
|
|
|
|
|
.no-data { |
|
|
text-align: center; |
|
|
padding: 2rem; |
|
|
color: rgba(255, 255, 255, 0.5); |
|
|
font-style: italic; |
|
|
} |
|
|
|
|
|
.no-data-state, .error-state { |
|
|
text-align: center; |
|
|
padding: 3rem 2rem; |
|
|
color: rgba(255, 255, 255, 0.6); |
|
|
} |
|
|
|
|
|
.error-state i { |
|
|
color: #ff6b6b; |
|
|
font-size: 2.5rem; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
|
|
|
.search-container { |
|
|
margin-bottom: 2rem; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.search-input { |
|
|
width: 100%; |
|
|
padding: 1rem 1rem 1rem 3rem; |
|
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
border-radius: 16px; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
font-size: 1rem; |
|
|
transition: all 0.3s ease; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
} |
|
|
|
|
|
.search-input::placeholder { |
|
|
color: rgba(255, 255, 255, 0.5); |
|
|
} |
|
|
|
|
|
.search-input:focus { |
|
|
outline: none; |
|
|
border-color: rgba(133, 48, 48, 0.8); |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
box-shadow: 0 0 0 3px rgba(133, 48, 48, 0.1); |
|
|
} |
|
|
|
|
|
.search-icon { |
|
|
position: absolute; |
|
|
left: 1rem; |
|
|
top: 50%; |
|
|
transform: translateY(-50%); |
|
|
color: rgba(133, 48, 48, 0.8); |
|
|
font-size: 1.2rem; |
|
|
} |
|
|
|
|
|
.plugin-card { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
border-radius: 16px; |
|
|
overflow: hidden; |
|
|
transition: all 0.3s ease; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
|
|
|
.plugin-card:hover { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.3); |
|
|
} |
|
|
|
|
|
.plugin-info { |
|
|
margin-top: 0.5rem; |
|
|
font-size: 0.85rem; |
|
|
} |
|
|
|
|
|
.limit-info { |
|
|
background: rgba(133, 48, 48, 0.1); |
|
|
color: #853030; |
|
|
padding: 0.25rem 0.5rem; |
|
|
border-radius: 4px; |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
.user-item { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
padding: 1.5rem; |
|
|
border-radius: 16px; |
|
|
margin-bottom: 1rem; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: flex-start; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.user-item:hover { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.3); |
|
|
} |
|
|
|
|
|
.user-item.temp-banned { |
|
|
border-left: 4px solid rgba(255, 193, 7, 0.8); |
|
|
background: rgba(255, 193, 7, 0.05); |
|
|
} |
|
|
|
|
|
.user-item.banned { |
|
|
border-left: 4px solid rgba(220, 53, 69, 0.8); |
|
|
background: rgba(220, 53, 69, 0.05); |
|
|
} |
|
|
|
|
|
.user-info { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
.user-name { |
|
|
font-size: 1.2rem; |
|
|
font-weight: 600; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
margin-bottom: 0.5rem; |
|
|
} |
|
|
|
|
|
.user-details { |
|
|
display: flex; |
|
|
flex-wrap: wrap; |
|
|
gap: 0.75rem; |
|
|
margin-bottom: 0.75rem; |
|
|
} |
|
|
|
|
|
.user-email { |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
font-size: 0.9rem; |
|
|
} |
|
|
|
|
|
.user-role { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
backdrop-filter: blur(5px); |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
padding: 0.25rem 0.75rem; |
|
|
border-radius: 12px; |
|
|
font-size: 0.8rem; |
|
|
font-weight: 500; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.premium-badge { |
|
|
background: linear-gradient(45deg, rgba(255, 215, 0, 0.3), rgba(255, 237, 78, 0.3)); |
|
|
backdrop-filter: blur(5px); |
|
|
color: rgba(255, 215, 0, 1); |
|
|
padding: 0.25rem 0.75rem; |
|
|
border-radius: 12px; |
|
|
font-size: 0.8rem; |
|
|
font-weight: 600; |
|
|
border: 1px solid rgba(255, 215, 0, 0.3); |
|
|
box-shadow: 0 0 10px rgba(255, 215, 0, 0.2); |
|
|
} |
|
|
|
|
|
.user-stats { |
|
|
display: flex; |
|
|
flex-wrap: wrap; |
|
|
gap: 1rem; |
|
|
font-size: 0.85rem; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
margin-bottom: 0.75rem; |
|
|
} |
|
|
|
|
|
.ban-info { |
|
|
background: rgba(255, 193, 7, 0.1); |
|
|
backdrop-filter: blur(5px); |
|
|
border: 1px solid rgba(255, 193, 7, 0.3); |
|
|
padding: 0.75rem; |
|
|
border-radius: 8px; |
|
|
font-size: 0.85rem; |
|
|
color: rgba(255, 193, 7, 0.9); |
|
|
margin-top: 0.5rem; |
|
|
} |
|
|
|
|
|
.user-actions { |
|
|
display: flex; |
|
|
gap: 0.5rem; |
|
|
flex-wrap: wrap; |
|
|
} |
|
|
|
|
|
.pagination-controls { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
padding: 1rem; |
|
|
margin-top: 1rem; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
border-radius: 12px; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.page-info { |
|
|
color: rgba(255, 255, 255, 0.8); |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
.users-pagination-info { |
|
|
color: rgba(255, 255, 255, 0.6); |
|
|
font-size: 0.9rem; |
|
|
margin-bottom: 1rem; |
|
|
text-align: center; |
|
|
padding: 0.5rem; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 8px; |
|
|
backdrop-filter: blur(5px); |
|
|
} |
|
|
|
|
|
.btn { |
|
|
padding: 0.5rem 1rem; |
|
|
border: none; |
|
|
border-radius: 8px; |
|
|
font-weight: 500; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
text-decoration: none; |
|
|
display: inline-flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
font-size: 0.9rem; |
|
|
backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.btn:disabled { |
|
|
opacity: 0.5; |
|
|
cursor: not-allowed; |
|
|
transform: none !important; |
|
|
} |
|
|
|
|
|
.btn-primary { |
|
|
background: rgba(133, 48, 48, 0.8); |
|
|
color: white; |
|
|
border: 1px solid rgba(133, 48, 48, 0.3); |
|
|
} |
|
|
|
|
|
.btn-primary:hover:not(:disabled) { |
|
|
background: rgba(133, 48, 48, 1); |
|
|
transform: translateY(-1px); |
|
|
box-shadow: 0 4px 12px rgba(133, 48, 48, 0.3); |
|
|
} |
|
|
|
|
|
.btn-secondary { |
|
|
background: rgba(108, 117, 125, 0.8); |
|
|
color: white; |
|
|
border: 1px solid rgba(108, 117, 125, 0.3); |
|
|
} |
|
|
|
|
|
.btn-secondary:hover:not(:disabled) { |
|
|
background: rgba(108, 117, 125, 1); |
|
|
transform: translateY(-1px); |
|
|
} |
|
|
|
|
|
.btn-warning { |
|
|
background: rgba(255, 193, 7, 0.8); |
|
|
color: rgba(133, 100, 4, 1); |
|
|
border: 1px solid rgba(255, 193, 7, 0.3); |
|
|
} |
|
|
|
|
|
.btn-warning:hover:not(:disabled) { |
|
|
background: rgba(255, 193, 7, 1); |
|
|
transform: translateY(-1px); |
|
|
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3); |
|
|
} |
|
|
|
|
|
.btn-success { |
|
|
background: rgba(40, 167, 69, 0.8); |
|
|
color: white; |
|
|
border: 1px solid rgba(40, 167, 69, 0.3); |
|
|
} |
|
|
|
|
|
.btn-success:hover:not(:disabled) { |
|
|
background: rgba(40, 167, 69, 1); |
|
|
transform: translateY(-1px); |
|
|
box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3); |
|
|
} |
|
|
|
|
|
.btn-danger { |
|
|
background: rgba(220, 53, 69, 0.8); |
|
|
color: white; |
|
|
border: 1px solid rgba(220, 53, 69, 0.3); |
|
|
} |
|
|
|
|
|
.btn-danger:hover:not(:disabled) { |
|
|
background: rgba(220, 53, 69, 1); |
|
|
transform: translateY(-1px); |
|
|
box-shadow: 0 4px 12px rgba(220, 53, 69, 0.3); |
|
|
} |
|
|
|
|
|
.no-users-state { |
|
|
text-align: center; |
|
|
padding: 3rem; |
|
|
color: rgba(255, 255, 255, 0.6); |
|
|
} |
|
|
|
|
|
.admin-card { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
border-radius: 16px; |
|
|
padding: 2rem; |
|
|
margin-bottom: 2rem; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.admin-card:hover { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.3); |
|
|
} |
|
|
|
|
|
.admin-card h3 { |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
margin-bottom: 1.5rem; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.admin-card h3 i { |
|
|
color: rgba(133, 48, 48, 0.8); |
|
|
} |
|
|
|
|
|
.stats-cards { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); |
|
|
gap: 1.5rem; |
|
|
margin-bottom: 2rem; |
|
|
} |
|
|
|
|
|
.stat-card { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
padding: 2rem; |
|
|
border-radius: 16px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 1rem; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.stat-card:hover { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
transform: translateY(-3px); |
|
|
box-shadow: 0 15px 50px 0 rgba(31, 38, 135, 0.4); |
|
|
} |
|
|
|
|
|
.form-row { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
|
|
gap: 1rem; |
|
|
margin-bottom: 1.5rem; |
|
|
} |
|
|
|
|
|
.form-group { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
} |
|
|
|
|
|
.form-group label { |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
margin-bottom: 0.5rem; |
|
|
font-weight: 500; |
|
|
font-size: 0.9rem; |
|
|
} |
|
|
|
|
|
.form-group .required { |
|
|
color: #ff6b6b; |
|
|
margin-left: 0.25rem; |
|
|
} |
|
|
|
|
|
.form-group input, |
|
|
.form-group select { |
|
|
padding: 0.75rem; |
|
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
border-radius: 8px; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
font-size: 0.95rem; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.form-group input:focus, |
|
|
.form-group select:focus { |
|
|
outline: none; |
|
|
border-color: rgba(133, 48, 48, 0.8); |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
box-shadow: 0 0 0 3px rgba(133, 48, 48, 0.1); |
|
|
} |
|
|
|
|
|
.form-group input::placeholder { |
|
|
color: rgba(255, 255, 255, 0.4); |
|
|
} |
|
|
|
|
|
.form-group small { |
|
|
color: rgba(255, 255, 255, 0.5); |
|
|
font-size: 0.8rem; |
|
|
margin-top: 0.25rem; |
|
|
} |
|
|
|
|
|
@media (max-width: 768px) { |
|
|
.countdown-time { |
|
|
font-size: 2rem; |
|
|
} |
|
|
|
|
|
.reset-timer-card { |
|
|
padding: 1rem; |
|
|
} |
|
|
|
|
|
.usage-overview { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
|
|
|
.usage-day { |
|
|
grid-template-columns: 60px 1fr 40px; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.user-item { |
|
|
flex-direction: column; |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.user-actions { |
|
|
width: 100%; |
|
|
justify-content: flex-end; |
|
|
} |
|
|
|
|
|
.pagination-controls { |
|
|
flex-direction: column; |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.dashboard-container { |
|
|
flex-direction: column; |
|
|
} |
|
|
|
|
|
.sidebar { |
|
|
width: 100%; |
|
|
position: static; |
|
|
height: auto; |
|
|
} |
|
|
|
|
|
.form-row { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
|
|
|
.stats-cards { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<nav class="navbar navbar-expand-lg navbar-dark"> |
|
|
<div class="container"> |
|
|
<a class="navbar-brand" href="/"> |
|
|
<i class="fas fa-bolt"></i> DashX |
|
|
</a> |
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> |
|
|
<span class="navbar-toggler-icon"></span> |
|
|
</button> |
|
|
<div class="collapse navbar-collapse" id="navbarNav"> |
|
|
<ul class="navbar-nav ms-auto"> |
|
|
<li class="nav-item"> |
|
|
<a class="nav-link" href="/profile" onclick="goToProfile()"> |
|
|
<i class="fas fa-user"></i> Profile |
|
|
</a> |
|
|
</li> |
|
|
<li class="nav-item"> |
|
|
<a class="nav-link text-danger" href="#" onclick="logout()"> |
|
|
<i class="fas fa-sign-out-alt"></i> Logout |
|
|
</a> |
|
|
</li> |
|
|
</ul> |
|
|
</div> |
|
|
</div> |
|
|
</nav> |
|
|
|
|
|
<div class="dashboard-container"> |
|
|
<div class="sidebar"> |
|
|
<div class="sidebar-menu"> |
|
|
<a href="#overview" class="menu-item active" onclick="showSection('overview')"> |
|
|
<i class="fas fa-chart-line"></i> Overview |
|
|
</a> |
|
|
<a href="#api-stats" class="menu-item" onclick="showSection('api-stats')"> |
|
|
<i class="fas fa-chart-area"></i> API Stats |
|
|
</a> |
|
|
<a href="#plugins" class="menu-item" onclick="showSection('plugins')"> |
|
|
<i class="fas fa-plug"></i> API Plugins |
|
|
</a> |
|
|
<a href="#server-stats" class="menu-item" onclick="showSection('server-stats')"> |
|
|
<i class="fas fa-server"></i> Server Stats |
|
|
</a> |
|
|
<a href="#events" class="menu-item" onclick="showSection('events')"> |
|
|
<i class="fas fa-calendar"></i> Events |
|
|
</a> |
|
|
<a href="#settings" class="menu-item" onclick="showSection('settings')"> |
|
|
<i class="fas fa-cog"></i> Settings |
|
|
</a> |
|
|
<div id="adminMenu" style="display: none;"> |
|
|
<a href="#management" class="menu-item" onclick="showSection('management')"> |
|
|
<i class="fas fa-users-cog"></i> Management |
|
|
</a> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="main-content"> |
|
|
<div id="overview" class="section active"> |
|
|
<h2><i class="fas fa-tachometer-alt"></i> Dashboard Overview</h2> |
|
|
<div class="stats-cards"> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/svgs/solid/key.svg" alt="key" style="width: 3rem; height: 3rem; filter: invert(78%) sepia(45%) saturate(548%) hue-rotate(314deg) brightness(101%) contrast(101%);"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="userApiKey">Loading...</div> |
|
|
<div class="stat-label">API Key</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/svgs/solid/chart-pie.svg" alt="chart" style="width: 3rem; height: 3rem; filter: invert(78%) sepia(45%) saturate(548%) hue-rotate(314deg) brightness(101%) contrast(101%);"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="userRequests">0</div> |
|
|
<div class="stat-label">Total Requests</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/svgs/solid/cloud.svg" alt="cloud" style="width: 3rem; height: 3rem; filter: invert(78%) sepia(45%) saturate(548%) hue-rotate(314deg) brightness(101%) contrast(101%);"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="userRequestsToday">0</div> |
|
|
<div class="stat-label">Today's Requests</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/svgs/solid/gauge-high.svg" alt="gauge" style="width: 3rem; height: 3rem; filter: invert(78%) sepia(45%) saturate(548%) hue-rotate(314deg) brightness(101%) contrast(101%);"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="userLimit">30</div> |
|
|
<div class="stat-label">Daily Limit</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/svgs/solid/battery-three-quarters.svg" alt="battery" style="width: 3rem; height: 3rem; filter: invert(78%) sepia(45%) saturate(548%) hue-rotate(314deg) brightness(101%) contrast(101%);"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="userLimitToday">30</div> |
|
|
<div class="stat-label">Remaining Limit (Personal)</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="reset-timer-card glassmorphism"> |
|
|
<div class="timer-header"> |
|
|
<i class="fas fa-clock"></i> |
|
|
<div> |
|
|
<h3>Next Reset</h3> |
|
|
<p>Daily limit resets at 00:00</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="countdown-display"> |
|
|
<div class="countdown-time"> |
|
|
<span class="reset-countdown">00:00:00</span> |
|
|
</div> |
|
|
<div class="countdown-label"> |
|
|
Hours : Minutes : Seconds |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="reset-progress-container"> |
|
|
<div class="reset-progress"></div> |
|
|
</div> |
|
|
|
|
|
<div class="reset-info"> |
|
|
<div> |
|
|
<i class="fas fa-info-circle"></i> |
|
|
<span>Your limit will be restored to maximum</span> |
|
|
</div> |
|
|
<div> |
|
|
<i class="fas fa-sync-alt"></i> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="usage-overview"> |
|
|
<div class="usage-section"> |
|
|
<h4><i class="fas fa-chart-bar"></i> API Usage Overview</h4> |
|
|
<div class="endpoint-list"> |
|
|
<div class="endpoint-item"> |
|
|
<span class="endpoint-name">Loading...</span> |
|
|
<span class="endpoint-count">0 requests</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="usage-section"> |
|
|
<h4><i class="fas fa-calendar-alt"></i> Daily Usage (Last 7 Days)</h4> |
|
|
<div class="daily-usage"> |
|
|
<div class="usage-day"> |
|
|
<span class="usage-date">Loading...</span> |
|
|
<div class="usage-bar-container"> |
|
|
<div class="usage-bar" style="width: 0%;"></div> |
|
|
</div> |
|
|
<span class="usage-count">0</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="usage-section"> |
|
|
<h4><i class="fas fa-network-wired"></i> Recent IP Addresses</h4> |
|
|
<div class="ip-list"> |
|
|
<div class="ip-item"> |
|
|
<div> |
|
|
<span class="ip-address">Loading...</span> |
|
|
<div class="ip-time">Just now</div> |
|
|
</div> |
|
|
<span class="ip-count">0 requests</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="plugins" class="section"> |
|
|
<h2><i class="fas fa-plug"></i> Available API Plugins</h2> |
|
|
<p style="margin-bottom: 2rem; opacity: 0.8;">Discover and test our API endpoints with interactive documentation</p> |
|
|
|
|
|
<div class="search-container"> |
|
|
<i class="fas fa-search search-icon"></i> |
|
|
<input type="text" |
|
|
class="search-input" |
|
|
placeholder="Search plugins by name, description, or tags..." |
|
|
oninput="searchPlugins(this.value)" |
|
|
id="pluginSearch"> |
|
|
</div> |
|
|
|
|
|
<div class="plugins-grid" id="pluginsGrid"> |
|
|
<div class="loading"> |
|
|
<i class="fas fa-spinner fa-spin" style="margin-right: 0.5rem;"></i> |
|
|
Loading plugins... |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div id="server-stats" class="section"> |
|
|
<h2><i class="fas fa-server"></i> Server Statistics</h2> |
|
|
|
|
|
|
|
|
|
|
|
<div class="stats-cards"> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://api.iconify.design/mdi/account-group.svg?color=%23ba68c8&width=48&height=48" alt="users"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="totalUsersCount">0</div> |
|
|
<div class="stat-label">Total Users</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://api.iconify.design/mdi/account.svg?color=%23ce93d8&width=48&height=48" alt="user"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="regularUsersCount">0</div> |
|
|
<div class="stat-label">Regular Users</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<img src="https://api.iconify.design/mdi/crown.svg?color=%23ba68c8&width=48&height=48" alt="crown"> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="premiumUsersCount">0</div> |
|
|
<div class="stat-label">Premium Users</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-chart-pie"></i> User Role Distribution</h3> |
|
|
<canvas id="roleChart" style="max-height: 300px;"></canvas> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-database"></i> Database Statistics</h3> |
|
|
<div class="stats-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem;"> |
|
|
<div class="stat-item"> |
|
|
<i class="fas fa-hdd" style="font-size: 2rem; color: rgba(133, 48, 48, 0.8); margin-bottom: 0.5rem;"></i> |
|
|
<span class="stat-value" id="dbSize">0 MB</span> |
|
|
<span class="stat-label">Database Size</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<i class="fas fa-memory" style="font-size: 2rem; color: rgba(133, 48, 48, 0.8); margin-bottom: 0.5rem;"></i> |
|
|
<span class="stat-value" id="ramUsage">0 MB</span> |
|
|
<span class="stat-label">RAM Usage</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<i class="fas fa-microchip" style="font-size: 2rem; color: rgba(133, 48, 48, 0.8); margin-bottom: 0.5rem;"></i> |
|
|
<span class="stat-value" id="cpuUsage">0%</span> |
|
|
<span class="stat-label">CPU Usage</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<i class="fas fa-server" style="font-size: 2rem; color: rgba(133, 48, 48, 0.8); margin-bottom: 0.5rem;"></i> |
|
|
<span class="stat-value" id="storageUsed">0 GB</span> |
|
|
<span class="stat-label">Storage Used</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-chart-bar"></i> Role Distribution Details</h3> |
|
|
<div class="stats-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem;"> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="cheapCount">0</span> |
|
|
<span class="stat-label">Cheap Role</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="premiumCount">0</span> |
|
|
<span class="stat-label">Premium Role</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="vipCount">0</span> |
|
|
<span class="stat-label">VIP Role</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="supremeCount">0</span> |
|
|
<span class="stat-label">Supreme Role</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="api-stats" class="section"> |
|
|
<h2><i class="fas fa-chart-area"></i> API Statistics</h2> |
|
|
<p style="margin-bottom: 2rem; opacity: 0.8;">Global API usage statistics and analytics</p> |
|
|
|
|
|
<div class="stats-cards"> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<i class="fas fa-globe"></i> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="globalTotalRequests">0</div> |
|
|
<div class="stat-label">Total Requests (All Users)</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<i class="fas fa-calendar-day"></i> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="globalTodayRequests">0</div> |
|
|
<div class="stat-label">Today's Requests (All Users)</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<i class="fas fa-check-circle"></i> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="successRate">0%</div> |
|
|
<div class="stat-label">Success Rate</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stat-card"> |
|
|
<div class="stat-icon"> |
|
|
<i class="fas fa-times-circle"></i> |
|
|
</div> |
|
|
<div class="stat-info"> |
|
|
<div class="stat-number" id="failRate">0%</div> |
|
|
<div class="stat-label">Fail Rate</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="charts-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 2rem; margin-top: 2rem;"> |
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-chart-pie"></i> Top Endpoints Distribution</h3> |
|
|
<canvas id="topEndpointsChart" style="max-height: 350px;"></canvas> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-percentage"></i> Success vs Fail Rate</h3> |
|
|
<canvas id="successFailChart" style="max-height: 350px;"></canvas> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card" style="margin-top: 2rem;"> |
|
|
<h3><i class="fas fa-chart-bar"></i> Daily Request Statistics (Last 7 Days)</h3> |
|
|
<canvas id="dailyRequestsChart" style="max-height: 400px;"></canvas> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card" style="margin-top: 2rem;"> |
|
|
<h3><i class="fas fa-chart-line"></i> Hourly Trends (Last 24 Hours)</h3> |
|
|
<canvas id="hourlyTrendsChart" style="max-height: 400px;"></canvas> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card" style="margin-top: 2rem;"> |
|
|
<h3><i class="fas fa-list-ol"></i> Top 10 Most Used Endpoints</h3> |
|
|
<div id="topEndpointsList"> |
|
|
<div class="loading"> |
|
|
<i class="fas fa-spinner fa-spin"></i> Loading... |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="events" class="section"> |
|
|
<h2><i class="fas fa-calendar"></i> Events & Rewards</h2> |
|
|
<div class="events-container"> |
|
|
<div class="redeem-section"> |
|
|
<h3><i class="fas fa-gift"></i> Redeem Code</h3> |
|
|
<p style="margin-bottom: 1.5rem; opacity: 0.8;">Enter a redeem code to unlock premium features or additional limits</p> |
|
|
<div class="form-group"> |
|
|
<input type="text" id="redeemCode" placeholder="Enter your redeem code" style="text-transform: uppercase;"> |
|
|
<button onclick="redeemCode()" class="btn btn-primary"> |
|
|
<i class="fas fa-magic"></i> Redeem |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="settings" class="section"> |
|
|
<h2><i class="fas fa-cog"></i> Settings</h2> |
|
|
<div class="settings-container"> |
|
|
<div class="setting-card"> |
|
|
<h3><i class="fas fa-user-edit"></i> Profile Settings</h3> |
|
|
<div class="form-group"> |
|
|
<label>Username</label> |
|
|
<input type="text" id="usernameInput" placeholder="Enter new username"> |
|
|
</div> |
|
|
<button onclick="updateProfile()" class="btn btn-primary"> |
|
|
<i class="fas fa-save"></i> Update Profile |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="setting-card" id="premiumSettings" style="display: none;"> |
|
|
<h3><i class="fas fa-crown"></i> Premium Features</h3> |
|
|
<button onclick="regenerateApiKey()" class="btn btn-warning"> |
|
|
<i class="fas fa-sync"></i> Regenerate API Key |
|
|
</button> |
|
|
<p class="text-muted">Generate a new API key (Premium only)</p> |
|
|
</div> |
|
|
|
|
|
<div class="setting-card danger-zone"> |
|
|
<h3><i class="fas fa-exclamation-triangle"></i> Danger Zone</h3> |
|
|
<button onclick="deleteAccount()" class="btn btn-danger"> |
|
|
<i class="fas fa-trash"></i> Delete Account |
|
|
</button> |
|
|
<p class="text-muted">This action cannot be undone</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="management" class="section"> |
|
|
<h2><i class="fas fa-users-cog"></i> Admin Management</h2> |
|
|
<div class="admin-container"> |
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-users"></i> User Management</h3> |
|
|
<div id="adminUsersList"> |
|
|
<div class="loading"> |
|
|
<i class="fas fa-spinner fa-spin"></i> Loading users... |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-user-tag"></i> Set User Role</h3> |
|
|
<div class="form-row"> |
|
|
<div class="form-group" style="grid-column: 1 / -1;"> |
|
|
<label>Search User <span class="required">*</span></label> |
|
|
<input type="text" id="searchUserInput" placeholder="Search by username or email" oninput="searchUsersForRole(this.value)"> |
|
|
<div id="userSearchResults" style="display: none; margin-top: 0.5rem; background: rgba(255,255,255,0.05); border-radius: 8px; max-height: 200px; overflow-y: auto;"></div> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label>Selected User</label> |
|
|
<input type="text" id="selectedUserDisplay" placeholder="No user selected" readonly> |
|
|
<input type="hidden" id="selectedUserId"> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label>Role <span class="required">*</span></label> |
|
|
<select id="assignRoleType"> |
|
|
<option value="cheap">Cheap (Limit 500)</option> |
|
|
<option value="premium">Premium (Limit 1500)</option> |
|
|
<option value="vip">VIP (Limit 2500)</option> |
|
|
<option value="supreme">Supreme (Limit 3000)</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label>Custom API Key <span style="color: #666; font-size: 0.85em;">(Optional)</span></label> |
|
|
<input type="text" id="customApiKey" placeholder="Leave empty for current key"> |
|
|
<small>All roles support custom API keys</small> |
|
|
</div> |
|
|
</div> |
|
|
<button onclick="assignUserRole()" class="btn btn-primary"> |
|
|
<i class="fas fa-user-check"></i> Assign Role |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-ticket-alt"></i> Create Redeem Code</h3> |
|
|
<div class="form-row"> |
|
|
<div class="form-group"> |
|
|
<label>Type <span class="required">*</span></label> |
|
|
<select id="redeemType"> |
|
|
<option value="limit">Limit Only</option> |
|
|
<option value="premium">Premium Only</option> |
|
|
<option value="both">Both</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="form-group" id="limitContainer" style="display: none;"> |
|
|
<label>Limit Value</label> |
|
|
<input type="number" id="limitValue" min="0" placeholder="Additional limit"> |
|
|
<small>Optional for Premium Only</small> |
|
|
</div> |
|
|
<div class="form-group" id="codeExpiredContainer" style="display: none;"> |
|
|
<label>Code Expired <span class="required">*</span></label> |
|
|
<input type="datetime-local" id="codeExpired" required> |
|
|
<small>When the code expires</small> |
|
|
</div> |
|
|
<div class="form-group" id="premiumExpiredContainer" style="display: none;"> |
|
|
<label>Premium Expired <span class="required">*</span></label> |
|
|
<input type="datetime-local" id="premiumExpired"> |
|
|
<small>When premium access expires</small> |
|
|
</div> |
|
|
</div> |
|
|
<button onclick="createRedeemCode()" class="btn btn-primary"> |
|
|
<i class="fas fa-plus"></i> Create Code |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="admin-card"> |
|
|
<h3><i class="fas fa-chart-pie"></i> System Statistics</h3> |
|
|
<div class="stats-grid"> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="adminTotalUsers">0</span> |
|
|
<span class="stat-label">Total Users</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="adminTotalRequests">0</span> |
|
|
<span class="stat-label">Total Requests</span> |
|
|
</div> |
|
|
<div class="stat-item"> |
|
|
<span class="stat-value" id="adminTodayRequests">0</span> |
|
|
<span class="stat-label">Today's Requests</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
(function(){ |
|
|
function detectDevTools(){ |
|
|
const threshold = 160; |
|
|
const widthThreshold = window.outerWidth - window.innerWidth > threshold; |
|
|
const heightThreshold = window.outerHeight - window.innerHeight > threshold; |
|
|
if(widthThreshold || heightThreshold) window.location.href = "/denied"; |
|
|
} |
|
|
|
|
|
document.addEventListener("contextmenu", e => e.preventDefault()); |
|
|
document.onkeydown = function(e){ |
|
|
if(e.keyCode === 123 || (e.ctrlKey && e.shiftKey && ['I','C','J'].includes(e.key?.toUpperCase())) || (e.ctrlKey && e.key?.toUpperCase() === 'U')){ |
|
|
e.preventDefault(); |
|
|
window.location.href = "/denied"; |
|
|
} |
|
|
}; |
|
|
|
|
|
setInterval(() => { |
|
|
if(window.eruda) window.location.href = "/denied"; |
|
|
detectDevTools(); |
|
|
try{ |
|
|
console.profile(); |
|
|
console.profileEnd(); |
|
|
}catch(e){} |
|
|
try{ |
|
|
if(console.clear.toString().length > 100) window.location.href = "/denied"; |
|
|
}catch(e){} |
|
|
}, 1000); |
|
|
})(); |
|
|
</script> |
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.10.8/sweetalert2.min.js"></script> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script> |
|
|
<script src="dashboard.js"></script> |
|
|
</body> |
|
|
</html> |