feat(UI): initial working frontend UI
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Authentication Failed - BDFR Web Interface</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.error-container {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
}
|
||||
.error-icon {
|
||||
font-size: 3rem;
|
||||
color: #f44336;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.error-title {
|
||||
color: #333;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.error-message {
|
||||
color: #666;
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.error-details {
|
||||
background: #f5f5f5;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 0.8rem;
|
||||
color: #888;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
.retry-button {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin-top: 1rem;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
.retry-button:hover {
|
||||
background: #5a67d8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error-container">
|
||||
<div class="error-icon">❌</div>
|
||||
<h1 class="error-title">Authentication Failed</h1>
|
||||
<p class="error-message">
|
||||
There was an error during the authentication process. This might be due to:
|
||||
</p>
|
||||
<ul style="text-align: left; color: #666; margin: 1rem 0;">
|
||||
<li>Invalid or expired authorization code</li>
|
||||
<li>Mismatched redirect URI configuration</li>
|
||||
<li>Reddit OAuth app not properly configured</li>
|
||||
</ul>
|
||||
<div class="error-details">{{ error }}</div>
|
||||
<a href="/?auth_error=true" class="retry-button">Return to Main Page</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Authentication Successful - BDFR Web Interface</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.success-container {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
}
|
||||
.success-icon {
|
||||
font-size: 3rem;
|
||||
color: #4CAF50;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.success-title {
|
||||
color: #333;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.success-message {
|
||||
color: #666;
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.redirect-message {
|
||||
color: #888;
|
||||
font-size: 0.9rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.spinner {
|
||||
border: 3px solid #f3f3f3;
|
||||
border-top: 3px solid #667eea;
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 1rem;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="success-container">
|
||||
<div class="success-icon">✅</div>
|
||||
<h1 class="success-title">Authentication Successful!</h1>
|
||||
<p class="success-message">
|
||||
You have successfully authenticated with Reddit. You can now use all features of the BDFR Web Interface.
|
||||
</p>
|
||||
<div class="spinner"></div>
|
||||
<p class="redirect-message">
|
||||
Redirecting you back to the main interface...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Redirect to main page after 3 seconds
|
||||
setTimeout(function() {
|
||||
window.location.href = '/?authenticated=true';
|
||||
}, 3000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,209 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>BDFR Web Interface</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Bulk Downloader for Reddit</h1>
|
||||
<p class="subtitle">Web Interface</p>
|
||||
|
||||
<!-- Authentication Status -->
|
||||
<div id="authSection" class="auth-section" style="display: none;">
|
||||
<div class="auth-status">
|
||||
<div class="auth-info">
|
||||
<span class="auth-label">Reddit Account:</span>
|
||||
<span id="authUser" class="auth-user">-</span>
|
||||
<span id="authStatus" class="auth-status-indicator">🔴 Not Connected</span>
|
||||
</div>
|
||||
<div class="auth-actions">
|
||||
<button id="loginBtn" class="btn btn-small btn-outline">🔐 Login with Reddit</button>
|
||||
<button id="logoutBtn" class="btn btn-small btn-outline" style="display: none;">🚪 Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- Unified Download Form Section -->
|
||||
<section class="download-section">
|
||||
<div class="form-container-unified">
|
||||
<div class="form-card-unified">
|
||||
<h2>📥 Download Reddit Content</h2>
|
||||
<form id="unifiedForm" class="download-form">
|
||||
<!-- Mode Selection -->
|
||||
<div class="form-section mode-section">
|
||||
<h4>🎯 Download Mode</h4>
|
||||
<div class="radio-group mode-radio-group">
|
||||
<label class="radio-label mode-option" data-tooltip="Download media files (images, videos, gifs) from posts">
|
||||
<input type="radio" name="download_mode" value="download" checked>
|
||||
<span class="radio-custom"></span>
|
||||
<span class="mode-label">
|
||||
<strong>Download</strong>
|
||||
<small>Media files only</small>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio-label mode-option" data-tooltip="Save post metadata (title, author, comments) as JSON/XML without downloading media">
|
||||
<input type="radio" name="download_mode" value="archive">
|
||||
<span class="radio-custom"></span>
|
||||
<span class="mode-label">
|
||||
<strong>Archive</strong>
|
||||
<small>Metadata only</small>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio-label mode-option" data-tooltip="Download media files AND save metadata - complete backup of posts">
|
||||
<input type="radio" name="download_mode" value="clone">
|
||||
<span class="radio-custom"></span>
|
||||
<span class="mode-label">
|
||||
<strong>Clone</strong>
|
||||
<small>Media + Metadata</small>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source Type Selection -->
|
||||
<div class="form-section">
|
||||
<h4>📍 Source Type</h4>
|
||||
<div class="radio-group">
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="source_type" value="subreddit" checked>
|
||||
<span class="radio-custom"></span>
|
||||
Subreddit
|
||||
</label>
|
||||
<label class="radio-label">
|
||||
<input type="radio" name="source_type" value="user">
|
||||
<span class="radio-custom"></span>
|
||||
User
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source Name Input -->
|
||||
<div class="form-group">
|
||||
<label for="sourceName" id="sourceNameLabel">Subreddit Name:</label>
|
||||
<input type="text" id="sourceName" name="source_name" placeholder="e.g., python, machinelearning" required>
|
||||
<small class="form-help" id="sourceNameHelp">Enter subreddit name without 'r/'</small>
|
||||
</div>
|
||||
|
||||
<!-- Filter Options -->
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="limit">Limit:</label>
|
||||
<input type="number" id="limit" name="limit" value="25" min="1" max="1000">
|
||||
<small class="form-help">Max posts to process (1-1000)</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sort">Sort by:</label>
|
||||
<select id="sort" name="sort">
|
||||
<option value="hot">Hot</option>
|
||||
<option value="top" selected>Top</option>
|
||||
<option value="new">New</option>
|
||||
<option value="rising">Rising</option>
|
||||
<option value="controversial">Controversial</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="timeFilter">Time Filter:</label>
|
||||
<select id="timeFilter" name="time_filter">
|
||||
<option value="">All Time</option>
|
||||
<option value="hour">Past Hour</option>
|
||||
<option value="day">Past Day</option>
|
||||
<option value="week">Past Week</option>
|
||||
<option value="month">Past Month</option>
|
||||
<option value="year">Past Year</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="minScore">Min Score:</label>
|
||||
<input type="number" id="minScore" name="min_score" value="" placeholder="0">
|
||||
<small class="form-help">Minimum upvotes</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Options -->
|
||||
<div class="form-section">
|
||||
<h4>⚙️ Advanced Options</h4>
|
||||
<div class="checkbox-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="noDupes" name="no_dupes">
|
||||
<span class="checkmark"></span>
|
||||
Avoid Duplicates
|
||||
</label>
|
||||
|
||||
<label class="checkbox-label" style="margin-left: 30px; font-size: 0.9em;">
|
||||
<input type="checkbox" id="simpleCheck" name="simple_check">
|
||||
<span class="checkmark"></span>
|
||||
Use Simple Check (faster URL-based detection)
|
||||
</label>
|
||||
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="makeHardLinks" name="make_hard_links">
|
||||
<span class="checkmark"></span>
|
||||
Create Hard Links
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="authState" name="auth_state" value="">
|
||||
<button type="submit" class="btn btn-primary">🚀 Start Download</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Progress Section -->
|
||||
<section class="progress-section">
|
||||
<h2>📊 Download Progress</h2>
|
||||
<div id="progressContainer" class="progress-container">
|
||||
<div class="no-downloads">
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon">📥</div>
|
||||
<p>No active downloads</p>
|
||||
<p>Start a download above to see progress here.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Active Downloads List -->
|
||||
<div id="downloadsList" class="downloads-list" style="display: none;">
|
||||
<div class="downloads-header">
|
||||
<h3>Active Downloads</h3>
|
||||
</div>
|
||||
<div id="downloadsItems" class="downloads-items"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Status Section -->
|
||||
<section class="status-section">
|
||||
<div class="status-card">
|
||||
<h3>System Status</h3>
|
||||
<div class="status-item">
|
||||
<span class="status-label">BDFR Status:</span>
|
||||
<span id="bdfrStatus" class="status-value">Checking...</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-label">WebSocket:</span>
|
||||
<span id="wsStatus" class="status-value">Disconnected</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 BDFR Web Interface. Powered by FastAPI.</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user