Files
Warracker/frontend/index.html
sassanix 7ead2f7aa7 Reverted
Reverted the changes, as performance and core usage was effected
2025-11-16 14:06:47 -04:00

1689 lines
114 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<!-- Authentication redirect script -->
<script src="auth-redirect.js?v=20250119001" data-protected="true"></script>
<!-- Include authentication script first to handle login state immediately -->
<script src="include-auth-new.js?v=20250119001"></script>
<!-- File utilities script for secure file handling -->
<script src="file-utils.js?v=20250119001"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Warracker - Warranty Tracker</title>
<!-- Add standard favicon.ico link -->
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- Replace the old favicon link -->
<!-- <link rel="icon" type="image/png" href="img/favicon.png"> -->
<!-- Add new favicon links -->
<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="apple-touch-icon" sizes="180x180" href="img/favicon-512x512.png">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="style.css?v=20250119004">
<script src="theme-loader.js?v=20250119001"></script> <!-- Apply theme early -->
<!-- Font Awesome for icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
<!-- Load header fix styles to ensure consistent header styling -->
<link rel="stylesheet" href="header-fix.css?v=20250119001">
<!-- Load fix for auth buttons -->
<script src="fix-auth-buttons-loader.js?v=20250119001"></script>
<!-- Mobile Header specific styles -->
<link rel="stylesheet" href="mobile-header.css?v=20250119002">
<!-- i18next Local Scripts -->
<script src="js/lib/i18next.min.js?v=20250119001"></script>
<script src="js/lib/i18nextHttpBackend.min.js?v=20250119001"></script>
<script src="js/lib/i18nextBrowserLanguageDetector.min.js?v=20250119001"></script>
<!-- i18n Configuration -->
<script src="js/i18n.js?v=20250119001"></script>
<!-- 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>
<!-- Registration status check script -->
<script src="registration-status.js?v=20250119001"></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 active">
<i class="fas fa-home"></i> <span data-i18n="nav.home">Home</span>
</a>
<a href="status.html" class="nav-link">
<i class="fas fa-chart-pie"></i> <span data-i18n="nav.status">Status</span>
</a>
</div>
<!-- Group for right-aligned elements -->
<div class="header-right-group">
<button class="mobile-menu-toggle" aria-label="Toggle menu"><i class="fas fa-bars"></i></button>
<div id="authContainer" class="auth-buttons">
<a href="login.html" class="auth-btn login-btn">
<i class="fas fa-sign-in-alt"></i> <span data-i18n="auth.login">Login</span>
</a>
<a href="register.html" class="auth-btn register-btn">
<i class="fas fa-user-plus"></i> <span data-i18n="auth.register">Register</span>
</a>
</div>
<div id="userMenu" class="user-menu" style="display: none;">
<button id="userMenuBtn" 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> <span data-i18n="nav.settings">Settings</span>
</a>
</div>
<div class="user-menu-item">
<a href="about.html" style="text-decoration: none; color: inherit;">
<i class="fas fa-info-circle"></i> <span data-i18n="nav.about">About</span>
</a>
</div>
<div class="user-menu-item" id="logoutMenuItem">
<span><i class="fas fa-sign-out-alt"></i> <span data-i18n="auth.logout">Logout</span></span>
</div>
</div>
</div>
</div> <!-- End header-right-group -->
</div>
</header>
<div class="mobile-menu-panel" id="mobileMenuPanel"></div>
<div class="mobile-menu-overlay" id="mobileMenuOverlay"></div>
<!-- Main Content -->
<div class="container">
<div class="main-content">
<!-- Warranties List Panel -->
<div class="warranties-panel">
<!-- Panel Header -->
<div class="panel-header">
<h2 id="warrantiesPanelTitle" data-i18n="warranties.title">Your Warranties</h2>
<!-- ADD BUTTON CONTAINER AND REFRESH BUTTON WRAPPER HERE -->
<div class="panel-header-actions">
<div class="add-warranty-button-container">
<button id="showAddWarrantyBtn" class="btn btn-primary btn-sm">
<i class="fas fa-plus"></i> <span data-i18n="warranties.add_new">Add New Warranty</span>
</button>
</div>
<button id="refreshBtn" class="btn btn-secondary btn-sm" data-i18n-title="actions.refresh" title="Refresh List">
<i class="fas fa-sync-alt"></i>
</button>
</div>
</div>
<!-- Filters and Search -->
<div class="filter-controls">
<div class="search-container" style="display: flex; width: 100%; gap: 8px; align-items: center;">
<!-- Make search box width controlled by CSS for consistency -->
<div class="search-box">
<button id="searchBtn" class="search-btn" title="Search">
<i class="fas fa-search"></i>
</button>
<input type="text" id="searchWarranties" data-i18n-placeholder="warranties.search_placeholder" placeholder="Find by name, model, vendors, notes, tag, or serial number..." style="width: 100%;">
<button id="clearSearch" class="clear-search-btn" title="Clear search" style="display: none;">
<i class="fas fa-times"></i>
</button>
</div>
<div class="filter-sort-container">
<button id="filterBtn" class="action-btn">
<i class="fas fa-filter"></i>
<span data-i18n="filters.filter">Filter</span>
<span id="filterIndicator" class="indicator" style="display: none;"></span>
</button>
<div id="filterPopover" class="popover">
<h4 data-i18n="filters.filter_by">Filter By</h4>
<div class="filter-group">
<label for="statusFilter" data-i18n="filters.status">Status</label>
<select id="statusFilter" class="filter-select">
<option value="all" data-i18n="filters.all_status">All Status</option>
<option value="active" data-i18n="warranties.active">Active</option>
<option value="expiring" data-i18n="warranties.expiring_soon">Expiring Soon</option>
<option value="expired" data-i18n="warranties.expired">Expired</option>
<option value="archived" data-i18n="warranties.archived">Archived</option>
</select>
</div>
<div class="filter-group">
<label for="tagFilter" data-i18n="filters.tags">Tag</label>
<select id="tagFilter" class="filter-select">
<option value="all" data-i18n="filters.all_tags">All Tags</option>
</select>
</div>
<div class="filter-group">
<label for="vendorFilter" data-i18n="filters.vendor">Vendor</label>
<select id="vendorFilter" class="filter-select">
<option value="all" data-i18n="filters.all_vendors">All Vendors</option>
</select>
</div>
<div class="filter-group">
<label for="warrantyTypeFilter" data-i18n="filters.warranty_type">Warranty Type</label>
<select id="warrantyTypeFilter" class="filter-select">
<option value="all" data-i18n="filters.all_types">All Types</option>
</select>
</div>
<div class="popover-actions">
<button id="clearFiltersBtn" class="btn btn-secondary" data-i18n="filters.clear">Clear</button>
<button id="applyFiltersBtn" class="btn btn-primary" data-i18n="filters.apply">Apply</button>
</div>
</div>
<button id="sortBtn" class="action-btn">
<i class="fas fa-sort-amount-down"></i>
<span data-i18n="filters.sort">Sort</span>
</button>
<div id="sortPopover" class="popover">
<h4 data-i18n="filters.sort_by">Sort By</h4>
<ul id="sortOptionsList" class="sort-options">
<li data-sort="expiration" class="active" data-i18n="filters.sort_expiration">Expiration Date</li>
<li data-sort="purchase" data-i18n="filters.sort_purchase">Purchase Date</li>
<li data-sort="age" data-i18n="filters.sort_age">Age</li>
<li data-sort="name" data-i18n="filters.sort_name">Product Name</li>
<li data-sort="vendor" data-i18n="filters.sort_vendor">Vendor</li>
<li data-sort="warranty_type" data-i18n="filters.sort_warranty_type">Warranty Type</li>
</ul>
<!-- Hidden select preserved for compatibility with existing JS -->
<select id="sortBy" class="filter-select" style="display: none;">
<option value="expiration" data-i18n="filters.sort_expiration">Expiration Date</option>
<option value="purchase" data-i18n="filters.sort_purchase">Purchase Date</option>
<option value="age" data-i18n="filters.sort_age">Age</option>
<option value="name" data-i18n="filters.sort_name">Product Name</option>
<option value="vendor" data-i18n="filters.sort_vendor">Vendor</option>
<option value="warranty_type" data-i18n="filters.sort_warranty_type">Warranty Type</option>
</select>
</div>
</div>
<div class="secondary-actions" style="display: flex; gap: 8px; flex-wrap: nowrap; flex-shrink: 1; min-width: 0;">
<div class="data-dropdown" style="position: relative;">
<button id="dataMenuBtn" class="action-btn" title="Data" style="white-space: nowrap;">
<i class="fas fa-database"></i> <span data-i18n="actions.data">Data</span> <i class="fas fa-caret-down"></i>
</button>
<div id="dataMenu" class="popover" style="min-width: 180px;">
<ul class="sort-options data-menu-options">
<li id="dataImportOption"><i class="fas fa-file-import"></i> <span data-i18n="actions.import">Import</span></li>
<li id="dataExportOption"><i class="fas fa-file-export"></i> <span data-i18n="actions.export">Export</span></li>
</ul>
</div>
</div>
<!-- Keep original buttons hidden to preserve existing JS behavior -->
<button id="exportBtn" class="export-btn" title="Export warranties" style="display:none;">
<i class="fas fa-file-export"></i> <span data-i18n="actions.export">Export</span>
</button>
<button id="importBtn" class="import-btn" title="Import warranties from CSV" style="display:none;">
<i class="fas fa-file-import"></i> <span data-i18n="actions.import">Import</span>
</button>
<button id="globalManageTagsBtn" class="action-btn export-btn" title="Tags" style="white-space: nowrap;">
<i class="fas fa-tags"></i> <span data-i18n="warranties.tags">Tags</span>
</button>
<!-- View Dropdown (moved after Tags) -->
<div class="data-dropdown" id="viewDropdownContainer" style="position: relative;">
<button id="viewMenuBtn" class="action-btn" title="View" style="white-space: nowrap;">
<i class="fas fa-eye"></i> <span data-i18n="filters.view">View</span> <i class="fas fa-caret-down"></i>
</button>
<div id="viewMenu" class="popover" style="min-width: 160px;">
<ul class="sort-options">
<li id="viewGridOption"><i class="fas fa-th-large"></i> <span>Grid</span></li>
<li id="viewListOption"><i class="fas fa-list"></i> <span>List</span></li>
<li id="viewTableOption"><i class="fas fa-table"></i> <span>Table</span></li>
</ul>
</div>
</div>
<!-- Scope Dropdown (moved after Tags) -->
<div class="data-dropdown" id="scopeDropdown" style="position: relative; display: none;">
<button id="scopeMenuBtn" class="action-btn" title="Scope" style="white-space: nowrap;">
<i class="fas fa-users"></i> <span data-i18n="filters.scope">Scope</span> <i class="fas fa-caret-down"></i>
</button>
<div id="scopeMenu" class="popover" style="min-width: 160px;">
<ul class="sort-options">
<li id="scopePersonalOption"><i class="fas fa-user"></i> <span>Personal</span></li>
<li id="scopeGlobalOption"><i class="fas fa-globe"></i> <span>Global</span></li>
</ul>
</div>
</div>
</div>
<input type="file" id="csvFileInput" accept=".csv" style="display: none;">
</div>
<div class="filter-options">
<div class="action-bar">
<div class="view-switcher" style="display: none;">
<label class="filter-label" data-i18n="filters.view">View</label>
<div class="view-buttons">
<button id="gridViewBtn" class="view-btn active" title="Grid View">
<i class="fas fa-th-large"></i>
</button>
<button id="listViewBtn" class="view-btn" title="List View">
<i class="fas fa-list"></i>
</button>
<button id="tableViewBtn" class="view-btn" title="Table View">
<i class="fas fa-table"></i>
</button>
</div>
</div>
<!-- Move scope switcher to bottom-right -->
<div class="admin-view-switcher" id="adminViewSwitcher" style="display: none; margin-left: auto;">
<label class="filter-label" data-i18n="filters.scope">Scope</label>
<div class="view-buttons" style="display: none;">
<button id="personalViewBtn" class="view-btn active" title="View your warranties only">
<i class="fas fa-user"></i>
</button>
<button id="globalViewBtn" class="view-btn" title="View all users' warranties (read-only for others)">
<i class="fas fa-globe"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="warrantiesList" class="warranties-list grid-view">
<!-- Table headers for table view -->
<div class="table-view-header">
<tr>
<th data-i18n="warranties.product">Product</th>
<th data-i18n="warranties.purchase_date">Purchase Date</th>
<th data-i18n="warranties.expiration">Expiration</th>
<th data-i18n="warranties.status">Status</th>
<th data-i18n="warranties.actions">Actions</th>
</tr>
</div>
<!-- Warranties will be loaded here -->
<div class="empty-state" style="display: none;">
<i class="fas fa-box-open"></i>
<h3 data-i18n="warranties.no_warranties_title">No warranties yet</h3>
<p data-i18n="warranties.no_warranties_desc">Add your first warranty to get started</p>
</div>
</div>
</div>
<!-- MOVE the Form Panel content below -->
<!-- Original <div class="form-panel"> should be removed from here -->
<div id="addWarrantyModal" class="modal-backdrop">
<div class="modal" style="max-width: 700px;"> <!-- Adjusted max-width for the wizard -->
<div class="modal-header">
<h3 class="modal-title" data-i18n="warranties.add_new">Add New Warranty</h3>
<button class="close-btn" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<!-- MOVE the entire original .form-panel content HERE -->
<div class="form-panel" style="box-shadow: none; padding: 0; background: none;">
<!-- Form Tabs -->
<div class="form-tabs" data-step="0">
<div class="form-tab active" data-tab="product-info" id="productInfoTabBtn">
<i class="fas fa-box"></i> <span data-i18n="warranties.product">Product</span>
</div>
<div class="form-tab" data-tab="warranty-details" id="warrantyDetailsTabBtn">
<i class="fas fa-shield-alt"></i> <span data-i18n="warranties.warranty">Warranty</span>
</div>
<div class="form-tab" data-tab="documents" id="documentsTabBtn">
<i class="fas fa-file-alt"></i> <span data-i18n="warranties.documents">Documents</span>
</div>
<div class="form-tab" data-tab="tags" id="tagsTabBtn">
<i class="fas fa-tags"></i> <span data-i18n="warranties.tags">Tags</span>
</div>
<div class="form-tab" data-tab="summary" id="summaryTabBtn">
<i class="fas fa-check-circle"></i> <span data-i18n="warranties.summary">Summary</span>
</div>
</div>
<!-- Warranty Form -->
<form id="warrantyForm" novalidate>
<!-- Product Information Tab -->
<div class="tab-content active" id="product-info">
<div class="form-group">
<label for="productName" data-i18n="warranties.product_name">Product Name</label>
<input type="text" id="productName" name="product_name" class="form-control" required>
</div>
<div class="form-group">
<label for="productUrl" data-i18n="warranties.product_url_optional">Product URL (Optional)</label>
<input type="text" id="productUrl" name="product_url" class="form-control" data-i18n-placeholder="warranties.product_url_placeholder" placeholder="https://example.com/product">
</div>
<div class="form-group">
<label data-i18n="warranties.serial_numbers">Serial Numbers</label>
<div id="serialNumbersContainer">
<!-- Serial number inputs will be added dynamically -->
<input type="text" name="serial_numbers[]" class="form-control" style="margin-bottom: 8px;" data-i18n-placeholder="warranties.enter_serial_number" placeholder="Enter serial number">
</div>
</div>
<div class="form-group">
<label for="modelNumber" data-i18n="warranties.model_number_optional">Model Number (Optional)</label>
<input type="text" id="modelNumber" name="model_number" class="form-control" data-i18n-placeholder="warranties.model_number_placeholder" placeholder="e.g. SM-G991U1">
</div>
<div class="form-group">
<label for="vendor" data-i18n="warranties.vendor_optional">Vendor (Optional)</label>
<input type="text" id="vendor" name="vendor" class="form-control" data-i18n-placeholder="warranties.vendor_placeholder" placeholder="e.g. Amazon, Best Buy, etc.">
</div>
</div>
<!-- Warranty Details Tab -->
<div class="tab-content" id="warranty-details">
<div class="form-group">
<label for="purchaseDate" data-i18n="warranties.purchase_date">Purchase Date</label>
<input type="date" id="purchaseDate" name="purchase_date" class="form-control" required>
</div>
<!-- Add Lifetime Checkbox -->
<div class="form-group">
<label class="lifetime-label">
<input type="checkbox" id="isLifetime" name="is_lifetime" value="true">
<span data-i18n="warranties.lifetime_warranty">Lifetime Warranty</span>
</label>
</div>
<!-- End Lifetime Checkbox -->
<!-- Warranty Entry Method Selection -->
<div class="form-group" id="warrantyEntryMethod">
<label data-i18n="warranties.warranty_entry_method">Warranty Entry Method</label>
<div class="warranty-method-options">
<label class="radio-option">
<input type="radio" id="durationMethod" name="warranty_method" value="duration" checked>
<span data-i18n="warranties.warranty_duration_option">Warranty Duration</span>
</label>
<label class="radio-option">
<input type="radio" id="exactDateMethod" name="warranty_method" value="exact_date">
<span data-i18n="warranties.exact_expiration_option">Exact Expiration Date</span>
</label>
</div>
</div>
<div id="warrantyDurationFields">
<div class="form-group">
<label for="warrantyDurationYears" data-i18n="warranties.warranty_period">Warranty Period</label>
<div class="duration-inputs">
<div>
<input type="number" id="warrantyDurationYears" name="warranty_duration_years" class="form-control" min="0" max="999" data-i18n-placeholder="warranties.years_placeholder" placeholder="Years">
<small data-i18n="warranties.years">Years</small>
</div>
<div>
<input type="number" id="warrantyDurationMonths" name="warranty_duration_months" class="form-control" min="0" max="999" data-i18n-placeholder="warranties.months_placeholder" placeholder="Months">
<small data-i18n="warranties.months">Months</small>
</div>
<div>
<input type="number" id="warrantyDurationDays" name="warranty_duration_days" class="form-control" min="0" max="9999" data-i18n-placeholder="warranties.days_placeholder" placeholder="Days">
<small data-i18n="warranties.days">Days</small>
</div>
</div>
</div>
</div>
<div id="exactExpirationField" style="display: none;">
<div class="form-group">
<label for="exactExpirationDate" data-i18n="warranties.expiration_date_label">Expiration Date</label>
<input type="date" id="exactExpirationDate" name="exact_expiration_date" class="form-control">
</div>
</div>
<div class="form-group">
<label for="warrantyType" data-i18n="warranties.warranty_type_optional">Warranty Type (Optional)</label>
<select id="warrantyType" name="warranty_type" class="form-control">
<option value="" data-i18n="warranties.select_warranty_type">Select warranty type...</option>
<option value="Standard" data-i18n="warranties.standard">Standard</option>
<option value="Extended" data-i18n="warranties.extended">Extended</option>
<option value="Manufacturer" data-i18n="warranties.manufacturer">Manufacturer</option>
<option value="Third Party" data-i18n="warranties.third_party">Third Party</option>
<option value="Store" data-i18n="warranties.store">Store</option>
<option value="Premium" data-i18n="warranties.premium">Premium</option>
<option value="Limited" data-i18n="warranties.limited">Limited</option>
<option value="Full" data-i18n="warranties.full">Full</option>
<option value="Parts Only" data-i18n="warranties.parts_only">Parts Only</option>
<option value="Labor Only" data-i18n="warranties.labor_only">Labor Only</option>
<option value="International" data-i18n="warranties.international">International</option>
<option value="Accidental Damage" data-i18n="warranties.accidental_damage">Accidental Damage</option>
<option value="other" data-i18n="warranties.other_custom">Other (Custom)</option>
</select>
<input type="text" id="warrantyTypeCustom" name="warranty_type_custom" class="form-control" style="display: none; margin-top: 8px;" data-i18n-placeholder="warranties.enter_custom_warranty_type_placeholder" placeholder="Enter custom warranty type">
</div>
<div class="form-group">
<label for="currency" data-i18n="warranties.currency">Currency</label>
<select id="currency" name="currency" class="form-control">
<option value="USD">USD - US Dollar ($)</option>
<!-- Currency options will be populated by JavaScript -->
</select>
</div>
<div class="form-group">
<label for="purchasePrice" data-i18n="warranties.purchase_price_optional">Purchase Price (Optional)</label>
<div class="price-input-wrapper" id="addPriceInputWrapper">
<span class="currency-symbol" id="addCurrencySymbol">$</span>
<input type="number" id="purchasePrice" name="purchase_price" class="form-control" min="0" step="0.01" placeholder="0.00">
</div>
</div>
<div class="form-group">
<label for="notes" data-i18n="warranties.notes_optional">Notes (Optional)</label>
<textarea id="notes" name="notes" class="form-control" rows="3" data-i18n-placeholder="warranties.add_any_notes_placeholder" placeholder="Add any notes about this warranty..."></textarea>
</div>
</div>
<!-- Documents Tab -->
<div class="tab-content" id="documents">
<!-- Paperless-ngx Info Alert (hidden by default, shown when enabled) -->
<div id="paperlessInfoAlert" class="alert alert-info" style="display: none;">
<i class="fas fa-info-circle"></i>
<strong>Paperless-ngx Integration Enabled!</strong> You can now choose to store documents in your Paperless-ngx instance instead of locally.
</div>
<div class="form-group">
<label data-i18n="warranties.product_photo_optional">Product Photo (Optional)</label>
<div class="file-input-wrapper">
<label for="productPhoto" class="file-input-label">
<i class="fas fa-camera"></i> <span data-i18n="warranties.choose_photo">Choose Photo</span>
</label>
<input type="file" id="productPhoto" name="product_photo" class="file-input" accept=".png,.jpg,.jpeg,.webp">
</div>
<div id="productPhotoFileName" class="file-name"></div>
<div id="productPhotoPreview" class="photo-preview" style="display: none;">
<img id="productPhotoImg" src="" alt="Product Photo Preview" style="max-width: 200px; max-height: 200px; border-radius: 8px; margin-top: 10px;">
</div>
</div>
<div class="form-group">
<label data-i18n="warranties.invoice_receipt">Invoice/Receipt</label>
<!-- Storage Selection -->
<div id="invoiceStorageSelection" class="storage-selection" style="display: none;">
<div class="storage-options">
<label class="storage-option">
<input type="radio" name="invoiceStorage" value="local" checked>
<span class="storage-label">
<i class="fas fa-hdd"></i> <span data-i18n="warranties.store_locally">Store Locally</span>
</span>
</label>
<label class="storage-option">
<input type="radio" name="invoiceStorage" value="paperless">
<span class="storage-label">
<i class="fas fa-cloud"></i> <span data-i18n="warranties.store_in_paperless">Store in Paperless-ngx</span>
</span>
</label>
</div>
</div>
<div class="file-input-wrapper">
<label for="invoice" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="invoice" name="invoice" class="file-input" accept=".pdf,.png,.jpg,.jpeg">
</div>
<div id="fileName" class="file-name"></div>
<!-- Paperless Browse Button -->
<div id="invoicePaperlessBrowse" class="paperless-browse-section" style="display: none;">
<button type="button" class="btn btn-secondary btn-sm" onclick="openPaperlessBrowser('invoice')">
<i class="fas fa-search"></i> <span data-i18n="warranties.browse_paperless">Browse Paperless-ngx Documents</span>
</button>
<div id="selectedInvoiceFromPaperless" class="selected-paperless-doc" style="display: none;">
<span class="selected-doc-name"></span>
<button type="button" class="btn btn-danger btn-xs" onclick="clearPaperlessSelection('invoice')">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- URL Input for Invoice -->
<div class="form-group url-input-group">
<label for="invoiceUrl" data-i18n="warranties.or_link_to_invoice_url">Or Link to Invoice URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="invoiceUrl" name="invoice_url" class="form-control" placeholder="https://example.com/invoice.pdf">
</div>
</div>
</div>
<div class="form-group">
<label data-i18n="warranties.product_manual_optional">Product Manual (Optional)</label>
<!-- Storage Selection -->
<div id="manualStorageSelection" class="storage-selection" style="display: none;">
<div class="storage-options">
<label class="storage-option">
<input type="radio" name="manualStorage" value="local" checked>
<span class="storage-label">
<i class="fas fa-hdd"></i> <span data-i18n="warranties.store_locally">Store Locally</span>
</span>
</label>
<label class="storage-option">
<input type="radio" name="manualStorage" value="paperless">
<span class="storage-label">
<i class="fas fa-cloud"></i> <span data-i18n="warranties.store_in_paperless">Store in Paperless-ngx</span>
</span>
</label>
</div>
</div>
<div class="file-input-wrapper">
<label for="manual" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="manual" name="manual" class="file-input" accept=".pdf,.png,.jpg,.jpeg">
</div>
<div id="manualFileName" class="file-name"></div>
<!-- Paperless Browse Button -->
<div id="manualPaperlessBrowse" class="paperless-browse-section" style="display: none;">
<button type="button" class="btn btn-secondary btn-sm" onclick="openPaperlessBrowser('manual')">
<i class="fas fa-search"></i> <span data-i18n="warranties.browse_paperless">Browse Paperless-ngx Documents</span>
</button>
<div id="selectedManualFromPaperless" class="selected-paperless-doc" style="display: none;">
<span class="selected-doc-name"></span>
<button type="button" class="btn btn-danger btn-xs" onclick="clearPaperlessSelection('manual')">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- URL Input for Manual -->
<div class="form-group url-input-group">
<label for="manualUrl" data-i18n="warranties.or_link_to_manual_url">Or Link to Manual URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="manualUrl" name="manual_url" class="form-control" placeholder="https://example.com/manual.pdf">
</div>
</div>
</div>
<div class="form-group">
<label data-i18n="warranties.files_zip_rar_optional">Files (ZIP/RAR, Optional)</label>
<div class="file-input-wrapper">
<label for="otherDocument" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="otherDocument" name="other_document" class="file-input" accept=".zip,.rar">
</div>
<div id="otherDocumentFileName" class="file-name"></div>
<!-- URL Input for Other Document -->
<div class="form-group url-input-group">
<label for="otherDocumentUrl" data-i18n="warranties.or_link_to_files_url">Or Link to Files URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="otherDocumentUrl" name="other_document_url" class="form-control" placeholder="https://example.com/files.zip">
</div>
</div>
</div>
</div>
<!-- Tags Tab -->
<div class="tab-content" id="tags">
<div class="form-group">
<label data-i18n="warranties.add_tags">Add Tags</label>
<p class="text-muted" data-i18n="warranties.add_tags_desc">Tags help you organize and filter your warranties</p>
<div class="tags-container">
<div class="selected-tags" id="selectedTags">
<!-- Selected tags will be displayed here -->
</div>
<div class="tags-dropdown">
<input type="text" id="tagSearch" class="form-control" data-i18n-placeholder="warranties.search_or_add_tag" placeholder="Search or add new tag...">
<div class="tags-list" id="tagsList">
<!-- Tag options will be populated by JavaScript -->
</div>
</div>
<div class="mt-10">
<button type="button" id="manageTagsBtn" class="btn btn-secondary btn-sm">
<i class="fas fa-cog"></i> <span data-i18n="actions.manage_tags">Manage Tags</span>
</button>
</div>
</div>
</div>
</div>
<!-- Summary Tab -->
<div class="tab-content" id="summary">
<div class="summary-container">
<div class="summary-section">
<h4><i class="fas fa-box"></i> <span data-i18n="warranties.product_information">Product Information</span></h4>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.product_name">Product Name:</span>
<span id="summary-product-name" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.product_url">Product URL:</span>
<span id="summary-product-url" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.serial_numbers">Serial Numbers:</span>
<span id="summary-serial-numbers" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.vendor">Vendor:</span>
<span id="summary-vendor" class="summary-value">-</span>
</div>
</div>
<div class="summary-section">
<h4><i class="fas fa-shield-alt"></i> <span data-i18n="warranties.warranty_details">Warranty Details</span></h4>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.purchase_date">Purchase Date:</span>
<span id="summary-purchase-date" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.warranty_period">Warranty Period:</span>
<span id="summary-warranty-duration" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.warranty_type">Warranty Type:</span>
<span id="summary-warranty-type" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.purchase_price">Purchase Price:</span>
<span id="summary-purchase-price" class="summary-value">-</span>
</div>
</div>
<div class="summary-section">
<h4><i class="fas fa-file-alt"></i> <span data-i18n="warranties.documents">Documents</span></h4>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.product_photo">Product Photo:</span>
<span id="summary-product-photo" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.invoice_receipt">Invoice/Receipt:</span>
<span id="summary-invoice" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.product_manual">Product Manual:</span>
<span id="summary-manual" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.files">Files:</span>
<span id="summary-other-document" class="summary-value">-</span>
</div>
</div>
<div class="summary-section">
<h4><i class="fas fa-tags"></i> <span data-i18n="warranties.tags">Tags</span></h4>
<div class="summary-item">
<span class="summary-label" data-i18n="warranties.selected_tags">Selected Tags:</span>
<div id="summary-tags" class="summary-value">-</div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" id="submitWarrantyBtn" data-i18n="warranties.add_warranty">Add Warranty</button>
</div>
</div>
<!-- Tab Navigation -->
<div class="tab-navigation">
<button type="button" class="btn btn-secondary prev-tab" id="prevTabBtn">
<i class="fas fa-arrow-left"></i> <span data-i18n="warranties.previous_tab">Previous</span>
</button>
<button type="button" class="btn btn-primary next-tab" id="nextTabBtn">
<span data-i18n="warranties.next_tab">Next</span> <i class="fas fa-arrow-right"></i>
</button>
</div>
</form>
</div> <!-- End form-panel -->
</div> <!-- End modal-body -->
<!-- Optional: Add a modal footer if you want separate Cancel/Submit buttons -->
<!-- <div class="modal-footer">
<button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div> -->
</div> <!-- End modal -->
</div> <!-- End addWarrantyModal -->
</div> <!-- End main-content -->
</div> <!-- End container -->
<!-- Edit Warranty Modal -->
<div id="editModal" class="modal-backdrop">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title" data-i18n="warranties.edit_warranty">Edit Warranty</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<!-- Tab Navigation -->
<div class="edit-tabs-nav">
<button type="button" class="edit-tab-btn active" data-tab="edit-product-info">
<i class="fas fa-box"></i> <span data-i18n="warranties.product">Product</span>
</button>
<button type="button" class="edit-tab-btn" data-tab="edit-warranty-details">
<i class="fas fa-shield-alt"></i> <span data-i18n="warranties.warranty">Warranty</span>
</button>
<button type="button" class="edit-tab-btn" data-tab="edit-documents">
<i class="fas fa-file-alt"></i> <span data-i18n="warranties.documents">Documents</span>
</button>
<button type="button" class="edit-tab-btn" data-tab="edit-tags">
<i class="fas fa-tags"></i> <span data-i18n="warranties.tags">Tags</span>
</button>
</div>
<form id="editWarrantyForm" novalidate>
<input type="hidden" id="editWarrantyId">
<!-- Product Info Tab -->
<div class="edit-tab-content active" id="edit-product-info">
<div class="form-group">
<label for="editProductName" data-i18n="warranties.product_name">Product Name</label>
<input type="text" id="editProductName" name="product_name" class="form-control" required>
</div>
<div class="form-group">
<label for="editProductUrl" data-i18n="warranties.product_url_optional">Product URL (Optional)</label>
<input type="text" id="editProductUrl" name="product_url" class="form-control" data-i18n-placeholder="warranties.product_url_placeholder" placeholder="https://example.com/product">
</div>
<div class="form-group">
<label data-i18n="warranties.serial_numbers">Serial Numbers</label>
<div id="editSerialNumbersContainer">
<!-- Serial number inputs will be added dynamically -->
</div>
</div>
<div class="form-group">
<label for="editModelNumber" data-i18n="warranties.model_number_optional">Model Number (Optional)</label>
<input type="text" id="editModelNumber" name="model_number" class="form-control" data-i18n-placeholder="warranties.model_number_placeholder" placeholder="e.g. SM-G991U1">
</div>
<div class="form-group">
<label for="editVendor" data-i18n="warranties.vendor_optional">Vendor (Optional)</label>
<input type="text" id="editVendor" name="vendor" class="form-control" data-i18n-placeholder="warranties.vendor_placeholder" placeholder="e.g. Amazon, Best Buy, etc.">
</div>
</div>
<!-- Warranty Details Tab -->
<div class="edit-tab-content" id="edit-warranty-details">
<div class="form-group">
<label for="editPurchaseDate" data-i18n="warranties.purchase_date">Purchase Date</label>
<input type="date" id="editPurchaseDate" name="purchase_date" class="form-control" required>
</div>
<!-- Add Lifetime Checkbox -->
<div class="form-group">
<label class="lifetime-label">
<input type="checkbox" id="editIsLifetime" name="is_lifetime" value="true">
<span data-i18n="warranties.lifetime_warranty">Lifetime Warranty</span>
</label>
</div>
<!-- End Lifetime Checkbox -->
<!-- Warranty Entry Method Selection -->
<div class="form-group" id="editWarrantyEntryMethod">
<label data-i18n="warranties.warranty_entry_method">Warranty Entry Method</label>
<div class="warranty-method-options">
<label class="radio-option">
<input type="radio" id="editDurationMethod" name="edit_warranty_method" value="duration" checked>
<span data-i18n="warranties.warranty_duration_option">Warranty Duration</span>
</label>
<label class="radio-option">
<input type="radio" id="editExactDateMethod" name="edit_warranty_method" value="exact_date">
<span data-i18n="warranties.exact_expiration_option">Exact Expiration Date</span>
</label>
</div>
</div>
<div id="editWarrantyDurationFields">
<div class="form-group">
<label for="editWarrantyDurationYears" data-i18n="warranties.warranty_period">Warranty Period</label>
<div class="duration-inputs">
<div>
<input type="number" id="editWarrantyDurationYears" name="warranty_duration_years" class="form-control" min="0" max="999" data-i18n-placeholder="warranties.years_placeholder" placeholder="Years">
<small data-i18n="warranties.years">Years</small>
</div>
<div>
<input type="number" id="editWarrantyDurationMonths" name="warranty_duration_months" class="form-control" min="0" max="999" data-i18n-placeholder="warranties.months_placeholder" placeholder="Months">
<small data-i18n="warranties.months">Months</small>
</div>
<div>
<input type="number" id="editWarrantyDurationDays" name="warranty_duration_days" class="form-control" min="0" max="9999" data-i18n-placeholder="warranties.days_placeholder" placeholder="Days">
<small data-i18n="warranties.days">Days</small>
</div>
</div>
</div>
</div>
<div id="editExactExpirationField" style="display: none;">
<div class="form-group">
<label for="editExactExpirationDate" data-i18n="warranties.expiration_date_label">Expiration Date</label>
<input type="date" id="editExactExpirationDate" name="exact_expiration_date" class="form-control">
</div>
</div>
<div class="form-group">
<label for="editWarrantyType" data-i18n="warranties.warranty_type_optional">Warranty Type (Optional)</label>
<select id="editWarrantyType" name="warranty_type" class="form-control">
<option value="" data-i18n="warranties.select_warranty_type">Select warranty type...</option>
<option value="Standard" data-i18n="warranties.standard">Standard</option>
<option value="Extended" data-i18n="warranties.extended">Extended</option>
<option value="Manufacturer" data-i18n="warranties.manufacturer">Manufacturer</option>
<option value="Third Party" data-i18n="warranties.third_party">Third Party</option>
<option value="Store" data-i18n="warranties.store">Store</option>
<option value="Premium" data-i18n="warranties.premium">Premium</option>
<option value="Limited" data-i18n="warranties.limited">Limited</option>
<option value="Full" data-i18n="warranties.full">Full</option>
<option value="Parts Only" data-i18n="warranties.parts_only">Parts Only</option>
<option value="Labor Only" data-i18n="warranties.labor_only">Labor Only</option>
<option value="International" data-i18n="warranties.international">International</option>
<option value="Accidental Damage" data-i18n="warranties.accidental_damage">Accidental Damage</option>
<option value="other" data-i18n="warranties.other_custom">Other (Custom)</option>
</select>
<input type="text" id="editWarrantyTypeCustom" name="warranty_type_custom" class="form-control" style="display: none; margin-top: 8px;" data-i18n-placeholder="warranties.enter_custom_warranty_type_placeholder" placeholder="Enter custom warranty type">
</div>
<div class="form-group">
<label for="editCurrency" data-i18n="warranties.currency">Currency</label>
<select id="editCurrency" name="currency" class="form-control">
<option value="USD">USD - US Dollar ($)</option>
<!-- Currency options will be populated by JavaScript -->
</select>
</div>
<div class="form-group">
<label for="editPurchasePrice" data-i18n="warranties.purchase_price_optional">Purchase Price (Optional)</label>
<div class="price-input-wrapper" id="editPriceInputWrapper">
<span class="currency-symbol" id="editCurrencySymbol">$</span>
<input type="number" id="editPurchasePrice" name="purchase_price" class="form-control" min="0" step="0.01" placeholder="0.00">
</div>
</div>
<div class="form-group">
<label for="editNotes" data-i18n="warranties.notes_optional">Notes (Optional)</label>
<textarea id="editNotes" name="notes" class="form-control" rows="3" data-i18n-placeholder="warranties.add_any_notes_placeholder" placeholder="Add any notes about this warranty..."></textarea>
</div>
</div>
<!-- Documents Tab -->
<div class="edit-tab-content" id="edit-documents">
<div class="form-group">
<label data-i18n="warranties.product_photo_optional">Product Photo (Optional)</label>
<div class="file-input-wrapper">
<label for="editProductPhoto" class="file-input-label">
<i class="fas fa-camera"></i> <span data-i18n="warranties.choose_photo">Choose Photo</span>
</label>
<input type="file" id="editProductPhoto" name="product_photo" class="file-input" accept=".png,.jpg,.jpeg,.webp">
</div>
<div id="editProductPhotoFileName" class="file-name"></div>
<div id="editProductPhotoPreview" class="photo-preview" style="display: none;">
<img id="editProductPhotoImg" src="" alt="Product Photo Preview" style="max-width: 200px; max-height: 200px; border-radius: 8px; margin-top: 10px;">
</div>
<div id="currentProductPhoto" class="mt-10"></div>
<button type="button" id="deleteProductPhotoBtn" class="btn btn-danger btn-sm mt-2" style="display:none;"><i class="fas fa-trash"></i> <span data-i18n="warranties.delete_photo">Delete Photo</span></button>
</div>
<div class="form-group">
<label data-i18n="warranties.invoice_receipt">Invoice/Receipt</label>
<!-- Storage Selection -->
<div id="editInvoiceStorageSelection" class="storage-selection" style="display: none;">
<div class="storage-options">
<label class="storage-option">
<input type="radio" name="editInvoiceStorage" value="local" checked>
<span class="storage-label">
<i class="fas fa-hdd"></i> <span data-i18n="warranties.store_locally">Store Locally</span>
</span>
</label>
<label class="storage-option">
<input type="radio" name="editInvoiceStorage" value="paperless">
<span class="storage-label">
<i class="fas fa-cloud"></i> <span data-i18n="warranties.store_in_paperless">Store in Paperless-ngx</span>
</span>
</label>
</div>
</div>
<div class="file-input-wrapper">
<label for="editInvoice" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="editInvoice" name="invoice" class="file-input" accept=".pdf,.png,.jpg,.jpeg">
</div>
<div id="editFileName" class="file-name"></div>
<div id="currentInvoice" class="mt-10"></div>
<button type="button" id="deleteInvoiceBtn" class="btn btn-danger btn-sm mt-2" style="display:none;"><i class="fas fa-trash"></i> <span data-i18n="warranties.delete_invoice">Delete Invoice</span></button>
<!-- Paperless Browse Button -->
<div id="editInvoicePaperlessBrowse" class="paperless-browse-section" style="display: none;">
<button type="button" class="btn btn-secondary btn-sm" onclick="openPaperlessBrowser('edit_invoice')">
<i class="fas fa-search"></i> <span data-i18n="warranties.browse_paperless">Browse Paperless-ngx Documents</span>
</button>
<div id="selectedEditInvoiceFromPaperless" class="selected-paperless-doc" style="display: none;">
<span class="selected-doc-name"></span>
<button type="button" class="btn btn-danger btn-xs" onclick="clearPaperlessSelection('edit_invoice')">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- URL Input for Invoice -->
<div class="form-group url-input-group">
<label for="editInvoiceUrl" data-i18n="warranties.or_link_to_invoice_url">Or Link to Invoice URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="editInvoiceUrl" name="invoice_url" class="form-control" placeholder="https://example.com/invoice.pdf">
</div>
</div>
</div>
<div class="form-group">
<label data-i18n="warranties.product_manual_optional">Product Manual (Optional)</label>
<!-- Storage Selection -->
<div id="editManualStorageSelection" class="storage-selection" style="display: none;">
<div class="storage-options">
<label class="storage-option">
<input type="radio" name="editManualStorage" value="local" checked>
<span class="storage-label">
<i class="fas fa-hdd"></i> <span data-i18n="warranties.store_locally">Store Locally</span>
</span>
</label>
<label class="storage-option">
<input type="radio" name="editManualStorage" value="paperless">
<span class="storage-label">
<i class="fas fa-cloud"></i> <span data-i18n="warranties.store_in_paperless">Store in Paperless-ngx</span>
</span>
</label>
</div>
</div>
<div class="file-input-wrapper">
<label for="editManual" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="editManual" name="manual" class="file-input" accept=".pdf,.png,.jpg,.jpeg">
</div>
<div id="editManualFileName" class="file-name"></div>
<div id="currentManual" class="mt-10"></div>
<button type="button" id="deleteManualBtn" class="btn btn-danger btn-sm mt-2" style="display:none;"><i class="fas fa-trash"></i> <span data-i18n="warranties.delete_manual">Delete Manual</span></button>
<!-- Paperless Browse Button -->
<div id="editManualPaperlessBrowse" class="paperless-browse-section" style="display: none;">
<button type="button" class="btn btn-secondary btn-sm" onclick="openPaperlessBrowser('edit_manual')">
<i class="fas fa-search"></i> <span data-i18n="warranties.browse_paperless">Browse Paperless-ngx Documents</span>
</button>
<div id="selectedEditManualFromPaperless" class="selected-paperless-doc" style="display: none;">
<span class="selected-doc-name"></span>
<button type="button" class="btn btn-danger btn-xs" onclick="clearPaperlessSelection('edit_manual')">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- URL Input for Manual -->
<div class="form-group url-input-group">
<label for="editManualUrl" data-i18n="warranties.or_link_to_manual_url">Or Link to Manual URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="editManualUrl" name="manual_url" class="form-control" placeholder="https://example.com/manual.pdf">
</div>
</div>
</div>
<div class="form-group">
<label data-i18n="warranties.files_zip_rar_optional">Files (ZIP/RAR, Optional)</label>
<div class="file-input-wrapper">
<label for="editOtherDocument" class="file-input-label">
<i class="fas fa-upload"></i> <span data-i18n="warranties.choose_file">Choose File</span>
</label>
<input type="file" id="editOtherDocument" name="other_document" class="file-input" accept=".zip,.rar">
</div>
<div id="editOtherDocumentFileName" class="file-name"></div>
<div id="currentOtherDocument" class="mt-10"></div>
<button type="button" id="deleteOtherDocumentBtn" class="btn btn-danger btn-sm mt-2" style="display:none;"><i class="fas fa-trash"></i> <span data-i18n="warranties.delete_files">Delete Files</span></button>
<!-- URL Input for Other Document -->
<div class="form-group url-input-group">
<label for="editOtherDocumentUrl" data-i18n="warranties.or_link_to_files_url">Or Link to Files URL</label>
<div class="input-with-icon">
<i class="fas fa-link"></i>
<input type="url" id="editOtherDocumentUrl" name="other_document_url" class="form-control" placeholder="https://example.com/files.zip">
</div>
</div>
</div>
</div>
<!-- Tags Tab -->
<div class="edit-tab-content" id="edit-tags">
<div class="form-group">
<label data-i18n="warranties.add_tags">Add Tags</label>
<p class="text-muted" data-i18n="warranties.add_tags_desc">Tags help you organize and filter your warranties</p>
<div class="tags-container">
<div class="selected-tags" id="editSelectedTags">
<!-- Selected tags will be displayed here -->
</div>
<div class="tags-dropdown">
<input type="text" id="editTagSearch" class="form-control" data-i18n-placeholder="warranties.search_or_add_new_tag" placeholder="Search or add new tag...">
<div class="tags-list" id="editTagsList">
<!-- Tag options will be populated by JavaScript -->
</div>
</div>
<div class="mt-10">
<button type="button" id="editManageTagsBtn" class="btn btn-secondary btn-sm">
<i class="fas fa-cog"></i> <span data-i18n="actions.manage_tags">Manage Tags</span>
</button>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-danger" data-dismiss="modal" data-i18n="actions.cancel">Cancel</button>
<button id="saveWarrantyBtn" class="btn btn-primary" data-i18n="warranties.save_changes">Save Changes</button>
</div>
</div>
</div>
<!-- Confirm Delete Modal -->
<div id="deleteModal" class="modal-backdrop">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title" data-i18n="warranties.confirm_delete">Confirm Delete</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<p data-i18n="warranties.confirm_delete_message">Are you sure you want to delete this warranty? This action cannot be undone.</p>
<p><strong><span data-i18n="warranties.product">Product</span>:</strong> <span id="deleteProductName"></span></p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-dismiss="modal" data-i18n="actions.cancel">Cancel</button>
<button id="confirmDeleteBtn" class="btn btn-danger" data-i18n="actions.delete">Delete</button>
</div>
</div>
</div>
<!-- Confirm Archive Modal -->
<div id="archiveModal" class="modal-backdrop">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title">Archive Warranty</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<p>Are you sure you want to archive this warranty?</p>
<p>Archived warranties are not deleted. You can find them by selecting the "Archived" status in Filters.</p>
<p><strong>Product:</strong> <span id="archiveProductName"></span></p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button id="confirmArchiveBtn" class="btn btn-primary">Archive</button>
</div>
</div>
</div>
<!-- Tag Management Modal -->
<div id="tagManagementModal" class="modal-backdrop">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title" data-i18n="actions.manage_tags">Manage Tags</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<form id="newTagForm" class="tag-form">
<input type="text" id="newTagName" class="form-control" data-i18n-placeholder="warranties.new_tag_name" placeholder="New tag name" required>
<input type="color" id="newTagColor" value="#808080">
<button type="submit" class="btn btn-primary" data-i18n="warranties.add_tag">Add Tag</button>
</form>
<h4 class="mt-20" data-i18n="warranties.existing_tags">Existing Tags</h4>
<div id="existingTags" class="existing-tags">
<!-- Tags will be populated here by JavaScript -->
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-dismiss="modal" data-i18n="actions.close">Close</button>
</div>
</div>
</div>
<!-- Paperless Document Browser Modal -->
<div id="paperlessBrowserModal" class="modal-backdrop">
<div class="modal modal-large">
<div class="modal-header">
<h3 class="modal-title">Browse Paperless-ngx Documents</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<div class="paperless-browser-controls">
<div class="search-section">
<input type="text" id="paperlessSearchInput" class="form-control" placeholder="Search documents by title, content, or tags...">
<button type="button" class="btn btn-primary" id="paperlessSearchBtn">
<i class="fas fa-search"></i> Search
</button>
<button type="button" class="btn btn-secondary" id="paperlessShowAllBtn">
<i class="fas fa-list"></i> Show All
</button>
</div>
<div class="filter-section">
<select id="paperlessTypeFilter" class="form-control">
<option value="">All Document Types</option>
<option value="application/pdf">PDF Documents</option>
<option value="image/jpeg,image/jpg,image/png">Images</option>
<option value="application/zip">Archives</option>
</select>
<select id="paperlessTagFilter" class="form-control">
<option value="">All Tags</option>
<!-- Tags will be populated dynamically -->
</select>
</div>
</div>
<div id="paperlessDocumentsList" class="paperless-documents-list">
<div class="loading-message" style="text-align: center; padding: 20px;">
<i class="fas fa-spinner fa-spin"></i> Loading documents...
</div>
</div>
<div class="pagination-controls" id="paperlessPagination" style="display: none;">
<button type="button" class="btn btn-secondary" id="prevPageBtn" onclick="changePage(-1)">
<i class="fas fa-chevron-left"></i> Previous
</button>
<span id="pageInfo">Page 1 of 1</span>
<button type="button" class="btn btn-secondary" id="nextPageBtn" onclick="changePage(1)">
Next <i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button id="selectPaperlessDocBtn" class="btn btn-primary" style="display: none;">
<i class="fas fa-check"></i> Select Document
</button>
</div>
</div>
</div>
<!-- Claims Modal -->
<div id="claimsModal" class="modal-backdrop">
<div class="modal modal-large">
<div class="modal-header">
<h3 class="modal-title" data-i18n="claims.warranty_claims">Warranty Claims</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<div class="claims-header">
<div id="warrantyClaimInfo" class="warranty-claim-info">
<!-- Warranty info will be populated here -->
</div>
</div>
<div id="claimsListBody" class="claims-list">
<div class="loading-message" style="text-align: center; padding: 20px;">
<i class="fas fa-spinner fa-spin"></i> Loading claims...
</div>
</div>
</div>
<div class="modal-footer">
<button id="addClaimBtn" class="btn btn-primary">
<i class="fas fa-plus"></i> <span data-i18n="claims.add_new_claim">Add New Claim</span>
</button>
<button class="btn btn-secondary" data-dismiss="modal" data-i18n="actions.close">Close</button>
</div>
</div>
</div>
<!-- Claim Form Modal -->
<div id="claimFormModal" class="modal-backdrop">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title" id="claimFormTitle" data-i18n="claims.add_claim">Add Claim</h3>
<button class="close-btn" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<form id="claimForm">
<input type="hidden" id="editClaimId" value="">
<div class="form-group">
<label for="claimDate" data-i18n="claims.claim_date">Claim Date:</label>
<input type="date" id="claimDate" name="claim_date" class="form-control" required>
</div>
<div class="form-group">
<label for="claimStatus" data-i18n="claims.status">Status:</label>
<select id="claimStatus" name="status" class="form-control" required>
<option value="Submitted" data-i18n="claims.status_submitted">Submitted</option>
<option value="In Progress" data-i18n="claims.status_in_progress">In Progress</option>
<option value="Approved" data-i18n="claims.status_approved">Approved</option>
<option value="Denied" data-i18n="claims.status_denied">Denied</option>
<option value="Resolved" data-i18n="claims.status_resolved">Resolved</option>
<option value="Cancelled" data-i18n="claims.status_cancelled">Cancelled</option>
</select>
</div>
<div class="form-group">
<label for="claimNumber" data-i18n="claims.claim_number">Claim Number:</label>
<input type="text" id="claimNumber" name="claim_number" class="form-control"
placeholder="e.g., CLM-2025-001">
</div>
<div class="form-group">
<label for="claimDescription" data-i18n="claims.description">Description:</label>
<textarea id="claimDescription" name="description" class="form-control" rows="4"
data-i18n-placeholder="claims.description_placeholder"
placeholder="Describe the issue and reason for the claim..."></textarea>
</div>
<div class="form-group">
<label for="claimResolution" data-i18n="claims.resolution">Resolution:</label>
<textarea id="claimResolution" name="resolution" class="form-control" rows="3"
data-i18n-placeholder="claims.resolution_placeholder"
placeholder="Resolution details (if any)..."></textarea>
</div>
<div class="form-group">
<label for="resolutionDate" data-i18n="claims.resolution_date">Resolution Date:</label>
<input type="date" id="resolutionDate" name="resolution_date" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" data-i18n="actions.cancel">Cancel</button>
<button type="submit" form="claimForm" class="btn btn-primary" id="saveClaimBtn">
<i class="fas fa-save"></i> <span data-i18n="actions.save">Save</span>
</button>
</div>
</div>
</div>
<!-- Toast Container -->
<div id="toastContainer" class="toast-container"></div>
<!-- Loading Spinner -->
<div class="loading-container" id="loadingContainer">
<div class="loading-spinner"></div>
</div>
<script src="auth.js?v=20250119001"></script>
<script src="script.js?v=20250119002"></script>
<script>
// Lightweight UI logic for Filter/Sort popovers (no change to core logic)
document.addEventListener('DOMContentLoaded', function () {
var filterBtn = document.getElementById('filterBtn');
var sortBtn = document.getElementById('sortBtn');
var viewMenuBtn = document.getElementById('viewMenuBtn');
var viewMenu = document.getElementById('viewMenu');
var viewGridOption = document.getElementById('viewGridOption');
var viewListOption = document.getElementById('viewListOption');
var viewTableOption = document.getElementById('viewTableOption');
var currentViewLabel = document.getElementById('currentViewLabel');
var scopeDropdown = document.getElementById('scopeDropdown');
var scopeMenuBtn = document.getElementById('scopeMenuBtn');
var scopeMenu = document.getElementById('scopeMenu');
var scopePersonalOption = document.getElementById('scopePersonalOption');
var scopeGlobalOption = document.getElementById('scopeGlobalOption');
var currentScopeLabel = document.getElementById('currentScopeLabel');
var filterPopover = document.getElementById('filterPopover');
var sortPopover = document.getElementById('sortPopover');
var sortOptionsList = document.getElementById('sortOptionsList');
var sortBy = document.getElementById('sortBy');
var statusFilter = document.getElementById('statusFilter');
var tagFilter = document.getElementById('tagFilter');
var vendorFilter = document.getElementById('vendorFilter');
var warrantyTypeFilter = document.getElementById('warrantyTypeFilter');
var clearFiltersBtn = document.getElementById('clearFiltersBtn');
var applyFiltersBtn = document.getElementById('applyFiltersBtn');
var filterIndicator = document.getElementById('filterIndicator');
// Data dropdown
var dataMenuBtn = document.getElementById('dataMenuBtn');
var dataMenu = document.getElementById('dataMenu');
var dataImportOption = document.getElementById('dataImportOption');
var dataExportOption = document.getElementById('dataExportOption');
var legacyImportBtn = document.getElementById('importBtn');
var legacyExportBtn = document.getElementById('exportBtn');
if (dataMenuBtn && dataMenu) {
dataMenuBtn.addEventListener('click', function (e) {
e.stopPropagation();
dataMenu.classList.toggle('active');
if (dataMenu.classList.contains('active')) closeAllPopovers(dataMenu);
});
}
if (dataImportOption && legacyImportBtn) {
dataImportOption.addEventListener('click', function () {
legacyImportBtn.click();
if (dataMenu) dataMenu.classList.remove('active');
});
}
if (dataExportOption && legacyExportBtn) {
dataExportOption.addEventListener('click', function () {
legacyExportBtn.click();
if (dataMenu) dataMenu.classList.remove('active');
});
}
// Expose globally so core script can trigger it after async loads
window.updateFilterIndicator = function () {
try {
var hasActive = false;
if (statusFilter && statusFilter.value && statusFilter.value !== 'all') hasActive = true;
if (tagFilter && tagFilter.value && tagFilter.value !== 'all') hasActive = true;
if (vendorFilter && vendorFilter.value && vendorFilter.value !== 'all') hasActive = true;
if (warrantyTypeFilter && warrantyTypeFilter.value && warrantyTypeFilter.value !== 'all') hasActive = true;
if (filterIndicator) filterIndicator.style.display = hasActive ? 'inline-block' : 'none';
} catch (e) { /* no-op */ }
};
function closeAllPopovers(except) {
[filterPopover, sortPopover, viewMenu, scopeMenu, dataMenu].forEach(function (p) {
if (p && p !== except) p.classList.remove('active');
});
}
if (filterBtn && filterPopover) {
filterBtn.addEventListener('click', function (e) {
e.stopPropagation();
filterPopover.classList.toggle('active');
if (filterPopover.classList.contains('active')) closeAllPopovers(filterPopover);
});
}
if (sortBtn && sortPopover) {
sortBtn.addEventListener('click', function (e) {
e.stopPropagation();
sortPopover.classList.toggle('active');
if (sortPopover.classList.contains('active')) closeAllPopovers(sortPopover);
});
}
if (viewMenuBtn && viewMenu) {
viewMenuBtn.addEventListener('click', function (e) {
e.stopPropagation();
viewMenu.classList.toggle('active');
if (viewMenu.classList.contains('active')) {
closeAllPopovers(viewMenu);
// Sync highlight with the currently selected view when opening
try {
var currentType = 'grid';
var wl = document.getElementById('warrantiesList');
if (wl) {
if (wl.classList.contains('list-view')) currentType = 'list';
else if (wl.classList.contains('table-view')) currentType = 'table';
} else {
var prefixV = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedV = localStorage.getItem(prefixV + 'defaultView') || localStorage.getItem(prefixV + 'warrantyView') || 'grid';
currentType = savedV;
}
if (typeof setViewIconFrom === 'function') setViewIconFrom(currentType);
} catch (e) { /* no-op */ }
}
});
function setViewIconFrom(viewType) {
var icon = document.getElementById('currentViewIcon');
if (icon) {
icon.className = 'fas';
if (viewType === 'list') {
icon.classList.add('fa-list');
icon.setAttribute('aria-label', 'List');
} else if (viewType === 'table') {
icon.classList.add('fa-table');
icon.setAttribute('aria-label', 'Table');
} else {
icon.classList.add('fa-th-large');
icon.setAttribute('aria-label', 'Grid');
}
}
// Highlight active option in the dropdown
try {
if (viewGridOption) viewGridOption.classList.toggle('active', viewType === 'grid');
if (viewListOption) viewListOption.classList.toggle('active', viewType === 'list');
if (viewTableOption) viewTableOption.classList.toggle('active', viewType === 'table');
} catch (e) { /* no-op */ }
}
if (viewGridOption) viewGridOption.addEventListener('click', function () { if (window.switchView) window.switchView('grid'); setViewIconFrom('grid'); viewMenu.classList.remove('active'); });
if (viewListOption) viewListOption.addEventListener('click', function () { if (window.switchView) window.switchView('list'); setViewIconFrom('list'); viewMenu.classList.remove('active'); });
if (viewTableOption) viewTableOption.addEventListener('click', function () { if (window.switchView) window.switchView('table'); setViewIconFrom('table'); viewMenu.classList.remove('active'); });
// Initialize label from saved preference
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedView = localStorage.getItem(prefix + 'defaultView') || localStorage.getItem(prefix + 'warrantyView') || 'grid';
setViewIconFrom(savedView);
} catch (e) { /* no-op */ }
}
if (scopeMenuBtn && scopeMenu) {
scopeMenuBtn.addEventListener('click', function (e) {
e.stopPropagation();
scopeMenu.classList.toggle('active');
if (scopeMenu.classList.contains('active')) {
closeAllPopovers(scopeMenu);
// Sync highlight with the currently selected scope when opening
try {
var prefixS = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedS = localStorage.getItem(prefixS + 'viewScope') || 'personal';
if (typeof setScopeIconFrom === 'function') setScopeIconFrom(savedS);
} catch (e) { /* no-op */ }
}
});
function setScopeIconFrom(scope) {
var icon = document.getElementById('currentScopeIcon');
if (icon) {
icon.className = 'fas';
if (scope === 'global') {
icon.classList.add('fa-globe');
icon.setAttribute('aria-label', 'Global');
} else {
icon.classList.add('fa-user');
icon.setAttribute('aria-label', 'Personal');
}
}
// Highlight active option in the dropdown
try {
if (scopePersonalOption) scopePersonalOption.classList.toggle('active', scope === 'personal');
if (scopeGlobalOption) scopeGlobalOption.classList.toggle('active', scope === 'global');
} catch (e) { /* no-op */ }
}
if (scopePersonalOption) scopePersonalOption.addEventListener('click', function () { if (window.switchToPersonalView) window.switchToPersonalView(); setScopeIconFrom('personal'); scopeMenu.classList.remove('active'); });
if (scopeGlobalOption) scopeGlobalOption.addEventListener('click', function () { if (window.switchToGlobalView) window.switchToGlobalView(); setScopeIconFrom('global'); scopeMenu.classList.remove('active'); });
// Initialize scope label from saved preference
try {
var prefix2 = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedScope = localStorage.getItem(prefix2 + 'viewScope') || 'personal';
setScopeIconFrom(savedScope);
} catch (e) { /* no-op */ }
}
document.addEventListener('click', function (e) {
if (filterPopover && !filterPopover.contains(e.target) && e.target !== filterBtn) filterPopover.classList.remove('active');
if (sortPopover && !sortPopover.contains(e.target) && e.target !== sortBtn) sortPopover.classList.remove('active');
if (viewMenu && !viewMenu.contains(e.target) && e.target !== viewMenuBtn) viewMenu.classList.remove('active');
if (scopeMenu && !scopeMenu.contains(e.target) && e.target !== scopeMenuBtn) scopeMenu.classList.remove('active');
if (dataMenu && !dataMenu.contains(e.target) && e.target !== dataMenuBtn) dataMenu.classList.remove('active');
});
// Restore saved filters early so indicator reflects persisted state immediately
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedFiltersRaw = localStorage.getItem(prefix + 'warrantyFilters');
if (savedFiltersRaw) {
var savedFilters = JSON.parse(savedFiltersRaw) || {};
if (statusFilter && savedFilters.status) statusFilter.value = savedFilters.status;
if (tagFilter && savedFilters.tag) tagFilter.value = savedFilters.tag;
if (vendorFilter && savedFilters.vendor) vendorFilter.value = savedFilters.vendor;
if (warrantyTypeFilter && savedFilters.warranty_type) warrantyTypeFilter.value = savedFilters.warranty_type;
// Restore search field if present
var searchInput = document.getElementById('searchWarranties');
var clearSearchBtn = document.getElementById('clearSearch');
if (searchInput && savedFilters.search) {
searchInput.value = savedFilters.search;
if (clearSearchBtn) clearSearchBtn.style.display = 'flex';
if (searchInput.parentElement) searchInput.parentElement.classList.add('active-search');
}
}
} catch (e) { /* no-op */ }
if (applyFiltersBtn) {
applyFiltersBtn.addEventListener('click', function () {
[statusFilter, tagFilter, vendorFilter, warrantyTypeFilter].forEach(function (el) {
if (el) el.dispatchEvent(new Event('change', { bubbles: true }));
});
// Persist filters including search
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var searchInput = document.getElementById('searchWarranties');
var filtersToSave = {
status: statusFilter ? statusFilter.value : 'all',
tag: tagFilter ? tagFilter.value : 'all',
vendor: vendorFilter ? vendorFilter.value : 'all',
warranty_type: warrantyTypeFilter ? warrantyTypeFilter.value : 'all',
search: searchInput ? searchInput.value : ''
};
localStorage.setItem(prefix + 'warrantyFilters', JSON.stringify(filtersToSave));
} catch (e) { /* no-op */ }
window.updateFilterIndicator();
if (filterPopover) filterPopover.classList.remove('active');
});
}
if (clearFiltersBtn) {
clearFiltersBtn.addEventListener('click', function () {
if (statusFilter) statusFilter.value = 'all';
if (tagFilter) tagFilter.value = 'all';
if (vendorFilter) vendorFilter.value = 'all';
if (warrantyTypeFilter) warrantyTypeFilter.value = 'all';
// Clear search field and its UI state
var searchInput = document.getElementById('searchWarranties');
var clearSearchBtn = document.getElementById('clearSearch');
if (searchInput) {
searchInput.value = '';
if (searchInput.parentElement) searchInput.parentElement.classList.remove('active-search');
}
if (clearSearchBtn) clearSearchBtn.style.display = 'none';
[statusFilter, tagFilter, vendorFilter, warrantyTypeFilter].forEach(function (el) {
if (el) el.dispatchEvent(new Event('change', { bubbles: true }));
});
// Clear persisted filter preferences on reset (including search and sort)
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
localStorage.removeItem(prefix + 'warrantyFilters');
localStorage.removeItem(prefix + 'warrantySortBy');
} catch (e) { /* no-op */ }
updateFilterIndicator();
if (filterPopover) filterPopover.classList.remove('active');
});
}
if (sortOptionsList) {
sortOptionsList.addEventListener('click', function (e) {
var li = e.target && e.target.closest('li[data-sort]');
if (!li) return;
Array.prototype.forEach.call(sortOptionsList.querySelectorAll('li'), function (n) { n.classList.remove('active'); });
li.classList.add('active');
if (sortBy) {
sortBy.value = li.getAttribute('data-sort');
sortBy.dispatchEvent(new Event('change', { bubbles: true }));
// Persist sort
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
localStorage.setItem(prefix + 'warrantySortBy', sortBy.value || 'expiration');
} catch (e) { /* no-op */ }
}
if (sortPopover) sortPopover.classList.remove('active');
});
}
// Initialize states
window.updateFilterIndicator();
if (sortBy && sortOptionsList) {
// Try to load saved sort preference
try {
var prefix = (window.getPreferenceKeyPrefix ? window.getPreferenceKeyPrefix() : 'user_');
var savedSort = localStorage.getItem(prefix + 'warrantySortBy');
if (savedSort) sortBy.value = savedSort;
} catch (e) { /* no-op */ }
var current = sortBy.value || 'expiration';
var activeLi = sortOptionsList.querySelector('li[data-sort="' + current + '"]');
if (activeLi) activeLi.classList.add('active');
}
});
</script>
<!-- Footer Width Fix -->
<script src="footer-fix.js?v=20251024001"></script>
<!-- Footer Content Manager -->
<script src="footer-content.js?v=20250119001"></script>
<!-- Powered by Warracker Footer -->
<footer class="warracker-footer" id="warrackerFooter">
<!-- Content will be dynamically generated by footer-content.js -->
</footer>
<script>
// Apply footer styles based on theme
function applyFooterStyles() {
const footer = document.getElementById('warrackerFooter');
const link = document.getElementById('warrackerFooterLink');
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark' ||
document.documentElement.classList.contains('dark-mode') ||
document.body.classList.contains('dark-mode');
if (footer) {
if (isDarkMode) {
// Dark mode styles - using same background as header (#2d2d2d)
footer.style.cssText = 'margin-top: 50px; padding: 20px; text-align: center; border-top: 1px solid #444; background-color: #2d2d2d; color: #e0e0e0; font-size: 0.9rem;';
if (link) link.style.cssText = 'color: #4dabf7; text-decoration: none; font-weight: 500;';
} else {
// Light mode styles - using same background as header (#ffffff)
footer.style.cssText = 'margin-top: 50px; padding: 20px; text-align: center; border-top: 1px solid #e0e0e0; background-color: #ffffff; color: #333333; font-size: 0.9rem;';
if (link) link.style.cssText = 'color: #3498db; text-decoration: none; font-weight: 500;';
}
}
}
// Apply styles when page loads
document.addEventListener('DOMContentLoaded', applyFooterStyles);
// Watch for theme changes
const observer = new MutationObserver(applyFooterStyles);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme', 'class']
});
// Also watch body for theme changes
observer.observe(document.body, {
attributes: true,
attributeFilter: ['class']
});
</script>
</body>
</html>