SirMeowManager / index.html
NikaMimi's picture
Upload index.html
45bd449 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CatGPT Model Manager</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="/static/styles.css" rel="stylesheet">
</head>
<body>
<div class="app">
<!-- Header -->
<header class="header">
<div class="container">
<div class="header-content">
<div class="logo">
<i class="fa-solid fa-paw"></i>
<h1>CatGPT Model Manager</h1>
</div>
<div class="header-stats">
<button class="logout-btn" id="logoutBtn" title="Logout" onclick="modelManager.logout()">
<i class="fas fa-sign-out-alt"></i>
</button>
<button class="theme-toggle" id="themeToggle" title="Toggle dark mode">
<i class="fas fa-moon" id="themeIcon"></i>
</button>
<button class="activity-logs-btn" id="activityLogsBtn" title="View activity logs">
<i class="fa-solid fa-scroll"></i>
</button>
<button class="bot-management-btn" id="botManagementBtn" title="Bot management">
<i class="fa-solid fa-shield-cat"></i>
</button>
<div class="stat-card">
<span class="stat-value" id="totalModels">0</span>
<span class="stat-label">Models</span>
</div>
<div class="stat-card">
<span class="stat-value" id="activeModels">0</span>
<span class="stat-label">Gen Ready</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="main">
<div class="container">
<!-- Category Tabs -->
<div class="tabs">
<button class="tab-button active" data-category="pony">
<i class="fas fa-horse"></i>
<span>Pony Models</span>
<span class="badge" id="ponyCount">0</span>
</button>
<button class="tab-button" data-category="illustrious">
<i class="fas fa-palette"></i>
<span>Illustrious Models</span>
<span class="badge" id="illustriousCount">0</span>
</button>
<button class="tab-button" data-category="sdxl">
<i class="fas fa-image"></i>
<span>SDXL Models</span>
<span class="badge" id="sdxlCount">0</span>
</button>
</div>
<!-- Tab Content -->
<div class="tab-content">
<!-- Add Model Form -->
<div class="add-model-section">
<div class="section-header">
<h2><i class="fas fa-plus-circle"></i> Add New Model</h2>
</div>
<form class="add-model-form" id="addModelForm">
<div class="form-row form-row-single">
<div class="form-group">
<label for="displayName">Display Name</label>
<input type="text" id="displayName" name="displayName" placeholder="e.g., Pony Diffusion V6" required>
</div>
<div class="form-group">
<label for="urn">URN</label>
<input type="text" id="urn" name="urn" placeholder="e.g., @cf/bytedance/stable-diffusion-xl-lightning" required>
</div>
<div class="form-group form-buttons">
<label>&nbsp;</label>
<div class="button-group">
<button type="submit" class="btn btn-primary">
<i class="fas fa-plus"></i>
Add Model
</button>
<button type="button" class="btn btn-outline" id="browseModelBtn" disabled title="Coming soon when Civitai fixes their shit">
<i class="fas fa-search"></i>
Browse
</button>
</div>
</div>
</div>
</form>
</div>
<!-- Models List -->
<div class="models-section">
<div class="section-header">
<h2><i class="fas fa-list"></i> Models (<span id="currentCategory">Pony</span>)</h2>
</div>
<div class="image-filters">
<div class="filter-group">
<label for="modelSortFilter">Sort Models:</label>
<select id="modelSortFilter" class="filter-select">
<option value="displayName-asc">Display Name (A-Z)</option>
<option value="displayName-desc">Display Name (Z-A)</option>
<option value="generation-yes">Onsite Gen (Yes First)</option>
<option value="generation-no">Onsite Gen (No First)</option>
</select>
</div>
<div class="filter-group">
<label for="sortFilter">Sort Images:</label>
<select id="sortFilter" class="filter-select">
<option value="Most Reactions">Most Reactions</option>
<option value="Most Comments">Most Comments</option>
<option value="Newest">Newest</option>
</select>
</div>
<div class="filter-group">
<label for="nsfwFilter">NSFW:</label>
<select id="nsfwFilter" class="filter-select">
<option value="None">None</option>
<option value="Soft">Soft</option>
<option value="Mature">Mature</option>
<option value="X">X</option>
</select>
</div>
<div class="filter-group">
<label for="periodFilter">Period:</label>
<select id="periodFilter" class="filter-select">
<option value="AllTime">All Time</option>
<option value="Year">Year</option>
<option value="Month">Month</option>
<option value="Week">Week</option>
<option value="Day">Day</option>
</select>
</div>
<button class="btn btn-outline btn-icon" id="refreshBtn" title="Refresh models">
<i class="fas fa-sync-alt"></i>
</button>
<button class="btn btn-danger" id="bulkDeleteBtn" title="Delete all models that don't support generation">
<i class="fas fa-trash-alt"></i>
Delete No-Gen
</button>
</div>
<div class="models-grid" id="modelsGrid">
<!-- Models will be loaded here -->
</div>
<div class="empty-state" id="emptyState" style="display: none;">
<i class="fas fa-inbox"></i>
<h3>No models found</h3>
<p>Add your first model using the form above.</p>
</div>
</div>
<!-- Activity Logs Section -->
<div class="logs-section" id="logsSection" style="display: none;">
<div class="section-header">
<h2><i class="fa-solid fa-scroll"></i> Activity Logs</h2>
<div class="logs-controls">
<select id="logFilter" class="filter-select">
<option value="all">All Actions</option>
<option value="added">Added</option>
<option value="edited">Edited</option>
<option value="deleted">Deleted</option>
<option value="bulk_deleted">Bulk Deleted</option>
</select>
<select id="categoryLogFilter" class="filter-select">
<option value="all">All Categories</option>
<option value="pony">Pony</option>
<option value="illustrious">Illustrious</option>
<option value="sdxl">SDXL</option>
</select>
<button class="btn btn-outline" id="refreshLogsBtn">
<i class="fas fa-sync-alt"></i>
Refresh
</button>
</div>
</div>
<div class="logs-table-container">
<table class="logs-table" id="logsTable">
<thead>
<tr>
<th>Timestamp</th>
<th>Action</th>
<th>Category</th>
<th>Display Name</th>
<th>URN</th>
<th>URL</th>
</tr>
</thead>
<tbody id="logsTableBody">
<!-- Logs will be loaded here -->
</tbody>
</table>
</div>
<div class="empty-state" id="emptyLogsState" style="display: none;">
<i class="fas fa-history"></i>
<h3>No activity logs found</h3>
<p>Model actions will appear here once they occur.</p>
</div>
</div>
<!-- Bot Management Section -->
<div class="management-section" id="managementSection" style="display: none;">
<div class="section-header">
<h2><i class="fas fa-cogs"></i> Discord Bot Management</h2>
</div>
<!-- Configuration Section -->
<div class="config-section">
<div class="config-card">
<div class="config-header">
<h3><i class="fas fa-cog"></i> Discord Bot Configuration</h3>
</div>
<div class="config-body">
<p>Configure Discord bot management API (stored securely in Firebase):</p>
<div class="config-form">
<label class="config-label">Bot API URL:</label>
<input type="url" id="botApiUrlInput" placeholder="http://YOUR_BOT_IP:8080" class="api-url-input">
</div>
<div class="config-form">
<label class="config-label">Discord Admin Key:</label>
<input type="password" id="discordAdminKeyInput" placeholder="Enter Discord admin key" class="api-url-input">
</div>
<div class="config-form">
<button class="btn btn-outline" id="testBotApiUrl">
<i class="fas fa-wifi"></i>
Test and Save
</button>
</div>
<div class="config-status" id="configStatus">
<span class="status-text">Not configured</span>
</div>
</div>
</div>
</div>
<div class="management-controls">
<div class="management-card">
<div class="card-header">
<h3><i class="fas fa-power-off"></i> Load Models and Restart Bot</h3>
</div>
<div class="card-body">
<p>Restart the Discord bot to reload all model configurations and apply changes.</p>
<button class="btn btn-danger management-btn" id="restartBotBtn">
<i class="fas fa-power-off"></i>
Load Models and Restart Bot
</button>
<div class="status-indicator" id="botStatus">
<span class="status-text">Ready</span>
</div>
</div>
</div>
<div class="management-card">
<div class="card-header">
<h3><i class="fas fa-info-circle"></i> Bot Status</h3>
</div>
<div class="card-body">
<p>Check current Discord bot connection and Firebase status.</p>
<button class="btn btn-outline management-btn" id="checkStatusBtn">
<i class="fas fa-info-circle"></i>
Check Status
</button>
<div class="status-display" id="statusDisplay">
<div class="status-item">
<span class="status-label">Bot Connected:</span>
<span class="status-value" id="botConnected">Unknown</span>
</div>
<div class="status-item">
<span class="status-label">Firebase Status:</span>
<span class="status-value" id="firebaseStatus">Unknown</span>
</div>
<div class="status-item">
<span class="status-label">Last Check:</span>
<span class="status-value" id="lastCheck">Never</span>
</div>
</div>
</div>
</div>
</div>
<div class="management-info">
<div class="info-card">
<h4><i class="fas fa-lightbulb"></i> Usage Instructions</h4>
<ul>
<li><strong>Load Models and Restart Bot:</strong> Use this after adding/editing models to reload all configurations and apply changes.</li>
<li><strong>Check Status:</strong> Monitor bot health and Firebase connectivity.</li>
</ul>
</div>
<div class="info-card">
<h4><i class="fas fa-terminal"></i> Alternative Commands</h4>
<p>You can also use this Discord slash command directly:</p>
<code>/restart_bot</code> - Restart the bot
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Loading Overlay -->
<div class="loading-overlay" id="loadingOverlay">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
<span>Loading...</span>
</div>
</div>
<!-- Toast Notifications -->
<div class="toast-container" id="toastContainer"></div>
<!-- Edit Model Modal -->
<div class="modal-overlay" id="modalOverlay">
<div class="modal">
<div class="modal-header">
<h3><i class="fas fa-edit"></i> Edit Model</h3>
<button class="modal-close" id="modalClose">
<i class="fas fa-times"></i>
</button>
</div>
<div class="modal-body">
<form id="editModelForm">
<div class="form-group">
<label for="editDisplayName">Display Name</label>
<input type="text" id="editDisplayName" name="displayName" required>
</div>
<div class="form-group">
<label for="editUrn">URN</label>
<input type="text" id="editUrn" name="urn" required>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-outline" id="modalCancel">Cancel</button>
<button class="btn btn-primary" id="modalSave">
<i class="fas fa-save"></i>
Save Changes
</button>
</div>
</div>
</div>
</div>
<!-- Browse Models Modal -->
<div class="modal-overlay" id="browseModelsModal">
<div class="modal modal-large">
<div class="modal-header">
<h3><i class="fas fa-search"></i> Browse Models</h3>
<button class="modal-close" id="browseModalsClose">
<i class="fas fa-times"></i>
</button>
</div>
<div class="modal-body">
<div class="browse-controls">
<div class="search-filters">
<div class="filter-group">
<input type="text" id="modelSearchInput" placeholder="Search models..." class="search-input">
</div>
<div class="filter-group">
<select id="sortModelsSelect" class="filter-select">
<option value="Newest">Newest</option>
<option value="Most Downloaded">Most Downloaded</option>
<option value="Highest Rated">Highest Rated</option>
<option value="Most Liked">Most Liked</option>
</select>
</div>
<div class="filter-group">
<select id="nsfwLevelSelect" class="filter-select">
<option value="None">SFW Only</option>
<option value="Soft">Include Soft</option>
<option value="Mature">Include Mature</option>
<option value="X">Include All</option>
</select>
</div>
<button class="btn btn-primary" id="searchModelsBtn">
<i class="fas fa-search"></i>
Search
</button>
</div>
</div>
<div class="browse-results">
<div class="loading-message" id="browseLoading" style="display: none;">
<i class="fas fa-spinner fa-spin"></i>
<span>Loading models...</span>
</div>
<div class="browse-models-grid" id="browseModelsGrid">
<!-- Models will be loaded here -->
</div>
<div class="browse-pagination" id="browsePagination" style="display: none;">
<button class="btn btn-outline" id="prevPageBtn" disabled>
<i class="fas fa-chevron-left"></i>
Previous
</button>
<span class="page-info" id="pageInfo">Page 1 of 1</span>
<button class="btn btn-outline" id="nextPageBtn">
Next
<i class="fas fa-chevron-right"></i>
</button>
</div>
<div class="empty-browse-state" id="emptyBrowseState" style="display: none;">
<i class="fas fa-search"></i>
<h3>No models found</h3>
<p>Try adjusting your search criteria.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Login Modal -->
<div class="modal-overlay" id="loginModal">
<div class="modal">
<div class="modal-header">
<h3><i class="fas fa-lock"></i> Admin Login</h3>
<button class="modal-close" id="loginModalClose">
<i class="fas fa-times"></i>
</button>
</div>
<div class="modal-body">
<form id="loginForm">
<div class="form-group">
<label for="adminKey">Admin Key</label>
<input type="password" id="adminKey" name="adminKey" required placeholder="Enter admin key">
</div>
<div id="loginError" class="error-message" style="display: none;"></div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" id="loginSubmit">
<i class="fas fa-sign-in-alt"></i>
Login
</button>
</div>
</div>
</div>
<footer class="app-footer">
<p>For aRfy's Cat Bot</p>
</footer>
<script src="/static/app.js"></script>
</body>
</html>