Use persistant_fields

This commit is contained in:
Mo 2023-02-23 20:19:20 +01:00
parent 2143da1766
commit 45f664bf9c
4 changed files with 38 additions and 36 deletions

View file

@ -1,13 +1,21 @@
use serde::Deserialize; use serde::Deserialize;
/// Fields of the contact form that persist after a redirection
/// (example after failed server side validation).
#[derive(Deserialize, Default)]
pub struct PersistantContactFormFields {
pub name: String,
pub email: String,
pub telefon: String,
pub message: String,
}
/// The contact form. /// The contact form.
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct ContactForm { pub struct ContactForm {
/// The id for the captcha. /// The id for the captcha.
pub id: u16, pub id: u16,
pub name: String, #[serde(flatten)]
pub email: String, pub persistant_fields: PersistantContactFormFields,
pub telefon: String,
pub message: String,
pub captcha_answer: String, pub captcha_answer: String,
} }

View file

@ -8,18 +8,19 @@ use std::sync::{Arc, Mutex};
use tracing::{error, info}; use tracing::{error, info};
use crate::{ use crate::{
captcha_solutions::CaptchaSolutions, config::Config, errors::AppError, forms::ContactForm, captcha_solutions::CaptchaSolutions,
mailer::Mailer, templates, config::Config,
errors::AppError,
forms::{ContactForm, PersistantContactFormFields},
mailer::Mailer,
templates,
}; };
pub struct IndexParams<'a> { pub struct ContactFormParams<'a> {
config: Arc<Config>, config: Arc<Config>,
captcha_solutions: Arc<Mutex<CaptchaSolutions>>, captcha_solutions: Arc<Mutex<CaptchaSolutions>>,
was_validated: bool, was_validated: bool,
name: Option<String>, persistant_fields: Option<PersistantContactFormFields>,
email: Option<String>,
telefon: Option<String>,
message: Option<String>,
error_message: Option<&'a str>, error_message: Option<&'a str>,
} }
@ -29,20 +30,17 @@ pub async fn index(
) -> Result<Response, AppError> { ) -> Result<Response, AppError> {
info!("Visited get(index)"); info!("Visited get(index)");
render_contact_form(IndexParams { render_contact_form(ContactFormParams {
config, config,
captcha_solutions, captcha_solutions,
was_validated: false, was_validated: false,
name: None, persistant_fields: None,
email: None,
telefon: None,
message: None,
error_message: None, error_message: None,
}) })
.await .await
} }
pub async fn render_contact_form(params: IndexParams<'_>) -> Result<Response, AppError> { pub async fn render_contact_form(params: ContactFormParams<'_>) -> Result<Response, AppError> {
let captcha = captcha::by_name(captcha::Difficulty::Easy, captcha::CaptchaName::Lucy); let captcha = captcha::by_name(captcha::Difficulty::Easy, captcha::CaptchaName::Lucy);
let captcha_base64 = captcha.as_base64().context("Failed to create a captcha!")?; let captcha_base64 = captcha.as_base64().context("Failed to create a captcha!")?;
@ -57,10 +55,7 @@ pub async fn render_contact_form(params: IndexParams<'_>) -> Result<Response, Ap
}, },
was_validated: params.was_validated, was_validated: params.was_validated,
id, id,
name: params.name.unwrap_or_default(), persistant_fields: params.persistant_fields.unwrap_or_default(),
email: params.email.unwrap_or_default(),
telefon: params.telefon.unwrap_or_default(),
message: params.message.unwrap_or_default(),
captcha: captcha_base64, captcha: captcha_base64,
error_message: params.error_message.unwrap_or_default(), error_message: params.error_message.unwrap_or_default(),
strings: &params.config.strings, strings: &params.config.strings,
@ -75,14 +70,11 @@ async fn failed_submission(
error_message: &str, error_message: &str,
form: ContactForm, form: ContactForm,
) -> Result<Response, AppError> { ) -> Result<Response, AppError> {
let params = IndexParams { let params = ContactFormParams {
config, config,
captcha_solutions, captcha_solutions,
was_validated: true, was_validated: true,
name: Some(form.name), persistant_fields: Some(form.persistant_fields),
email: Some(form.email),
telefon: Some(form.telefon),
message: Some(form.message),
error_message: Some(error_message), error_message: Some(error_message),
}; };
@ -113,7 +105,12 @@ pub async fn submit(
} }
match mailer match mailer
.send(&form.name, &form.email, &form.telefon, &form.message) .send(
&form.persistant_fields.name,
&form.persistant_fields.email,
&form.persistant_fields.telefon,
&form.persistant_fields.message,
)
.await .await
{ {
Ok(_) => (), Ok(_) => (),

View file

@ -1,6 +1,6 @@
use askama::Template; use askama::Template;
use crate::config; use crate::{config, forms::PersistantContactFormFields};
pub struct Base<'a> { pub struct Base<'a> {
pub lang: &'a str, pub lang: &'a str,
@ -13,10 +13,7 @@ pub struct ContactForm<'a> {
pub base: Base<'a>, pub base: Base<'a>,
pub was_validated: bool, pub was_validated: bool,
pub id: u16, pub id: u16,
pub name: String, pub persistant_fields: PersistantContactFormFields,
pub email: String,
pub telefon: String,
pub message: String,
pub captcha: String, pub captcha: String,
pub error_message: &'a str, pub error_message: &'a str,
pub strings: &'a config::Strings, pub strings: &'a config::Strings,

View file

@ -16,7 +16,7 @@
<label for="name" class="form-label">{{ strings.name_field.label }}</label> <label for="name" class="form-label">{{ strings.name_field.label }}</label>
<input type="text" <input type="text"
name="name" name="name"
value="{{ name }}" value="{{ persistant_fields.name }}"
class="form-control" class="form-control"
id="exampleInputEmail1" id="exampleInputEmail1"
required> required>
@ -26,7 +26,7 @@
<label for="email" class="form-label">{{ strings.email_field.label }}</label> <label for="email" class="form-label">{{ strings.email_field.label }}</label>
<input type="email" <input type="email"
name="email" name="email"
value="{{ email }}" value="{{ persistant_fields.email }}"
class="form-control" class="form-control"
id="email" id="email"
required> required>
@ -36,7 +36,7 @@
<label for="telefon" class="form-label">{{ strings.telefon_field_label }}</label> <label for="telefon" class="form-label">{{ strings.telefon_field_label }}</label>
<input type="text" <input type="text"
name="telefon" name="telefon"
value="{{ telefon }}" value="{{ persistant_fields.telefon }}"
class="form-control" class="form-control"
id="telefon"> id="telefon">
</div> </div>
@ -47,7 +47,7 @@
class="form-control" class="form-control"
id="message" id="message"
style="resize: none" style="resize: none"
required>{{ message }}</textarea> required>{{ persistant_fields.message }}</textarea>
<div class="invalid-feedback">{{ strings.message_field.invalid_feedback }}</div> <div class="invalid-feedback">{{ strings.message_field.invalid_feedback }}</div>
</div> </div>