mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-25 10:18:38 +02:00
feat signin form
This commit is contained in:
@@ -26,6 +26,7 @@ use zettle_db::{
|
||||
html::{
|
||||
index::index_handler,
|
||||
search_result::search_result_handler,
|
||||
signin::{authenticate_user, show_signin_form},
|
||||
signout::sign_out_user,
|
||||
signup::{process_signup_and_show_verification, show_signup_form},
|
||||
},
|
||||
@@ -149,6 +150,7 @@ fn html_routes(
|
||||
.route("/", get(index_handler))
|
||||
.route("/search", get(search_result_handler))
|
||||
.route("/signout", get(sign_out_user))
|
||||
.route("/signin", get(show_signin_form).post(authenticate_user))
|
||||
.route(
|
||||
"/signup",
|
||||
get(show_signup_form).post(process_signup_and_show_verification),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::{StatusCode, Uri},
|
||||
response::{IntoResponse, Redirect},
|
||||
Form,
|
||||
};
|
||||
use axum_htmx::HxBoosted;
|
||||
use axum_htmx::{HxBoosted, HxRedirect};
|
||||
use axum_session_auth::AuthSession;
|
||||
use axum_session_surreal::SessionSurrealPool;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -17,6 +18,7 @@ use super::{render_block, render_template};
|
||||
pub struct SignupParams {
|
||||
pub email: String,
|
||||
pub password: String,
|
||||
pub remember_me: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -24,7 +26,7 @@ struct PageData {
|
||||
// name: String,
|
||||
}
|
||||
|
||||
pub async fn show_login_form(
|
||||
pub async fn show_signin_form(
|
||||
State(state): State<AppState>,
|
||||
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
||||
HxBoosted(boosted): HxBoosted,
|
||||
@@ -34,12 +36,12 @@ pub async fn show_login_form(
|
||||
}
|
||||
let output = match boosted {
|
||||
true => render_block(
|
||||
"auth/signup_form.html",
|
||||
"auth/signin_form.html",
|
||||
"body",
|
||||
PageData {},
|
||||
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())
|
||||
@@ -50,7 +52,13 @@ pub async fn authenticate_user(
|
||||
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
|
||||
Form(form): Form<SignupParams>,
|
||||
) -> 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);
|
||||
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