Settings page

This commit is contained in:
Greg Shuflin 2025-02-16 00:42:02 -08:00
parent d3ebd66c9a
commit 9f3f5c28be
6 changed files with 270 additions and 0 deletions

View File

@ -71,6 +71,11 @@ fn login(demo_mode: &State<bool>) -> Template {
Template::render("login", context! { demo_mode: **demo_mode }) Template::render("login", context! { demo_mode: **demo_mode })
} }
#[get("/settings")]
fn settings(_user: AuthenticatedUser) -> Template {
Template::render("settings", context! {})
}
// Run migrations and setup demo data if needed // Run migrations and setup demo data if needed
async fn setup_database(demo: bool, rocket: Rocket<Build>) -> fairing::Result { async fn setup_database(demo: bool, rocket: Rocket<Build>) -> fairing::Result {
let db = match Db::fetch(&rocket) { let db = match Db::fetch(&rocket) {
@ -150,6 +155,7 @@ fn rocket() -> _ {
index, index,
index_redirect, index_redirect,
login, login,
settings,
user::create_user, user::create_user,
user::get_users, user::get_users,
user::delete_user, user::delete_user,

View File

@ -0,0 +1,163 @@
.settings-container {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
min-height: 100vh;
background-color: var(--dark-bg);
}
.settings-header {
display: flex;
align-items: center;
margin-bottom: 2rem;
gap: 2rem;
}
.settings-header h1 {
margin: 0;
color: var(--text-color);
font-size: 1.8rem;
}
.back-button {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-color);
text-decoration: none;
padding: 0.5rem;
border-radius: 4px;
transition: background-color 0.2s ease;
}
.back-button:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.settings-content {
background-color: var(--sidebar-bg);
border-radius: 8px;
padding: 2rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.settings-section {
margin-bottom: 3rem;
}
.settings-section:last-child {
margin-bottom: 0;
}
.settings-section h2 {
color: var(--text-color);
font-size: 1.4rem;
margin: 0 0 1.5rem 0;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
gap: 0.75rem;
}
.settings-section h2 i {
color: var(--primary-red);
}
.settings-group {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.setting-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background-color: var(--dark-bg);
border-radius: 6px;
gap: 2rem;
}
.setting-info {
flex: 1;
}
.setting-info h3 {
color: var(--text-color);
margin: 0 0 0.5rem 0;
font-size: 1.1rem;
}
.setting-info p {
color: var(--text-muted);
margin: 0;
font-size: 0.9rem;
}
.setting-control {
position: relative;
min-width: 200px;
display: flex;
align-items: center;
gap: 1rem;
}
.setting-control select,
.setting-control input {
width: 100%;
padding: 0.5rem;
background-color: var(--sidebar-bg);
border: 1px solid var(--text-muted);
border-radius: 4px;
color: var(--text-color);
}
.setting-control select:disabled,
.setting-control input:disabled,
.setting-control button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-secondary,
.btn-danger {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
color: var(--text-color);
cursor: pointer;
transition: background-color 0.2s ease;
font-size: 0.9rem;
min-width: 120px;
}
.btn-secondary {
background-color: var(--sidebar-bg);
border: 1px solid var(--text-muted);
}
.btn-secondary:not(:disabled):hover {
background-color: rgba(255, 255, 255, 0.1);
}
.btn-danger {
background-color: var(--primary-red);
}
.btn-danger:not(:disabled):hover {
background-color: #d63030;
}
.coming-soon {
position: absolute;
right: -90px;
color: var(--text-muted);
font-size: 0.8rem;
font-style: italic;
}
.danger-zone {
border: 1px solid rgba(244, 63, 63, 0.3);
}

View File

@ -7,6 +7,7 @@
@import 'components/feed-entries.css'; @import 'components/feed-entries.css';
@import 'components/dropdown.css'; @import 'components/dropdown.css';
@import 'components/scrollbar.css'; @import 'components/scrollbar.css';
@import 'components/settings.css';
body { body {
margin: 0; margin: 0;

View File

@ -89,6 +89,11 @@ document.addEventListener('DOMContentLoaded', function() {
userMenuDropdown.classList.remove('show'); userMenuDropdown.classList.remove('show');
}); });
document.getElementById('settingsButton').addEventListener('click', () => {
window.location.href = '/settings';
userMenuDropdown.classList.remove('show');
});
document.getElementById('logoutButton').addEventListener('click', async () => { document.getElementById('logoutButton').addEventListener('click', async () => {
try { try {
const response = await fetch('/logout', { const response = await fetch('/logout', {

View File

@ -61,6 +61,7 @@
</button> </button>
<div class="user-menu-dropdown" id="userMenuDropdown"> <div class="user-menu-dropdown" id="userMenuDropdown">
<button class="user-menu-item" id="importOpmlButton">Import OPML</button> <button class="user-menu-item" id="importOpmlButton">Import OPML</button>
<button class="user-menu-item" id="settingsButton">Settings</button>
<button class="user-menu-item" id="logoutButton">Logout</button> <button class="user-menu-item" id="logoutButton">Logout</button>
</div> </div>
</div> </div>

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Settings - RSS Reader</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="settings-container">
<header class="settings-header">
<a href="/" class="back-button">
<i class="fas fa-arrow-left"></i>
Back to Feeds
</a>
<h1>Settings</h1>
</header>
<main class="settings-content">
<section class="settings-section">
<h2>
<i class="fas fa-rss"></i>
Feed Management
</h2>
<div class="settings-group">
<div class="setting-item">
<div class="setting-info">
<h3>Feed Refresh Interval</h3>
<p>How often to check feeds for new content</p>
</div>
<div class="setting-control">
<select disabled>
<option>Every 15 minutes</option>
<option>Every 30 minutes</option>
<option>Every hour</option>
</select>
<span class="coming-soon">Coming soon</span>
</div>
</div>
<div class="setting-item">
<div class="setting-info">
<h3>Default Feed Category</h3>
<p>Category to assign to new feeds when none is specified</p>
</div>
<div class="setting-control">
<input type="text" placeholder="Uncategorized" disabled>
<span class="coming-soon">Coming soon</span>
</div>
</div>
</div>
</section>
<section class="settings-section">
<h2>
<i class="fas fa-user-gear"></i>
User Management
</h2>
<div class="settings-group">
<div class="setting-item">
<div class="setting-info">
<h3>Change Password</h3>
<p>Update your login password</p>
</div>
<div class="setting-control">
<button class="btn-secondary" disabled>Change Password</button>
<span class="coming-soon">Coming soon</span>
</div>
</div>
<div class="setting-item">
<div class="setting-info">
<h3>Export Data</h3>
<p>Export your feeds and settings</p>
</div>
<div class="setting-control">
<button class="btn-secondary" disabled>Export</button>
<span class="coming-soon">Coming soon</span>
</div>
</div>
<div class="setting-item danger-zone">
<div class="setting-info">
<h3>Delete Account</h3>
<p>Permanently delete your account and all associated data</p>
</div>
<div class="setting-control">
<button class="btn-danger" disabled>Delete Account</button>
<span class="coming-soon">Coming soon</span>
</div>
</div>
</div>
</section>
</main>
</div>
</body>
</html>