improve home page design
This commit is contained in:
parent
e7ddb993d3
commit
61b332cf6b
|
|
@ -6,275 +6,592 @@
|
|||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container" style="background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); min-height: 100vh; padding: 20px;">
|
||||
<div class="container-fluid" style="background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); min-height: 100vh; padding: 20px;">
|
||||
<div id="page-title" style="text-align: center; margin-bottom: 40px; padding: 30px; background: rgba(255,255,255,0.9); border-radius: 20px; backdrop-filter: blur(10px); box-shadow: 0 8px 32px rgba(0,0,0,0.1);">
|
||||
<h2 style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 2.5rem; font-weight: 700; margin-bottom: 10px; text-shadow: none;">{% trans "Home" %}</h2>
|
||||
<h2 style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 2.5rem; font-weight: 700; margin-bottom: 10px;">{% trans "Home" %}</h2>
|
||||
<p style="color: #6c757d; font-size: 1.1rem; margin: 0; font-weight: 400;">{% trans "Use the tabs to navigate through the control panel." %}</p>
|
||||
</div>
|
||||
|
||||
<!-- Dashboard Stats Section -->
|
||||
<div ng-controller="dashboardStatsController" style="margin-bottom: 40px;">
|
||||
<!-- Info Cards Row -->
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 40px; justify-content: center;">
|
||||
<div class="row" style="margin-bottom: 40px;">
|
||||
<!-- Total Sites Card -->
|
||||
<a href="{% url 'listWebsites' %}" style="flex: 1; min-width: 240px; max-width: 280px; text-decoration: none; transform: translateY(0); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);" onmouseover="this.style.transform='translateY(-10px) scale(1.02)'; this.style.boxShadow='0 20px 40px rgba(0,123,255,0.4)'" onmouseout="this.style.transform='translateY(0) scale(1)'; this.style.boxShadow='0 8px 25px rgba(0,123,255,0.25)'">
|
||||
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #fff; padding: 25px; border-radius: 20px; box-shadow: 0 8px 25px rgba(0,123,255,0.25); height: 100%; cursor: pointer; position: relative; overflow: hidden;">
|
||||
<div style="position: absolute; top: -50%; right: -50%; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); pointer-events: none;"></div>
|
||||
<div style="display: flex; align-items: center; position: relative; z-index: 1;">
|
||||
<div style="font-size: 3rem; margin-right: 20px; opacity: 0.9; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));"><i class="fa fa-globe"></i></div>
|
||||
<div>
|
||||
<div style="font-size: 2.8rem; font-weight: 700; line-height: 1; text-shadow: 0 2px 4px rgba(0,0,0,0.2);">{$ totalSites $}</div>
|
||||
<div style="font-size: 1rem; opacity: 0.9; margin-top: 8px; font-weight: 500;">Total Sites</div>
|
||||
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 mb-4">
|
||||
<a href="{% url 'listWebsites' %}" class="stat-card-link">
|
||||
<div class="stat-card gradient-purple">
|
||||
<div class="stat-card-overlay"></div>
|
||||
<div class="stat-card-content">
|
||||
<div class="stat-icon"><i class="fa fa-globe"></i></div>
|
||||
<div class="stat-details">
|
||||
<div class="stat-number">{$ totalSites $}</div>
|
||||
<div class="stat-label">Total Sites</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- WordPress Sites Card -->
|
||||
<a href="{% url 'ListWPSites' %}?wp=1" style="flex: 1; min-width: 240px; max-width: 280px; text-decoration: none; transform: translateY(0); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);" onmouseover="this.style.transform='translateY(-10px) scale(1.02)'; this.style.boxShadow='0 20px 40px rgba(111,66,193,0.4)'" onmouseout="this.style.transform='translateY(0) scale(1)'; this.style.boxShadow='0 8px 25px rgba(111,66,193,0.25)'">
|
||||
<div style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); color: #fff; padding: 25px; border-radius: 20px; box-shadow: 0 8px 25px rgba(111,66,193,0.25); height: 100%; cursor: pointer; position: relative; overflow: hidden;">
|
||||
<div style="position: absolute; top: -50%; right: -50%; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); pointer-events: none;"></div>
|
||||
<div style="display: flex; align-items: center; position: relative; z-index: 1;">
|
||||
<div style="font-size: 3rem; margin-right: 20px; opacity: 0.9; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2)); color: #6f42c1;"><i class="fa fa-wordpress"></i></div>
|
||||
<div>
|
||||
<div style="font-size: 2.8rem; font-weight: 700; line-height: 1; text-shadow: 0 2px 4px rgba(0,0,0,0.2); color: #6f42c1;">{$ totalWPSites $}</div>
|
||||
<div style="font-size: 1rem; opacity: 0.8; margin-top: 8px; font-weight: 500; color: #6f42c1;">WordPress Sites</div>
|
||||
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 mb-4">
|
||||
<a href="{% url 'ListWPSites' %}?wp=1" class="stat-card-link">
|
||||
<div class="stat-card gradient-pink">
|
||||
<div class="stat-card-overlay"></div>
|
||||
<div class="stat-card-content">
|
||||
<div class="stat-icon" style="color: #6f42c1;"><i class="fa fa-wordpress"></i></div>
|
||||
<div class="stat-details">
|
||||
<div class="stat-number" style="color: #6f42c1;">{$ totalWPSites $}</div>
|
||||
<div class="stat-label" style="color: #6f42c1;">WordPress Sites</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Total Databases Card -->
|
||||
<a href="{% url 'listDBs' %}" style="flex: 1; min-width: 240px; max-width: 280px; text-decoration: none; transform: translateY(0); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);" onmouseover="this.style.transform='translateY(-10px) scale(1.02)'; this.style.boxShadow='0 20px 40px rgba(23,162,184,0.4)'" onmouseout="this.style.transform='translateY(0) scale(1)'; this.style.boxShadow='0 8px 25px rgba(23,162,184,0.25)'">
|
||||
<div style="background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%); color: #fff; padding: 25px; border-radius: 20px; box-shadow: 0 8px 25px rgba(23,162,184,0.25); height: 100%; cursor: pointer; position: relative; overflow: hidden;">
|
||||
<div style="position: absolute; top: -50%; right: -50%; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); pointer-events: none;"></div>
|
||||
<div style="display: flex; align-items: center; position: relative; z-index: 1;">
|
||||
<div style="font-size: 3rem; margin-right: 20px; opacity: 0.9; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2)); color: #17a2b8;"><i class="fa fa-database"></i></div>
|
||||
<div>
|
||||
<div style="font-size: 2.8rem; font-weight: 700; line-height: 1; text-shadow: 0 2px 4px rgba(0,0,0,0.2); color: #17a2b8;">{$ totalDBs $}</div>
|
||||
<div style="font-size: 1rem; opacity: 0.8; margin-top: 8px; font-weight: 500; color: #17a2b8;">Total Databases</div>
|
||||
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 mb-4">
|
||||
<a href="{% url 'listDBs' %}" class="stat-card-link">
|
||||
<div class="stat-card gradient-red">
|
||||
<div class="stat-card-overlay"></div>
|
||||
<div class="stat-card-content">
|
||||
<div class="stat-icon" style="color: #17a2b8;"><i class="fa fa-database"></i></div>
|
||||
<div class="stat-details">
|
||||
<div class="stat-number" style="color: #17a2b8;">{$ totalDBs $}</div>
|
||||
<div class="stat-label" style="color: #17a2b8;">Total Databases</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Total Emails Card -->
|
||||
<a href="{% url 'listEmails' %}" style="flex: 1; min-width: 240px; max-width: 280px; text-decoration: none; transform: translateY(0); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);" onmouseover="this.style.transform='translateY(-10px) scale(1.02)'; this.style.boxShadow='0 20px 40px rgba(255,152,0,0.4)'" onmouseout="this.style.transform='translateY(0) scale(1)'; this.style.boxShadow='0 8px 25px rgba(255,152,0,0.25)'">
|
||||
<div style="background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); color: #fff; padding: 25px; border-radius: 20px; box-shadow: 0 8px 25px rgba(255,152,0,0.25); height: 100%; cursor: pointer; position: relative; overflow: hidden;">
|
||||
<div style="position: absolute; top: -50%; right: -50%; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); pointer-events: none;"></div>
|
||||
<div style="display: flex; align-items: center; position: relative; z-index: 1;">
|
||||
<div style="font-size: 3rem; margin-right: 20px; opacity: 0.9; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2)); color: #ff9800;"><i class="fa fa-envelope"></i></div>
|
||||
<div>
|
||||
<div style="font-size: 2.8rem; font-weight: 700; line-height: 1; text-shadow: 0 2px 4px rgba(0,0,0,0.2); color: #ff9800;">{$ totalEmails $}</div>
|
||||
<div style="font-size: 1rem; opacity: 0.8; margin-top: 8px; font-weight: 500; color: #ff9800;">Total Emails</div>
|
||||
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 mb-4">
|
||||
<a href="{% url 'listEmails' %}" class="stat-card-link">
|
||||
<div class="stat-card gradient-orange">
|
||||
<div class="stat-card-overlay"></div>
|
||||
<div class="stat-card-content">
|
||||
<div class="stat-icon" style="color: #ff9800;"><i class="fa fa-envelope"></i></div>
|
||||
<div class="stat-details">
|
||||
<div class="stat-number" style="color: #ff9800;">{$ totalEmails $}</div>
|
||||
<div class="stat-label" style="color: #ff9800;">Total Emails</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if admin %}
|
||||
<!-- System Stats Row -->
|
||||
<div ng-controller="homePageStatus" style="margin-bottom: 40px;">
|
||||
<div style="display: flex; justify-content: center; gap: 40px; align-items: stretch; flex-wrap: wrap;">
|
||||
<div class="row justify-content-center">
|
||||
<!-- CPU Usage -->
|
||||
<div style="background: rgba(255,255,255,0.95); border-radius: 20px; box-shadow: 0 8px 32px rgba(229,57,53,0.15); padding: 30px 40px; min-width: 200px; text-align: center; backdrop-filter: blur(10px); border: 1px solid rgba(229,57,53,0.1); transform: translateY(0); transition: all 0.3s ease;" onmouseover="this.style.transform='translateY(-5px)'; this.style.boxShadow='0 15px 40px rgba(229,57,53,0.25)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 8px 32px rgba(229,57,53,0.15)'">
|
||||
<div style="font-size: 1.2rem; color: #e53935; font-weight: 700; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "CPU Usage" %}</div>
|
||||
<div id="redcircle" class="c100 red cpu" style="margin: 0 auto; filter: drop-shadow(0 4px 8px rgba(229,57,53,0.2));">
|
||||
<span style="font-weight: 700; font-size: 1.2rem;">{$ cpuUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12 mb-4">
|
||||
<div class="system-stat-card">
|
||||
<div class="system-stat-title">{% trans "CPU Usage" %}</div>
|
||||
<div id="redcircle" class="c100 red cpu">
|
||||
<span class="system-stat-value">{$ cpuUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RAM Usage -->
|
||||
<div style="background: rgba(255,255,255,0.95); border-radius: 20px; box-shadow: 0 8px 32px rgba(67,160,71,0.15); padding: 30px 40px; min-width: 200px; text-align: center; backdrop-filter: blur(10px); border: 1px solid rgba(67,160,71,0.1); transform: translateY(0); transition: all 0.3s ease;" onmouseover="this.style.transform='translateY(-5px)'; this.style.boxShadow='0 15px 40px rgba(67,160,71,0.25)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 8px 32px rgba(67,160,71,0.15)'">
|
||||
<div style="font-size: 1.2rem; color: #43a047; font-weight: 700; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Ram Usage" %}</div>
|
||||
<div id="greencircle" class="c100 p0 green ram" style="margin: 0 auto; filter: drop-shadow(0 4px 8px rgba(67,160,71,0.2));">
|
||||
<span style="font-weight: 700; font-size: 1.2rem;">{$ ramUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12 mb-4">
|
||||
<div class="system-stat-card">
|
||||
<div class="system-stat-title">{% trans "Ram Usage" %}</div>
|
||||
<div id="greencircle" class="c100 p0 green ram">
|
||||
<span class="system-stat-value">{$ ramUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Disk Usage -->
|
||||
<div style="background: rgba(255,255,255,0.95); border-radius: 20px; box-shadow: 0 8px 32px rgba(216,27,96,0.15); padding: 30px 40px; min-width: 200px; text-align: center; backdrop-filter: blur(10px); border: 1px solid rgba(216,27,96,0.1); transform: translateY(0); transition: all 0.3s ease;" onmouseover="this.style.transform='translateY(-5px)'; this.style.boxShadow='0 15px 40px rgba(216,27,96,0.25)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 8px 32px rgba(216,27,96,0.15)'">
|
||||
<div style="font-size: 1.2rem; color: #d81b60; font-weight: 700; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Disk Usage '/'" %}</div>
|
||||
<div id="pinkcircle" class="c100 pink disk" style="margin: 0 auto; filter: drop-shadow(0 4px 8px rgba(216,27,96,0.2));">
|
||||
<span style="font-weight: 700; font-size: 1.2rem;">{$ diskUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
<div class="col-lg-4 col-md-6 col-sm-12 mb-4">
|
||||
<div class="system-stat-card">
|
||||
<div class="system-stat-title">{% trans "Disk Usage '/'" %}</div>
|
||||
<div id="pinkcircle" class="c100 pink disk">
|
||||
<span class="system-stat-value">{$ diskUsage $}%</span>
|
||||
<div class="slice">
|
||||
<div class="bar"></div>
|
||||
<div class="fill"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent SSH Logins Widget -->
|
||||
<div style="margin-bottom: 40px;">
|
||||
<div style="background: rgba(255,255,255,0.97); border-radius: 18px; box-shadow: 0 8px 32px rgba(102,126,234,0.10); padding: 25px 30px; max-width: 900px; margin: 0 auto 0 auto;">
|
||||
<div style="display: flex; align-items: center; margin-bottom: 18px;">
|
||||
<i class="fa fa-terminal" style="font-size: 1.6rem; color: #667eea; margin-right: 12px;"></i>
|
||||
<span style="font-size: 1.25rem; font-weight: 700; color: #333; letter-spacing: 0.5px;">Recent SSH Logins</span>
|
||||
</div>
|
||||
<div ng-if="loadingSSHLogins" style="text-align: center; padding: 20px; color: #888;">
|
||||
<i class="fa fa-spinner fa-spin"></i> Loading recent SSH logins...
|
||||
</div>
|
||||
<div ng-if="!loadingSSHLogins && sshLogins.length === 0" style="text-align: center; color: #888;">
|
||||
No recent SSH logins found.
|
||||
</div>
|
||||
<div ng-if="!loadingSSHLogins && sshLogins.length > 0" style="overflow-x: auto;">
|
||||
<table style="width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #fff;">
|
||||
<th style="padding: 10px 8px; border-radius: 8px 0 0 8px; text-align: left;">User</th>
|
||||
<th style="padding: 10px 8px; text-align: left;">IP</th>
|
||||
<th style="padding: 10px 8px; text-align: left;">Country</th>
|
||||
<th style="padding: 10px 8px; text-align: left;">Date/Time</th>
|
||||
<th style="padding: 10px 8px; border-radius: 0 8px 8px 0; text-align: left;">Session</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="login in sshLogins" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef;">
|
||||
<td style="padding: 8px 8px; font-weight: 600; color: #333;">{{login.user}}</td>
|
||||
<td style="padding: 8px 8px; color: #555;">{{login.ip}}</td>
|
||||
<td style="padding: 8px 8px;">
|
||||
<span ng-if="login.flag"><img ng-src="{{login.flag}}" alt="{{login.country}}" style="height: 18px; margin-right: 6px; vertical-align: middle;" /></span>
|
||||
<span ng-if="!login.flag && login.country">{{login.country}}</span>
|
||||
<span ng-if="!login.flag && !login.country">-</span>
|
||||
</td>
|
||||
<td style="padding: 8px 8px; color: #555;">{{login.date}}</td>
|
||||
<td style="padding: 8px 8px; color: #888;">{{login.session}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row" style="margin-bottom: 40px;">
|
||||
<div class="col-12">
|
||||
<div class="ssh-logins-card">
|
||||
<div class="ssh-logins-header">
|
||||
<i class="fa fa-terminal"></i>
|
||||
<span>Recent SSH Logins</span>
|
||||
</div>
|
||||
<div ng-if="loadingSSHLogins" class="ssh-logins-loading">
|
||||
<i class="fa fa-spinner fa-spin"></i> Loading recent SSH logins...
|
||||
</div>
|
||||
<div ng-if="!loadingSSHLogins && sshLogins.length === 0" class="ssh-logins-empty">
|
||||
No recent SSH logins found.
|
||||
</div>
|
||||
<div ng-if="!loadingSSHLogins && sshLogins.length > 0" class="table-responsive">
|
||||
<table class="ssh-logins-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th>IP</th>
|
||||
<th>Country</th>
|
||||
<th>Date/Time</th>
|
||||
<th>Session</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="login in sshLogins">
|
||||
<td>{{login.user}}</td>
|
||||
<td>{{login.ip}}</td>
|
||||
<td>
|
||||
<span ng-if="login.flag"><img ng-src="{{login.flag}}" alt="{{login.country}}" class="country-flag" /></span>
|
||||
<span ng-if="!login.flag && login.country">{{login.country}}</span>
|
||||
<span ng-if="!login.flag && !login.country">-</span>
|
||||
</td>
|
||||
<td>{{login.date}}</td>
|
||||
<td>{{login.session}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Graphs Section -->
|
||||
<div style="background: rgba(255,255,255,0.95); border-radius: 25px; box-shadow: 0 12px 40px rgba(0,0,0,0.1); padding: 35px; backdrop-filter: blur(15px); border: 1px solid rgba(255,255,255,0.2);">
|
||||
<!-- Tab Navigation -->
|
||||
<div style="text-align: center; margin-bottom: 30px;">
|
||||
<ul style="list-style: none; padding: 0; margin: 0; display: inline-flex; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; padding: 8px; gap: 8px; box-shadow: 0 8px 25px rgba(102,126,234,0.3);">
|
||||
<li style="display: inline-block;">
|
||||
<a href="#traffic" id="traffic-tab" data-toggle="tab" style="display: block; padding: 15px 30px; background: rgba(255,255,255,0.9); color: #667eea; border-radius: 12px; text-decoration: none; font-weight: 600; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); text-transform: uppercase; letter-spacing: 0.5px; font-size: 0.9rem;">
|
||||
<i class="fa fa-exchange" style="margin-right: 8px;"></i> Traffic
|
||||
</a>
|
||||
</li>
|
||||
<li style="display: inline-block;">
|
||||
<a href="#diskio" id="diskio-tab" data-toggle="tab" style="display: block; padding: 15px 30px; background: transparent; color: rgba(255,255,255,0.8); border-radius: 12px; text-decoration: none; font-weight: 600; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); text-transform: uppercase; letter-spacing: 0.5px; font-size: 0.9rem;">
|
||||
<i class="fa fa-hdd-o" style="margin-right: 8px;"></i> Disk IO
|
||||
</a>
|
||||
</li>
|
||||
<li style="display: inline-block;">
|
||||
<a href="#cpu" id="cpu-tab" data-toggle="tab" style="display: block; padding: 15px 30px; background: transparent; color: rgba(255,255,255,0.8); border-radius: 12px; text-decoration: none; font-weight: 600; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); text-transform: uppercase; letter-spacing: 0.5px; font-size: 0.9rem;">
|
||||
<i class="fa fa-microchip" style="margin-right: 8px;"></i> CPU Usage
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="tab-content" style="background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 18px; padding: 30px; min-height: 350px; border: 2px solid rgba(255,255,255,0.5); box-shadow: inset 0 2px 10px rgba(0,0,0,0.05);">
|
||||
<div class="tab-pane fade show active" id="traffic" role="tabpanel">
|
||||
<canvas id="trafficChart" height="80"></canvas>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="diskio" role="tabpanel">
|
||||
<canvas id="diskIOChart" height="80"></canvas>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="cpu" role="tabpanel">
|
||||
<canvas id="cpuChart" height="80"></canvas>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="graphs-card">
|
||||
<!-- Tab Navigation -->
|
||||
<div class="graphs-tabs">
|
||||
<ul class="nav nav-tabs" id="dashboardGraphTabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#traffic" data-toggle="tab">
|
||||
<i class="fa fa-exchange"></i> Traffic
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#diskio" data-toggle="tab">
|
||||
<i class="fa fa-hdd-o"></i> Disk IO
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#cpu" data-toggle="tab">
|
||||
<i class="fa fa-microchip"></i> CPU Usage
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="traffic" role="tabpanel">
|
||||
<canvas id="trafficChart" height="80"></canvas>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="diskio" role="tabpanel">
|
||||
<canvas id="diskIOChart" height="80"></canvas>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="cpu" role="tabpanel">
|
||||
<canvas id="cpuChart" height="80"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Dashboard Stats Section -->
|
||||
|
||||
<!-- Add custom styles for tab switching -->
|
||||
<style>
|
||||
#dashboardGraphTabs a[data-toggle="tab"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
#dashboardGraphTabs a[data-toggle="tab"]:hover {
|
||||
background: rgba(255,255,255,0.9) !important;
|
||||
color: #667eea !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(102,126,234,0.3);
|
||||
}
|
||||
#dashboardGraphTabs a[data-toggle="tab"].active {
|
||||
background: rgba(255,255,255,0.9) !important;
|
||||
color: #667eea !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(102,126,234,0.3);
|
||||
}
|
||||
|
||||
/* Enhanced hover effects for tabs */
|
||||
a[data-toggle="tab"]:hover {
|
||||
background: rgba(255,255,255,0.9) !important;
|
||||
color: #667eea !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(102,126,234,0.3);
|
||||
}
|
||||
|
||||
/* Smooth animations for all interactive elements */
|
||||
* {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Chart.js CDN -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<!-- FontAwesome for icons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
|
||||
<script>
|
||||
// Handle tab switching
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var tabs = document.querySelectorAll('a[data-toggle="tab"]');
|
||||
tabs.forEach(function(tab) {
|
||||
tab.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Remove active from all tabs and panes
|
||||
tabs.forEach(function(t) {
|
||||
t.classList.remove('active');
|
||||
t.style.background = 'transparent';
|
||||
t.style.color = 'rgba(255,255,255,0.8)';
|
||||
t.style.transform = 'translateY(0)';
|
||||
t.style.boxShadow = 'none';
|
||||
});
|
||||
document.querySelectorAll('.tab-pane').forEach(function(pane) {
|
||||
pane.classList.remove('show', 'active');
|
||||
});
|
||||
|
||||
// Add active to clicked tab
|
||||
this.classList.add('active');
|
||||
this.style.background = 'rgba(255,255,255,0.9)';
|
||||
this.style.color = '#667eea';
|
||||
this.style.transform = 'translateY(-2px)';
|
||||
this.style.boxShadow = '0 4px 15px rgba(102,126,234,0.3)';
|
||||
|
||||
// Show corresponding pane
|
||||
var target = this.getAttribute('href');
|
||||
var targetPane = document.querySelector(target);
|
||||
if (targetPane) {
|
||||
targetPane.classList.add('show', 'active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Force traffic tab to be active on page load
|
||||
setTimeout(function() {
|
||||
var trafficTab = document.getElementById('traffic-tab');
|
||||
if (trafficTab) {
|
||||
trafficTab.click();
|
||||
console.log('Traffic tab manually activated on page load');
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Custom Styles -->
|
||||
<style>
|
||||
/* Stat Cards */
|
||||
.stat-card-link {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: 25px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-10px) scale(1.02);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.gradient-purple {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.gradient-pink {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
}
|
||||
|
||||
.gradient-red {
|
||||
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
|
||||
}
|
||||
|
||||
.gradient-orange {
|
||||
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
|
||||
}
|
||||
|
||||
.stat-card-overlay {
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.stat-card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 3rem;
|
||||
margin-right: 20px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 2.8rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 1rem;
|
||||
opacity: 0.9;
|
||||
margin-top: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* System Stats */
|
||||
.system-stat-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(0,0,0,0.05);
|
||||
transition: all 0.3s ease;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.system-stat-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 40px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.system-stat-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 15px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.system-stat-value {
|
||||
font-weight: 700;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* SSH Logins */
|
||||
.ssh-logins-card {
|
||||
background: rgba(255,255,255,0.97);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
padding: 25px 30px;
|
||||
}
|
||||
|
||||
.ssh-logins-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 18px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.ssh-logins-header i {
|
||||
font-size: 1.6rem;
|
||||
color: #667eea;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.ssh-logins-loading,
|
||||
.ssh-logins-empty {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.ssh-logins-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.ssh-logins-table thead tr {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ssh-logins-table th {
|
||||
padding: 10px 15px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ssh-logins-table th:first-child {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
.ssh-logins-table th:last-child {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
.ssh-logins-table tbody tr {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.ssh-logins-table tbody tr:hover {
|
||||
background: #e9ecef;
|
||||
}
|
||||
|
||||
.ssh-logins-table td {
|
||||
padding: 8px 15px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.ssh-logins-table td:first-child {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.country-flag {
|
||||
height: 18px;
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Graphs */
|
||||
.graphs-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 25px;
|
||||
box-shadow: 0 12px 40px rgba(0,0,0,0.1);
|
||||
padding: 35px;
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.graphs-tabs {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-tabs {
|
||||
border: none;
|
||||
display: inline-flex;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 15px;
|
||||
padding: 8px;
|
||||
gap: 8px;
|
||||
box-shadow: 0 8px 25px rgba(102,126,234,0.3);
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-link {
|
||||
padding: 15px 30px;
|
||||
background: transparent;
|
||||
color: rgba(255,255,255,0.8);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-link:hover {
|
||||
background: rgba(255,255,255,0.2);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-link.active {
|
||||
background: rgba(255,255,255,0.9);
|
||||
color: #667eea;
|
||||
box-shadow: 0 4px 15px rgba(102,126,234,0.3);
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-link i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
border-radius: 18px;
|
||||
padding: 30px;
|
||||
min-height: 350px;
|
||||
border: 2px solid rgba(255,255,255,0.5);
|
||||
box-shadow: inset 0 2px 10px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
/* Progress Circles */
|
||||
.c100 {
|
||||
position: relative;
|
||||
font-size: 120px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
background-color: #f3f3f3;
|
||||
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1));
|
||||
}
|
||||
|
||||
.c100 > span {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 5em;
|
||||
line-height: 5em;
|
||||
font-size: 0.25em;
|
||||
color: #000;
|
||||
display: block;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.c100:after {
|
||||
position: absolute;
|
||||
top: 0.08em;
|
||||
left: 0.08em;
|
||||
display: block;
|
||||
content: "";
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
width: 0.84em;
|
||||
height: 0.84em;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.c100 .slice {
|
||||
position: absolute;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
clip: rect(0em, 1em, 1em, 0.5em);
|
||||
}
|
||||
|
||||
.c100.red .bar {
|
||||
border-color: #e53935;
|
||||
}
|
||||
|
||||
.c100.red .system-stat-title {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.c100.green .bar {
|
||||
border-color: #43a047;
|
||||
}
|
||||
|
||||
.c100.green .system-stat-title {
|
||||
color: #43a047;
|
||||
}
|
||||
|
||||
.c100.pink .bar {
|
||||
border-color: #d81b60;
|
||||
}
|
||||
|
||||
.c100.pink .system-stat-title {
|
||||
color: #d81b60;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.stat-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-tabs {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.graphs-tabs .nav-link {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Chart.js CDN -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<!-- FontAwesome for icons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
|
||||
<script>
|
||||
// Handle tab switching
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var tabs = document.querySelectorAll('a[data-toggle="tab"]');
|
||||
tabs.forEach(function(tab) {
|
||||
tab.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Remove active from all tabs
|
||||
tabs.forEach(function(t) {
|
||||
t.classList.remove('active');
|
||||
});
|
||||
|
||||
// Remove active from all panes
|
||||
document.querySelectorAll('.tab-pane').forEach(function(pane) {
|
||||
pane.classList.remove('show', 'active');
|
||||
});
|
||||
|
||||
// Add active to clicked tab
|
||||
this.classList.add('active');
|
||||
|
||||
// Show corresponding pane
|
||||
var target = this.getAttribute('href');
|
||||
var targetPane = document.querySelector(target);
|
||||
if (targetPane) {
|
||||
targetPane.classList.add('show', 'active');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue