mirror of
https://github.com/sassanix/Warracker.git
synced 2026-01-07 06:00:13 -06:00
Major update to the UI, lots of fixes, about page added, please refer to changelog for more details
417 lines
16 KiB
HTML
417 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<!-- Authentication redirect script -->
|
|
<script src="auth-redirect.js" data-protected="true"></script>
|
|
|
|
<!-- Include authentication script first to handle login state immediately -->
|
|
<script src="include-auth-new.js"></script>
|
|
|
|
<!-- File utilities script for secure file handling -->
|
|
<script src="file-utils.js"></script>
|
|
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Status - Warracker</title>
|
|
<!-- Favicons -->
|
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png?v=2">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="img/favicon-32x32.png?v=2">
|
|
<link rel="stylesheet" href="style.css">
|
|
<script src="theme-loader.js"></script> <!-- Apply theme early -->
|
|
<!-- Font Awesome for icons -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<!-- Load header fix styles to ensure consistent header styling -->
|
|
<link rel="stylesheet" href="header-fix.css">
|
|
<!-- Chart.js for visualizations -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<!-- Load fix for auth buttons -->
|
|
<script src="fix-auth-buttons-loader.js"></script>
|
|
<style>
|
|
.user-menu {
|
|
position: relative;
|
|
margin-left: 15px;
|
|
}
|
|
|
|
.user-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 0.9rem;
|
|
padding: 5px 10px;
|
|
border-radius: 20px;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
.user-btn:hover {
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.dark-mode .user-btn:hover {
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.user-btn i {
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.user-menu-dropdown {
|
|
position: absolute;
|
|
top: 100%;
|
|
right: 0;
|
|
background-color: var(--card-bg);
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
width: 200px;
|
|
z-index: 1000;
|
|
display: none;
|
|
padding: 10px 0;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.user-menu-dropdown.active {
|
|
display: block;
|
|
}
|
|
|
|
.user-info {
|
|
padding: 10px 15px;
|
|
border-bottom: 1px solid var(--border-color);
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.user-name {
|
|
font-weight: bold;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.user-email {
|
|
font-size: 0.8rem;
|
|
color: var(--text-muted);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.user-menu-item {
|
|
padding: 8px 15px;
|
|
cursor: pointer;
|
|
transition: background-color 0.3s;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.user-menu-item:hover {
|
|
background-color: var(--hover-bg);
|
|
}
|
|
|
|
.user-menu-item i {
|
|
margin-right: 10px;
|
|
width: 16px;
|
|
text-align: center;
|
|
}
|
|
|
|
.auth-buttons {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-left: 15px;
|
|
}
|
|
|
|
.auth-btn {
|
|
padding: 5px 15px;
|
|
border-radius: 20px;
|
|
font-size: 0.9rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.auth-btn i {
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.login-btn {
|
|
background-color: transparent;
|
|
border: 1px solid var(--primary-color);
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.login-btn:hover {
|
|
background-color: rgba(var(--primary-rgb), 0.1);
|
|
}
|
|
|
|
.register-btn {
|
|
background-color: var(--primary-color);
|
|
border: 1px solid var(--primary-color);
|
|
color: white;
|
|
}
|
|
|
|
.register-btn:hover {
|
|
background-color: var(--primary-dark);
|
|
}
|
|
</style>
|
|
|
|
<!-- Immediate authentication check script -->
|
|
<script>
|
|
// Check if user is logged in immediately to hide buttons
|
|
(function() {
|
|
if (localStorage.getItem('auth_token')) {
|
|
// Hide login and register buttons immediately
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('Inline script: User is logged in, hiding login/register buttons');
|
|
|
|
// Hide auth container
|
|
var authContainer = document.getElementById('authContainer');
|
|
if (authContainer) {
|
|
authContainer.style.display = 'none';
|
|
authContainer.style.visibility = 'hidden';
|
|
}
|
|
|
|
// Show user menu
|
|
var userMenu = document.getElementById('userMenu');
|
|
if (userMenu) {
|
|
userMenu.style.display = 'block';
|
|
userMenu.style.visibility = 'visible';
|
|
}
|
|
|
|
// Update user info if possible
|
|
try {
|
|
var userInfo = JSON.parse(localStorage.getItem('user_info'));
|
|
if (userInfo) {
|
|
var displayName = userInfo.first_name || userInfo.username || 'User';
|
|
var userDisplayName = document.getElementById('userDisplayName');
|
|
if (userDisplayName) {
|
|
userDisplayName.textContent = displayName;
|
|
}
|
|
|
|
var userName = document.getElementById('userName');
|
|
if (userName) {
|
|
userName.textContent = (userInfo.first_name || '') + ' ' + (userInfo.last_name || '');
|
|
if (!userName.textContent.trim()) userName.textContent = userInfo.username || 'User';
|
|
}
|
|
|
|
var userEmail = document.getElementById('userEmail');
|
|
if (userEmail && userInfo.email) {
|
|
userEmail.textContent = userInfo.email;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('Error updating user info:', e);
|
|
}
|
|
}, { once: true });
|
|
}
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<!-- Header -->
|
|
<header>
|
|
<div class="container">
|
|
<div class="app-title">
|
|
<i class="fas fa-shield-alt"></i>
|
|
<h1>Warracker</h1>
|
|
</div>
|
|
<div class="nav-links">
|
|
<a href="index.html" class="nav-link">
|
|
<i class="fas fa-home"></i> Home
|
|
</a>
|
|
<a href="status.html" class="nav-link active">
|
|
<i class="fas fa-chart-pie"></i> Status
|
|
</a>
|
|
</div>
|
|
<div id="authContainer" class="auth-buttons">
|
|
<a href="login.html" class="auth-btn login-btn">
|
|
<i class="fas fa-sign-in-alt"></i> Login
|
|
</a>
|
|
<a href="register.html" class="auth-btn register-btn">
|
|
<i class="fas fa-user-plus"></i> Register
|
|
</a>
|
|
</div>
|
|
<div id="userMenu" class="user-menu" style="display: none;">
|
|
<button id="userBtn" class="user-btn">
|
|
<i class="fas fa-user-circle"></i>
|
|
<span id="userDisplayName">User</span>
|
|
</button>
|
|
<div id="userMenuDropdown" class="user-menu-dropdown">
|
|
<div class="user-info">
|
|
<div id="userName" class="user-name">User Name</div>
|
|
<div id="userEmail" class="user-email">user@example.com</div>
|
|
</div>
|
|
<div class="user-menu-item">
|
|
<a href="settings-new.html" style="color: inherit; text-decoration: none; display: block;">
|
|
<i class="fas fa-cog"></i> Settings
|
|
</a>
|
|
</div>
|
|
<div class="user-menu-item">
|
|
<i class="fas fa-info-circle"></i>
|
|
<a href="about.html" style="text-decoration: none; color: inherit;">About</a>
|
|
</div>
|
|
<div class="user-menu-item" id="logoutMenuItem">
|
|
<i class="fas fa-sign-out-alt"></i> Logout
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="settings-container">
|
|
<button id="settingsBtn" class="settings-btn" aria-label="Settings" type="button">
|
|
<i class="fas fa-cog"></i>
|
|
</button>
|
|
<div id="settingsMenu" class="settings-menu">
|
|
<div class="settings-item">
|
|
<span>Dark Mode</span>
|
|
<label class="toggle-switch" title="Toggle dark mode">
|
|
<input type="checkbox" id="darkModeToggle">
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
</div>
|
|
<div class="settings-item">
|
|
<a href="https://github.com/sassanix/Warracker" class="settings-link github-link" target="_blank" rel="noopener noreferrer">
|
|
<i class="fab fa-github"></i> GitHub
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main Content -->
|
|
<div class="container">
|
|
<div class="status-content">
|
|
<div class="dashboard-header">
|
|
<h2>Warranty Status Dashboard</h2>
|
|
<button id="refreshDashboardBtn" class="refresh-btn" title="Refresh dashboard">
|
|
<i class="fas fa-sync-alt"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Loading Indicator -->
|
|
<div id="loadingIndicator" class="loading-container active">
|
|
<div class="loading-spinner"></div>
|
|
</div>
|
|
|
|
<!-- Error Message Container -->
|
|
<div id="errorContainer" style="display: none;" class="error-message">
|
|
<i class="fas fa-exclamation-circle"></i>
|
|
<h3>Error Loading Dashboard</h3>
|
|
<p id="errorMessage">There was a problem loading the warranty statistics. Please try refreshing the page.</p>
|
|
<p id="errorDetails" class="error-details"></p>
|
|
</div>
|
|
|
|
<!-- Dashboard Content -->
|
|
<div id="dashboardContent">
|
|
<!-- Summary Cards -->
|
|
<div class="status-cards">
|
|
<div class="status-card" data-status="active">
|
|
<div class="card-icon">
|
|
<i class="fas fa-check-circle"></i>
|
|
</div>
|
|
<div class="card-content">
|
|
<h3>Active</h3>
|
|
<p class="count" id="activeCount">0</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="status-card" data-status="expiring">
|
|
<div class="card-icon">
|
|
<i class="fas fa-exclamation-circle"></i>
|
|
</div>
|
|
<div class="card-content">
|
|
<h3>Expiring Soon</h3>
|
|
<p class="count" id="expiringCount">0</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="status-card" data-status="expired">
|
|
<div class="card-icon">
|
|
<i class="fas fa-times-circle"></i>
|
|
</div>
|
|
<div class="card-content">
|
|
<h3>Expired</h3>
|
|
<p class="count" id="expiredCount">0</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="status-card" data-status="total">
|
|
<div class="card-icon">
|
|
<i class="fas fa-shield-alt"></i>
|
|
</div>
|
|
<div class="card-content">
|
|
<h3>Total</h3>
|
|
<p class="count" id="totalCount">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts Section -->
|
|
<div class="charts-container">
|
|
<div class="chart-card">
|
|
<h3>Warranty Status Distribution</h3>
|
|
<div class="chart-container">
|
|
<canvas id="statusChart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chart-card">
|
|
<h3>Expiration Timeline</h3>
|
|
<div class="chart-container">
|
|
<canvas id="timelineChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Expirations -->
|
|
<div class="recent-expirations">
|
|
<div class="table-header">
|
|
<h3>Recently Expired or Expiring Soon</h3>
|
|
<div class="table-actions">
|
|
<div class="search-box">
|
|
<i class="fas fa-search"></i>
|
|
<input type="text" id="searchWarranties" placeholder="Search warranties...">
|
|
</div>
|
|
<div class="filter-options">
|
|
<select id="statusFilter" class="filter-select">
|
|
<option value="all">All Statuses</option>
|
|
<option value="active">Active</option>
|
|
<option value="expiring">Expiring Soon</option>
|
|
<option value="expired">Expired</option>
|
|
</select>
|
|
</div>
|
|
<button id="exportBtn" class="export-btn" title="Export data">
|
|
<i class="fas fa-download"></i> Export
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table id="recentExpirationsTable">
|
|
<thead>
|
|
<tr>
|
|
<th class="sortable" data-sort="product">Product <i class="fas fa-sort"></i></th>
|
|
<th class="sortable" data-sort="purchase">Purchase Date <i class="fas fa-sort"></i></th>
|
|
<th class="sortable" data-sort="expiration">Expiration Date <i class="fas fa-sort"></i></th>
|
|
<th class="sortable" data-sort="status">Status <i class="fas fa-sort"></i></th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="recentExpirationsBody">
|
|
<!-- Data will be filled by JavaScript -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Toast Notifications -->
|
|
<div class="toast-container" id="toastContainer"></div>
|
|
|
|
<!-- Loading Spinner -->
|
|
<div class="loading-container" id="loadingContainer">
|
|
<div class="loading-spinner"></div>
|
|
</div>
|
|
|
|
<script src="auth.js"></script>
|
|
<script src="status.js"></script>
|
|
</body>
|
|
</html> |