new dashboard page

This commit is contained in:
2025-12-31 21:51:17 +01:00
parent c9c4cc074c
commit 20ea5bee9c
14 changed files with 2261 additions and 3425 deletions

View File

@@ -13,6 +13,7 @@
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon">
</head>
<body>
<div class="hero-wrapper">
<div class="hero-background">
<img id="hero-bg-media" alt="">
@@ -103,45 +104,6 @@
</section>
</main>
<!-- Local Library Mode Content -->
<main id="local-content" class="hidden">
<section class="section">
<div class="section-header">
<div class="section-title">Local Anime Library</div>
<button class="btn-secondary" onclick="scanLocalLibrary()">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M21 12a9 9 0 1 1-9-9"/>
<path d="M21 3v6h-6"/>
</svg>
<span id="scan-text">Scan Library</span>
</button>
</div>
<div class="local-filters">
<div class="filter-group">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="watching">Watching</button>
<button class="filter-btn" data-filter="completed">Completed</button>
<button class="filter-btn" data-filter="unwatched">Unwatched</button>
<button class="filter-btn" data-filter="unlinked">Unlinked</button>
</div>
<div class="filter-group">
<button class="filter-btn" data-sort="az">AZ</button>
<button class="filter-btn" data-sort="recent">Recent</button>
</div>
</div>
<div class="local-library-grid" id="local-entries-grid">
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
</div>
</section>
</main>
<div id="updateToast" class="hidden">
<p>Update available: <span id="latestVersionDisplay">v1.x</span></p>
@@ -156,8 +118,8 @@
<script src="/src/scripts/utils/continue-watching-manager.js"></script>
<script src="/src/scripts/utils/youtube-player-utils.js"></script>
<script src="/src/scripts/anime/animes.js"></script>
<script src="/src/scripts/local-library.js"></script>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/rpc-inapp.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
<script src="/src/scripts/settings.js"></script>
</body>

View File

@@ -37,39 +37,7 @@
</div>
</div>
</div>
<button class="library-mode-btn icon-only" id="library-mode-btn" onclick="toggleLibraryMode()" title="Switch library mode">
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>
</button>
</div>
<main id="local-content" class="hidden">
<section class="section">
<div class="section-header">
<div class="section-title">Local Books Library</div>
<button class="btn-secondary" onclick="scanLocalLibrary()">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M21 12a9 9 0 1 1-9-9"/><path d="M21 3v6h-6"/>
</svg>
<span id="scan-text">Scan Library</span>
</button>
</div>
<div class="local-filters">
<div class="filter-group">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="unlinked">Unlinked</button>
</div>
<div class="filter-group">
<button class="filter-btn" data-sort="az">AZ</button>
</div>
</div>
<div class="local-library-grid" id="local-entries-grid">
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
</div>
</section>
</main>
<main id="online-content">
<section class="section">
<div class="section-header">
@@ -119,7 +87,6 @@
<script src="/src/scripts/utils/list-modal-manager.js"></script>
<script src="/src/scripts/utils/continue-watching-manager.js"></script>
<script src="/src/scripts/books/books.js"></script>
<script src="/src/scripts/local-library-books.js"></script>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
</body>

File diff suppressed because it is too large Load Diff

View File

