Login & add feed form progressive enhancement

This commit is contained in:
Tyler Hallada 2023-12-16 01:03:04 -05:00
parent ea4784ff07
commit 5881412b59
5 changed files with 49 additions and 9 deletions

Binary file not shown.

View File

@ -1,5 +1,3 @@
#!/usr/bin/env just --justfile
build: build-frontend build: build-frontend
cargo build --release cargo build --release

View File

@ -1,6 +1,7 @@
use axum::response::{IntoResponse, Response}; use axum::response::{IntoResponse, Response};
use axum::TypedHeader; use axum::TypedHeader;
use axum::{extract::State, Form}; use axum::{extract::State, Form};
use http::HeaderValue;
use maud::html; use maud::html;
use serde::Deserialize; use serde::Deserialize;
use serde_with::serde_as; use serde_with::serde_as;
@ -9,7 +10,7 @@ use tracing::info;
use crate::auth::verify_password; use crate::auth::verify_password;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::htmx::{HXRedirect, HXTarget, HXRequest}; use crate::htmx::{HXRedirect, HXRequest, HXTarget};
use crate::partials::login_form::{login_form, LoginFormProps}; use crate::partials::login_form::{login_form, LoginFormProps};
use crate::{ use crate::{
models::user::{AuthContext, User}, models::user::{AuthContext, User},
@ -28,6 +29,11 @@ pub fn login_page(
layout: Layout, layout: Layout,
form_props: LoginFormProps, form_props: LoginFormProps,
) -> Response { ) -> Response {
if let Some(hx_target) = &hx_target {
if hx_target.target == HeaderValue::from_static("login-form") {
return login_form(form_props).into_response();
}
}
layout layout
.with_subtitle("login") .with_subtitle("login")
.targeted(hx_target) .targeted(hx_target)

View File

@ -2,10 +2,23 @@ use maud::{html, Markup};
pub fn add_feed_form() -> Markup { pub fn add_feed_form() -> Markup {
html! { html! {
form hx-post="/feed" hx-swap="outerHTML" class="feed-form" { form
action="/feed"
method="post"
id="add-feed-form"
hx-post="/feed"
hx-target="#add-feed-form"
hx-swap="outerHTML"
class="feed-form"
{
div class="form-grid" { div class="form-grid" {
label for="url" { "URL: " } label for="url" { "URL: " }
input type="text" id="url" name="url" placeholder="https://example.com/feed.xml" required="true"; input
type="text"
id="url"
name="url"
placeholder="https://example.com/feed.xml"
required="true";
button type="submit" { "Add Feed" } button type="submit" { "Add Feed" }
} }
} }

View File

@ -16,14 +16,35 @@ pub fn login_form(props: LoginFormProps) -> Markup {
general_error, general_error,
} = props; } = props;
html! { html! {
form action="/login" method="post" class="auth-form-grid" { form
action="/login"
method="post"
hx-post="/login"
hx-target="#login-form"
hx-swap="outerHTML"
id="login-form"
class="auth-form-grid"
{
label for="email" { "Email" } label for="email" { "Email" }
input type="email" name="email" id="email" placeholder="Email" value=(email.unwrap_or_default()) required; input
type="email"
name="email"
id="email"
placeholder="Email"
value=(email.unwrap_or_default())
required;
@if let Some(email_error) = email_error { @if let Some(email_error) = email_error {
span class="error" { (email_error) } span class="error" { (email_error) }
} }
label for="email" { "Password" } label for="email" { "Password" }
input type="password" name="password" id="password" placeholder="Password" minlength="8" maxlength="255" required; input
type="password"
name="password"
id="password"
placeholder="Password"
minlength="8"
maxlength="255"
required;
@if let Some(password_error) = password_error { @if let Some(password_error) = password_error {
span class="error" { (password_error) } span class="error" { (password_error) }
} }
@ -31,7 +52,9 @@ pub fn login_form(props: LoginFormProps) -> Markup {
@if let Some(general_error) = general_error { @if let Some(general_error) = general_error {
span class="error" { (general_error) } span class="error" { (general_error) }
} }
a href="/forgot-password" class="forgot-password" { "Forgot password" } a href="/forgot-password" hx-target="#main-content" hx-swap="unset" class="forgot-password" {
"Forgot password"
}
} }
} }
} }