Files
comfyui-serverless/frontend/public/index.html
Debian 890543fb77
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Add frontend service with auth, MFA, and content management
- Node.js/Express backend with TypeScript
- SQLite database for users, sessions, and content metadata
- Authentication with TOTP and WebAuthn MFA support
- Admin user auto-created on first startup
- User content gallery with view/delete functionality
- RunPod API proxy (keeps API keys server-side)
- Docker setup with CI/CD for Gitea registry

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:57:08 +00:00

182 lines
9.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ComfyUI Video Generator</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div id="app">
<!-- Login Page -->
<div id="login-page" class="page">
<div class="auth-container">
<div class="auth-header">
<h1>ComfyUI Video Generator</h1>
<p>Sign in to continue</p>
</div>
<form id="login-form" class="auth-form">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" required autocomplete="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required autocomplete="current-password">
</div>
<button type="submit" class="btn btn-primary btn-block">Sign In</button>
</form>
<div id="login-error" class="error-message"></div>
</div>
</div>
<!-- MFA Page -->
<div id="mfa-page" class="page hidden">
<div class="auth-container">
<div class="auth-header">
<h1>Two-Factor Authentication</h1>
<p>Enter your verification code</p>
</div>
<div id="mfa-options">
<div id="totp-section" class="mfa-section hidden">
<form id="totp-form" class="auth-form">
<div class="form-group">
<label for="totp-code">Authenticator Code</label>
<input type="text" id="totp-code" name="code" pattern="[0-9]{6}" maxlength="6" required autocomplete="one-time-code" inputmode="numeric">
</div>
<button type="submit" class="btn btn-primary btn-block">Verify</button>
</form>
</div>
<div id="webauthn-section" class="mfa-section hidden">
<button id="webauthn-btn" class="btn btn-secondary btn-block">Use Security Key</button>
</div>
</div>
<div id="mfa-error" class="error-message"></div>
<button id="mfa-back" class="btn btn-link">Back to Login</button>
</div>
</div>
<!-- Main App -->
<div id="main-page" class="page hidden">
<nav class="navbar">
<div class="navbar-brand">ComfyUI Video Generator</div>
<div class="navbar-menu">
<a href="#" class="nav-link active" data-page="generate">Generate</a>
<a href="#" class="nav-link" data-page="gallery">My Videos</a>
<a href="#" class="nav-link admin-only hidden" data-page="admin">Admin</a>
<div class="navbar-user">
<span id="current-user"></span>
<button id="logout-btn" class="btn btn-sm">Logout</button>
</div>
</div>
</nav>
<main class="main-content">
<!-- Generate Section -->
<section id="generate-section" class="content-section">
<div class="section-grid">
<div class="card">
<h2>Input Image</h2>
<div class="file-upload" id="image-upload-area">
<input type="file" id="image-input" accept="image/*">
<label for="image-input" class="file-upload-label">
<span class="upload-icon">+</span>
<span class="upload-text">Click or drag to upload</span>
</label>
<img id="preview-image" class="preview-image hidden" alt="Preview">
</div>
</div>
<div class="card">
<h2>Generation Settings</h2>
<form id="generate-form">
<div class="form-group">
<label for="prompt">Prompt</label>
<textarea id="prompt" name="prompt" rows="3" required placeholder="Describe the motion you want..."></textarea>
</div>
<div class="form-group">
<label for="negative-prompt">Negative Prompt</label>
<textarea id="negative-prompt" name="negativePrompt" rows="2" placeholder="What to avoid...">blurry, low quality, distorted</textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="resolution">Resolution</label>
<select id="resolution" name="resolution">
<option value="480">480p</option>
<option value="720" selected>720p</option>
<option value="1080">1080p</option>
</select>
</div>
<div class="form-group">
<label for="steps">Steps</label>
<input type="number" id="steps" name="steps" value="8" min="1" max="50">
</div>
</div>
<button type="submit" class="btn btn-primary btn-block" id="generate-btn">Generate Video</button>
</form>
</div>
<div class="card full-width">
<h2>Output</h2>
<div id="output-container">
<div id="generation-status" class="status-message hidden"></div>
<video id="output-video" class="output-video hidden" controls loop></video>
</div>
</div>
</div>
</section>
<!-- Gallery Section -->
<section id="gallery-section" class="content-section hidden">
<div class="section-header">
<h2>My Videos</h2>
<div class="filter-group">
<select id="status-filter">
<option value="">All Status</option>
<option value="completed">Completed</option>
<option value="processing">Processing</option>
<option value="pending">Pending</option>
<option value="failed">Failed</option>
</select>
</div>
</div>
<div id="gallery-grid" class="gallery-grid"></div>
<div id="gallery-pagination" class="pagination"></div>
</section>
<!-- Admin Section -->
<section id="admin-section" class="content-section hidden">
<div class="admin-tabs">
<button class="tab-btn active" data-tab="users">Users</button>
<button class="tab-btn" data-tab="all-content">All Content</button>
</div>
<div id="users-tab" class="admin-tab">
<div class="section-header">
<h2>User Management</h2>
<button id="add-user-btn" class="btn btn-primary">Add User</button>
</div>
<div id="users-list" class="users-list"></div>
</div>
<div id="all-content-tab" class="admin-tab hidden">
<div class="section-header">
<h2>All Content</h2>
</div>
<div id="admin-gallery-grid" class="gallery-grid"></div>
<div id="admin-gallery-pagination" class="pagination"></div>
</div>
</section>
</main>
</div>
<!-- Modals -->
<div id="modal-overlay" class="modal-overlay hidden">
<div id="modal-content" class="modal-content"></div>
</div>
</div>
<script src="/js/app.js"></script>
</body>
</html>