@@ -10,31 +10,14 @@
<link rel="stylesheet" href="/views/css/components/anilist-modal.css">
<link rel="stylesheet" href="/views/css/dashboard.css">
<link rel="stylesheet" href="/views/css/components/updateNotifier.css">
<link rel="stylesheet" href="/views/css/components/titlebar.css">
<script src="/src/scripts/titlebar.js"></script>
</head>
<body>
<div id="titlebar">
<div class="title-left">
<img class="app-icon" src="/public/assets/waifuboards.ico" alt=""/>
<span class="app-title">WaifuBoard</span>
</div>
<div class="title-right">
<button class="min"></button>
<button class="max">🗖</button>
<button class="close"></button>
</div>
</div>
<div class="main-wrapper">
<section class="profile-header">
<div class="profile-banner"></div> <div class="profile-body">
<div class="profile-avatar-wrapper">
<img id="user-avatar" src="/public/assets/placeholder.svg" alt="Profile" class="avatar-img">
<label for="avatar-upload" class="avatar-edit-overlay">
<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/><path d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
</label>
<input type="file" id="avatar-upload" accept="image/*" style="display: none;">
</div>
<div class="profile-details">
@@ -77,7 +60,8 @@
<div class="toolbar">
<div class="search-box">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
<input type="text" class="search-input" placeholder="Search your list...">
<input type="text" id="tracking-search-input" class="search-input" placeholder="Search your list...">
</div>
<div class="filters-inline">
<select id="status-filter" class="minimal-select"><option value="all">Status: All</option><option value="CURRENT">Watching</option><option value="COMPLETED">Completed</option><option value="PLANNING">Planning</option><option value="PAUSED">Paused</option><option value="DROPPED">Dropped</option></select>
@@ -98,81 +82,100 @@
</div>
<div id="section-local" class="tab-section">
<div class="section-header-row">
<h2>Local Library</h2>
<div class="actions">
<button id="scan-incremental-btn" class="btn-primary">Update Library</button>
<button id="scan-full-btn" class="btn-blur">Full Rescan</button>
<div class="toolbar local-toolbar">
<div class="search-box">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
<input type="text" id="local-search-input" class="search-input" placeholder="Filter local files...">
</div>
<div class="local-type-switcher">
<button class="type-pill-btn active" onclick="switchLocalType('anime', this)">Anime</button>
<button class="type-pill-btn" onclick="switchLocalType('manga', this)">Manga</button>
<button class="type-pill-btn" onclick="switchLocalType('novels', this)">Novels</button>
</div>
<div class="actions-group">
<button id="scan-incremental-btn" class="action-icon-btn" title="Update Library (Fast)">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
</button>
<button id="scan-full-btn" class="action-icon-btn danger" title="Full Rescan (Slow)">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
</button>
</div>
</div>
<div class="local-stats-grid">
<div class="local-card"><h3>Anime Files</h3><p id="local-anime-count">0</p></div>
<div class="local-card"><h3>Manga Files</h3><p id="local-manga-count">0</p></div>
<div class="local-card"><h3>Novel Files</h3><p id="local-novel-count">0</p></div>
</div>
<div class="console-output" id="scan-console" style="display: none;">
<div class="spinner small"></div> <span id="scan-status-text">Scanning...</span>
<div class="spinner small"></div>
<span id="scan-status-text">Scanning folders...</span>
</div>
<div id="local-list-container" class="list-grid"></div>
<div id="local-loading" class="loading-state" style="display: none;">
<div class="spinner"></div>
</div>
</div>
<div id="section-settings" class="tab-section">
<div class="settings-layout">
<div class="settings-card">
<h3>Edit Profile</h3>
<form id="profile-form">
<div class="form-group">
<label>Display Name</label>
<input type="text" id="setting-username" class="input-modern" placeholder="Username">
<div class="stream-settings-container">
<div class="stream-section">
<h3 class="section-label">Profile</h3>
<form id="profile-form" class="stream-profile-row">
<div class="stream-avatar-wrapper">
<img id="setting-avatar-preview" src="/public/assets/placeholder.svg" alt="Avatar">
<div class="avatar-overlay" onclick="document.getElementById('avatar-upload').click()">
<span>Edit</span>
</div>
<input type="file" id="avatar-upload" accept="image/*" style="display: none;">
</div>
<div class="form-group">
<label>Avatar Source</label>
<div class="avatar-options">
<button type="button" class="btn-secondary small" onclick="document.getElementById('avatar-upload').click()">Upload File</button>
<span class="divider-text">OR</span>
<input type="text" id="setting-avatar-url" class="input-modern" placeholder="Paste Image URL (https://...)">
<div class="stream-inputs-col">
<div class="stream-input-group">
<label>Username</label>
<input type="text" id="setting-username" class="stream-input">
</div>
<div class="stream-actions">
<button type="submit" class="btn-stream-primary">Submit</button>
</div>
<small style="color: var(--color-text-muted); display:block; margin-top:5px;">
* If you upload a file, it will be converted automatically. The text box above is only for external URLs.
</small>
</div>
<button type="submit" class="btn-primary full-width">Save Profile Changes</button>
</form>
</div>
<div class="settings-stack">
<div class="settings-card">
<h3>Security</h3>
<form id="password-form">
<div class="form-group">
<label>Current Password</label>
<input type="password" id="current-password" class="input-modern" placeholder="••••••">
</div>
<div class="form-group">
<label>New Password</label>
<input type="password" id="new-password" class="input-modern" placeholder="••••••">
</div>
<button type="submit" class="btn-blur full-width">Update Password</button>
</form>
</div>
<div class="settings-card">
<h3>Integrations</h3>
<div class="integration-item">
<div class="int-icon anilist-bg"><img src="https://anilist.co/img/icons/android-chrome-512x512.png" alt="AL"></div>
<div class="int-details">
<strong>AniList</strong>
<span id="anilist-status">Checking...</span>
</div>
<button id="anilist-action-btn" class="btn-sm">Connect</button>
<div class="stream-section">
<h3 class="section-label">Change password</h3>
<form id="password-form" class="stream-form-row">
<div class="stream-input-group">
<label>Current password</label>
<input type="password" id="current-password" class="stream-input" placeholder="••••••">
</div>
</div>
<div class="stream-input-group">
<label>New password</label>
<input type="password" id="new-password" class="stream-input" placeholder="••••••">
</div>
<div class="stream-actions-inline">
<button type="submit" class="btn-stream-ghost">Update password</button>
</div>
</form>
</div>
<div class="settings-card danger-zone">
<h3>Danger Zone</h3>
<button id="logout-btn" class="btn-danger">Log Out</button>
<div class="stream-section">
<h3 class="section-label">Connections</h3>
<div class="stream-integration-row">
<div class="int-info">
<img src="https://anilist.co/img/icons/android-chrome-512x512.png" alt="AL" class="int-logo">
<div class="int-text">
<span class="int-name">AniList</span>
<span id="anilist-status" class="int-status">Checking...</span>
</div>
</div>
<button id="anilist-action-btn" class="btn-stream-outline">Manage</button>
</div>
</div>
</div>
</div>