mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-23 09:18:36 +02:00
feat signin form
This commit is contained in:
@@ -26,6 +26,7 @@ use zettle_db::{
|
|||||||
html::{
|
html::{
|
||||||
index::index_handler,
|
index::index_handler,
|
||||||
search_result::search_result_handler,
|
search_result::search_result_handler,
|
||||||
|
signin::{authenticate_user, show_signin_form},
|
||||||
signout::sign_out_user,
|
signout::sign_out_user,
|
||||||
signup::{process_signup_and_show_verification, show_signup_form},
|
signup::{process_signup_and_show_verification, show_signup_form},
|
||||||
},
|
},
|
||||||
@@ -149,6 +150,7 @@ fn html_routes(
|
|||||||
.route("/", get(index_handler))
|
.route("/", get(index_handler))
|
||||||
.route("/search", get(search_result_handler))
|
.route("/search", get(search_result_handler))
|
||||||
.route("/signout", get(sign_out_user))
|
.route("/signout", get(sign_out_user))
|
||||||
|
.route("/signin", get(show_signin_form).post(authenticate_user))
|
||||||
.route(
|
.route(
|
||||||
"/signup",
|
"/signup",
|
||||||
get(show_signup_form).post(process_signup_and_show_verification),
|
get(show_signup_form).post(process_signup_and_show_verification),
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
|
http::{StatusCode, Uri},
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
Form,
|
Form,
|
||||||
};
|
};
|
||||||
use axum_htmx::HxBoosted;
|
use axum_htmx::{HxBoosted, HxRedirect};
|
||||||
use axum_session_auth::AuthSession;
|
use axum_session_auth::AuthSession;
|
||||||
use axum_session_surreal::SessionSurrealPool;
|
use axum_session_surreal::SessionSurrealPool;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -17,6 +18,7 @@ use super::{render_block, render_template};
|
|||||||
pub struct SignupParams {
|
pub struct SignupParams {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
pub remember_me: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@@ -24,7 +26,7 @@ struct PageData {
|
|||||||
// name: String,
|
// name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn show_login_form(
|
pub async fn show_signin_form(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
||||||
HxBoosted(boosted): HxBoosted,
|
HxBoosted(boosted): HxBoosted,
|
||||||
@@ -34,12 +36,12 @@ pub async fn show_login_form(
|
|||||||
}
|
}
|
||||||
let output = match boosted {
|
let output = match boosted {
|
||||||
true => render_block(
|
true => render_block(
|
||||||
"auth/signup_form.html",
|
"auth/signin_form.html",
|
||||||
"body",
|
"body",
|
||||||
PageData {},
|
PageData {},
|
||||||
state.templates,
|
state.templates,
|
||||||
)?,
|
)?,
|
||||||
false => render_template("auth/signup_form.html", PageData {}, state.templates)?,
|
false => render_template("auth/signin_form.html", PageData {}, state.templates)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(output.into_response())
|
Ok(output.into_response())
|
||||||
@@ -50,7 +52,13 @@ pub async fn authenticate_user(
|
|||||||
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
||||||
Form(form): Form<SignupParams>,
|
Form(form): Form<SignupParams>,
|
||||||
) -> Result<impl IntoResponse, ApiError> {
|
) -> Result<impl IntoResponse, ApiError> {
|
||||||
let user = User::create_new(form.email, form.password, &state.surreal_db_client).await?;
|
let user = User::authenticate(form.email, form.password, &state.surreal_db_client).await?;
|
||||||
auth.login_user(user.id);
|
auth.login_user(user.id);
|
||||||
Ok(())
|
if form
|
||||||
|
.remember_me
|
||||||
|
.is_some_and(|string| string == "on".to_string())
|
||||||
|
{
|
||||||
|
auth.remember_user(true);
|
||||||
|
}
|
||||||
|
Ok((HxRedirect::from(Uri::from_static("/")), StatusCode::OK).into_response())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
{% block content %}
|
|
||||||
<div class="max-w-md mx-auto">
|
|
||||||
<h2 class="text-2xl font-bold text-center mb-8">Sign in to your account</h2>
|
|
||||||
|
|
||||||
<form hx-post="/signin" hx-target="#signin-result" hx-indicator="#spinner" class="space-y-6">
|
|
||||||
<div class="form-control">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text">Email</span>
|
|
||||||
</label>
|
|
||||||
<input type="email" name="email" placeholder="Enter your email" class="input input-bordered w-full" required
|
|
||||||
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text">Password</span>
|
|
||||||
</label>
|
|
||||||
<input type="password" name="password" placeholder="Enter your password" class="input input-bordered w-full"
|
|
||||||
required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<label class="label cursor-pointer">
|
|
||||||
<input type="checkbox" name="remember" class="checkbox checkbox-primary checkbox-sm mr-2" />
|
|
||||||
<span class="label-text">Remember me</span>
|
|
||||||
</label>
|
|
||||||
<a href="/forgot-password" class="link link-primary text-sm">Forgot password?</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control mt-6">
|
|
||||||
<button class="btn btn-primary w-full">
|
|
||||||
Sign in
|
|
||||||
<span id="spinner" class="loading loading-spinner text-primary htmx-indicator"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="signin-result"></div>
|
|
||||||
|
|
||||||
<div class="divider">OR</div>
|
|
||||||
|
|
||||||
<div class="text-center text-sm">
|
|
||||||
Don't have an account?
|
|
||||||
<a href="/signup" class="link link-primary">Create one</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
45
templates/auth/signin_form.html
Normal file
45
templates/auth/signin_form.html
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{% extends "head_base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<style>
|
||||||
|
form.htmx-request {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="min-h-screen grid place-items-center place-content-center">
|
||||||
|
<div class="max-w-lg mx-auto">
|
||||||
|
<h2 class="text-2xl font-bold text-center mb-8">Login to your account</h2>
|
||||||
|
<form hx-post="/signin">
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label">
|
||||||
|
<span class="label-text">Email</span>
|
||||||
|
</label>
|
||||||
|
<input type="email" name="email" placeholder="Enter your email" class="input input-bordered w-full" required />
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label">
|
||||||
|
<span class="label-text">Password</span>
|
||||||
|
</label>
|
||||||
|
<input type="password" name="password" placeholder="Enter your password" class="input input-bordered w-full"
|
||||||
|
required minlength="8" />
|
||||||
|
</div>
|
||||||
|
<div class="form-control mt-4">
|
||||||
|
<label class="label cursor-pointer justify-start gap-2">
|
||||||
|
<input type="checkbox" name="remember_me" class="checkbox checkbox-primary" />
|
||||||
|
<span class="label-text">Remember me</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-control mt-6">
|
||||||
|
<button id="submit-btn" class="btn btn-primary w-full">
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="login-result"></div>
|
||||||
|
</form>
|
||||||
|
<div class="divider">OR</div>
|
||||||
|
<div class="text-center text-sm">
|
||||||
|
Don't have an account?
|
||||||
|
<a href="/signup" class="link link-primary">Sign up</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user