Add a login button

This commit is contained in:
Nettika 2026-01-25 17:09:52 -08:00
parent dc167fd8a0
commit 5e28192a64
No known key found for this signature in database
2 changed files with 19 additions and 5 deletions

View file

@ -15,7 +15,7 @@
[x] Add a rouille::session manager to set a session cookie. [x] Add a rouille::session manager to set a session cookie.
[x] Create a `POST /login` endpoint that validates credentials against USERNAME and PASSWORD environment variables. [x] Create a `POST /login` endpoint that validates credentials against USERNAME and PASSWORD environment variables.
[x] Protect write endpoints (POST /projects, and any future write operations) with authentication. Redirect to /login if not authenticated. [x] Protect write endpoints (POST /projects, and any future write operations) with authentication. Redirect to /login if not authenticated.
[ ] Add a login button to the front page (GET /projects) that links to /login. [x] Add a login button to the front page (GET /projects) that links to /login.
[ ] When logged in, show a "Create Project" button on the front page that links to /new-project. [x] When logged in, show a "Create Project" button on the front page that links to /new-project.
[ ] When logged in, add an edit icon to each project-card web component. Clicking the icon opens a dialog with a form to update the progress percentage and archive/unarchive the project. [ ] When logged in, add an edit icon to each project-card web component. Clicking the icon opens a dialog with a form to update the progress percentage and archive/unarchive the project.
[ ] Create POST endpoints for updating project progress and archiving/unarchiving projects (these will be called from the edit dialog). [ ] Create POST endpoints for updating project progress and archiving/unarchiving projects (these will be called from the edit dialog).

View file

@ -34,7 +34,7 @@ fn main() {
let js = include_bytes!("project-card.js"); let js = include_bytes!("project-card.js");
rouille::Response::from_data("application/javascript", js.as_ref()) rouille::Response::from_data("application/javascript", js.as_ref())
}, },
(GET) ["/projects"] => display_projects(), (GET) ["/projects"] => display_projects(session, &authenticated_sessions),
(GET) ["/new-project"] => { (GET) ["/new-project"] => {
if is_authenticated(session, &authenticated_sessions) { if is_authenticated(session, &authenticated_sessions) {
new_project_form() new_project_form()
@ -57,15 +57,22 @@ fn main() {
}); });
} }
fn is_authenticated(session: &session::Session, authenticated_sessions: &Mutex<HashSet<String>>) -> bool { fn is_authenticated(
session: &session::Session,
authenticated_sessions: &Mutex<HashSet<String>>,
) -> bool {
authenticated_sessions authenticated_sessions
.lock() .lock()
.map(|sessions| sessions.contains(session.id())) .map(|sessions| sessions.contains(session.id()))
.unwrap_or(false) .unwrap_or(false)
} }
fn display_projects() -> rouille::Response { fn display_projects(
session: &session::Session,
authenticated_sessions: &Mutex<HashSet<String>>,
) -> rouille::Response {
let projects = db::list_all_projects().unwrap_or_default(); let projects = db::list_all_projects().unwrap_or_default();
let is_logged_in = is_authenticated(session, authenticated_sessions);
let now = std::time::SystemTime::now() let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH) .duration_since(std::time::UNIX_EPOCH)
@ -93,6 +100,13 @@ fn display_projects() -> rouille::Response {
} }
body { body {
main { main {
nav {
@if is_logged_in {
a href="/new-project" { strong { "Create Project" } }
} @else {
a href="/login" { strong { "Login" } }
}
}
section { section {
@for project in &active_projects { @for project in &active_projects {
project-card project-card